Imported Upstream version 0.9.2 upstream/0.9.2
authorYoungjae Shin <yj99.shin@samsung.com>
Mon, 31 Aug 2015 05:35:18 +0000 (14:35 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Mon, 31 Aug 2015 05:35:18 +0000 (14:35 +0900)
771 files changed:
.gitignore
NOTICE.md
Readme.scons.txt
android/BuildInstructionsForAndroidAPI.txt
android/android_api/base/base.iml
android/android_api/base/jni/Android.mk
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcPlatform.h
android/android_api/base/jni/JniOcRepresentation.cpp
android/android_api/base/jni/JniOcRepresentation.h
android/android_api/base/jni/JniOcSecurity.cpp [new file with mode: 0644]
android/android_api/base/jni/JniOcSecurity.h [new file with mode: 0644]
android/android_api/base/jni/JniOnPlatformInfoListener.cpp [new file with mode: 0644]
android/android_api/base/jni/JniOnPlatformInfoListener.h [new file with mode: 0644]
android/android_api/base/jni/JniUtils.cpp
android/android_api/base/jni/JniUtils.h
android/android_api/base/src/androidTest/java/org/iotivity/base/OcRepresentationTest.java
android/android_api/base/src/androidTest/java/org/iotivity/base/SmokeTest.java
android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java
android/android_api/base/src/main/java/org/iotivity/base/OcConnectivityType.java
android/android_api/base/src/main/java/org/iotivity/base/OcDeviceInfo.java
android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java
android/android_api/base/src/main/java/org/iotivity/base/OcPlatformInfo.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/base/OcRepresentation.java
android/android_api/base/src/main/java/org/iotivity/base/OcResource.java
android/android_api/base/src/main/java/org/iotivity/base/OcStackConfig.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/base/ResourceProperty.java
android/android_api/base/src/main/java/org/iotivity/ca/CaEdrInterface.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/ca/CaLeServerInterface.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java [deleted file]
android/examples/fridgeclient/src/main/AndroidManifest.xml
android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/FridgeClient.java
android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/StringConstants.java
android/examples/fridgeserver/src/main/AndroidManifest.xml
android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DeviceResource.java
android/examples/guiclient/.gitignore [new file with mode: 0644]
android/examples/guiclient/build.gradle [new file with mode: 0644]
android/examples/guiclient/guiclient.iml [new file with mode: 0644]
android/examples/guiclient/proguard-rules.pro [moved from resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt with 62% similarity]
android/examples/guiclient/src/main/AndroidManifest.xml [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/ExpandableResourceListAdapter.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/MainActivity.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcAttributeInfo.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcProtocolStrings.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcResourceInfo.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorker.java [new file with mode: 0644]
android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorkerListener.java [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/android_resource_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/attribute_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/ic_action_discard.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/ic_action_discard_dark.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/ic_action_refresh.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/iotivity_hex_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/led_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/light_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/drawable/thermometer_icon.png [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/actionbar_indeterminate_progress.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/activity_main.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/attribute_layout_on_off_switch.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/attribute_layout_progress_bar.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/attribute_layout_slider.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/layout/resource_list_item_layout.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/menu/menu_main.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values-large/refs.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values-sw600dp/refs.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values-w820dp/dimens.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values/dimens.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values/refs.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values/strings.xml [new file with mode: 0644]
android/examples/guiclient/src/main/res/values/styles.xml [new file with mode: 0644]
android/examples/settings.gradle
android/examples/simpleclient/src/main/AndroidManifest.xml
android/examples/simpleclient/src/main/assets/oic_svr_db_client.json [new file with mode: 0755]
android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/SimpleClient.java
android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/StringConstants.java
android/examples/simpleserver/src/main/AndroidManifest.xml
android/examples/simpleserver/src/main/assets/oic_svr_db_server.json [new file with mode: 0755]
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightResource.java
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/SimpleServer.java
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/StringConstants.java
arduino.scons
auto_build.sh
build_common/SConscript
build_common/android/SConscript
build_common/arduino/SConscript
build_common/darwin/SConscript
build_common/external_libs.scons
build_common/tizen/SConscript
build_docs.sh [new file with mode: 0755]
examples/OICMiddle/Client.cpp
examples/OICMiddle/LineInput.cpp
examples/OICMiddle/OICMiddle.cpp
examples/OICMiddle/OICMiddle.h
examples/OICMiddle/RestInput.cpp
examples/OICMiddle/RestInput.h
examples/OICMiddle/SConstruct [deleted file]
examples/OICMiddle/WrapResource.cpp
examples/OICSensorBoard/Makefile [new file with mode: 0644]
examples/OICSensorBoard/OICSensorBoardREADME.pdf [deleted file]
examples/OICSensorBoard/README [new file with mode: 0644]
examples/OICSensorBoard/SConstruct [deleted file]
examples/OICSensorBoard/client.cpp
examples/OICSensorBoard/sensors.h
examples/OICSensorBoard/server.cpp
extlibs/android/sdk/SConscript
extlibs/arduino/SConscript
extlibs/boost/SConscript
extlibs/buildDependencies.sh
extlibs/cereal/SConscript [deleted file]
extlibs/gtest/SConscript
extlibs/raxmpp/SConscript [new file with mode: 0644]
extlibs/tinycbor/SConscript [new file with mode: 0644]
extlibs/tinydtls/0001-Added-anonymous-ecdh-cipher-suite-into-tinydtls.patch [new file with mode: 0644]
extlibs/tinydtls/SConscript
extlibs/tinydtls/aes/rijndael.h
extlibs/tinydtls/crypto.c
extlibs/tinydtls/crypto.h
extlibs/tinydtls/dtls.c
extlibs/tinydtls/dtls.h
extlibs/tinydtls/ecc/Makefile.contiki [changed mode: 0644->0755]
extlibs/tinydtls/ecc/Makefile.ecc [changed mode: 0644->0755]
extlibs/tinydtls/ecc/test_helper.c [deleted file]
extlibs/tinydtls/ecc/test_helper.h [deleted file]
extlibs/tinydtls/ecc/testecc.c [deleted file]
extlibs/tinydtls/ecc/testfield.c [deleted file]
extlibs/tinydtls/global.h
extlibs/tinydtls/tests/dtls-client.c
extlibs/tinydtls/tests/dtls-server.c
extlibs/tinydtls/tinydtls.h
extlibs/tinydtls/uthash.h
extlibs/tinydtls/utlist.h
extra_options.scons
gbsbuild.sh
resource/SConscript
resource/android/SConscript
resource/c_common/SConscript [new file with mode: 0644]
resource/c_common/oic_malloc/include/oic_malloc.h [moved from resource/csdk/connectivity/common/inc/oic_malloc.h with 78% similarity]
resource/c_common/oic_malloc/src/oic_malloc.c [moved from resource/csdk/connectivity/common/src/oic_malloc.c with 88% similarity]
resource/c_common/oic_malloc/test/SConscript [new file with mode: 0644]
resource/c_common/oic_malloc/test/linux/oic_malloc_tests.cpp [moved from resource/csdk/ocmalloc/test/linux/unittest.cpp with 69% similarity]
resource/c_common/oic_string/include/oic_string.h [new file with mode: 0644]
resource/c_common/oic_string/src/oic_string.c [new file with mode: 0644]
resource/c_common/oic_string/test/SConscript [new file with mode: 0644]
resource/c_common/oic_string/test/linux/oic_string_tests.cpp [new file with mode: 0644]
resource/csdk/SConscript
resource/csdk/connectivity/SConscript
resource/csdk/connectivity/SConstruct [deleted file]
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/build/How_To_Build.txt
resource/csdk/connectivity/build/SConscript
resource/csdk/connectivity/build/android/SConscript
resource/csdk/connectivity/build/android/jni/Android.mk
resource/csdk/connectivity/build/arduino/arduinomega.properties
resource/csdk/connectivity/build/common.mk [deleted file]
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/caremotehandler.h [moved from resource/csdk/connectivity/inc/caremotehandler.h with 66% similarity]
resource/csdk/connectivity/common/inc/logger.h
resource/csdk/connectivity/common/inc/uarraylist.h
resource/csdk/connectivity/common/src/camutex_noop.c [new file with mode: 0644]
resource/csdk/connectivity/common/src/caremotehandler.c [new file with mode: 0644]
resource/csdk/connectivity/common/src/logger.c
resource/csdk/connectivity/common/src/oic_logger.c
resource/csdk/connectivity/common/src/uarraylist.c
resource/csdk/connectivity/common/src/uqueue.c
resource/csdk/connectivity/inc/caadapterinterface.h
resource/csdk/connectivity/inc/caadapternetdtls.h
resource/csdk/connectivity/inc/caadapterutils.h
resource/csdk/connectivity/inc/caedradapter.h
resource/csdk/connectivity/inc/caedradapter_singlethread.h
resource/csdk/connectivity/inc/caedrinterface.h
resource/csdk/connectivity/inc/cafragmentation.h [moved from resource/csdk/connectivity/inc/camsgparser.h with 72% similarity]
resource/csdk/connectivity/inc/cainterfacecontroller.h
resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h
resource/csdk/connectivity/inc/caipadapter.h
resource/csdk/connectivity/inc/caipadapter_singlethread.h [deleted file]
resource/csdk/connectivity/inc/caipinterface.h
resource/csdk/connectivity/inc/caipinterface_singlethread.h [deleted file]
resource/csdk/connectivity/inc/caleadapter.h
resource/csdk/connectivity/inc/caleadapter_singlethread.h [deleted file]
resource/csdk/connectivity/inc/caleinterface.h
resource/csdk/connectivity/inc/caleinterface_singlethread.h [deleted file]
resource/csdk/connectivity/inc/camessagehandler.h
resource/csdk/connectivity/inc/camessagehandler_singlethread.h
resource/csdk/connectivity/inc/canetworkconfigurator.h
resource/csdk/connectivity/inc/caprotocolmessage.h
resource/csdk/connectivity/inc/caraadapter.h [new file with mode: 0644]
resource/csdk/connectivity/inc/caretransmission.h
resource/csdk/connectivity/inc/caretransmission_singlethread.h [deleted file]
resource/csdk/connectivity/inc/ifaddrs.h [new file with mode: 0644]
resource/csdk/connectivity/lib/libcoap-4.1.1/SConscript
resource/csdk/connectivity/lib/libcoap-4.1.1/config.h
resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c
resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c
resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h
resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c
resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h
resource/csdk/connectivity/samples/android/SConscript
resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml
resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk
resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c
resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_ca_service_RMInterface.h [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h [deleted file]
resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml
resource/csdk/connectivity/samples/android/sample_service/res/menu/main.xml
resource/csdk/connectivity/samples/android/sample_service/res/values/strings.xml
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaEdrInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaIpInterface.java
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeClientInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeServerInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/service/DLog.java [moved from resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/service/DLog.java with 95% similarity]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/service/MainActivity.java [moved from resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/service/MainActivity.java with 78% similarity]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/service/RMInterface.java [moved from resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/service/RMInterface.java with 89% similarity]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/CALeInterface.java [deleted file]
resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/caipinterface.java [deleted file]
resource/csdk/connectivity/samples/arduino/SConscript
resource/csdk/connectivity/samples/arduino/casample.cpp
resource/csdk/connectivity/samples/linux/README
resource/csdk/connectivity/samples/linux/SConscript [changed mode: 0644->0755]
resource/csdk/connectivity/samples/linux/sample.sh [deleted file]
resource/csdk/connectivity/samples/linux/sample_main.c
resource/csdk/connectivity/samples/tizen/SConscript
resource/csdk/connectivity/samples/tizen/casample.c
resource/csdk/connectivity/samples/tizen/packaging/com.oic.ca.sample.spec
resource/csdk/connectivity/samples/tizen/scons/SConscript
resource/csdk/connectivity/src/SConscript [changed mode: 0644->0755]
resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
resource/csdk/connectivity/src/adapter_util/caadapterutils.c
resource/csdk/connectivity/src/adapter_util/cafragmentation.c [moved from resource/csdk/connectivity/src/adapter_util/camsgparser.c with 70% similarity]
resource/csdk/connectivity/src/adapter_util/ifaddrs.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_edr_adapter/SConscript
resource/csdk/connectivity/src/bt_edr_adapter/android/SConscript [new file with mode: 0644]
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/android/org_iotivity_ca_CaEdrInterface.h [moved from resource/csdk/connectivity/common/inc/oic_string.h with 56% similarity]
resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h [deleted file]
resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c
resource/csdk/connectivity/src/bt_edr_adapter/linux/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/SConscript [new file with mode: 0644]
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/caedrnwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/SConscript
resource/csdk/connectivity/src/bt_le_adapter/android/SConscript [new file with mode: 0644]
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/caleutils.h
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeClientInterface.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeServerInterface.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/arduino/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/arduino/cableclient.cpp [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/arduino/cablenwmonitor.cpp
resource/csdk/connectivity/src/bt_le_adapter/arduino/cableserver.cpp
resource/csdk/connectivity/src/bt_le_adapter/arduino/cableserver.h
resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c
resource/csdk/connectivity/src/bt_le_adapter/caleadapter_singlethread.c [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/linux/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableutil.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableutil.h
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c [deleted file]
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c [deleted file]
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/camessagehandler_singlethread.c
resource/csdk/connectivity/src/canetworkconfigurator.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/src/caqueueingthread.c
resource/csdk/connectivity/src/caremotehandler.c [deleted file]
resource/csdk/connectivity/src/caretransmission.c
resource/csdk/connectivity/src/caretransmission_singlethread.c [deleted file]
resource/csdk/connectivity/src/ip_adapter/SConscript
resource/csdk/connectivity/src/ip_adapter/android/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/android/org_iotivity_ca_CaIpInterface.h
resource/csdk/connectivity/src/ip_adapter/arduino/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/arduino/caipadapterutils_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipadapterutils_eth.h
resource/csdk/connectivity/src/ip_adapter/arduino/caipclient_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipclient_wifi.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor.cpp [deleted file]
resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_eth.cpp [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_wifi.cpp [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/arduino/caipserver_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipserver_wifi.cpp
resource/csdk/connectivity/src/ip_adapter/caipadapter.c
resource/csdk/connectivity/src/ip_adapter/caipadapter_singlethread.c [deleted file]
resource/csdk/connectivity/src/ip_adapter/caipclient.c [deleted file]
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/tizen/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c
resource/csdk/connectivity/src/ra_adapter/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ra_adapter/caraadapter.c [new file with mode: 0644]
resource/csdk/connectivity/test/SConscript
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/connectivity/test/caprotocolmessagetest.cpp
resource/csdk/doc/Doxyfile
resource/csdk/logger/src/logger.c
resource/csdk/ocmalloc/include/ocmalloc.h [deleted file]
resource/csdk/ocmalloc/src/ocmalloc.c [deleted file]
resource/csdk/ocmalloc/test/linux/README [deleted file]
resource/csdk/ocrandom/include/ocrandom.h
resource/csdk/ocrandom/test/SConscript
resource/csdk/ocrandom/test/android/randomtest.cpp
resource/csdk/ocrandom/test/arduino/randomtest.cpp
resource/csdk/ocrandom/test/linux/randomtest.cpp
resource/csdk/security/README-building-and-running-secure-IoTivity-stack.txt [new file with mode: 0644]
resource/csdk/security/SConscript [new file with mode: 0644]
resource/csdk/security/include/base64.h [new file with mode: 0644]
resource/csdk/security/include/internal/aclresource.h [new file with mode: 0755]
resource/csdk/security/include/internal/credresource.h [new file with mode: 0644]
resource/csdk/security/include/internal/doxmresource.h [new file with mode: 0644]
resource/csdk/security/include/internal/policyengine.h [new file with mode: 0644]
resource/csdk/security/include/internal/psinterface.h [moved from resource/csdk/security/include/internal/ocsecurityinternal.h with 50% similarity]
resource/csdk/security/include/internal/pstatresource.h [new file with mode: 0644]
resource/csdk/security/include/internal/resourcemanager.h [new file with mode: 0644]
resource/csdk/security/include/internal/secureresourcemanager.h [new file with mode: 0644]
resource/csdk/security/include/internal/srmresourcestrings.h [new file with mode: 0644]
resource/csdk/security/include/ocsecurityconfig.h [deleted file]
resource/csdk/security/include/securevirtualresourcetypes.h [new file with mode: 0644]
resource/csdk/security/include/srmutility.h [new file with mode: 0644]
resource/csdk/security/provisioning/SConscript [new file with mode: 0644]
resource/csdk/security/provisioning/include/internal/credentialgenerator.h [new file with mode: 0644]
resource/csdk/security/provisioning/include/provisioningmanager.h [new file with mode: 0644]
resource/csdk/security/provisioning/sample/README-Provisioning-Tool.txt [new file with mode: 0644]
resource/csdk/security/provisioning/sample/SConscript [new file with mode: 0755]
resource/csdk/security/provisioning/sample/oic_svr_db_prov_tool.json [new file with mode: 0755]
resource/csdk/security/provisioning/sample/oic_svr_db_unowned_server.json [new file with mode: 0644]
resource/csdk/security/provisioning/sample/provisioningclient.c [new file with mode: 0755]
resource/csdk/security/provisioning/src/credentialgenerator.c [new file with mode: 0644]
resource/csdk/security/provisioning/src/provisioningmanager.c [new file with mode: 0644]
resource/csdk/security/provisioning/unittest/SConscript [new file with mode: 0644]
resource/csdk/security/provisioning/unittest/provisioningmanager.cpp [new file with mode: 0644]
resource/csdk/security/src/aclresource.c [new file with mode: 0644]
resource/csdk/security/src/base64.c [new file with mode: 0644]
resource/csdk/security/src/credresource.c [new file with mode: 0755]
resource/csdk/security/src/doxmresource.c [new file with mode: 0755]
resource/csdk/security/src/ocsecurity.c [deleted file]
resource/csdk/security/src/policyengine.c [new file with mode: 0644]
resource/csdk/security/src/psinterface.c [new file with mode: 0644]
resource/csdk/security/src/pstatresource.c [new file with mode: 0644]
resource/csdk/security/src/resourcemanager.c [new file with mode: 0644]
resource/csdk/security/src/secureresourcemanager.c [new file with mode: 0644]
resource/csdk/security/src/srmresourcestrings.c [new file with mode: 0644]
resource/csdk/security/src/srmutility.c [new file with mode: 0644]
resource/csdk/security/unittest/SConscript [new file with mode: 0644]
resource/csdk/security/unittest/aclresourcetest.cpp [new file with mode: 0644]
resource/csdk/security/unittest/base64tests.cpp [new file with mode: 0644]
resource/csdk/security/unittest/credentialresource.cpp [new file with mode: 0644]
resource/csdk/security/unittest/doxmresource.cpp [new file with mode: 0644]
resource/csdk/security/unittest/oic_svr_db.json [new file with mode: 0644]
resource/csdk/security/unittest/oic_unittest.json [new file with mode: 0644]
resource/csdk/security/unittest/oic_unittest_acl1.json [new file with mode: 0644]
resource/csdk/security/unittest/oic_unittest_default_acl.json [new file with mode: 0644]
resource/csdk/security/unittest/policyengine.cpp [new file with mode: 0644]
resource/csdk/security/unittest/pstatresource.cpp [new file with mode: 0644]
resource/csdk/security/unittest/securityresourcemanager.cpp [new file with mode: 0644]
resource/csdk/security/unittest/srmutility.cpp [new file with mode: 0644]
resource/csdk/stack/README
resource/csdk/stack/include/internal/occlientcb.h
resource/csdk/stack/include/internal/ocobserve.h
resource/csdk/stack/include/internal/ocpayloadcbor.h [moved from resource/csdk/security/include/ocsecurity.h with 59% similarity]
resource/csdk/stack/include/internal/ocresource.h
resource/csdk/stack/include/internal/ocresourcehandler.h
resource/csdk/stack/include/internal/ocserverrequest.h
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/ocpayload.h [new file with mode: 0644]
resource/csdk/stack/include/ocpresence.h [new file with mode: 0644]
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/samples/arduino/SimpleClientServer/ocserver/SConscript
resource/csdk/stack/samples/arduino/SimpleClientServer/ocserver/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/SConscript
resource/csdk/stack/samples/linux/SimpleClientServer/common.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlientbasicops.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientbasicops.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientslow.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientslow.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp [new file with mode: 0644]
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h [new file with mode: 0644]
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverbasicops.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverbasicops.h
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/common.cpp
resource/csdk/stack/samples/linux/secure/common.h
resource/csdk/stack/samples/linux/secure/gen_sec_bin.cpp [deleted file]
resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp
resource/csdk/stack/samples/linux/secure/occlientbasicops.h
resource/csdk/stack/samples/linux/secure/ocserverbasicops.cpp
resource/csdk/stack/samples/linux/secure/ocserverbasicops.h
resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json [new file with mode: 0644]
resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json [new file with mode: 0644]
resource/csdk/stack/src/occlientcb.c
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocobserve.c
resource/csdk/stack/src/ocpayload.c [new file with mode: 0644]
resource/csdk/stack/src/ocpayloadconvert.c [new file with mode: 0644]
resource/csdk/stack/src/ocpayloadparse.c [new file with mode: 0644]
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c [changed mode: 0644->0755]
resource/csdk/stack/test/SConscript
resource/csdk/stack/test/linux/occlient.c
resource/csdk/stack/test/stacktests.cpp
resource/docs/Doxyfile
resource/docs/devdocs.doxyfile
resource/docs/devdox/dot/ca_arch.gv
resource/examples/SConscript
resource/examples/devicediscoveryclient.cpp
resource/examples/devicediscoveryserver.cpp
resource/examples/fridgeclient.cpp
resource/examples/fridgeserver.cpp
resource/examples/garageclient.cpp
resource/examples/groupclient.cpp
resource/examples/groupserver.cpp
resource/examples/oic_svr_db_client.json [new file with mode: 0755]
resource/examples/oic_svr_db_server.json [new file with mode: 0755]
resource/examples/presenceclient.cpp
resource/examples/roomclient.cpp
resource/examples/simpleclient.cpp
resource/examples/simpleclientHQ.cpp
resource/examples/simpleclientserver.cpp
resource/examples/simpleserver.cpp
resource/examples/threadingsample.cpp
resource/include/IClientWrapper.h
resource/include/IServerWrapper.h
resource/include/InProcClientWrapper.h
resource/include/InProcServerWrapper.h
resource/include/InitializeException.h
resource/include/OCApi.h [changed mode: 0644->0755]
resource/include/OCException.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCRepresentation.h
resource/include/OCResource.h
resource/include/OCResourceRequest.h
resource/include/OCResourceResponse.h
resource/include/OCSerialization.h
resource/include/OicJsonSerializer.hpp [deleted file]
resource/include/OutOfProcClientWrapper.h
resource/include/ResourceInitException.h
resource/include/StringConstants.h
resource/oc_logger/SConscript
resource/oc_logger/c/oc_logger.c
resource/patches/cereal_gcc46.patch [deleted file]
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCException.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCRepresentation.cpp
resource/src/OCResource.cpp
resource/src/OCResourceRequest.cpp
resource/src/OCUtilities.cpp
resource/src/SConscript
resource/unit_tests.scons
resource/unittests/OCExceptionTest.cpp
resource/unittests/OCPlatformTest.cpp
resource/unittests/OCResourceResponseTest.cpp
resource/unittests/OCResourceTest.cpp
resource/unittests/SConscript
service/SConscript
service/notification-manager/NotificationManager/android/resource_hosting/.classpath [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/.classpath with 72% similarity, mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/.project [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/.project with 100% similarity, mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/AndroidManifest.xml [new file with mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/jni/Android.mk [new file with mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/jni/Application.mk [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/Application.mk with 100% similarity, mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/jni/ResourceHosing_JNI.cpp [moved from service/notification-manager/NotificationManager/src/resourceCoordinator_JNI.cpp with 59% similarity, mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/jni/ResourceHosing_JNI.h [moved from service/notification-manager/NotificationManager/src/resourceCoordinator_JNI.h with 64% similarity, mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/project.properties [new file with mode: 0755]
service/notification-manager/NotificationManager/android/resource_hosting/src/org/iotivity/ResourceHosting/ResourceHosting.java [new file with mode: 0755]
service/notification-manager/NotificationManager/include/hosting.h
service/notification-manager/NotificationManager/src/HostingObject.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/HostingObject.h [new file with mode: 0644]
service/notification-manager/NotificationManager/src/RequestObject.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/RequestObject.h [new file with mode: 0644]
service/notification-manager/NotificationManager/src/ResourceHosting.cpp [new file with mode: 0755]
service/notification-manager/NotificationManager/src/ResourceHosting.h [new file with mode: 0644]
service/notification-manager/NotificationManager/src/hosting.c [deleted file]
service/notification-manager/NotificationManager/src/hosting.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/requestHandler.c [deleted file]
service/notification-manager/NotificationManager/src/virtualResource.c [deleted file]
service/notification-manager/NotificationManager/src/virtualResource.h [deleted file]
service/notification-manager/SConscript
service/notification-manager/SampleApp/android/ResourceHostingSampleApp/ic_launcher-web.png [deleted file]
service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/Android.mk [deleted file]
service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/armeabi [deleted file]
service/notification-manager/SampleApp/android/SampleConsumer/src/com/example/sample/consumer/SampleConsumer.java
service/notification-manager/SampleApp/android/SampleProviderApp/src/com/example/sample/provider/SampleProvider.java
service/notification-manager/SampleApp/android/SampleProviderApp/src/com/example/sample/provider/TemperatureResource.java
service/notification-manager/SampleApp/android/SampleResourceHosting/AndroidManifest.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/AndroidManifest.xml with 98% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/project.properties [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/project.properties with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/drawable-hdpi/ic_launcher.png [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/drawable-hdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/drawable-mdpi/ic_launcher.png [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/drawable-mdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/drawable-xhdpi/ic_launcher.png [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/drawable-xhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/drawable-xxhdpi/ic_launcher.png [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/drawable-xxhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/layout/activity_main.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/layout/activity_main.xml with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/values-v11/styles.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/values-v11/styles.xml with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/values-v14/styles.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/values-v14/styles.xml with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/values/strings.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/values/strings.xml with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/res/values/styles.xml [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/res/values/styles.xml with 100% similarity, mode: 0755]
service/notification-manager/SampleApp/android/SampleResourceHosting/src/com/example/resourcehostingsampleapp/ResourceHostingSampleApp.java [moved from service/notification-manager/SampleApp/android/ResourceHostingSampleApp/src/com/example/resourcehostingsampleapp/ResourceHosting.java with 71% similarity, mode: 0755]
service/notification-manager/SampleApp/linux/SConscript
service/notification-manager/SampleApp/linux/notificationManager/main.cpp [moved from service/notification-manager/SampleApp/linux/notificationManager/main.c with 76% similarity]
service/notification-manager/SampleApp/linux/sampleConsumer/SampleConsumer.cpp
service/notification-manager/SampleApp/linux/sampleProvider/SampleProvider.cpp
service/notification-manager/SampleApp/tizen/NMSampleApp/.cproject
service/notification-manager/SampleApp/tizen/NMSampleApp/src/main.cpp
service/protocol-plugin/lib/cpluff/SConscript
service/protocol-plugin/plugin-manager/SConscript
service/protocol-plugin/plugin-manager/src/Android/jni/Android.mk
service/protocol-plugin/plugin-manager/src/Android/jni/PluginManager.cpp
service/protocol-plugin/plugin-manager/src/Android/jni/PluginManager.h
service/protocol-plugin/plugin-manager/src/Android/jni/SConscript
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/FelixManager.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/FoundResource.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/MainActivity.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnGetBelkinplug.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnGetGear.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnGetHuebulb.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnPutBelkinplug.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnPutGear.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/OnPutHuebulb.java
service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/PluginManager.java
service/protocol-plugin/plugin-manager/src/Config.cpp
service/protocol-plugin/plugin-manager/src/Config.h
service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp
service/protocol-plugin/plugin-manager/src/CpluffAdapter.h
service/protocol-plugin/plugin-manager/src/FelixAdapter.cpp
service/protocol-plugin/plugin-manager/src/FelixAdapter.h
service/protocol-plugin/plugin-manager/src/PluginManager.cpp
service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp
service/protocol-plugin/plugin-manager/src/PluginManagerImpl.h
service/protocol-plugin/plugins/Android/plugin.gear.noti/.project [new file with mode: 0644]
service/protocol-plugin/plugins/Android/plugin.gear.noti/src/oic/plugin/gear/noti/Activator.java
service/protocol-plugin/plugins/Android/plugin.gear.noti/src/oic/plugin/gear/noti/EntityHandlerNoti.java
service/protocol-plugin/plugins/Android/plugin.hue/.project [new file with mode: 0644]
service/protocol-plugin/plugins/Android/plugin.hue/src/oic/plugin/hue/Activator.java
service/protocol-plugin/plugins/Android/plugin.hue/src/oic/plugin/hue/EntityHandlerHue.java
service/protocol-plugin/plugins/Android/plugin.wemo/.project [new file with mode: 0644]
service/protocol-plugin/plugins/Android/plugin.wemo/src/oic/plugin/wemo/Activator.java
service/protocol-plugin/plugins/Android/plugin.wemo/src/oic/plugin/wemo/EntityHandlerWemo.java
service/protocol-plugin/plugins/SConscript
service/protocol-plugin/plugins/mqtt-fan/lib/SConscript
service/protocol-plugin/plugins/mqtt-fan/lib/cpp/SConscript
service/protocol-plugin/sample-app/linux/SConscript
service/protocol-plugin/sample-app/linux/mqtt/mqttclient.cpp
service/protocol-plugin/sample-app/tizen/PPMSampleApp/.cproject
service/protocol-plugin/sample-app/tizen/PPMSampleApp/src/ppmsampleapp.cpp
service/resource-encapsulation/README [new file with mode: 0644]
service/resource-encapsulation/SConscript [new file with mode: 0644]
service/resource-encapsulation/examples/SConscript [new file with mode: 0644]
service/resource-encapsulation/examples/linux/SConscript [new file with mode: 0644]
service/resource-encapsulation/examples/linux/SampleResourceClient.cpp [new file with mode: 0755]
service/resource-encapsulation/examples/linux/SampleResourceServer.cpp [new file with mode: 0755]
service/resource-encapsulation/include/RCSAddress.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSBundleInfo.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSDiscoveryManager.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSException.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSRemoteResourceObject.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSRequest.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSResourceAttributes.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSResourceContainer.h [new file with mode: 0644]
service/resource-encapsulation/include/RCSResourceObject.h [new file with mode: 0755]
service/resource-encapsulation/include/RCSResponse.h [new file with mode: 0644]
service/resource-encapsulation/src/common/SConscript [new file with mode: 0755]
service/resource-encapsulation/src/common/expiryTimer/include/ExpiryTimer.h [new file with mode: 0644]
service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimer.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.h [new file with mode: 0644]
service/resource-encapsulation/src/common/expiryTimer/unittests/ExpiryTimerTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/PresenceSubscriber.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/RCSAddressDetail.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesConverter.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesUtils.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/include/ResponseStatement.h [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/PresenceSubscriber.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/PrimitiveResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/RCSAddress.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/src/ResponseStatement.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/unittests/PresenceSubscriberTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/unittests/PrimitiveResourceTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/common/utils/include/ScopeLogger.h [new file with mode: 0644]
service/resource-encapsulation/src/common/utils/include/UnitTestHelper.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/include/BrokerTypes.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/include/DeviceAssociation.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/include/DevicePresence.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/include/ResourceBroker.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/include/ResourcePresence.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/src/DeviceAssociation.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/src/DevicePresence.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/src/ResourceBroker.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/src/ResourcePresence.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/unittest/DeviceAssociationUnitTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/unittest/DevicePresenceUnitTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/unittest/ResourceBrokerUnitTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/unittest/ResourcePresenceUnitTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceBroker/unittest/SConscript [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/include/CacheTypes.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/include/DataCache.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/include/ResourceCacheManager.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/src/DataCache.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/src/ResourceCacheManager.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/unittests/DataCacheTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/unittests/ResourceCacheTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceCache/unittests/SConscript [new file with mode: 0644]
service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/SConscript [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleActivator.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleResource.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/NotificationReceiver.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeConnector.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeResource.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/ResourceContainerBundleAPI.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-api/include/SoftSensorResource.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/pom.xml [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BaseActivator.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleActivator.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleResource.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ProtocolBridgeConnector.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ResourceConfig.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/ContainerSample.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/ContainerSampleClient.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/pom.xml [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueBundleActivator.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueConnector.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueLightResource.java [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueConnector.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueLight.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/ResourceContainerConfig.xml [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensor.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensorResource.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/SoftSensorBundleActivator.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/SysTimer.h [moved from resource/csdk/connectivity/common/src/oic_string.c with 69% similarity]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensor.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensorResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SoftSensorBundleActivator.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SysTimer.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/include/BundleInfoInternal.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/include/Configuration.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/include/JavaBundleResource.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/include/ResourceContainerImpl.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/include/org_iotivity_resourcecontainer_bundle_api_BaseActivator.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/BaseActivator.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/BundleActivator.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/BundleInfoInternal.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/BundleResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/Configuration.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/JavaBundleResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeConnector.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/RCSBundleInfo.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/RCSResourceContainer.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/ResourceContainerBundleAPI.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/ResourceContainerImpl.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/src/SoftSensorResource.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerInvalidConfig.xml [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTestConfig.xml [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/SConscript [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/include/TestBundleActivator.h [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/src/TestBundleActivator.cpp [new file with mode: 0644]
service/resource-encapsulation/src/resourceContainer/unittests/TestBundleJava/hue-0.1-jar-with-dependencies.jar [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/SConscript [new file with mode: 0755]
service/resource-encapsulation/src/serverBuilder/include/RequestHandler.h [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/src/RCSRequest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp [new file with mode: 0755]
service/resource-encapsulation/src/serverBuilder/src/RCSResponse.cpp [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/src/RequestHandler.cpp [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/unittests/RCSResourceObjectTest.cpp [new file with mode: 0755]
service/resource-encapsulation/src/serverBuilder/unittests/RCSResponseTest.cpp [new file with mode: 0644]
service/resource-encapsulation/src/serverBuilder/unittests/RequestHandlerTest.cpp [new file with mode: 0644]
service/resource-encapsulation/unittests/ResourceClientTest.cpp [new file with mode: 0644]
service/resource-encapsulation/unittests/SConscript [new file with mode: 0755]
service/soft-sensor-manager/SConscript
service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp
service/soft-sensor-manager/SSMCore/src/SSMInterface/SSMModelDefinition.h
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h
service/soft-sensor-manager/SampleApp/android/SSMTesterApp/jni/Android.mk
service/soft-sensor-manager/SampleApp/android/SSMTesterApp/src/org/iotivity/service/ssm/sample/MainActivity.java
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/trackee.cpp
service/soft-sensor-manager/SampleApp/linux/THSensorApp/include/ThingResourceServer.h
service/soft-sensor-manager/SampleApp/linux/THSensorApp1/include/ThingResourceServer1.h
service/soft-sensor-manager/SampleApp/tizen/SSMTesterApp/.cproject
service/soft-sensor-manager/SampleApp/tizen/SSMTesterApp/src/ssmtesterapp.cpp
service/things-manager/SConscript
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/ActionListener.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/ConfigurationApiActivity.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/ConfigurationListener.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/DiagnosticListener.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/GroupApiActivity.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/GroupClient.java
service/things-manager/sampleapp/android/Sample/src/com/tm/sample/MainActivity.java
service/things-manager/sampleapp/android/con-server/src/com/example/con_server/MainActivity.java
service/things-manager/sampleapp/linux/configuration/SConscript
service/things-manager/sampleapp/linux/configuration/con-client.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/linux/configuration/con-server.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/linux/groupaction/groupserver.cpp
service/things-manager/sampleapp/linux/groupsyncaction/SConscript
service/things-manager/sampleapp/linux/groupsyncaction/group.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp [changed mode: 0644->0755]
service/things-manager/sampleapp/tizen/ConServerApp/.cproject
service/things-manager/sampleapp/tizen/ConServerApp/src/conserverapp.cpp
service/things-manager/sampleapp/tizen/ConServerApp/src/diagnosticsresource.cpp
service/things-manager/sampleapp/tizen/TMSampleApp/.cproject
service/things-manager/sampleapp/tizen/TMSampleApp/src/configuration.cpp
service/things-manager/sampleapp/tizen/TMSampleApp/src/group.cpp
service/things-manager/sdk/inc/ThingsManager.h
service/things-manager/sdk/java/jni/Android.mk
service/things-manager/sdk/java/jni/Application.mk
service/things-manager/sdk/java/jni/SConscript
service/things-manager/sdk/src/GroupManager.cpp
service/things-manager/sdk/src/GroupSynchronization.cpp
service/things-manager/sdk/src/ThingsConfiguration.cpp
service/things-manager/sdk/src/ThingsDiagnostics.cpp
tools/__init__.py [new file with mode: 0644]
tools/darwin/build-ios.sh
tools/darwin/mkfwk_ios.sh
tools/darwin/mkfwk_osx.sh
tools/scons/RunTest.py [new file with mode: 0644]
tools/scons/__init__.py [new file with mode: 0644]
tools/vagrant/iotivity-setup.sh
tools/valgrind/iotivity.supp [new file with mode: 0644]

index d0fbb21..c891e5c 100644 (file)
@@ -48,18 +48,28 @@ resource/unittests/debug/
 service/things-manager/build/linux/release
 service/things-manager/build/linux/debug
 service/things-manager/sdk/build/linux/
+
 # Ignore any object files
 *.o
+*.os
 *.obj
 
+# Ignore libraries
+*.a
+*.so
 
 # Ignore Eclipse workspace files
 *.settings/
 
+# Ignore proguard file generated by Eclipse
+proguard-project.txt
+
 # Ignore CTags default data
 tags
+
 # Ignore dependencies folder, which should be generated
 dependencies/
+dep/
 
 #ignore Klocwork stuff
 .kwlp/
@@ -86,14 +96,21 @@ extlibs/android/gradle/gradle-2.2.1
 extlibs/android/ndk/android-ndk-r10d
 extlibs/android/sdk/android-sdk_r24.2
 extlibs/boost/boost_1_58_0
+extlibs/tinycbor/tinycbor
 *.tgz
 *.zip
 extlibs/arduino/arduino-1.5.8
 build_common/arduino/extlibs/arduino/arduino-1.5.8
+extlibs/tinydtls/dtls-client
+extlibs/tinydtls/dtls-server
 
 # Ignore editor (e.g. Emacs) backup and autosave files
 *~
 *#*#
+*.orig
 
 # Ignore byte-compiled Python scripts
 *.pyc
+
+# Ignore Valgrind generated files.
+*.memcheck
index 6d243f8..027511d 100644 (file)
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -40,20 +40,13 @@ license can be found at
 The original software is available from
   http://sourceforge.net/projects/boost/files/boost
 
-JSON serialization is provided by the cereal package,
-which is open source software, written by Philip Hazel, and copyright
-by the University of Cambridge, England. The original software is
-available from
-  ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
-
+CBOR serialization is provided by the tinycbor package,
+which is open source software, written by Thiago Macieira and is
+copyright by the Intel Corporation.  The original software is available
+from
+  https://github.com/01org/tinycbor/
 JSON serialization is provided by the cjson package,
 which is open source software, written and copyright by Dave Gamble
 with an MIT license. The original software is available from
   http://sourceforge.net/projects/cjson/
 
-JSON serialization is provided by the rapidjson package,
-which is open source software, written and copyright by Milo Yip
-with an MIT license. The original software is available from
-  http://code.google.com/p/rapidjson/
-
-
index d433b3b..fd0b3a0 100644 (file)
@@ -5,12 +5,12 @@
 command in this directory)
 
     Install external libraries:
-      $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev
+      $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev libssl-dev
 
     Build release binaries:
       $ scons
-(Note: C++ sdk requires cereal. Please follow the instruction in the build
-message to install cereal)
+(Note: C sdk requires tiny-cbor. Please follow the instruction in the build
+message to install tiny-cbor)
 
     Build debug binaries:
       $scons RELEASE=false
@@ -90,7 +90,7 @@ To build for Android, Andorid NDK and SDK are required.
 Arduino:
 To build for Arduino, Arduino IDE is required.
   Arduino IDE: http://arduino.cc/en/Main/Software
-  (Note: recommend install Arduino IDE >=1.5.7)
+  (Note: recommend install Arduino IDE >=1.5.8)
 
 Arduino builds are dependent on latest Time library. Download it from here:
     http://www.pjrc.com/teensy/td_libs_Time.html
@@ -116,13 +116,10 @@ so you don't need to add it in command line each time. The build script will
 guide you to do that.)
 
 Tizen:
-To build for tizen platform cereal library is needed.
-Please download cereal if it is not present in extlibs/cereal folder
-and apply the patch as following:
-       $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal
-       $ cd  extlibs/cereal/cereal
-       $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
-       $ git apply ../../../resource/patches/cereal_gcc46.patch
+To build for tizen platform tiny-cbor library is needed.
+Please download tiny-cbor if it is not present in extlibs/tiny-cbor folder
+by doing the following:
+       $ git clone https://github.com/01org/tinycbor.git extlibs/tinycbor/tinycbor
 
 
 * 3. External libraries
@@ -140,7 +137,7 @@ to skip it.
 
 1. Build IoTivity project for Linux
       $ cd <top directory of the project>
-      $ sudo apt-get install libboost-dev libexpat1-dev libboost-thread-dev
+      $ sudo apt-get install libboost-dev libexpat1-dev libboost-thread-dev libssl-dev
       $ scons
 
 2. Build IoTivity project for Android
@@ -151,13 +148,14 @@ allowed value, please execute command 'scons TARGET_OS=android -Q -h')
 
 3. Build IoTivity project for Arduino
       $ cd <top directory of the project>
-      $ scons TARGET_OS=arduino TARGET_ARCH=xxx BOARD=yyy
-(xxx can be avr, arm; yyy is the name of the board, to get its allowed value
-run: scons TARGET_OS=arduino TARGET_ARCH=xxx -h. You may see a option 'CPU' in
-the output of above command line, that's due to some boards have different
-processors, to specify the processor, add 'CPU=zzz' in the command line. If no
-'CPU' option exists, that means the board only support one kind of processor,
-it's unnecessary to specify it)
+      $ sudo apt-get install dos2unix
+      $ scons TARGET_OS=arduino TARGET_ARCH=xxx BOARD=yyy SHIELD=zzz
+(xxx can be avr, arm; yyy is the name of the board, zzz is the shield type, to
+get allowed values run: scons TARGET_OS=arduino TARGET_ARCH=xxx SHIELD=zzz -h.
+You may see a option 'CPU' in the output of above command line, that's due to
+some boards have different processors, to specify the processor, add 'CPU=zzz'
+in the command line. If no 'CPU' option exists, that means the board only
+support one kind of processor, it's unnecessary to specify it)
 
 4. Build Iotivity project for Tizen
       $ cd <top directory of the project>
@@ -167,24 +165,6 @@ gbs is default build tool for Tizen platfrom, we can refer the following
 wiki to setup Tizen development environment:
 https://source.tizen.org/documentation/developer-guide/getting-started-guide)
 
-=== Build IoTivity project on Android ===
-
-1. Build IoTivity project for Android(It's the same as on Ubuntu)
-      $ cd <top directory of the project>
-      $ scons TARGET_OS=android TARGET_ARCH=xxx
-(xxx can be x86, armeabi, armeabi-v7a, armeabi-v7a-hard ...)
-
-2. Build IoTivity project for Arduino(It's the same as on Ubuntu)
-      $ cd <top directory of the project>
-      $ scons TARGET_OS=arduino TARGET_ARCH=xxx BOARD=yyy
-(xxx can be avr, arm; yyy is the name of the board, to get its allowed value
-run: scons TARGET_OS=arduino TARGET_ARCH=xxx -h. You may see a option 'CPU' in
-the output of above command line, that's due to some boards have different
-processor, to specify the processor, add 'CPU=zzz' in the command line. If no
-'CPU' option exists, that means the board only support one kind of processor,
-it's unnecessary to specify it)
-
-
 Note: Currently most IoTivity project doesn't support Windows, so you can't set
 TARGET_OS to 'windows' except the project support Windows.
 
@@ -220,6 +200,3 @@ To build:
      $ auto_build.sh <path-to-android-ndk>
 To clean:
      $ auto_build.sh -c
-
-2) For Arduino build, the Time library should >=1.3. The old can only be built
-with Arduino IDE 1.0.x
index 8dda6db..4bc0515 100644 (file)
@@ -26,7 +26,7 @@ TO RUN UNIT TESTS IN ANDROID-API
 \r
 TO USE THE .AAR FILE IN <iotivity>/android/examples project\r
 \r
-6. Verify that 9 different *.so files exist inside <iotivity>/android/android-api/base/libs/<TARGET_ARCH> directory. (They should already be present in the *.aar file.)\r
+6. Verify that 7 different *.so files exist inside <iotivity>/android/android-api/base/libs/<TARGET_ARCH> directory. (They should already be present in the *.aar file.)\r
 7. Import Project 'Examples' into android-studio.\r
 8.To add an .aar file to the 'Examples' project,\r
    a.Right click on Examples->New->Module->Import .JAR or .AAR Package\r
@@ -39,7 +39,7 @@ TO USE THE .AAR FILE IN <iotivity>/android/examples project
 \r
 TO USE THE .AAR FILE IN A DIFFERENT PROJECT\r
 \r
-9. Verify that 9 different *.so files exist inside <iotivity base>/android/android-api/base/libs/<TARGET_ARCH> directory.\r
+9. Verify that 7 different *.so files exist inside <iotivity base>/android/android-api/base/libs/<TARGET_ARCH> directory.\r
 10. Import the .aar file in your project to use it\r
 \r
 \r
index 36cf651..49b2159 100755 (executable)
@@ -9,7 +9,6 @@
     <facet type="android" name="Android">\r
       <configuration>\r
         <option name="SELECTED_BUILD_VARIANT" value="debug" />\r
-        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />\r
         <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />\r
         <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />\r
         <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />\r
index aa2cbae..be7e3ca 100644 (file)
@@ -43,6 +43,7 @@ LOCAL_SRC_FILES :=  JniOcStack.cpp \
                     JniEntityHandler.cpp \\r
                     JniOnResourceFoundListener.cpp \\r
                     JniOnDeviceInfoListener.cpp \\r
+                   JniOnPlatformInfoListener.cpp \\r
                     JniOnPresenceListener.cpp \\r
                     JniOnGetListener.cpp \\r
                     JniOnPutListener.cpp \\r
@@ -57,7 +58,8 @@ LOCAL_SRC_FILES :=  JniOcStack.cpp \
                     JniOcResourceResponse.cpp \\r
                     JniOcPlatform.cpp \\r
                     JniOcResource.cpp \\r
-                    JniOcResourceIdentifier.cpp\r
+                    JniOcResourceIdentifier.cpp \
+                    JniOcSecurity.cpp
 \r
 LOCAL_LDLIBS := -llog\r
 LOCAL_STATIC_LIBRARIES := android-oc\r
index 0a50d8e..c8a619e 100644 (file)
-/*\r
-* //******************************************************************\r
-* //\r
-* // Copyright 2015 Intel Corporation.\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 "JniOcPlatform.h"\r
-#include "OCPlatform.h"\r
-#include "JniOcResource.h"\r
-#include "JniOcResourceHandle.h"\r
-#include "JniOcPresenceHandle.h"\r
-#include "JniOcResourceResponse.h"\r
-#include "JniUtils.h"\r
-\r
-using namespace OC;\r
-\r
-JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener)\r
-{\r
-    JniOnResourceFoundListener *onResourceFoundListener = NULL;\r
-\r
-    resourceFoundMapLock.lock();\r
-\r
-    for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            onResourceFoundListener = refPair.first;\r
-            refPair.second++;\r
-            it->second = refPair;\r
-            onResourceFoundListenerMap.insert(*it);\r
-            LOGD("OnResourceFoundListener: ref. count incremented");\r
-            break;\r
-        }\r
-    }\r
-\r
-    if (!onResourceFoundListener)\r
-    {\r
-        onResourceFoundListener = new JniOnResourceFoundListener(env, jListener, RemoveOnResourceFoundListener);\r
-        jobject jgListener = env->NewGlobalRef(jListener);\r
-\r
-        onResourceFoundListenerMap.insert(std::pair < jobject, std::pair < JniOnResourceFoundListener*,\r
-            int >> (jgListener, std::pair<JniOnResourceFoundListener*, int>(onResourceFoundListener, 1)));\r
-        LOGD("OnResourceFoundListener: new listener");\r
-    }\r
-    resourceFoundMapLock.unlock();\r
-    return onResourceFoundListener;\r
-}\r
-\r
-void RemoveOnResourceFoundListener(JNIEnv* env, jobject jListener)\r
-{\r
-    resourceFoundMapLock.lock();\r
-\r
-    for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            if (refPair.second > 1)\r
-            {\r
-                refPair.second--;\r
-                it->second = refPair;\r
-                onResourceFoundListenerMap.insert(*it);\r
-                LOGI("OnResourceFoundListener: ref. count decremented");\r
-            }\r
-            else\r
-            {\r
-                env->DeleteGlobalRef(it->first);\r
-                JniOnResourceFoundListener* listener = refPair.first;\r
-                delete listener;\r
-                onResourceFoundListenerMap.erase(it);\r
-                LOGI("OnResourceFoundListener removed");\r
-            }\r
-            break;\r
-        }\r
-    }\r
-    resourceFoundMapLock.unlock();\r
-}\r
-\r
-JniOnDeviceInfoListener* AddOnDeviceInfoListener(JNIEnv* env, jobject jListener)\r
-{\r
-    JniOnDeviceInfoListener *onDeviceInfoListener = NULL;\r
-\r
-    deviceInfoMapLock.lock();\r
-\r
-    for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            onDeviceInfoListener = refPair.first;\r
-            refPair.second++;\r
-            it->second = refPair;\r
-            onDeviceInfoListenerMap.insert(*it);\r
-            LOGD("OnDeviceInfoListener: ref. count incremented");\r
-            break;\r
-        }\r
-    }\r
-\r
-    if (!onDeviceInfoListener)\r
-    {\r
-        onDeviceInfoListener = new JniOnDeviceInfoListener(env, jListener, RemoveOnDeviceInfoListener);\r
-        jobject jgListener = env->NewGlobalRef(jListener);\r
-\r
-        onDeviceInfoListenerMap.insert(std::pair < jobject, std::pair < JniOnDeviceInfoListener*,\r
-            int >> (jgListener, std::pair<JniOnDeviceInfoListener*, int>(onDeviceInfoListener, 1)));\r
-        LOGI("OnDeviceInfoListener: new listener");\r
-    }\r
-\r
-    deviceInfoMapLock.unlock();\r
-    return onDeviceInfoListener;\r
-}\r
-\r
-void RemoveOnDeviceInfoListener(JNIEnv* env, jobject jListener)\r
-{\r
-    deviceInfoMapLock.lock();\r
-    bool isFound = false;\r
-    for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            if (refPair.second > 1)\r
-            {\r
-                refPair.second--;\r
-                it->second = refPair;\r
-                onDeviceInfoListenerMap.insert(*it);\r
-                LOGI("OnDeviceInfoListener: ref. count decremented");\r
-            }\r
-            else\r
-            {\r
-                env->DeleteGlobalRef(it->first);\r
-                JniOnDeviceInfoListener* listener = refPair.first;\r
-                delete listener;\r
-                onDeviceInfoListenerMap.erase(it);\r
-\r
-                LOGI("OnDeviceInfoListener removed");\r
-            }\r
-\r
-            isFound = true;\r
-            break;\r
-        }\r
-    }\r
-\r
-    if (!isFound)\r
-    {\r
-        ThrowOcException(JNI_EXCEPTION, "OnDeviceInfoListenet not found");\r
-    }\r
-    deviceInfoMapLock.unlock();\r
-}\r
-\r
-JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener)\r
-{\r
-    JniOnPresenceListener *onPresenceListener = NULL;\r
-\r
-    presenceMapLock.lock();\r
-\r
-    for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            onPresenceListener = refPair.first;\r
-            refPair.second++;\r
-            it->second = refPair;\r
-            onPresenceListenerMap.insert(*it);\r
-            LOGD("OnPresenceListener: ref. count incremented");\r
-            break;\r
-        }\r
-    }\r
-    if (!onPresenceListener)\r
-    {\r
-        onPresenceListener = new JniOnPresenceListener(env, jListener, RemoveOnPresenceListener);\r
-        jobject jgListener = env->NewGlobalRef(jListener);\r
-        onPresenceListenerMap.insert(std::pair < jobject, std::pair < JniOnPresenceListener*,\r
-            int >> (jgListener, std::pair<JniOnPresenceListener*, int>(onPresenceListener, 1)));\r
-        LOGI("OnPresenceListener: new listener");\r
-    }\r
-    presenceMapLock.unlock();\r
-    return onPresenceListener;\r
-}\r
-\r
-void RemoveOnPresenceListener(JNIEnv* env, jobject jListener)\r
-{\r
-    presenceMapLock.lock();\r
-    bool isFound = false;\r
-    for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it)\r
-    {\r
-        if (env->IsSameObject(jListener, it->first))\r
-        {\r
-            auto refPair = it->second;\r
-            if (refPair.second > 1)\r
-            {\r
-                refPair.second--;\r
-                it->second = refPair;\r
-                onPresenceListenerMap.insert(*it);\r
-                LOGI("OnPresenceListener: ref. count decremented");\r
-            }\r
-            else\r
-            {\r
-                env->DeleteGlobalRef(it->first);\r
-                JniOnPresenceListener* listener = refPair.first;\r
-                delete listener;\r
-                onPresenceListenerMap.erase(it);\r
-                LOGI("OnPresenceListener is removed");\r
-            }\r
-            isFound = true;\r
-            break;\r
-        }\r
-    }\r
-    if (!isFound)\r
-    {\r
-        ThrowOcException(JNI_EXCEPTION, "OnPresenceListener not found");\r
-    }\r
-    presenceMapLock.unlock();\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    configure\r
-* Signature: (IILjava/lang/String;II)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure\r
-(JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort, jint jQOS)\r
-{\r
-    LOGI("OcPlatform_configure");\r
-\r
-    std::string ipAddress;\r
-    if (jIpAddress)\r
-    {\r
-        ipAddress = env->GetStringUTFChars(jIpAddress, NULL);\r
-    }\r
-    uint16_t port;\r
-    if (jPort > 0)\r
-    {\r
-        port = static_cast<uint16_t>(jPort);\r
-    }\r
-    PlatformConfig cfg{\r
-        JniUtils::getServiceType(env, jServiceType),\r
-        JniUtils::getModeType(env, jModeType),\r
-        ipAddress,\r
-        port,\r
-        JniUtils::getQOS(env, static_cast<int>(jQOS))\r
-    };\r
-\r
-    OCPlatform::Configure(cfg);\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    notifyAllObservers0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers0\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle)\r
-{\r
-    LOGI("OcPlatform_notifyAllObservers");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::notifyAllObservers(jniOcResourceHandle->getOCResourceHandle());\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to notify all observers");\r
-            return;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    notifyAllObservers1\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;I)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers1\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle, jint jQoS)\r
-{\r
-    LOGI("OcPlatform_notifyAllObservers1");\r
-\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try{\r
-        OCStackResult result = OCPlatform::notifyAllObservers(\r
-            jniOcResourceHandle->getOCResourceHandle(),\r
-            JniUtils::getQOS(env, static_cast<int>(jQoS)));\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to notify all observers");\r
-            return;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    notifyListOfObservers2\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers2\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse)\r
-{\r
-    LOGD("OcPlatform_notifyListOfObservers2");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jObservationIdArr)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceResponse)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(\r
-        env, jResourceResponse);\r
-    if (!jniOcResourceResponse) return;\r
-\r
-    int len = env->GetArrayLength(jObservationIdArr);\r
-    uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0);\r
-\r
-    ObservationIds observationIds;\r
-    for (int i = 0; i < len; ++i)\r
-    {\r
-        observationIds.push_back(bArr[i]);\r
-    }\r
-\r
-    env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0);\r
-\r
-    try{\r
-        OCStackResult result = OCPlatform::notifyListOfObservers(\r
-            jniOcResourceHandle->getOCResourceHandle(),\r
-            observationIds,\r
-            jniOcResourceResponse->getOCResourceResponse());\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to notify all observers");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    notifyListOfObservers3\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;I)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers3\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse, jint jQoS)\r
-{\r
-    LOGD("OcPlatform_notifyListOfObservers3");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jObservationIdArr)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceResponse)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(\r
-        env, jResourceResponse);\r
-    if (!jniOcResourceResponse) return;\r
-\r
-    int len = env->GetArrayLength(jObservationIdArr);\r
-    uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0);\r
-\r
-    ObservationIds observationIds;\r
-    for (int i = 0; i < len; ++i)\r
-    {\r
-        observationIds.push_back(bArr[i]);\r
-    }\r
-\r
-    env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0);\r
-\r
-    try{\r
-        OCStackResult result = OCPlatform::notifyListOfObservers(\r
-            jniOcResourceHandle->getOCResourceHandle(),\r
-            observationIds,\r
-            jniOcResourceResponse->getOCResourceResponse(),\r
-            JniUtils::getQOS(env, static_cast<int>(jQoS)));\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to notify all observers");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    findResource0\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource0\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener)\r
-{\r
-    LOGD("OcPlatform_findResource");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string resourceUri;\r
-    if (jResourceUri)\r
-    {\r
-        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener);\r
-\r
-    FindCallback findCallback = [onResFoundListener](std::shared_ptr<OCResource> resource)\r
-    {\r
-        onResFoundListener->foundResourceCallback(resource);\r
-    };\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::findResource(\r
-            host,\r
-            resourceUri,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            findCallback);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Find resource has failed");\r
-            return;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    findResource1\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;I)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource1\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS)\r
-{\r
-    LOGD("OcPlatform_findResource");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string resourceUri;\r
-    if (jResourceUri)\r
-    {\r
-        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null");\r
-        return;\r
-    }\r
-    JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener);\r
-\r
-    FindCallback findCallback = [onResFoundListener](std::shared_ptr<OCResource> resource)\r
-    {\r
-        onResFoundListener->foundResourceCallback(resource);\r
-    };\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::findResource(\r
-            host,\r
-            resourceUri,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            findCallback,\r
-            JniUtils::getQOS(env, static_cast<int>(jQoS)));\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Find resource has failed");\r
-            return;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    getDeviceInfo0\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo0\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener)\r
-{\r
-    LOGD("OcPlatform_getDeviceInfo0");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string resourceUri;\r
-    if (jResourceUri)\r
-    {\r
-        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null");\r
-        return;\r
-    }\r
-    JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener);\r
-\r
-    FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation)\r
-    {\r
-        onDeviceInfoListener->foundDeviceCallback(ocRepresentation);\r
-    };\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::getDeviceInfo(\r
-            host,\r
-            resourceUri,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            findDeviceCallback);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Find device has failed");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    getDeviceInfo1\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;I)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo1\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS)\r
-{\r
-    LOGD("OcPlatform_getDeviceInfo1");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string resourceUri;\r
-    if (jResourceUri)\r
-    {\r
-        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null");\r
-        return;\r
-    }\r
-    JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener);\r
-\r
-    FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation)\r
-    {\r
-        onDeviceInfoListener->foundDeviceCallback(ocRepresentation);\r
-    };\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::getDeviceInfo(\r
-            host,\r
-            resourceUri,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            findDeviceCallback,\r
-            JniUtils::getQOS(env, static_cast<int>(jQoS)));\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Find device has failed");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    registerResource0\r
-* Signature: (Lorg/iotivity/base/OcResource;)Lorg/iotivity/base/OcResourceHandle;\r
-*/\r
-JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource0\r
-(JNIEnv *env, jclass clazz, jobject jResource)\r
-{\r
-    LOGD("OcPlatform_registerResource");\r
-    if (!jResource)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "Resource cannot be null");\r
-        return nullptr;\r
-    }\r
-    JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, jResource);\r
-    if (!resource) return nullptr;\r
-\r
-    OCResourceHandle resourceHandle;\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::registerResource(\r
-            resourceHandle,\r
-            resource->getOCResource());\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "register resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-        return nullptr;\r
-    }\r
-\r
-    JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle);\r
-    jlong handle = reinterpret_cast<jlong>(jniHandle);\r
-    jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle);\r
-    if (!jResourceHandle)\r
-    {\r
-        LOGE("Failed to create OcResourceHandle");\r
-        delete jniHandle;\r
-    }\r
-    return jResourceHandle;\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    registerResource1\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcPlatform/EntityHandler;I)Lorg/iotivity/base/OcResourceHandle;\r
-*/\r
-JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource1\r
-(JNIEnv *env, jclass clazz, jstring jResourceUri, jstring jResourceTypeName, jstring jResourceInterface,\r
-jobject jListener, jint jResourceProperty)\r
-{\r
-    LOGI("OcPlatform_registerResource1");\r
-    std::string resourceUri;\r
-    if (jResourceUri)\r
-    {\r
-        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);\r
-    }\r
-    std::string resourceTypeName;\r
-    if (jResourceTypeName)\r
-    {\r
-        resourceTypeName = env->GetStringUTFChars(jResourceTypeName, NULL);\r
-    }\r
-    std::string resourceInterface;\r
-    if (jResourceInterface)\r
-    {\r
-        resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "entityHandler cannot be null");\r
-        return nullptr;\r
-    }\r
-    JniEntityHandler* entityHandler = new JniEntityHandler(env, jListener);\r
-    EntityHandler handleEntityCallback = [entityHandler](const std::shared_ptr<OCResourceRequest> request) ->\r
-        OCEntityHandlerResult{\r
-        return entityHandler->handleEntity(request);\r
-    };\r
-\r
-    OCResourceHandle resourceHandle;\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::registerResource(\r
-            resourceHandle,\r
-            resourceUri,\r
-            resourceTypeName,\r
-            resourceInterface,\r
-            handleEntityCallback,\r
-            static_cast<int>(jResourceProperty));\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            delete entityHandler;\r
-            ThrowOcException(result, "register resource");\r
-            return nullptr;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        delete entityHandler;\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-        return nullptr;\r
-    }\r
-\r
-    JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle);\r
-    jlong handle = reinterpret_cast<jlong>(jniHandle);\r
-    jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle);\r
-    if (!jResourceHandle)\r
-    {\r
-        LOGE("Failed to create OcResourceHandle");\r
-        delete jniHandle;\r
-    }\r
-\r
-    return jResourceHandle;\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    registerDeviceInfo0\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0\r
-(JNIEnv *env,\r
-jclass clazz,\r
-jstring jDeviceName,\r
-jstring jHostName,\r
-jstring jDeviceUUID,\r
-jstring jContentType,\r
-jstring jVersion,\r
-jstring jManufacturerName,\r
-jstring jManufacturerUrl,\r
-jstring jModelNumber,\r
-jstring jDateOfManufacture,\r
-jstring jPlatformVersion,\r
-jstring jFirmwareVersion,\r
-jstring jSupportUrl)\r
-{\r
-    LOGI("OcPlatform_registerDeviceInfo");\r
-\r
-    std::string deviceName;\r
-    if (jDeviceName)\r
-    {\r
-        deviceName = env->GetStringUTFChars(jDeviceName, NULL);\r
-    }\r
-    std::string hostName;\r
-    if (jHostName)\r
-    {\r
-        hostName = env->GetStringUTFChars(jHostName, NULL);\r
-    }\r
-    std::string deviceUUID;\r
-    if (jDeviceUUID)\r
-    {\r
-        deviceUUID = env->GetStringUTFChars(jDeviceUUID, NULL);\r
-    }\r
-    std::string contentType;\r
-    if (jContentType)\r
-    {\r
-        contentType = env->GetStringUTFChars(jContentType, NULL);\r
-    }\r
-    std::string version;\r
-    if (jVersion)\r
-    {\r
-        version = env->GetStringUTFChars(jVersion, NULL);\r
-    }\r
-    std::string manufacturerName;\r
-    if (jManufacturerName)\r
-    {\r
-        manufacturerName = env->GetStringUTFChars(jManufacturerName, NULL);\r
-    }\r
-    std::string manufacturerUrl;\r
-    if (jManufacturerUrl)\r
-    {\r
-        manufacturerUrl = env->GetStringUTFChars(jManufacturerUrl, NULL);\r
-    }\r
-    std::string modelNumber;\r
-    if (jModelNumber)\r
-    {\r
-        modelNumber = env->GetStringUTFChars(jModelNumber, NULL);\r
-    }\r
-    std::string dateOfManufacture;\r
-    if (jDateOfManufacture)\r
-    {\r
-        dateOfManufacture = env->GetStringUTFChars(jDateOfManufacture, NULL);\r
-    }\r
-    std::string platformVersion;\r
-    if (jPlatformVersion)\r
-    {\r
-        platformVersion = env->GetStringUTFChars(jPlatformVersion, NULL);\r
-    }\r
-    std::string firmwareVersion;\r
-    if (jFirmwareVersion)\r
-    {\r
-        firmwareVersion = env->GetStringUTFChars(jFirmwareVersion, NULL);\r
-    }\r
-    std::string supportUrl;\r
-    if (jSupportUrl)\r
-    {\r
-        supportUrl = env->GetStringUTFChars(jSupportUrl, NULL);\r
-    }\r
-\r
-    OCDeviceInfo deviceInfo;\r
-    try\r
-    {\r
-        DuplicateString(&deviceInfo.contentType, contentType);\r
-        DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture);\r
-        DuplicateString(&deviceInfo.deviceName, deviceName);\r
-        DuplicateString(&deviceInfo.deviceUUID, deviceUUID);\r
-        DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion);\r
-        DuplicateString(&deviceInfo.hostName, hostName);\r
-        DuplicateString(&deviceInfo.manufacturerName, manufacturerName);\r
-        DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl);\r
-        DuplicateString(&deviceInfo.modelNumber, modelNumber);\r
-        DuplicateString(&deviceInfo.platformVersion, platformVersion);\r
-        DuplicateString(&deviceInfo.supportUrl, supportUrl);\r
-        DuplicateString(&deviceInfo.version, version);\r
-    }\r
-    catch (std::exception &e)\r
-    {\r
-        ThrowOcException(JNI_EXCEPTION, "Failed to register device info");\r
-        return;\r
-    }\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::registerDeviceInfo(deviceInfo);\r
-\r
-        delete deviceInfo.contentType;\r
-        delete deviceInfo.dateOfManufacture;\r
-        delete deviceInfo.deviceName;\r
-        delete deviceInfo.deviceUUID;\r
-        delete deviceInfo.firmwareVersion;\r
-        delete deviceInfo.hostName;\r
-        delete deviceInfo.manufacturerName;\r
-        delete deviceInfo.manufacturerUrl;\r
-        delete deviceInfo.modelNumber;\r
-        delete deviceInfo.platformVersion;\r
-        delete deviceInfo.supportUrl;\r
-        delete deviceInfo.version;\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to register device info");\r
-            return;\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    unregisterResource0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unregisterResource0\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle)\r
-{\r
-    LOGI("OcPlatform_unregisterResource");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCResourceHandle resHandle = jniOcResourceHandle->getOCResourceHandle();\r
-        OCStackResult result = OCPlatform::unregisterResource(resHandle);\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to unregister resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    bindResource0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResource0\r
-(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle)\r
-{\r
-    LOGI("OcPlatform_bindResource");\r
-    if (!jResourceCollectionHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceCollectionHandle);\r
-    if (!jniOcResourceCollectionHandle) return;\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::bindResource(\r
-            jniOcResourceCollectionHandle->getOCResourceHandle(),\r
-            jniOcResourceHandle->getOCResourceHandle()\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to bind resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    bindResources0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResources0\r
-(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray)\r
-{\r
-    LOGI("OcPlatform_bindResources");\r
-\r
-    if (!jResourceCollectionHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceHandleArray)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceCollectionHandle);\r
-    if (!jniOcResourceCollectionHandle) return;\r
-\r
-    std::vector<OCResourceHandle> resourceHandleList;\r
-    int len = env->GetArrayLength(jResourceHandleArray);\r
-    for (int i = 0; i < len; ++i)\r
-    {\r
-        jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i);\r
-        if (!jResourceHandle)\r
-        {\r
-            ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null");\r
-            return;\r
-        }\r
-\r
-        JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-            env, jResourceHandle);\r
-        if (!jniOcResourceHandle) return;\r
-\r
-        resourceHandleList.push_back(\r
-            jniOcResourceHandle->getOCResourceHandle());\r
-    }\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::bindResources(\r
-            jniOcResourceCollectionHandle->getOCResourceHandle(),\r
-            resourceHandleList\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to bind resources");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    unbindResource0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResource0\r
-(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle)\r
-{\r
-    LOGI("OcPlatform_unbindResource");\r
-    if (!jResourceCollectionHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceCollectionHandle);\r
-    if (!jniOcResourceCollectionHandle) return;\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::unbindResource(\r
-            jniOcResourceCollectionHandle->getOCResourceHandle(),\r
-            jniOcResourceHandle->getOCResourceHandle()\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to unbind resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    unbindResources0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResources0\r
-(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray)\r
-{\r
-    LOGI("OcPlatform_unbindResources");\r
-    if (!jResourceCollectionHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");\r
-        return;\r
-    }\r
-    if (!jResourceHandleArray)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceCollectionHandle);\r
-    if (!jniOcResourceCollectionHandle) return;\r
-\r
-    std::vector<OCResourceHandle> resourceHandleList;\r
-    int len = env->GetArrayLength(jResourceHandleArray);\r
-    for (int i = 0; i < len; ++i)\r
-    {\r
-        jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i);\r
-        if (!jResourceHandle)\r
-        {\r
-            ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null");\r
-            return;\r
-        }\r
-\r
-        JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-            env, jResourceHandle);\r
-        if (!jniOcResourceHandle) return;\r
-\r
-        resourceHandleList.push_back(\r
-            jniOcResourceHandle->getOCResourceHandle());\r
-    }\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::unbindResources(\r
-            jniOcResourceCollectionHandle->getOCResourceHandle(),\r
-            resourceHandleList\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to unbind resources");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    bindTypeToResource0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindTypeToResource0\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceTypeName)\r
-{\r
-    LOGI("OcPlatform_bindTypeToResource");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    std::string typeName;\r
-    if (jResourceTypeName)\r
-    {\r
-        typeName = env->GetStringUTFChars(jResourceTypeName, NULL);\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::bindTypeToResource(\r
-            jniOcResourceHandle->getOCResourceHandle(),\r
-            typeName\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to bind type to resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    bindInterfaceToResource0\r
-* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindInterfaceToResource0\r
-(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceInterfaceName)\r
-{\r
-    LOGI("OcPlatform_bindInterfaceToResource");\r
-    if (!jResourceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");\r
-        return;\r
-    }\r
-    std::string interfaceName;\r
-    if (jResourceInterfaceName)\r
-    {\r
-        interfaceName = env->GetStringUTFChars(jResourceInterfaceName, NULL);\r
-    }\r
-\r
-    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(\r
-        env, jResourceHandle);\r
-    if (!jniOcResourceHandle) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::bindInterfaceToResource(\r
-            jniOcResourceHandle->getOCResourceHandle(),\r
-            interfaceName\r
-            );\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to bind interface to resource");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    startPresence0\r
-* Signature: (I)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_startPresence0\r
-(JNIEnv *env, jclass clazz, jint ttl)\r
-{\r
-    LOGI("OcPlatform_startPresence");\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::startPresence((unsigned int)ttl);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to start presence");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    stopPresence0\r
-* Signature: ()V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stopPresence0\r
-(JNIEnv *env, jclass clazz)\r
-{\r
-    LOGI("OcPlatform_stopPresence");\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::stopPresence();\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "Failed to stop presence");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    subscribePresence0\r
-* Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle;\r
-*/\r
-JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence0\r
-(JNIEnv *env, jclass clazz, jstring jHost, jint jConnectivityType, jobject jListener)\r
-{\r
-    LOGD("OcPlatform_subscribePresence");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null");\r
-        return nullptr;\r
-    }\r
-\r
-    JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener);\r
-\r
-    SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result, const unsigned int nonce,\r
-        const std::string& hostAddress)\r
-    {\r
-        onPresenceListener->onPresenceCallback(result, nonce, hostAddress);\r
-    };\r
-\r
-    OCPlatform::OCPresenceHandle presenceHandle;\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::subscribePresence(\r
-            presenceHandle,\r
-            host,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            subscribeCallback);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "subscribe presence has failed");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-        return nullptr;\r
-    }\r
-\r
-    JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle);\r
-    jlong jhandle = reinterpret_cast<jlong>(jniPresenceHandle);\r
-    jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle);\r
-    if (!jPresenceHandle)\r
-    {\r
-        LOGE("Failed to create OcPresenceHandle");\r
-        delete jniPresenceHandle;\r
-    }\r
-\r
-    return jPresenceHandle;\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    subscribePresence1\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;I\r
-Lorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle;\r
-*/\r
-JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence1\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceType, jint jConnectivityType, jobject jListener)\r
-{\r
-    LOGD("OcPlatform_subscribePresence1");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string resourceType;\r
-    if (jResourceType)\r
-    {\r
-        resourceType = env->GetStringUTFChars(jResourceType, NULL);\r
-    }\r
-    if (!jListener)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null");\r
-        return nullptr;\r
-    }\r
-\r
-    JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener);\r
-\r
-    SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result,\r
-        const unsigned int nonce, const std::string& hostAddress)\r
-    {\r
-        onPresenceListener->onPresenceCallback(result, nonce, hostAddress);\r
-    };\r
-\r
-    OCPlatform::OCPresenceHandle presenceHandle;\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::subscribePresence(\r
-            presenceHandle,\r
-            host,\r
-            resourceType,\r
-            JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-            subscribeCallback);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "subscribe presence has failed");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-        return nullptr;\r
-    }\r
-\r
-    JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle);\r
-    jlong jhandle = reinterpret_cast<jlong>(jniPresenceHandle);\r
-    jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle);\r
-    if (!jPresenceHandle)\r
-    {\r
-        LOGE("Failed to create OcPresenceHandle");\r
-        delete jniPresenceHandle;\r
-    }\r
-    return jPresenceHandle;\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    unsubscribePresence0\r
-* Signature: (Lorg/iotivity/base/OcPresenceHandle;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unsubscribePresence0\r
-(JNIEnv *env, jclass clazz, jobject jPresenceHandle)\r
-{\r
-    LOGD("OcPlatform_unsubscribePresence");\r
-    if (!jPresenceHandle)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "presenceHandle cannot be null");\r
-        return;\r
-    }\r
-    JniOcPresenceHandle* jniPresenceHandle = JniOcPresenceHandle::getJniOcPresenceHandlePtr(env, jPresenceHandle);\r
-    if (!jniPresenceHandle) return;\r
-\r
-    OCPresenceHandle presenceHandle = jniPresenceHandle->getOCPresenceHandle();\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::unsubscribePresence(presenceHandle);\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "unsubscribe presence has failed");\r
-            return;\r
-        }\r
-        jweak jwOnPresenceListener = jniPresenceHandle->getJniOnPresenceListener()->getJWListener();\r
-        if (jwOnPresenceListener)\r
-        {\r
-            RemoveOnPresenceListener(env, jwOnPresenceListener);\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    constructResourceObject0\r
-* Signature: (Ljava/lang/String;Ljava/lang/String;IZ[Ljava/lang/String;[Ljava/lang/String;)\r
-Lorg/iotivity/base/OcResource;\r
-*/\r
-JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_constructResourceObject0\r
-(JNIEnv *env, jclass clazz, jstring jHost, jstring jUri, jint jConnectivityType,\r
-jboolean jIsObservable, jobjectArray jResourceTypeArray, jobjectArray jInterfaceArray)\r
-{\r
-    LOGD("OcPlatform_constructResourceObject");\r
-    std::string host;\r
-    if (jHost)\r
-    {\r
-        host = env->GetStringUTFChars(jHost, NULL);\r
-    }\r
-    std::string uri;\r
-    if (jUri)\r
-    {\r
-        uri = env->GetStringUTFChars(jUri, NULL);\r
-    }\r
-    if (!jResourceTypeArray)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceTypeList cannot be null");\r
-        return nullptr;\r
-    }\r
-    if (!jInterfaceArray)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "interfaceList cannot be null");\r
-        return nullptr;\r
-    }\r
-\r
-    std::vector<std::string> resourceTypes;\r
-    JniUtils::convertJavaStrArrToStrVector(env, jResourceTypeArray, resourceTypes);\r
-\r
-    std::vector<std::string> interfaces;\r
-    JniUtils::convertJavaStrArrToStrVector(env, jInterfaceArray, interfaces);\r
-\r
-    std::shared_ptr<OCResource> resource = OCPlatform::constructResourceObject(\r
-        host,\r
-        uri,\r
-        JniUtils::getConnectivityType(env, static_cast<int>(jConnectivityType)),\r
-        static_cast<bool>(jIsObservable),\r
-        resourceTypes,\r
-        interfaces);\r
-\r
-    if (!resource)\r
-    {\r
-        ThrowOcException(OC_STACK_ERROR, "Failed to create OCResource");\r
-        return nullptr;\r
-    }\r
-\r
-    JniOcResource *jniOcResource = new JniOcResource(resource);\r
-    jlong handle = reinterpret_cast<jlong>(jniOcResource);\r
-\r
-    jobject jResource = env->NewObject(g_cls_OcResource, g_mid_OcResource_ctor);\r
-    if (!jResource)\r
-    {\r
-        delete jniOcResource;\r
-        return nullptr;\r
-    }\r
-    SetHandle<JniOcResource>(env, jResource, jniOcResource);\r
-    if (env->ExceptionCheck())\r
-    {\r
-        delete jniOcResource;\r
-        return nullptr;\r
-    }\r
-    return jResource;\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcPlatform\r
-* Method:    sendResponse0\r
-* Signature: (Lorg/iotivity/base/OcResourceResponse;)V\r
-*/\r
-JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0\r
-(JNIEnv *env, jclass clazz, jobject jResourceResponse)\r
-{\r
-    LOGD("OcPlatform_sendResponse");\r
-    if (!jResourceResponse)\r
-    {\r
-        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");\r
-        return;\r
-    }\r
-\r
-    JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(\r
-        env, jResourceResponse);\r
-    if (!jniResponse) return;\r
-\r
-    try\r
-    {\r
-        OCStackResult result = OCPlatform::sendResponse(jniResponse->getOCResourceResponse());\r
-\r
-        if (OC_STACK_OK != result)\r
-        {\r
-            ThrowOcException(result, "failed to send response");\r
-        }\r
-    }\r
-    catch (OCException& e)\r
-    {\r
-        LOGE("%s", e.reason().c_str());\r
-        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
-    }\r
-}
\ No newline at end of file
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 Intel Corporation.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+* //
+* // Licensed under the Apache License, Version 2.0 (the "License");
+* // you may not use this file except in compliance with the License.
+* // You may obtain a copy of the License at
+* //
+* //      http://www.apache.org/licenses/LICENSE-2.0
+* //
+* // Unless required by applicable law or agreed to in writing, software
+* // distributed under the License is distributed on an "AS IS" BASIS,
+* // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* // See the License for the specific language governing permissions and
+* // limitations under the License.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+#include "JniOcPlatform.h"
+#include "OCPlatform.h"
+#include "JniOcResource.h"
+#include "JniOcResourceHandle.h"
+#include "JniOcPresenceHandle.h"
+#include "JniOcResourceResponse.h"
+#include "JniOcSecurity.h"
+#include "JniUtils.h"
+
+using namespace OC;
+
+JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener)
+{
+    JniOnResourceFoundListener *onResourceFoundListener = NULL;
+
+    resourceFoundMapLock.lock();
+
+    for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            onResourceFoundListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            onResourceFoundListenerMap.insert(*it);
+            LOGD("OnResourceFoundListener: ref. count incremented");
+            break;
+        }
+    }
+
+    if (!onResourceFoundListener)
+    {
+        onResourceFoundListener = new JniOnResourceFoundListener(env, jListener, RemoveOnResourceFoundListener);
+        jobject jgListener = env->NewGlobalRef(jListener);
+
+        onResourceFoundListenerMap.insert(std::pair < jobject, std::pair < JniOnResourceFoundListener*,
+            int >> (jgListener, std::pair<JniOnResourceFoundListener*, int>(onResourceFoundListener, 1)));
+        LOGD("OnResourceFoundListener: new listener");
+    }
+    resourceFoundMapLock.unlock();
+    return onResourceFoundListener;
+}
+
+void RemoveOnResourceFoundListener(JNIEnv* env, jobject jListener)
+{
+    resourceFoundMapLock.lock();
+
+    for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                onResourceFoundListenerMap.insert(*it);
+                LOGI("OnResourceFoundListener: ref. count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniOnResourceFoundListener* listener = refPair.first;
+                delete listener;
+                onResourceFoundListenerMap.erase(it);
+                LOGI("OnResourceFoundListener removed");
+            }
+            break;
+        }
+    }
+    resourceFoundMapLock.unlock();
+}
+
+JniOnDeviceInfoListener* AddOnDeviceInfoListener(JNIEnv* env, jobject jListener)
+{
+    JniOnDeviceInfoListener *onDeviceInfoListener = NULL;
+
+    deviceInfoMapLock.lock();
+
+    for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            onDeviceInfoListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            onDeviceInfoListenerMap.insert(*it);
+            LOGD("OnDeviceInfoListener: ref. count incremented");
+            break;
+        }
+    }
+
+    if (!onDeviceInfoListener)
+    {
+        onDeviceInfoListener = new JniOnDeviceInfoListener(env, jListener, RemoveOnDeviceInfoListener);
+        jobject jgListener = env->NewGlobalRef(jListener);
+
+        onDeviceInfoListenerMap.insert(std::pair < jobject, std::pair < JniOnDeviceInfoListener*,
+            int >> (jgListener, std::pair<JniOnDeviceInfoListener*, int>(onDeviceInfoListener, 1)));
+        LOGI("OnDeviceInfoListener: new listener");
+    }
+
+    deviceInfoMapLock.unlock();
+    return onDeviceInfoListener;
+}
+
+void RemoveOnDeviceInfoListener(JNIEnv* env, jobject jListener)
+{
+    deviceInfoMapLock.lock();
+    bool isFound = false;
+    for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                onDeviceInfoListenerMap.insert(*it);
+                LOGI("OnDeviceInfoListener: ref. count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniOnDeviceInfoListener* listener = refPair.first;
+                delete listener;
+                onDeviceInfoListenerMap.erase(it);
+
+                LOGI("OnDeviceInfoListener removed");
+            }
+
+            isFound = true;
+            break;
+        }
+    }
+
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "OnDeviceInfoListenet not found");
+    }
+    deviceInfoMapLock.unlock();
+}
+
+JniOnPlatformInfoListener* AddOnPlatformInfoListener(JNIEnv* env, jobject jListener)
+{
+    JniOnPlatformInfoListener *onPlatformInfoListener = NULL;
+
+    platformInfoMapLock.lock();
+
+    for (auto it = onPlatformInfoListenerMap.begin(); it != onPlatformInfoListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            onPlatformInfoListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            onPlatformInfoListenerMap.insert(*it);
+            LOGD("OnPlatformInfoListener: ref. count incremented");
+            break;
+        }
+    }
+
+    if (!onPlatformInfoListener)
+    {
+        onPlatformInfoListener = new JniOnPlatformInfoListener(env, jListener, RemoveOnPlatformInfoListener);
+        jobject jgListener = env->NewGlobalRef(jListener);
+
+        onPlatformInfoListenerMap.insert(std::pair < jobject, std::pair < JniOnPlatformInfoListener*,
+            int >> (jgListener, std::pair<JniOnPlatformInfoListener*, int>(onPlatformInfoListener, 1)));
+        LOGI("OnPlatformInfoListener: new listener");
+    }
+
+    platformInfoMapLock.unlock();
+    return onPlatformInfoListener;
+}
+
+void RemoveOnPlatformInfoListener(JNIEnv* env, jobject jListener)
+{
+    platformInfoMapLock.lock();
+    bool isFound = false;
+    for (auto it = onPlatformInfoListenerMap.begin(); it != onPlatformInfoListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                onPlatformInfoListenerMap.insert(*it);
+                LOGI("OnPlatformInfoListener: ref. count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniOnPlatformInfoListener* listener = refPair.first;
+                delete listener;
+                onPlatformInfoListenerMap.erase(it);
+
+                LOGI("OnPlatformInfoListener removed");
+            }
+
+            isFound = true;
+            break;
+        }
+    }
+
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "OnPlatformInfoListenet not found");
+    }
+    platformInfoMapLock.unlock();
+}
+
+JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener)
+{
+    JniOnPresenceListener *onPresenceListener = NULL;
+
+    presenceMapLock.lock();
+
+    for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            onPresenceListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            onPresenceListenerMap.insert(*it);
+            LOGD("OnPresenceListener: ref. count incremented");
+            break;
+        }
+    }
+    if (!onPresenceListener)
+    {
+        onPresenceListener = new JniOnPresenceListener(env, jListener, RemoveOnPresenceListener);
+        jobject jgListener = env->NewGlobalRef(jListener);
+        onPresenceListenerMap.insert(std::pair < jobject, std::pair < JniOnPresenceListener*,
+            int >> (jgListener, std::pair<JniOnPresenceListener*, int>(onPresenceListener, 1)));
+        LOGI("OnPresenceListener: new listener");
+    }
+    presenceMapLock.unlock();
+    return onPresenceListener;
+}
+
+void RemoveOnPresenceListener(JNIEnv* env, jobject jListener)
+{
+    presenceMapLock.lock();
+    bool isFound = false;
+    for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                onPresenceListenerMap.insert(*it);
+                LOGI("OnPresenceListener: ref. count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniOnPresenceListener* listener = refPair.first;
+                delete listener;
+                onPresenceListenerMap.erase(it);
+                LOGI("OnPresenceListener is removed");
+            }
+            isFound = true;
+            break;
+        }
+    }
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "OnPresenceListener not found");
+    }
+    presenceMapLock.unlock();
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    configure
+* Signature: (IILjava/lang/String;II)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
+(JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort,
+                                                                 jint jQOS, jstring jDbPath)
+{
+    LOGI("OcPlatform_configure");
+
+    std::string ipAddress;
+    std::string dbfile;
+    if (jIpAddress)
+    {
+        ipAddress = env->GetStringUTFChars(jIpAddress, NULL);
+    }
+    if (jDbPath)
+    {
+        dbfile = env->GetStringUTFChars(jDbPath, nullptr);
+        JniOcSecurity::StoreDbPath(dbfile);
+    }
+    uint16_t port;
+    if (jPort > 0)
+    {
+        port = static_cast<uint16_t>(jPort);
+    }
+    PlatformConfig cfg{
+        JniUtils::getServiceType(env, jServiceType),
+        JniUtils::getModeType(env, jModeType),
+        ipAddress,
+        port,
+        JniUtils::getQOS(env, static_cast<int>(jQOS)),
+        JniOcSecurity::getOCPersistentStorage()
+    };
+
+    OCPlatform::Configure(cfg);
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    notifyAllObservers0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers0
+(JNIEnv *env, jclass clazz, jobject jResourceHandle)
+{
+    LOGI("OcPlatform_notifyAllObservers");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::notifyAllObservers(jniOcResourceHandle->getOCResourceHandle());
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to notify all observers");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    notifyAllObservers1
+* Signature: (Lorg/iotivity/base/OcResourceHandle;I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers1
+(JNIEnv *env, jclass clazz, jobject jResourceHandle, jint jQoS)
+{
+    LOGI("OcPlatform_notifyAllObservers1");
+
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try{
+        OCStackResult result = OCPlatform::notifyAllObservers(
+            jniOcResourceHandle->getOCResourceHandle(),
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to notify all observers");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    notifyListOfObservers2
+* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers2
+(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse)
+{
+    LOGD("OcPlatform_notifyListOfObservers2");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    if (!jObservationIdArr)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null");
+        return;
+    }
+    if (!jResourceResponse)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(
+        env, jResourceResponse);
+    if (!jniOcResourceResponse) return;
+
+    int len = env->GetArrayLength(jObservationIdArr);
+    uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0);
+
+    ObservationIds observationIds;
+    for (int i = 0; i < len; ++i)
+    {
+        observationIds.push_back(bArr[i]);
+    }
+
+    env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0);
+
+    try{
+        OCStackResult result = OCPlatform::notifyListOfObservers(
+            jniOcResourceHandle->getOCResourceHandle(),
+            observationIds,
+            jniOcResourceResponse->getOCResourceResponse());
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to notify all observers");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    notifyListOfObservers3
+* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers3
+(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse, jint jQoS)
+{
+    LOGD("OcPlatform_notifyListOfObservers3");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    if (!jObservationIdArr)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null");
+        return;
+    }
+    if (!jResourceResponse)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(
+        env, jResourceResponse);
+    if (!jniOcResourceResponse) return;
+
+    int len = env->GetArrayLength(jObservationIdArr);
+    uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0);
+
+    ObservationIds observationIds;
+    for (int i = 0; i < len; ++i)
+    {
+        observationIds.push_back(bArr[i]);
+    }
+
+    env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0);
+
+    try{
+        OCStackResult result = OCPlatform::notifyListOfObservers(
+            jniOcResourceHandle->getOCResourceHandle(),
+            observationIds,
+            jniOcResourceResponse->getOCResourceResponse(),
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to notify all observers");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    findResource0
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource0
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener)
+{
+    LOGD("OcPlatform_findResource");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null");
+        return;
+    }
+
+    JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener);
+
+    FindCallback findCallback = [onResFoundListener](std::shared_ptr<OCResource> resource)
+    {
+        onResFoundListener->foundResourceCallback(resource);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::findResource(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find resource has failed");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    findResource1
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource1
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS)
+{
+    LOGD("OcPlatform_findResource");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null");
+        return;
+    }
+    JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener);
+
+    FindCallback findCallback = [onResFoundListener](std::shared_ptr<OCResource> resource)
+    {
+        onResFoundListener->foundResourceCallback(resource);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::findResource(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findCallback,
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find resource has failed");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    getDeviceInfo0
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo0
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener)
+{
+    LOGD("OcPlatform_getDeviceInfo0");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null");
+        return;
+    }
+    JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener);
+
+    FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation)
+    {
+        onDeviceInfoListener->foundDeviceCallback(ocRepresentation);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::getDeviceInfo(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findDeviceCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find device has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    getDeviceInfo1
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo1
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS)
+{
+    LOGD("OcPlatform_getDeviceInfo1");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null");
+        return;
+    }
+    JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener);
+
+    FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation)
+    {
+        onDeviceInfoListener->foundDeviceCallback(ocRepresentation);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::getDeviceInfo(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findDeviceCallback,
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find device has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    getPlatformInfo0
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPlatformFoundListener;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getPlatformInfo0
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener)
+{
+    LOGD("OcPlatform_getPlatformInfo0");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPlatformFoundListener cannot be null");
+        return;
+    }
+    JniOnPlatformInfoListener *onPlatformInfoListener = AddOnPlatformInfoListener(env, jListener);
+
+    FindPlatformCallback findPlatformCallback = [onPlatformInfoListener](const OCRepresentation& ocRepresentation)
+    {
+        onPlatformInfoListener->foundPlatformCallback(ocRepresentation);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::getPlatformInfo(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findPlatformCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find platform has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    getPlatformInfo1
+* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPlatformFoundListener;I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getPlatformInfo1
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS)
+{
+    LOGD("OcPlatform_getPlatformInfo1");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPlatformFoundListener cannot be null");
+        return;
+    }
+    JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener);
+
+    FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation)
+    {
+        onDeviceInfoListener->foundDeviceCallback(ocRepresentation);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::getPlatformInfo(
+            host,
+            resourceUri,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            findDeviceCallback,
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Find platform has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    registerResource0
+* Signature: (Lorg/iotivity/base/OcResource;)Lorg/iotivity/base/OcResourceHandle;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource0
+(JNIEnv *env, jclass clazz, jobject jResource)
+{
+    LOGD("OcPlatform_registerResource");
+    if (!jResource)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "Resource cannot be null");
+        return nullptr;
+    }
+    JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, jResource);
+    if (!resource) return nullptr;
+
+    OCResourceHandle resourceHandle;
+    try
+    {
+        OCStackResult result = OCPlatform::registerResource(
+            resourceHandle,
+            resource->getOCResource());
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "register resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return nullptr;
+    }
+    JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle);
+    jlong handle = reinterpret_cast<jlong>(jniHandle);
+    jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle);
+
+    if (!jResourceHandle)
+    {
+        LOGE("Failed to create OcResourceHandle");
+        delete jniHandle;
+    }
+    return jResourceHandle;
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    registerResource1
+* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcPlatform/EntityHandler;I)Lorg/iotivity/base/OcResourceHandle;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource1
+(JNIEnv *env, jclass clazz, jstring jResourceUri, jstring jResourceTypeName, jstring jResourceInterface,
+jobject jListener, jint jResourceProperty)
+{
+    LOGI("OcPlatform_registerResource1");
+    std::string resourceUri;
+    if (jResourceUri)
+    {
+        resourceUri = env->GetStringUTFChars(jResourceUri, NULL);
+    }
+    std::string resourceTypeName;
+    if (jResourceTypeName)
+    {
+        resourceTypeName = env->GetStringUTFChars(jResourceTypeName, NULL);
+    }
+    std::string resourceInterface;
+    if (jResourceInterface)
+    {
+        resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "entityHandler cannot be null");
+        return nullptr;
+    }
+    JniEntityHandler* entityHandler = new JniEntityHandler(env, jListener);
+    EntityHandler handleEntityCallback = [entityHandler](const std::shared_ptr<OCResourceRequest> request) ->
+        OCEntityHandlerResult{
+        return entityHandler->handleEntity(request);
+    };
+
+    OCResourceHandle resourceHandle;
+    try
+    {
+        OCStackResult result = OCPlatform::registerResource(
+            resourceHandle,
+            resourceUri,
+            resourceTypeName,
+            resourceInterface,
+            handleEntityCallback,
+            static_cast<int>(jResourceProperty));
+
+        if (OC_STACK_OK != result)
+        {
+            delete entityHandler;
+            ThrowOcException(result, "register resource");
+            return nullptr;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        delete entityHandler;
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return nullptr;
+    }
+
+    JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle);
+    jlong handle = reinterpret_cast<jlong>(jniHandle);
+    jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle);
+    if (!jResourceHandle)
+    {
+        LOGE("Failed to create OcResourceHandle");
+        delete jniHandle;
+    }
+
+    return jResourceHandle;
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    registerDeviceInfo0
+* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0
+(JNIEnv *env,
+jclass clazz,
+jstring jDeviceName)
+{
+    LOGI("OcPlatform_registerDeviceInfo");
+
+    std::string deviceName;
+    if (jDeviceName)
+    {
+        deviceName = env->GetStringUTFChars(jDeviceName, NULL);
+    }
+
+    OCDeviceInfo deviceInfo;
+    try
+    {
+        DuplicateString(&deviceInfo.deviceName, deviceName);
+    }
+    catch (std::exception &e)
+    {
+        ThrowOcException(JNI_EXCEPTION, "Failed to construct device info");
+        return;
+    }
+
+    try
+    {
+        OCStackResult result = OCPlatform::registerDeviceInfo(deviceInfo);
+
+        delete deviceInfo.deviceName;
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to register device info");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    registerPlatformInfo0
+* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerPlatformInfo0
+(JNIEnv *env,
+jclass clazz,
+jstring jPlatformID,
+jstring jManufacturerName,
+jstring jManufacturerUrl,
+jstring jModelNumber,
+jstring jDateOfManufacture,
+jstring jPlatformVersion,
+jstring jOperatingSystemVersion,
+jstring jHardwareVersion,
+jstring jFirmwareVersion,
+jstring jSupportUrl,
+jstring jSystemTime)
+{
+    LOGI("OcPlatform_registerPlatformInfo");
+
+
+    std::string platformID;
+        std::string manufacturerName;
+        std::string manufacturerUrl;
+        std::string modelNumber;
+        std::string dateOfManufacture;
+        std::string platformVersion;
+        std::string operatingSystemVersion;
+        std::string hardwareVersion;
+        std::string firmwareVersion;
+        std::string supportUrl;
+        std::string systemTime;
+
+        if (jPlatformID)
+        {
+            platformID = env->GetStringUTFChars(jPlatformID, NULL);
+        }
+        if (jManufacturerName)
+        {
+            manufacturerName = env->GetStringUTFChars(jManufacturerName, NULL);
+        }
+        if (jManufacturerUrl)
+        {
+            manufacturerUrl = env->GetStringUTFChars(jManufacturerUrl, NULL);
+        }
+        if (jModelNumber)
+        {
+            modelNumber = env->GetStringUTFChars(jModelNumber, NULL);
+        }
+        if (jDateOfManufacture)
+        {
+            dateOfManufacture = env->GetStringUTFChars(jDateOfManufacture, NULL);
+        }
+        if (jPlatformVersion)
+        {
+            platformVersion = env->GetStringUTFChars(jPlatformVersion, NULL);
+        }
+        if (jOperatingSystemVersion)
+        {
+            operatingSystemVersion = env->GetStringUTFChars(jOperatingSystemVersion, NULL);
+        }
+        if (jHardwareVersion)
+        {
+            hardwareVersion = env->GetStringUTFChars(jHardwareVersion, NULL);
+        }
+        if (jFirmwareVersion)
+        {
+            firmwareVersion = env->GetStringUTFChars(jFirmwareVersion, NULL);
+        }
+        if (jSupportUrl)
+        {
+            supportUrl = env->GetStringUTFChars(jSupportUrl, NULL);
+        }
+        if (jSystemTime)
+        {
+            systemTime = env->GetStringUTFChars(jSystemTime, NULL);
+        }
+
+        OCPlatformInfo platformInfo;
+        try
+        {
+            DuplicateString(&platformInfo.platformID, platformID);
+            DuplicateString(&platformInfo.manufacturerName, manufacturerName);
+            DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl);
+            DuplicateString(&platformInfo.modelNumber, modelNumber);
+            DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture);
+            DuplicateString(&platformInfo.platformVersion, platformVersion);
+            DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion);
+            DuplicateString(&platformInfo.hardwareVersion, hardwareVersion);
+            DuplicateString(&platformInfo.firmwareVersion, firmwareVersion);
+            DuplicateString(&platformInfo.supportUrl, supportUrl);
+            DuplicateString(&platformInfo.systemTime, systemTime);
+        }
+        catch (std::exception &e)
+        {
+            ThrowOcException(JNI_EXCEPTION, "Failed to construct platform info");
+            return;
+        }
+
+       // __android_log_print(ANDROID_LOG_INFO, "Rahul", "platformID  = %s", platformID);
+        try
+        {
+            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;
+
+            if (OC_STACK_OK != result)
+            {
+                ThrowOcException(result, "Failed to register platform info");
+                return;
+            }
+        }
+        catch (OCException& e)
+        {
+            LOGE("Error is due to %s", e.reason().c_str());
+            ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        }
+
+
+
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    unregisterResource0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unregisterResource0
+(JNIEnv *env, jclass clazz, jobject jResourceHandle)
+{
+    LOGI("OcPlatform_unregisterResource");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCResourceHandle resHandle = jniOcResourceHandle->getOCResourceHandle();
+        OCStackResult result = OCPlatform::unregisterResource(resHandle);
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to unregister resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    bindResource0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResource0
+(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle)
+{
+    LOGI("OcPlatform_bindResource");
+    if (!jResourceCollectionHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");
+        return;
+    }
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceCollectionHandle);
+    if (!jniOcResourceCollectionHandle) return;
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::bindResource(
+            jniOcResourceCollectionHandle->getOCResourceHandle(),
+            jniOcResourceHandle->getOCResourceHandle()
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to bind resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    bindResources0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResources0
+(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray)
+{
+    LOGI("OcPlatform_bindResources");
+
+    if (!jResourceCollectionHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");
+        return;
+    }
+    if (!jResourceHandleArray)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceCollectionHandle);
+    if (!jniOcResourceCollectionHandle) return;
+
+    std::vector<OCResourceHandle> resourceHandleList;
+    int len = env->GetArrayLength(jResourceHandleArray);
+    for (int i = 0; i < len; ++i)
+    {
+        jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i);
+        if (!jResourceHandle)
+        {
+            ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null");
+            return;
+        }
+
+        JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+            env, jResourceHandle);
+        if (!jniOcResourceHandle) return;
+
+        resourceHandleList.push_back(
+            jniOcResourceHandle->getOCResourceHandle());
+    }
+
+    try
+    {
+        OCStackResult result = OCPlatform::bindResources(
+            jniOcResourceCollectionHandle->getOCResourceHandle(),
+            resourceHandleList
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to bind resources");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    unbindResource0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResource0
+(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle)
+{
+    LOGI("OcPlatform_unbindResource");
+    if (!jResourceCollectionHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");
+        return;
+    }
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceCollectionHandle);
+    if (!jniOcResourceCollectionHandle) return;
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::unbindResource(
+            jniOcResourceCollectionHandle->getOCResourceHandle(),
+            jniOcResourceHandle->getOCResourceHandle()
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to unbind resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    unbindResources0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResources0
+(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray)
+{
+    LOGI("OcPlatform_unbindResources");
+    if (!jResourceCollectionHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null");
+        return;
+    }
+    if (!jResourceHandleArray)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null");
+        return;
+    }
+
+    JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceCollectionHandle);
+    if (!jniOcResourceCollectionHandle) return;
+
+    std::vector<OCResourceHandle> resourceHandleList;
+    int len = env->GetArrayLength(jResourceHandleArray);
+    for (int i = 0; i < len; ++i)
+    {
+        jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i);
+        if (!jResourceHandle)
+        {
+            ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null");
+            return;
+        }
+
+        JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+            env, jResourceHandle);
+        if (!jniOcResourceHandle) return;
+
+        resourceHandleList.push_back(
+            jniOcResourceHandle->getOCResourceHandle());
+    }
+
+    try
+    {
+        OCStackResult result = OCPlatform::unbindResources(
+            jniOcResourceCollectionHandle->getOCResourceHandle(),
+            resourceHandleList
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to unbind resources");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    bindTypeToResource0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindTypeToResource0
+(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceTypeName)
+{
+    LOGI("OcPlatform_bindTypeToResource");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    std::string typeName;
+    if (jResourceTypeName)
+    {
+        typeName = env->GetStringUTFChars(jResourceTypeName, NULL);
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::bindTypeToResource(
+            jniOcResourceHandle->getOCResourceHandle(),
+            typeName
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to bind type to resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    bindInterfaceToResource0
+* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindInterfaceToResource0
+(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceInterfaceName)
+{
+    LOGI("OcPlatform_bindInterfaceToResource");
+    if (!jResourceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null");
+        return;
+    }
+    std::string interfaceName;
+    if (jResourceInterfaceName)
+    {
+        interfaceName = env->GetStringUTFChars(jResourceInterfaceName, NULL);
+    }
+
+    JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(
+        env, jResourceHandle);
+    if (!jniOcResourceHandle) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::bindInterfaceToResource(
+            jniOcResourceHandle->getOCResourceHandle(),
+            interfaceName
+            );
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to bind interface to resource");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    startPresence0
+* Signature: (I)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_startPresence0
+(JNIEnv *env, jclass clazz, jint ttl)
+{
+    LOGI("OcPlatform_startPresence");
+
+    try
+    {
+        OCStackResult result = OCPlatform::startPresence((unsigned int)ttl);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to start presence");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    stopPresence0
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stopPresence0
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform_stopPresence");
+
+    try
+    {
+        OCStackResult result = OCPlatform::stopPresence();
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to stop presence");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    subscribePresence0
+* Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence0
+(JNIEnv *env, jclass clazz, jstring jHost, jint jConnectivityType, jobject jListener)
+{
+    LOGD("OcPlatform_subscribePresence");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null");
+        return nullptr;
+    }
+
+    JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener);
+
+    SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result, const unsigned int nonce,
+        const std::string& hostAddress)
+    {
+        onPresenceListener->onPresenceCallback(result, nonce, hostAddress);
+    };
+
+    OCPlatform::OCPresenceHandle presenceHandle;
+    try
+    {
+        OCStackResult result = OCPlatform::subscribePresence(
+            presenceHandle,
+            host,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            subscribeCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "subscribe presence has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return nullptr;
+    }
+
+    JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle);
+    jlong jhandle = reinterpret_cast<jlong>(jniPresenceHandle);
+    jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle);
+    if (!jPresenceHandle)
+    {
+        LOGE("Failed to create OcPresenceHandle");
+        delete jniPresenceHandle;
+    }
+    return jPresenceHandle;
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    subscribePresence1
+* Signature: (Ljava/lang/String;Ljava/lang/String;I
+Lorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence1
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceType, jint jConnectivityType, jobject jListener)
+{
+    LOGD("OcPlatform_subscribePresence1");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string resourceType;
+    if (jResourceType)
+    {
+        resourceType = env->GetStringUTFChars(jResourceType, NULL);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null");
+        return nullptr;
+    }
+
+    JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener);
+
+    SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result,
+        const unsigned int nonce, const std::string& hostAddress)
+    {
+        onPresenceListener->onPresenceCallback(result, nonce, hostAddress);
+    };
+
+    OCPlatform::OCPresenceHandle presenceHandle;
+    try
+    {
+        OCStackResult result = OCPlatform::subscribePresence(
+            presenceHandle,
+            host,
+            resourceType,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            subscribeCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "subscribe presence has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return nullptr;
+    }
+
+    JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle);
+    jlong jhandle = reinterpret_cast<jlong>(jniPresenceHandle);
+    jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle);
+    if (!jPresenceHandle)
+    {
+        LOGE("Failed to create OcPresenceHandle");
+        delete jniPresenceHandle;
+    }
+    return jPresenceHandle;
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    unsubscribePresence0
+* Signature: (Lorg/iotivity/base/OcPresenceHandle;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unsubscribePresence0
+(JNIEnv *env, jclass clazz, jobject jPresenceHandle)
+{
+    LOGD("OcPlatform_unsubscribePresence");
+    if (!jPresenceHandle)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "presenceHandle cannot be null");
+        return;
+    }
+    JniOcPresenceHandle* jniPresenceHandle = JniOcPresenceHandle::getJniOcPresenceHandlePtr(env, jPresenceHandle);
+    if (!jniPresenceHandle) return;
+
+    OCPresenceHandle presenceHandle = jniPresenceHandle->getOCPresenceHandle();
+
+    try
+    {
+        OCStackResult result = OCPlatform::unsubscribePresence(presenceHandle);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "unsubscribe presence has failed");
+            return;
+        }
+        jweak jwOnPresenceListener = jniPresenceHandle->getJniOnPresenceListener()->getJWListener();
+        if (jwOnPresenceListener)
+        {
+            RemoveOnPresenceListener(env, jwOnPresenceListener);
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    constructResourceObject0
+* Signature: (Ljava/lang/String;Ljava/lang/String;IZ[Ljava/lang/String;[Ljava/lang/String;)
+Lorg/iotivity/base/OcResource;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_constructResourceObject0
+(JNIEnv *env, jclass clazz, jstring jHost, jstring jUri, jint jConnectivityType,
+jboolean jIsObservable, jobjectArray jResourceTypeArray, jobjectArray jInterfaceArray)
+{
+    LOGD("OcPlatform_constructResourceObject");
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, NULL);
+    }
+    std::string uri;
+    if (jUri)
+    {
+        uri = env->GetStringUTFChars(jUri, NULL);
+    }
+    if (!jResourceTypeArray)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceTypeList cannot be null");
+        return nullptr;
+    }
+    if (!jInterfaceArray)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "interfaceList cannot be null");
+        return nullptr;
+    }
+
+    std::vector<std::string> resourceTypes;
+    JniUtils::convertJavaStrArrToStrVector(env, jResourceTypeArray, resourceTypes);
+
+    std::vector<std::string> interfaces;
+    JniUtils::convertJavaStrArrToStrVector(env, jInterfaceArray, interfaces);
+
+    std::shared_ptr<OCResource> resource = OCPlatform::constructResourceObject(
+        host,
+        uri,
+        static_cast<OCConnectivityType>(jConnectivityType),
+        static_cast<bool>(jIsObservable),
+        resourceTypes,
+        interfaces);
+
+    if (!resource)
+    {
+        ThrowOcException(OC_STACK_ERROR, "Failed to create OCResource");
+        return nullptr;
+    }
+
+    JniOcResource *jniOcResource = new JniOcResource(resource);
+    jlong handle = reinterpret_cast<jlong>(jniOcResource);
+
+    jobject jResource = env->NewObject(g_cls_OcResource, g_mid_OcResource_ctor);
+    if (!jResource)
+    {
+        delete jniOcResource;
+        return nullptr;
+    }
+    SetHandle<JniOcResource>(env, jResource, jniOcResource);
+    if (env->ExceptionCheck())
+    {
+        delete jniOcResource;
+        return nullptr;
+    }
+    return jResource;
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    sendResponse0
+* Signature: (Lorg/iotivity/base/OcResourceResponse;)V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0
+(JNIEnv *env, jclass clazz, jobject jResourceResponse)
+{
+    LOGD("OcPlatform_sendResponse");
+    if (!jResourceResponse)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null");
+        return;
+    }
+
+    JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(
+        env, jResourceResponse);
+    if (!jniResponse) return;
+
+    try
+    {
+        OCStackResult result = OCPlatform::sendResponse(jniResponse->getOCResourceResponse());
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "failed to send response");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
index 1019147..ca7051e 100644 (file)
@@ -22,6 +22,7 @@
 #include "JniOcStack.h"\r
 #include "JniOnResourceFoundListener.h"\r
 #include "JniOnDeviceInfoListener.h"\r
+#include "JniOnPlatformInfoListener.h"
 #include "JniOnPresenceListener.h"\r
 #include <mutex>\r
 \r
@@ -36,15 +37,20 @@ void RemoveOnResourceFoundListener(JNIEnv* env, jobject jListener);
 JniOnDeviceInfoListener* AddOnDeviceInfoListener(JNIEnv* env, jobject jListener);\r
 void RemoveOnDeviceInfoListener(JNIEnv* env, jobject jListener);\r
 \r
+JniOnPlatformInfoListener* AddOnPlatformInfoListener(JNIEnv* env, jobject jListener);
+void RemoveOnPlatformInfoListener(JNIEnv* env, jobject jListener);
+
 JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener);\r
 void RemoveOnPresenceListener(JNIEnv* env, jobject jListener);\r
 \r
 std::map<jobject, std::pair<JniOnResourceFoundListener*, int>> onResourceFoundListenerMap;\r
 std::map<jobject, std::pair<JniOnDeviceInfoListener*, int>> onDeviceInfoListenerMap;\r
+std::map<jobject, std::pair<JniOnPlatformInfoListener*, int>> onPlatformInfoListenerMap;
 std::map<jobject, std::pair<JniOnPresenceListener*, int>> onPresenceListenerMap;\r
 \r
 std::mutex resourceFoundMapLock;\r
 std::mutex deviceInfoMapLock;\r
+std::mutex platformInfoMapLock;
 std::mutex presenceMapLock;\r
 \r
 #ifdef __cplusplus\r
@@ -56,7 +62,7 @@ extern "C" {
     * Signature: (IILjava/lang/String;II)V\r
     */\r
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure\r
-        (JNIEnv *, jclass, jint, jint, jstring, jint, jint);\r
+        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring);
 \r
     /*\r
     * Class:     org_iotivity_base_OcPlatform\r
@@ -120,6 +126,22 @@ extern "C" {
     * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;I)V\r
     */\r
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo1\r
+        (JNIEnv *, jclass, jstring, jstring, jint, jobject, jint);
+
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    getPlatformInfo0
+     * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPlatformFoundListener;)V
+     */
+     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getPlatformInfo0
+        (JNIEnv *, jclass, jstring, jstring, jint, jobject);
+
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    getPlatformInfo1
+     * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPlatformFoundListener;I)V
+     */
+     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getPlatformInfo1
         (JNIEnv *, jclass, jstring, jstring, jint, jobject, jint);\r
 \r
     /*\r
@@ -141,10 +163,18 @@ extern "C" {
     /*\r
     * Class:     org_iotivity_base_OcPlatform\r
     * Method:    registerDeviceInfo0\r
-    * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V\r
+    * Signature: (Ljava/lang/String;)V
     */\r
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0\r
-        (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring);\r
+        (JNIEnv *, jclass, jstring);
+
+    /*
+    * Class:     org_iotivity_base_OcPlatform
+    * Method:    registerPlatformInfo0
+    * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+    */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerPlatformInfo0
+        (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring);
 \r
     /*\r
     * Class:     org_iotivity_base_OcPlatform\r
@@ -262,3 +292,4 @@ extern "C" {
 }\r
 #endif\r
 #endif\r
+
index e2c2cd0..c143069 100644 (file)
@@ -722,22 +722,6 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresent
 \r
 /*\r
 * Class:     org_iotivity_base_OcRepresentation\r
-* Method:    getJSONRepresentation\r
-* Signature: ()Ljava/lang/String;\r
-*/\r
-JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation\r
-(JNIEnv *env, jobject thiz)\r
-{\r
-    LOGD("OcRepresentation_getJSONRepresentation");\r
-    OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz);\r
-    if (!rep) return nullptr;\r
-\r
-    std::string jsonStr = rep->getJSONRepresentation();\r
-    return env->NewStringUTF(jsonStr.c_str());\r
-}\r
-\r
-/*\r
-* Class:     org_iotivity_base_OcRepresentation\r
 * Method:    addChild\r
 * Signature: (Lorg/iotivity/base/OcRepresentation;)V\r
 */\r
@@ -1037,4 +1021,4 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_dispose
     {\r
         delete rep;\r
     }\r
-}
\ No newline at end of file
+}\r
index 3f25c29..fbf3131 100644 (file)
@@ -621,14 +621,6 @@ extern "C" {
 \r
     /*\r
     * Class:     org_iotivity_base_OcRepresentation\r
-    * Method:    getJSONRepresentation\r
-    * Signature: ()Ljava/lang/String;\r
-    */\r
-    JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation\r
-        (JNIEnv *, jobject);\r
-\r
-    /*\r
-    * Class:     org_iotivity_base_OcRepresentation\r
     * Method:    addChild\r
     * Signature: (Lorg/iotivity/base/OcRepresentation;)V\r
     */\r
@@ -766,4 +758,4 @@ extern "C" {
 #ifdef __cplusplus\r
 }\r
 #endif\r
-#endif
\ No newline at end of file
+#endif
diff --git a/android/android_api/base/jni/JniOcSecurity.cpp b/android/android_api/base/jni/JniOcSecurity.cpp
new file mode 100644 (file)
index 0000000..54821ee
--- /dev/null
@@ -0,0 +1,60 @@
+/******************************************************************
+ *
+ * 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 "JniOcSecurity.h"
+#include "JniOcStack.h"
+
+/*
+ * TODO: Persistant Storage Handling should be done by App.
+ * For 0.9.2 , Handling is done at JNI. As of now Plaform Config only
+ * SVR Database fileName(fullpath) is passed.
+ */
+using namespace std;
+namespace PH = std::placeholders;
+namespace OC {
+
+    string& JniOcSecurity::store_path()
+    {
+        static string s_dbPath;
+        return s_dbPath;
+    }
+
+    void JniOcSecurity::StoreDbPath(const string &path)
+    {
+        store_path() = path;
+    }
+
+    OCPersistentStorage* JniOcSecurity::getOCPersistentStorage()
+    {
+        if (store_path().empty())
+        {
+            return nullptr;
+        }
+        static OCPersistentStorage s_ps { &JniOcSecurity::client_open, fread,
+            fwrite, fclose, unlink };
+        return &s_ps;
+    }
+
+    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);
+    }
+}
diff --git a/android/android_api/base/jni/JniOcSecurity.h b/android/android_api/base/jni/JniOcSecurity.h
new file mode 100644 (file)
index 0000000..78293e6
--- /dev/null
@@ -0,0 +1,43 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef __JNIOCSECURITY_H
+#define __JNIOCSECURITY_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string>
+#include "octypes.h"
+#include <unistd.h>
+
+namespace OC
+{
+    class JniOcSecurity
+    {
+        private:
+            static FILE* client_open(const char*, const char*);
+        public:
+            static std::string& store_path(void);
+            static void StoreDbPath(const std::string&);
+            static OCPersistentStorage* getOCPersistentStorage(void);
+    };
+}
+#endif //__JNIOCSECURITY_H
diff --git a/android/android_api/base/jni/JniOnPlatformInfoListener.cpp b/android/android_api/base/jni/JniOnPlatformInfoListener.cpp
new file mode 100644 (file)
index 0000000..27ecf74
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 Intel Corporation.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+* //
+* // Licensed under the Apache License, Version 2.0 (the "License");
+* // you may not use this file except in compliance with the License.
+* // You may obtain a copy of the License at
+* //
+* //      http://www.apache.org/licenses/LICENSE-2.0
+* //
+* // Unless required by applicable law or agreed to in writing, software
+* // distributed under the License is distributed on an "AS IS" BASIS,
+* // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* // See the License for the specific language governing permissions and
+* // limitations under the License.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+#include "JniOnPlatformInfoListener.h"
+#include "JniOcRepresentation.h"
+
+JniOnPlatformInfoListener::JniOnPlatformInfoListener(JNIEnv *env, jobject jListener,
+    RemoveListenerCallback removeListenerCallback)
+{
+    m_jwListener = env->NewWeakGlobalRef(jListener);
+    m_removeListenerCallback = removeListenerCallback;
+}
+
+JniOnPlatformInfoListener::~JniOnPlatformInfoListener()
+{
+    LOGI("~JniOnPlatformInfoListener");
+    if (m_jwListener)
+    {
+        jint ret;
+        JNIEnv *env = GetJNIEnv(ret);
+        if (NULL == env) return;
+        env->DeleteWeakGlobalRef(m_jwListener);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+    }
+}
+
+void JniOnPlatformInfoListener::foundPlatformCallback(const OC::OCRepresentation& ocRepresentation)
+{
+    jint ret;
+    JNIEnv *env = GetJNIEnv(ret);
+    if (NULL == env) return;
+
+    jobject jListener = env->NewLocalRef(m_jwListener);
+    if (!jListener)
+    {
+        LOGI("Java onPlatformInfoListener object is already destroyed, quiting");
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return;
+    }
+
+    OCRepresentation* rep = new OCRepresentation(ocRepresentation);
+    jlong handle = reinterpret_cast<jlong>(rep);
+    jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,
+        handle, true);
+    if (!jRepresentation)
+    {
+        delete rep;
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return;
+    }
+
+    jclass clsL = env->GetObjectClass(jListener);
+    if (!clsL)
+    {
+        delete rep;
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return;
+    }
+    jmethodID midL = env->GetMethodID(clsL, "onPlatformFound", "(Lorg/iotivity/base/OcRepresentation;)V");
+    if (!midL)
+    {
+        delete rep;
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return;
+    }
+
+    env->CallVoidMethod(jListener, midL, jRepresentation);
+    if (env->ExceptionCheck())
+    {
+        LOGE("Java exception is thrown");
+        delete rep;
+        checkExAndRemoveListener(env);
+    }
+
+    if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+}
+
+void JniOnPlatformInfoListener::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);
+    }
+}
+
diff --git a/android/android_api/base/jni/JniOnPlatformInfoListener.h b/android/android_api/base/jni/JniOnPlatformInfoListener.h
new file mode 100644 (file)
index 0000000..ebc3c09
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 Intel Corporation.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+* //
+* // Licensed under the Apache License, Version 2.0 (the "License");
+* // you may not use this file except in compliance with the License.
+* // You may obtain a copy of the License at
+* //
+* //      http://www.apache.org/licenses/LICENSE-2.0
+* //
+* // Unless required by applicable law or agreed to in writing, software
+* // distributed under the License is distributed on an "AS IS" BASIS,
+* // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* // See the License for the specific language governing permissions and
+* // limitations under the License.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+#include <jni.h>
+#include "JniOcStack.h"
+
+#ifndef _Included_org_iotivity_base_OcPlatform_OnPlatformFoundListener
+#define _Included_org_iotivity_base_OcPlatform_OnPlatformFoundListener
+
+class JniOnPlatformInfoListener
+{
+public:
+    JniOnPlatformInfoListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
+    ~JniOnPlatformInfoListener();
+
+    void foundPlatformCallback(const OC::OCRepresentation& ocRepresentation);
+
+private:
+    jweak m_jwListener;
+    RemoveListenerCallback m_removeListenerCallback;
+    void checkExAndRemoveListener(JNIEnv* env);
+};
+
+#endif
index 6ec806c..e26a82c 100644 (file)
-/*\r
-* //******************************************************************\r
-* //\r
-* // Copyright 2015 Intel Corporation.\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
-#include "JniUtils.h"\r
-#include "JniOcRepresentation.h"\r
-\r
-jobject JniUtils::convertStrVectorToJavaStrList(JNIEnv *env, std::vector<std::string> &vector)\r
-{\r
-    jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);\r
-    if (!jList) return nullptr;\r
-    for (size_t i = 0; i < vector.size(); ++i)\r
-    {\r
-        jstring jStr = env->NewStringUTF(vector[i].c_str());\r
-        if (!jStr) return nullptr;\r
-        env->CallBooleanMethod(jList, g_mid_LinkedList_add_object, jStr);\r
-        if (env->ExceptionCheck()) return nullptr;\r
-        env->DeleteLocalRef(jStr);\r
-    }\r
-    return jList;\r
-}\r
-\r
-void JniUtils::convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr, std::vector<std::string> &vector)\r
-{\r
-    if (!jStrArr) return;\r
-\r
-    jsize len = env->GetArrayLength(jStrArr);\r
-    for (jsize i = 0; i < len; ++i)\r
-    {\r
-        jstring jStr = (jstring)env->GetObjectArrayElement(jStrArr, i);\r
-        if (!jStr) return;\r
-        vector.push_back(env->GetStringUTFChars(jStr, NULL));\r
-        if (env->ExceptionCheck()) return;\r
-        env->DeleteLocalRef(jStr);\r
-    }\r
-}\r
-\r
-void JniUtils::convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions,\r
-    OC::HeaderOptions &headerOptions)\r
-{\r
-    if (!jHeaderOptions) return;\r
-\r
-    jsize len = env->GetArrayLength(jHeaderOptions);\r
-    for (jsize i = 0; i < len; ++i)\r
-    {\r
-        jobject header = env->GetObjectArrayElement(jHeaderOptions, i);\r
-        if (!header) nullptr;\r
-        jint jId = env->CallIntMethod(header, g_mid_OcHeaderOption_get_id);\r
-        jstring jData = (jstring)env->CallObjectMethod(header, g_mid_OcHeaderOption_get_data);\r
-        if (jData) return;\r
-\r
-        OC::HeaderOption::OCHeaderOption hopt(\r
-            static_cast<int>(jId),\r
-            env->GetStringUTFChars(jData, NULL));\r
-\r
-        headerOptions.push_back(hopt);\r
-\r
-        if (env->ExceptionCheck()) return;\r
-        env->DeleteLocalRef(header);\r
-        env->DeleteLocalRef(jData);\r
-    }\r
-}\r
-\r
-jobject JniUtils::convertHeaderOptionsVectorToJavaList(JNIEnv *env, const OC::HeaderOptions& headerOptions)\r
-{\r
-    jobject jHeaderOptionList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);\r
-    if (!jHeaderOptionList) return nullptr;\r
-\r
-    for (size_t i = 0; i < headerOptions.size(); ++i)\r
-    {\r
-        jobject jHeaderOption = env->NewObject(\r
-            g_cls_OcHeaderOption,\r
-            g_mid_OcHeaderOption_ctor,\r
-            static_cast<jint>(headerOptions[i].getOptionID()),\r
-            env->NewStringUTF(headerOptions[i].getOptionData().c_str())\r
-            );\r
-        if (!jHeaderOption) return nullptr;\r
-\r
-        env->CallBooleanMethod(jHeaderOptionList, g_mid_LinkedList_add_object, jHeaderOption);\r
-        if (env->ExceptionCheck()) return nullptr;\r
-        env->DeleteLocalRef(jHeaderOption);\r
-    }\r
-\r
-    return jHeaderOptionList;\r
-}\r
-\r
-void JniUtils::convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap, OC::QueryParamsMap &map)\r
-{\r
-    if (!hashMap) return;\r
-\r
-    jobject jEntrySet = env->CallObjectMethod(hashMap, g_mid_Map_entrySet);\r
-    jobject jIterator = env->CallObjectMethod(jEntrySet, g_mid_Set_iterator);\r
-    if (!jEntrySet || !jIterator || env->ExceptionCheck()) return;\r
-\r
-    while (env->CallBooleanMethod(jIterator, g_mid_Iterator_hasNext))\r
-    {\r
-        jobject jEntry = env->CallObjectMethod(jIterator, g_mid_Iterator_next);\r
-        if (!jEntry) return;\r
-        jstring jKey = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getKey);\r
-        if (!jKey) return;\r
-        jstring jValue = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getValue);\r
-        if (!jValue) return;\r
-\r
-        map.insert(std::make_pair(env->GetStringUTFChars(jKey, NULL),\r
-            env->GetStringUTFChars(jValue, NULL)));\r
-\r
-        if (env->ExceptionCheck()) return;\r
-        env->DeleteLocalRef(jEntry);\r
-        env->DeleteLocalRef(jKey);\r
-        env->DeleteLocalRef(jValue);\r
-    }\r
-}\r
-\r
-jobject JniUtils::convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map)\r
-{\r
-    jobject hashMap = env->NewObject(g_cls_HashMap, g_mid_HashMap_ctor);\r
-    if (!hashMap) return nullptr;\r
-\r
-    for (auto it = map.begin(); it != map.end(); ++it)\r
-    {\r
-        std::string key = it->first;\r
-        std::string value = it->second;\r
-\r
-        env->CallObjectMethod(hashMap,\r
-            g_mid_HashMap_put,\r
-            env->NewStringUTF(key.c_str()),\r
-            env->NewStringUTF(value.c_str()));\r
-        if (env->ExceptionCheck()) return nullptr;\r
-    }\r
-\r
-    return hashMap;\r
-}\r
-\r
-void JniUtils::convertJavaRepresentationArrToVector(JNIEnv *env,\r
-    jobjectArray jRepresentationArray,\r
-    std::vector<OC::OCRepresentation>& representationVector)\r
-{\r
-    if (!jRepresentationArray) return;\r
-    jsize len = env->GetArrayLength(jRepresentationArray);\r
-\r
-    for (jsize i = 0; i < len; ++i)\r
-    {\r
-        jobject jRep = env->GetObjectArrayElement(jRepresentationArray, i);\r
-        if (!jRep) return;\r
-        OC::OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, jRep);\r
-        representationVector.push_back(*rep);\r
-        if (env->ExceptionCheck()) return;\r
-        env->DeleteLocalRef(jRep);\r
-    }\r
-}\r
-\r
-jobjectArray JniUtils::convertRepresentationVectorToJavaArray(JNIEnv *env,\r
-    const std::vector<OC::OCRepresentation>& representationVector)\r
-{\r
-    jsize len = static_cast<jsize>(representationVector.size());\r
-    jobjectArray repArr = env->NewObjectArray(len, g_cls_OcRepresentation, NULL);\r
-    if (!repArr) return nullptr;\r
-    for (jsize i = 0; i < len; ++i)\r
-    {\r
-        OCRepresentation* rep = new OCRepresentation(representationVector[i]);\r
-        jlong handle = reinterpret_cast<jlong>(rep);\r
-        jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,\r
-            handle, true);\r
-        if (!jRepresentation)\r
-        {\r
-            delete rep;\r
-            return nullptr;\r
-        }\r
-        env->SetObjectArrayElement(repArr, i, jRepresentation);\r
-        if (env->ExceptionCheck()) return nullptr;\r
-        env->DeleteLocalRef(jRepresentation);\r
-    }\r
-\r
-    return repArr;\r
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 Intel Corporation.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+* //
+* // Licensed under the Apache License, Version 2.0 (the "License");
+* // you may not use this file except in compliance with the License.
+* // You may obtain a copy of the License at
+* //
+* //      http://www.apache.org/licenses/LICENSE-2.0
+* //
+* // Unless required by applicable law or agreed to in writing, software
+* // distributed under the License is distributed on an "AS IS" BASIS,
+* // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* // See the License for the specific language governing permissions and
+* // limitations under the License.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+
+#include "JniUtils.h"
+#include "JniOcRepresentation.h"
+
+jobject JniUtils::convertStrVectorToJavaStrList(JNIEnv *env, std::vector<std::string> &vector)
+{
+    jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
+    if (!jList) return nullptr;
+    for (size_t i = 0; i < vector.size(); ++i)
+    {
+        jstring jStr = env->NewStringUTF(vector[i].c_str());
+        if (!jStr) return nullptr;
+        env->CallBooleanMethod(jList, g_mid_LinkedList_add_object, jStr);
+        if (env->ExceptionCheck()) return nullptr;
+        env->DeleteLocalRef(jStr);
+    }
+    return jList;
+}
+
+void JniUtils::convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr, std::vector<std::string> &vector)
+{
+    if (!jStrArr) return;
+
+    jsize len = env->GetArrayLength(jStrArr);
+    for (jsize i = 0; i < len; ++i)
+    {
+        jstring jStr = (jstring)env->GetObjectArrayElement(jStrArr, i);
+        if (!jStr) return;
+        vector.push_back(env->GetStringUTFChars(jStr, NULL));
+        if (env->ExceptionCheck()) return;
+        env->DeleteLocalRef(jStr);
+    }
+}
+
+void JniUtils::convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions,
+    OC::HeaderOptions &headerOptions)
+{
+    if (!jHeaderOptions) return;
+    jsize len = env->GetArrayLength(jHeaderOptions);
+    for (jsize i = 0; i < len; ++i)
+    {
+        jobject header = env->GetObjectArrayElement(jHeaderOptions, i);
+        if (!header) return;
+        jint jId = env->CallIntMethod(header, g_mid_OcHeaderOption_get_id);
+        jstring jData = (jstring)env->CallObjectMethod(header, g_mid_OcHeaderOption_get_data);
+        OC::HeaderOption::OCHeaderOption hopt(
+            static_cast<int>(jId),
+            env->GetStringUTFChars(jData, NULL));
+
+        headerOptions.push_back(hopt);
+
+        if (env->ExceptionCheck()) return;
+        env->DeleteLocalRef(header);
+        env->DeleteLocalRef(jData);
+    }
+}
+
+jobject JniUtils::convertHeaderOptionsVectorToJavaList(JNIEnv *env, const OC::HeaderOptions& headerOptions)
+{
+    jobject jHeaderOptionList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
+    if (!jHeaderOptionList) return nullptr;
+
+    for (size_t i = 0; i < headerOptions.size(); ++i)
+    {
+        jobject jHeaderOption = env->NewObject(
+            g_cls_OcHeaderOption,
+            g_mid_OcHeaderOption_ctor,
+            static_cast<jint>(headerOptions[i].getOptionID()),
+            env->NewStringUTF(headerOptions[i].getOptionData().c_str())
+            );
+        if (!jHeaderOption) return nullptr;
+
+        env->CallBooleanMethod(jHeaderOptionList, g_mid_LinkedList_add_object, jHeaderOption);
+        if (env->ExceptionCheck()) return nullptr;
+        env->DeleteLocalRef(jHeaderOption);
+    }
+
+    return jHeaderOptionList;
+}
+
+void JniUtils::convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap, OC::QueryParamsMap &map)
+{
+    if (!hashMap) return;
+
+    jobject jEntrySet = env->CallObjectMethod(hashMap, g_mid_Map_entrySet);
+    jobject jIterator = env->CallObjectMethod(jEntrySet, g_mid_Set_iterator);
+    if (!jEntrySet || !jIterator || env->ExceptionCheck()) return;
+
+    while (env->CallBooleanMethod(jIterator, g_mid_Iterator_hasNext))
+    {
+        jobject jEntry = env->CallObjectMethod(jIterator, g_mid_Iterator_next);
+        if (!jEntry) return;
+        jstring jKey = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getKey);
+        if (!jKey) return;
+        jstring jValue = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getValue);
+        if (!jValue) return;
+
+        map.insert(std::make_pair(env->GetStringUTFChars(jKey, NULL),
+            env->GetStringUTFChars(jValue, NULL)));
+
+        if (env->ExceptionCheck()) return;
+        env->DeleteLocalRef(jEntry);
+        env->DeleteLocalRef(jKey);
+        env->DeleteLocalRef(jValue);
+    }
+}
+
+jobject JniUtils::convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map)
+{
+    jobject hashMap = env->NewObject(g_cls_HashMap, g_mid_HashMap_ctor);
+    if (!hashMap) return nullptr;
+
+    for (auto it = map.begin(); it != map.end(); ++it)
+    {
+        std::string key = it->first;
+        std::string value = it->second;
+
+        env->CallObjectMethod(hashMap,
+            g_mid_HashMap_put,
+            env->NewStringUTF(key.c_str()),
+            env->NewStringUTF(value.c_str()));
+        if (env->ExceptionCheck()) return nullptr;
+    }
+
+    return hashMap;
+}
+
+void JniUtils::convertJavaRepresentationArrToVector(JNIEnv *env,
+    jobjectArray jRepresentationArray,
+    std::vector<OC::OCRepresentation>& representationVector)
+{
+    if (!jRepresentationArray) return;
+    jsize len = env->GetArrayLength(jRepresentationArray);
+
+    for (jsize i = 0; i < len; ++i)
+    {
+        jobject jRep = env->GetObjectArrayElement(jRepresentationArray, i);
+        if (!jRep) return;
+        OC::OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, jRep);
+        representationVector.push_back(*rep);
+        if (env->ExceptionCheck()) return;
+        env->DeleteLocalRef(jRep);
+    }
+}
+
+jobjectArray JniUtils::convertRepresentationVectorToJavaArray(JNIEnv *env,
+    const std::vector<OC::OCRepresentation>& representationVector)
+{
+    jsize len = static_cast<jsize>(representationVector.size());
+    jobjectArray repArr = env->NewObjectArray(len, g_cls_OcRepresentation, NULL);
+    if (!repArr) return nullptr;
+    for (jsize i = 0; i < len; ++i)
+    {
+        OCRepresentation* rep = new OCRepresentation(representationVector[i]);
+        jlong handle = reinterpret_cast<jlong>(rep);
+        jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,
+            handle, true);
+        if (!jRepresentation)
+        {
+            delete rep;
+            return nullptr;
+        }
+        env->SetObjectArrayElement(repArr, i, jRepresentation);
+        if (env->ExceptionCheck()) return nullptr;
+        env->DeleteLocalRef(jRepresentation);
+    }
+
+    return repArr;
 }
\ No newline at end of file
index c4553ff..70e8054 100644 (file)
-/*\r
-* //******************************************************************\r
-* //\r
-* // Copyright 2015 Intel Corporation.\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
-#include "JniOcStack.h"\r
-#include "OCRepresentation.h"\r
-\r
-class JniUtils\r
-{\r
-public:\r
-    static void convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap,\r
-        OC::QueryParamsMap &map);\r
-    static jobject convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map);\r
-\r
-    static jobject convertStrVectorToJavaStrList(JNIEnv *env, std::vector<std::string> &vector);\r
-    static void convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr,\r
-        std::vector<std::string> &vector);\r
-\r
-    static void convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions,\r
-        OC::HeaderOptions& headerOptions);\r
-    static jobject convertHeaderOptionsVectorToJavaList(JNIEnv *env,\r
-        const OC::HeaderOptions& headerOptions);\r
-\r
-    static void convertJavaRepresentationArrToVector(JNIEnv *env,\r
-        jobjectArray jRepresentationArray,\r
-        std::vector<OC::OCRepresentation>& representationVector);\r
-    static jobjectArray convertRepresentationVectorToJavaArray(JNIEnv *env,\r
-        const std::vector<OC::OCRepresentation>& representationVector);\r
-\r
-    static OC::ServiceType getServiceType(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OC::ServiceType::InProc;\r
-        case 1:\r
-            return OC::ServiceType::OutOfProc;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected service type");\r
-            return OC::ServiceType::OutOfProc;\r
-        };\r
-    }\r
-\r
-    static OC::ModeType getModeType(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OC::ModeType::Server;\r
-        case 1:\r
-            return OC::ModeType::Client;\r
-        case 2:\r
-            return OC::ModeType::Both;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected mode type");\r
-            return OC::ModeType::Both;\r
-        };\r
-    }\r
-\r
-    static OC::QualityOfService getQOS(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OC::QualityOfService::LowQos;\r
-        case 1:\r
-            return OC::QualityOfService::MidQos;\r
-        case 2:\r
-            return OC::QualityOfService::HighQos;\r
-        case 3:\r
-            return OC::QualityOfService::NaQos;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected quality of service");\r
-            return OC::QualityOfService::NaQos;\r
-        };\r
-    }\r
-\r
-    static OC::ObserveType getObserveType(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OC::ObserveType::Observe;\r
-        case 1:\r
-            return OC::ObserveType::ObserveAll;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected observe type");\r
-            return OC::ObserveType::ObserveAll;\r
-        };\r
-    }\r
-\r
-    static OCEntityHandlerResult getOCEntityHandlerResult(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OCEntityHandlerResult::OC_EH_OK;\r
-        case 1:\r
-            return OCEntityHandlerResult::OC_EH_ERROR;\r
-        case 2:\r
-            return OCEntityHandlerResult::OC_EH_RESOURCE_CREATED;\r
-        case 3:\r
-            return OCEntityHandlerResult::OC_EH_RESOURCE_DELETED;\r
-        case 4:\r
-            return OCEntityHandlerResult::OC_EH_SLOW;\r
-        case 5:\r
-            return OCEntityHandlerResult::OC_EH_FORBIDDEN;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected OCEntityHandlerResult");\r
-            return OCEntityHandlerResult::OC_EH_ERROR;\r
-        };\r
-    }\r
-\r
-    static OCConnectivityType getConnectivityType(JNIEnv *env, int type)\r
-    {\r
-        switch (type) {\r
-        case 0:\r
-            return OCConnectivityType::OC_IPV4;\r
-        case 1:\r
-            return OCConnectivityType::OC_IPV6;\r
-        case 2:\r
-            return OCConnectivityType::OC_EDR;\r
-        case 3:\r
-            return OCConnectivityType::OC_LE;\r
-        case 4:\r
-            return OCConnectivityType::OC_ALL;\r
-        default:\r
-            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected connectivity type");\r
-            return OCConnectivityType::OC_ALL;\r
-        };\r
-    }\r
-\r
-    static std::string stackResultToStr(const int result)\r
-    {\r
-        switch (result)\r
-        {\r
-        case OC_STACK_OK:\r
-            return "OK";\r
-        case OC_STACK_RESOURCE_CREATED:\r
-            return "RESOURCE_CREATED";\r
-        case OC_STACK_RESOURCE_DELETED:\r
-            return "RESOURCE_DELETED";\r
-        case OC_STACK_CONTINUE:\r
-            return "CONTINUE";\r
-            /* Success status code - END HERE */\r
-            /* Error status code - START HERE */\r
-        case OC_STACK_INVALID_URI:\r
-            return "INVALID_URI";\r
-        case OC_STACK_INVALID_QUERY:\r
-            return "INVALID_QUERY";\r
-        case OC_STACK_INVALID_IP:\r
-            return "INVALID_IP";\r
-\r
-        case OC_STACK_INVALID_PORT:\r
-            return "INVALID_PORT";\r
-        case OC_STACK_INVALID_CALLBACK:\r
-            return "INVALID_CALLBACK";\r
-        case OC_STACK_INVALID_METHOD:\r
-            return "INVALID_METHOD";\r
-        case OC_STACK_INVALID_PARAM:\r
-            return "INVALID_PARAM";\r
-        case OC_STACK_INVALID_OBSERVE_PARAM:\r
-            return "INVALID_OBSERVE_PARAM";\r
-        case OC_STACK_NO_MEMORY:\r
-            return "NO_MEMORY";\r
-        case OC_STACK_COMM_ERROR:\r
-            return "COMM_ERROR";\r
-        case OC_STACK_NOTIMPL:\r
-            return "NOTIMPL";\r
-        case OC_STACK_NO_RESOURCE:\r
-            return "NO_RESOURCE";\r
-        case  OC_STACK_RESOURCE_ERROR:\r
-            return "RESOURCE_ERROR";\r
-        case OC_STACK_SLOW_RESOURCE:\r
-            return "SLOW_RESOURCE";\r
-            //case OC_STACK_DUPLICATE_REQUEST:\r
-            //    return "DUPLICATE_REQUEST";\r
-        case OC_STACK_NO_OBSERVERS:\r
-            return "NO_OBSERVERS";\r
-        case OC_STACK_OBSERVER_NOT_FOUND:\r
-            return "OBSERVER_NOT_FOUND";\r
-        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:\r
-            return "VIRTUAL_DO_NOT_HANDLE";\r
-        case OC_STACK_INVALID_OPTION:\r
-            return "INVALID_OPTION";\r
-        case OC_STACK_MALFORMED_RESPONSE:\r
-            return "MALFORMED_RESPONSE";\r
-        case OC_STACK_PERSISTENT_BUFFER_REQUIRED:\r
-            return "PERSISTENT_BUFFER_REQUIRED";\r
-        case OC_STACK_INVALID_REQUEST_HANDLE:\r
-            return "INVALID_REQUEST_HANDLE";\r
-        case OC_STACK_INVALID_DEVICE_INFO:\r
-            return "INVALID_DEVICE_INFO";\r
-            //case OC_STACK_INVALID_JSON:\r
-            //    return "INVALID_JSON";\r
-\r
-        case OC_STACK_PRESENCE_STOPPED:\r
-            return "PRESENCE_STOPPED";\r
-        case OC_STACK_PRESENCE_TIMEOUT:\r
-            return "PRESENCE_TIMEOUT";\r
-        case OC_STACK_PRESENCE_DO_NOT_HANDLE:\r
-            return "PRESENCE_DO_NOT_HANDLE";\r
-\r
-        case OC_STACK_ERROR:\r
-            return "ERROR";\r
-\r
-        case JNI_EXCEPTION:\r
-            return "JNI_EXCEPTION";\r
-        case JNI_NO_NATIVE_POINTER:\r
-            return "JNI_NO_NATIVE_POINTER";\r
-        case JNI_INVALID_VALUE:\r
-            return "JNI_INVALID_VALUE";\r
-        default:\r
-            return "";\r
-        }\r
-    }\r
-};\r
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 Intel Corporation.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+* //
+* // Licensed under the Apache License, Version 2.0 (the "License");
+* // you may not use this file except in compliance with the License.
+* // You may obtain a copy of the License at
+* //
+* //      http://www.apache.org/licenses/LICENSE-2.0
+* //
+* // Unless required by applicable law or agreed to in writing, software
+* // distributed under the License is distributed on an "AS IS" BASIS,
+* // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* // See the License for the specific language governing permissions and
+* // limitations under the License.
+* //
+* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+
+#include "JniOcStack.h"
+#include "OCRepresentation.h"
+
+class JniUtils
+{
+public:
+    static void convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap,
+        OC::QueryParamsMap &map);
+    static jobject convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map);
+
+    static jobject convertStrVectorToJavaStrList(JNIEnv *env, std::vector<std::string> &vector);
+    static void convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr,
+        std::vector<std::string> &vector);
+
+    static void convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions,
+        OC::HeaderOptions& headerOptions);
+    static jobject convertHeaderOptionsVectorToJavaList(JNIEnv *env,
+        const OC::HeaderOptions& headerOptions);
+
+    static void convertJavaRepresentationArrToVector(JNIEnv *env,
+        jobjectArray jRepresentationArray,
+        std::vector<OC::OCRepresentation>& representationVector);
+    static jobjectArray convertRepresentationVectorToJavaArray(JNIEnv *env,
+        const std::vector<OC::OCRepresentation>& representationVector);
+
+    static OC::ServiceType getServiceType(JNIEnv *env, int type)
+    {
+        switch (type) {
+        case 0:
+            return OC::ServiceType::InProc;
+        case 1:
+            return OC::ServiceType::OutOfProc;
+        default:
+            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected service type");
+            return OC::ServiceType::OutOfProc;
+        };
+    }
+
+    static OC::ModeType getModeType(JNIEnv *env, int type)
+    {
+        switch (type) {
+        case 0:
+            return OC::ModeType::Server;
+        case 1:
+            return OC::ModeType::Client;
+        case 2:
+            return OC::ModeType::Both;
+        default:
+            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected mode type");
+            return OC::ModeType::Both;
+        };
+    }
+
+    static OC::QualityOfService getQOS(JNIEnv *env, int type)
+    {
+        switch (type) {
+        case 0:
+            return OC::QualityOfService::LowQos;
+        case 1:
+            return OC::QualityOfService::MidQos;
+        case 2:
+            return OC::QualityOfService::HighQos;
+        case 3:
+            return OC::QualityOfService::NaQos;
+        default:
+            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected quality of service");
+            return OC::QualityOfService::NaQos;
+        };
+    }
+
+    static OC::ObserveType getObserveType(JNIEnv *env, int type)
+    {
+        switch (type) {
+        case 0:
+            return OC::ObserveType::Observe;
+        case 1:
+            return OC::ObserveType::ObserveAll;
+        default:
+            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected observe type");
+            return OC::ObserveType::ObserveAll;
+        };
+    }
+
+    static OCEntityHandlerResult getOCEntityHandlerResult(JNIEnv *env, int type)
+    {
+        switch (type) {
+        case 0:
+            return OCEntityHandlerResult::OC_EH_OK;
+        case 1:
+            return OCEntityHandlerResult::OC_EH_ERROR;
+        case 2:
+            return OCEntityHandlerResult::OC_EH_RESOURCE_CREATED;
+        case 3:
+            return OCEntityHandlerResult::OC_EH_RESOURCE_DELETED;
+        case 4:
+            return OCEntityHandlerResult::OC_EH_SLOW;
+        case 5:
+            return OCEntityHandlerResult::OC_EH_FORBIDDEN;
+        default:
+            ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected OCEntityHandlerResult");
+            return OCEntityHandlerResult::OC_EH_ERROR;
+        };
+    }
+
+    static std::string stackResultToStr(const int result)
+    {
+        switch (result)
+        {
+        case OC_STACK_OK:
+            return "OK";
+        case OC_STACK_RESOURCE_CREATED:
+            return "RESOURCE_CREATED";
+        case OC_STACK_RESOURCE_DELETED:
+            return "RESOURCE_DELETED";
+        case OC_STACK_CONTINUE:
+            return "CONTINUE";
+            /* Success status code - END HERE */
+            /* Error status code - START HERE */
+        case OC_STACK_INVALID_URI:
+            return "INVALID_URI";
+        case OC_STACK_INVALID_QUERY:
+            return "INVALID_QUERY";
+        case OC_STACK_INVALID_IP:
+            return "INVALID_IP";
+
+        case OC_STACK_INVALID_PORT:
+            return "INVALID_PORT";
+        case OC_STACK_INVALID_CALLBACK:
+            return "INVALID_CALLBACK";
+        case OC_STACK_INVALID_METHOD:
+            return "INVALID_METHOD";
+        case OC_STACK_INVALID_PARAM:
+            return "INVALID_PARAM";
+        case OC_STACK_INVALID_OBSERVE_PARAM:
+            return "INVALID_OBSERVE_PARAM";
+        case OC_STACK_NO_MEMORY:
+            return "NO_MEMORY";
+        case OC_STACK_COMM_ERROR:
+            return "COMM_ERROR";
+        case OC_STACK_NOTIMPL:
+            return "NOTIMPL";
+        case OC_STACK_NO_RESOURCE:
+            return "NO_RESOURCE";
+        case  OC_STACK_RESOURCE_ERROR:
+            return "RESOURCE_ERROR";
+        case OC_STACK_SLOW_RESOURCE:
+            return "SLOW_RESOURCE";
+            //case OC_STACK_DUPLICATE_REQUEST:
+            //    return "DUPLICATE_REQUEST";
+        case OC_STACK_NO_OBSERVERS:
+            return "NO_OBSERVERS";
+        case OC_STACK_OBSERVER_NOT_FOUND:
+            return "OBSERVER_NOT_FOUND";
+        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
+            return "VIRTUAL_DO_NOT_HANDLE";
+        case OC_STACK_INVALID_OPTION:
+            return "INVALID_OPTION";
+        case OC_STACK_MALFORMED_RESPONSE:
+            return "MALFORMED_RESPONSE";
+        case OC_STACK_PERSISTENT_BUFFER_REQUIRED:
+            return "PERSISTENT_BUFFER_REQUIRED";
+        case OC_STACK_INVALID_REQUEST_HANDLE:
+            return "INVALID_REQUEST_HANDLE";
+        case OC_STACK_INVALID_DEVICE_INFO:
+            return "INVALID_DEVICE_INFO";
+            //case OC_STACK_INVALID_JSON:
+            //    return "INVALID_JSON";
+
+        case OC_STACK_PRESENCE_STOPPED:
+            return "PRESENCE_STOPPED";
+        case OC_STACK_PRESENCE_TIMEOUT:
+            return "PRESENCE_TIMEOUT";
+        case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+            return "PRESENCE_DO_NOT_HANDLE";
+
+        case OC_STACK_ERROR:
+            return "ERROR";
+
+        case JNI_EXCEPTION:
+            return "JNI_EXCEPTION";
+        case JNI_NO_NATIVE_POINTER:
+            return "JNI_NO_NATIVE_POINTER";
+        case JNI_INVALID_VALUE:
+            return "JNI_INVALID_VALUE";
+        default:
+            return "";
+        }
+    }
+};
index 0834201..cbed2d5 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-import android.test.InstrumentationTestCase;\r
-\r
-import java.security.InvalidParameterException;\r
-import java.util.Arrays;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-\r
-public class OcRepresentationTest extends InstrumentationTestCase {\r
-\r
-    private static final String TAG = "OcRepresentationTest";\r
-\r
-    @Override\r
-    protected void setUp() throws Exception {\r
-        super.setUp();\r
-    }\r
-\r
-    public void testChildrenManagement() throws OcException {\r
-        OcRepresentation representation = new OcRepresentation();\r
-\r
-        List<OcRepresentation> emptyList = representation.getChildren();\r
-        assertTrue(emptyList.isEmpty());\r
-\r
-        OcRepresentation child1 = new OcRepresentation();\r
-        OcRepresentation child2 = new OcRepresentation();\r
-        String key = "key";\r
-        int value = 75;\r
-\r
-        child1.setValue(key, value);\r
-        child2.setValue(key, value);\r
-        representation.addChild(child1);\r
-        representation.addChild(child2);\r
-        List<OcRepresentation> twoChildren = representation.getChildren();\r
-        assertEquals(2, twoChildren.size());\r
-        for (OcRepresentation rep : twoChildren) {\r
-            assertEquals(value, rep.getValue(key));\r
-        }\r
-\r
-        representation.clearChildren();\r
-        emptyList = representation.getChildren();\r
-        assertTrue(emptyList.isEmpty());\r
-    }\r
-\r
-    public void testUriGetSet() {\r
-        OcRepresentation representation = new OcRepresentation();\r
-\r
-        String emptyUri = representation.getUri();\r
-        assertTrue(emptyUri.isEmpty());\r
-\r
-        String expected = "a/resource/uri";\r
-        representation.setUri(expected);\r
-        String actual = representation.getUri();\r
-        assertEquals(expected, actual);\r
-    }\r
-\r
-    public void testJSONRepresentation() throws OcException {\r
-        OcRepresentation representation = new OcRepresentation();\r
-        String key = "key";\r
-        int value = 75;\r
-\r
-        String emptyJson1 = representation.getJSONRepresentation();\r
-        representation.setValue(key, value);\r
-        String intValue1 = representation.getJSONRepresentation();\r
-        representation.remove(key);\r
-        String emptyJson2 = representation.getJSONRepresentation();\r
-        assertEquals(emptyJson1, emptyJson2);\r
-        representation.setValue(key, value);\r
-        String intValue2 = representation.getJSONRepresentation();\r
-        assertEquals(intValue1, intValue2);\r
-    }\r
-\r
-    public void testResourceTypesGetSet() {\r
-        OcRepresentation representation = new OcRepresentation();\r
-\r
-        List<String> emptyResourceTypeList = representation.getResourceTypes();\r
-        assertTrue(emptyResourceTypeList.isEmpty());\r
-\r
-        representation.setResourceTypes(emptyResourceTypeList);\r
-        emptyResourceTypeList = representation.getResourceTypes();\r
-        assertTrue(emptyResourceTypeList.isEmpty());\r
-\r
-        List<String> resourceTypeListExpected = new LinkedList<String>();\r
-        resourceTypeListExpected.add("type1");\r
-        resourceTypeListExpected.add("type2");\r
-        resourceTypeListExpected.add("type3");\r
-\r
-        representation.setResourceTypes(resourceTypeListExpected);\r
-        List<String> resourceTypeListActual = representation.getResourceTypes();\r
-        assertEquals(resourceTypeListExpected.size(), resourceTypeListActual.size());\r
-        for (int i = 0; i < resourceTypeListExpected.size(); i++) {\r
-            assertEquals(resourceTypeListExpected.get(i), resourceTypeListActual.get(i));\r
-        }\r
-\r
-        boolean thrown = false;\r
-        try {\r
-            representation.setResourceTypes(null);\r
-        } catch (InvalidParameterException e) {\r
-            thrown = true;\r
-        }\r
-        assertTrue(thrown);\r
-    }\r
-\r
-    public void testResourceInterfacesGetSet() {\r
-        OcRepresentation representation = new OcRepresentation();\r
-\r
-        List<String> emptyResourceInterfaceList = representation.getResourceInterfaces();\r
-        assertTrue(emptyResourceInterfaceList.isEmpty());\r
-\r
-        representation.setResourceInterfaces(emptyResourceInterfaceList);\r
-        emptyResourceInterfaceList = representation.getResourceInterfaces();\r
-        assertTrue(emptyResourceInterfaceList.isEmpty());\r
-\r
-        List<String> resourceInterfaceListExpected = new LinkedList<String>();\r
-        resourceInterfaceListExpected.add("Interface1");\r
-        resourceInterfaceListExpected.add("Interface2");\r
-        resourceInterfaceListExpected.add("Interface3");\r
-\r
-        representation.setResourceInterfaces(resourceInterfaceListExpected);\r
-        List<String> resourceInterfaceListActual = representation.getResourceInterfaces();\r
-        assertEquals(resourceInterfaceListExpected.size(), resourceInterfaceListActual.size());\r
-        for (int i = 0; i < resourceInterfaceListExpected.size(); i++) {\r
-            assertEquals(resourceInterfaceListExpected.get(i), resourceInterfaceListActual.get(i));\r
-        }\r
-\r
-        boolean thrown = false;\r
-        try {\r
-            representation.setResourceInterfaces(null);\r
-        } catch (InvalidParameterException e) {\r
-            thrown = true;\r
-        }\r
-        assertTrue(thrown);\r
-    }\r
-\r
-    public void testAttributeManagement() {\r
-        OcRepresentation representation = new OcRepresentation();\r
-\r
-        assertTrue(representation.isEmpty());\r
-        assertEquals(0, representation.size());\r
-\r
-        try {\r
-            String integerKey = "integerKey";\r
-            int integerValue = 75;\r
-            representation.setValue(integerKey, integerValue);\r
-            assertFalse(representation.isEmpty());\r
-            assertEquals(1, representation.size());\r
-\r
-            int actualIntValue = representation.getValue(integerKey);\r
-            assertEquals(integerValue, actualIntValue);\r
-\r
-            String stringKey = "stringKey";\r
-            String stringValue = "stringValue";\r
-            representation.setValue(stringKey, stringValue);\r
-            assertEquals(2, representation.size());\r
-\r
-            assertTrue(representation.hasAttribute(integerKey));\r
-            representation.remove(integerKey);\r
-            assertFalse(representation.hasAttribute(integerKey));\r
-            assertEquals(1, representation.size());\r
-\r
-            representation.setValue(integerKey, integerValue);\r
-            assertFalse(representation.isNull(integerKey));\r
-            representation.setNull(integerKey);\r
-            assertTrue(representation.isNull(integerKey));\r
-        } catch (OcException e) {\r
-            assertTrue(false);\r
-        }\r
-\r
-        String nonexistentKey = "nonexistentKey";\r
-        assertFalse(representation.hasAttribute(nonexistentKey));\r
-        representation.setNull(nonexistentKey);\r
-        assertTrue(representation.isNull(nonexistentKey));\r
-\r
-        String nonexistentKey2 = "nonexistentKey2";\r
-        boolean thrown = false;\r
-        try {\r
-            boolean nonexistentValue = representation.getValue(nonexistentKey2);\r
-        } catch (OcException e) {\r
-            thrown = true;\r
-        }\r
-        assertTrue(thrown);\r
-    }\r
-\r
-    public void testAttributeAccessByType() throws OcException {\r
-        OcRepresentation rep = new OcRepresentation();\r
-\r
-        //integer\r
-        String intK = "intK";\r
-        int intV = 4;\r
-        rep.setValue(intK, intV);\r
-        int intVa = rep.getValue(intK);\r
-        assertEquals(intV, intVa);\r
-\r
-        //double\r
-        String doubleK = "doubleK";\r
-        double doubleV = 4.5;\r
-        rep.setValue(doubleK, doubleV);\r
-        double doubleVa = rep.getValue(doubleK);\r
-        assertEquals(doubleV, doubleVa);\r
-\r
-        //boolean\r
-        String booleanK = "booleanK";\r
-        boolean booleanV = true;\r
-        rep.setValue(booleanK, booleanV);\r
-        boolean booleanVa = rep.getValue(booleanK);\r
-        assertEquals(booleanV, booleanVa);\r
-\r
-        //String\r
-        String stringK = "stringK";\r
-        String stringV = "stringV";\r
-        rep.setValue(stringK, stringV);\r
-        String stringVa = rep.getValue(stringK);\r
-        assertEquals(stringV, stringVa);\r
-\r
-        //OcRepresentation\r
-        String repK = "repK";\r
-        OcRepresentation repV = new OcRepresentation();\r
-        repV.setValue(intK, intV);\r
-        rep.setValue(repK, repV);\r
-        OcRepresentation repVa = rep.getValue(repK);\r
-        assertEquals(intV, repVa.getValue(intK));\r
-    }\r
-\r
-    public void testAttributeAccessBySequenceType() throws OcException {\r
-        OcRepresentation rep = new OcRepresentation();\r
-\r
-        //integer\r
-        String intK = "intK";\r
-        int[] intArrV = {1, 2, 3, 4};\r
-        rep.setValue(intK, intArrV);\r
-        int[] intArrVa = rep.getValue(intK);\r
-        assertTrue(Arrays.equals(intArrV, intArrVa));\r
-\r
-        int[] intArrVEmpty = {};\r
-        rep.setValue(intK, intArrVEmpty);\r
-        int[] intArrVEmptyA = rep.getValue(intK);\r
-        assertTrue(Arrays.equals(intArrVEmpty, intArrVEmptyA));\r
-\r
-        //double\r
-        String doubleK = "doubleK";\r
-        double[] doubleArrV = {1.1, 2.2, 3.3, 4.4};\r
-        rep.setValue(doubleK, doubleArrV);\r
-        double[] doubleArrVa = rep.getValue(doubleK);\r
-        assertTrue(Arrays.equals(doubleArrV, doubleArrVa));\r
-\r
-        double[] doubleArrVEmpty = {};\r
-        rep.setValue(doubleK, doubleArrVEmpty);\r
-        double[] doubleArrVEmptyA = rep.getValue(doubleK);\r
-        assertTrue(Arrays.equals(doubleArrVEmpty, doubleArrVEmptyA));\r
-\r
-        //boolean\r
-        String booleanK = "booleanK";\r
-        boolean[] booleanArrV = {true, false, true, false};\r
-        rep.setValue(booleanK, booleanArrV);\r
-        boolean[] booleanArrVa = rep.getValue(booleanK);\r
-        assertTrue(Arrays.equals(booleanArrV, booleanArrVa));\r
-\r
-        boolean[] booleanArrVEmpty = {};\r
-        rep.setValue(booleanK, booleanArrVEmpty);\r
-        boolean[] booleanArrVEmptyA = rep.getValue(booleanK);\r
-        assertTrue(Arrays.equals(booleanArrVEmpty, booleanArrVEmptyA));\r
-\r
-        //String\r
-        String stringK = "stringK";\r
-        String[] stringArrV = {"aaa", "bbb", "ccc", "ddd"};\r
-        rep.setValue(stringK, stringArrV);\r
-        String[] stringArrVa = rep.getValue(stringK);\r
-        assertTrue(Arrays.equals(stringArrV, stringArrVa));\r
-\r
-        String[] stringArrVEmpty = {};\r
-        rep.setValue(stringK, stringArrVEmpty);\r
-        String[] stringArrVEmptyA = rep.getValue(stringK);\r
-        assertTrue(Arrays.equals(stringArrVEmpty, stringArrVEmptyA));\r
-\r
-        //OcRepresentation\r
-        String representationK = "representationK";\r
-        OcRepresentation[] representationArrV = {\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation()};\r
-        representationArrV[0].setValue(intK, 0);\r
-        representationArrV[1].setValue(intK, 1);\r
-        representationArrV[2].setValue(intK, 2);\r
-        representationArrV[3].setValue(intK, 3);\r
-\r
-        rep.setValue(representationK, representationArrV);\r
-        OcRepresentation[] representationArrVa = rep.getValue(representationK);\r
-\r
-        assertEquals(representationArrV.length, representationArrVa.length);\r
-        for (int i = 0; i < representationArrV.length; ++i) {\r
-            assertEquals(representationArrV[i].getValue(intK),\r
-                    representationArrVa[i].getValue(intK));\r
-        }\r
-\r
-        OcRepresentation[] representationArrVEmpty = {};\r
-        rep.setValue(representationK, representationArrVEmpty);\r
-        OcRepresentation[] representationArrVEmptyA = rep.getValue(representationK);\r
-        assertEquals(representationArrVEmpty.length, representationArrVEmptyA.length);\r
-    }\r
-\r
-    public void testAttributeAccessBy2DType() throws OcException {\r
-        OcRepresentation rep = new OcRepresentation();\r
-        //integer\r
-        String int2DK = "int2DK";\r
-        int[] intArrV1 = {1, 2, 3, 4};\r
-        int[] intArrV2 = {5, 6, 7, 8};\r
-        int[][] int2DArrV = {intArrV1, intArrV2};\r
-        rep.setValue(int2DK, int2DArrV);\r
-        int[][] int2DArrVa = rep.getValue(int2DK);\r
-        for (int i = 0; i < int2DArrV.length; i++) {\r
-            assertTrue(Arrays.equals(int2DArrV[i], int2DArrVa[i]));\r
-        }\r
-        //double\r
-        String double2DK = "double2DK";\r
-        double[] doubleArrV1 = {1.1, 2.2, 3.3, 4.4};\r
-        double[] doubleArrV2 = {5, 6, 7, 8};\r
-        double[][] double2DArrV = {doubleArrV1, doubleArrV2};\r
-        rep.setValue(double2DK, double2DArrV);\r
-        double[][] double2DArrVa = rep.getValue(double2DK);\r
-        for (int i = 0; i < double2DArrV.length; i++) {\r
-            assertTrue(Arrays.equals(double2DArrV[i], double2DArrVa[i]));\r
-        }\r
-        double[][] double2DArrVEmpty = {{}};\r
-        rep.setValue(double2DK, double2DArrVEmpty);\r
-        double[][] double2DArrVEmptyA = rep.getValue(double2DK);\r
-        for (int i = 0; i < double2DArrVEmpty.length; i++) {\r
-            assertTrue(Arrays.equals(double2DArrVEmpty[i], double2DArrVEmptyA[i]));\r
-        }\r
-        //boolean\r
-        String boolean2DK = "boolean2DK";\r
-        boolean[] booleanArrV1 = {true, true, false};\r
-        boolean[] booleanArrV2 = {true, false, false, true};\r
-        boolean[][] boolean2DArrV = {booleanArrV1, booleanArrV2};\r
-        rep.setValue(boolean2DK, boolean2DArrV);\r
-        boolean[][] boolean2DArrVa = rep.getValue(boolean2DK);\r
-        for (int i = 0; i < boolean2DArrV.length; i++) {\r
-            assertTrue(Arrays.equals(boolean2DArrV[i], boolean2DArrVa[i]));\r
-        }\r
-        boolean[][] boolean2DArrVEmpty = {{}};\r
-        rep.setValue(boolean2DK, boolean2DArrVEmpty);\r
-        boolean[][] boolean2DArrVEmptyA = rep.getValue(boolean2DK);\r
-        for (int i = 0; i < boolean2DArrVEmpty.length; i++) {\r
-            assertTrue(Arrays.equals(boolean2DArrVEmpty[i], boolean2DArrVEmptyA[i]));\r
-        }\r
-\r
-        //String\r
-        String string2DK = "string2DK";\r
-        String[] stringArrV1 = {"aaa", "bbb", "ccc"};\r
-        String[] stringArrV2 = {"111", "222", "333", "444"};\r
-        String[][] string2DArrV = {stringArrV1, stringArrV2};\r
-        rep.setValue(string2DK, string2DArrV);\r
-        String[][] string2DArrVa = rep.getValue(string2DK);\r
-        for (int i = 0; i < string2DArrV.length; i++) {\r
-            assertTrue(Arrays.equals(string2DArrV[i], string2DArrVa[i]));\r
-        }\r
-        String[][] string2DArrVEmpty = {{}};\r
-        rep.setValue(string2DK, string2DArrVEmpty);\r
-        String[][] string2DArrVEmptyA = rep.getValue(string2DK);\r
-        for (int i = 0; i < string2DArrVEmpty.length; i++) {\r
-            assertTrue(Arrays.equals(string2DArrVEmpty[i], string2DArrVEmptyA[i]));\r
-        }\r
-\r
-        //OcRepresentation\r
-        String intK = "intK";\r
-        String representation2DK = "representation2DK";\r
-        OcRepresentation[] representation2DArrV1 = {\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation()};\r
-        representation2DArrV1[0].setValue(intK, 0);\r
-        representation2DArrV1[1].setValue(intK, 1);\r
-        representation2DArrV1[2].setValue(intK, 2);\r
-        representation2DArrV1[3].setValue(intK, 3);\r
-\r
-        OcRepresentation[] representation2DArrV2 = {\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation()};\r
-        representation2DArrV2[0].setValue(intK, 4);\r
-        representation2DArrV2[1].setValue(intK, 5);\r
-        representation2DArrV2[2].setValue(intK, 6);\r
-        representation2DArrV2[3].setValue(intK, 7);\r
-\r
-        OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2};\r
-        rep.setValue(representation2DK, representation2DArrV);\r
-        OcRepresentation[][] representation2DArrVa = rep.getValue(representation2DK);\r
-        assertEquals(representation2DArrV.length, representation2DArrVa.length);\r
-        for (int i = 0; i < representation2DArrV.length; ++i) {\r
-            OcRepresentation[] repArrV = representation2DArrV[i];\r
-            OcRepresentation[] repArrVa = representation2DArrVa[i];\r
-            assertEquals(repArrV.length, repArrVa.length);\r
-            for (int j = 0; j < representation2DArrV.length; ++j) {\r
-                assertEquals(repArrV[j].getValue(intK),\r
-                        repArrVa[j].getValue(intK));\r
-            }\r
-        }\r
-\r
-        OcRepresentation[][] representation2DArrVEmpty = {{}};\r
-        rep.setValue(representation2DK, representation2DArrVEmpty);\r
-        OcRepresentation[][] representation2DArrVEmptyA = rep.getValue(representation2DK);\r
-        assertEquals(representation2DArrVEmpty.length, representation2DArrVEmptyA.length);\r
-    }\r
-\r
-    public void testAttributeAccessBy3DType() throws OcException {\r
-        OcRepresentation rep = new OcRepresentation();\r
-        //integer\r
-        String int3DK = "int3DK";\r
-        int[] intArrV1 = {0, 1, 2, 3, 4};\r
-        int[] intArrV2 = {5, 6, 7, 8};\r
-        int[][] int2DArrV1 = {intArrV1, intArrV2};\r
-        int[] intArrV3 = {9, 10};\r
-        int[] intArrV4 = {11};\r
-        int[][] int2DArrV2 = {intArrV3, intArrV4};\r
-        int[][][] int3DArrV = {int2DArrV1, int2DArrV2};\r
-        rep.setValue(int3DK, int3DArrV);\r
-        int[][][] int3DArrVa = rep.getValue(int3DK);\r
-        assertEquals(int3DArrV.length, int3DArrVa.length);\r
-        for (int i = 0; i < int3DArrV.length; i++) {\r
-            int[][] int2DT = int3DArrV[i];\r
-            int[][] int2DTa = int3DArrVa[i];\r
-            assertEquals(int2DT.length, int2DTa.length);\r
-            for (int j = 0; j < int2DT.length; j++) {\r
-                assertTrue(Arrays.equals(int2DT[j], int2DTa[j]));\r
-            }\r
-        }\r
-        //double\r
-        String double3DK = "double3DK";\r
-        double[] doubleArrV1 = {0.0, 1.1, 2.2, 3.3, 4.4};\r
-        double[] doubleArrV2 = {5.5, 6.6, 7.7, 8.8};\r
-        double[][] double2DArrV1 = {doubleArrV1, doubleArrV2};\r
-        double[] doubleArrV3 = {9.9, 10.1};\r
-        double[] doubleArrV4 = {11.1};\r
-        double[][] double2DArrV2 = {doubleArrV3, doubleArrV4};\r
-        double[][][] double3DArrV = {double2DArrV1, double2DArrV2};\r
-        rep.setValue(double3DK, double3DArrV);\r
-        double[][][] double3DArrVa = rep.getValue(double3DK);\r
-        assertEquals(double3DArrV.length, double3DArrVa.length);\r
-        for (int i = 0; i < double3DArrV.length; i++) {\r
-            double[][] double2DT = double3DArrV[i];\r
-            double[][] double2DTa = double3DArrVa[i];\r
-            assertEquals(double2DT.length, double2DTa.length);\r
-            for (int j = 0; j < double2DT.length; j++) {\r
-                assertTrue(Arrays.equals(double2DT[j], double2DTa[j]));\r
-            }\r
-        }\r
-        double[][][] double3DArrVEmpty = {};\r
-        rep.setValue(double3DK, double3DArrVEmpty);\r
-        double[][][] double3DArrVEmptyA = rep.getValue(double3DK);\r
-        assertEquals(double3DArrVEmpty.length, double3DArrVEmptyA.length);\r
-        for (int i = 0; i < double3DArrVEmpty.length; i++) {\r
-            double[][] double2DT = double3DArrVEmpty[i];\r
-            double[][] double2DTa = double3DArrVEmptyA[i];\r
-            assertEquals(double2DT.length, double2DTa.length);\r
-            for (int j = 0; j < double2DT.length; j++) {\r
-                assertTrue(Arrays.equals(double2DT[j], double2DTa[j]));\r
-            }\r
-        }\r
-\r
-        //boolean\r
-        String boolean3DK = "boolean3DK";\r
-        boolean[] booleanArrV1 = {true, false, true, true, false};\r
-        boolean[] booleanArrV2 = {false, false, false, true};\r
-        boolean[][] boolean2DArrV1 = {booleanArrV1, booleanArrV2};\r
-        boolean[] booleanArrV3 = {true, true};\r
-        boolean[] booleanArrV4 = {false};\r
-        boolean[][] boolean2DArrV2 = {booleanArrV3, booleanArrV4};\r
-        boolean[][][] boolean3DArrV = {boolean2DArrV1, boolean2DArrV2};\r
-        rep.setValue(boolean3DK, boolean3DArrV);\r
-        boolean[][][] boolean3DArrVa = rep.getValue(boolean3DK);\r
-        assertEquals(boolean3DArrV.length, boolean3DArrVa.length);\r
-        for (int i = 0; i < boolean3DArrV.length; i++) {\r
-            boolean[][] boolean2DT = boolean3DArrV[i];\r
-            boolean[][] boolean2DTa = boolean3DArrVa[i];\r
-            assertEquals(boolean2DT.length, boolean2DTa.length);\r
-            for (int j = 0; j < boolean2DT.length; j++) {\r
-                assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j]));\r
-            }\r
-        }\r
-        boolean[][][] boolean3DArrVEmpty = {};\r
-        rep.setValue(boolean3DK, boolean3DArrVEmpty);\r
-        boolean[][][] boolean3DArrVEmptyA = rep.getValue(boolean3DK);\r
-        assertEquals(boolean3DArrVEmpty.length, boolean3DArrVEmptyA.length);\r
-        for (int i = 0; i < boolean3DArrVEmpty.length; i++) {\r
-            boolean[][] boolean2DT = boolean3DArrVEmpty[i];\r
-            boolean[][] boolean2DTa = boolean3DArrVEmptyA[i];\r
-            assertEquals(boolean2DT.length, boolean2DTa.length);\r
-            for (int j = 0; j < boolean2DT.length; j++) {\r
-                assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j]));\r
-            }\r
-        }\r
-\r
-        //String\r
-        String string3DK = "string3DK";\r
-        String[] stringArrV1 = {"a", "bb", "ccc", "dddd", "eeee"};\r
-        String[] stringArrV2 = {"f", "gg", "hhh", "ii"};\r
-        String[][] string2DArrV1 = {stringArrV1, stringArrV2};\r
-        String[] stringArrV3 = {"j", "jj"};\r
-        String[] stringArrV4 = {"jjj"};\r
-        String[][] string2DArrV2 = {stringArrV3, stringArrV4};\r
-        String[][][] string3DArrV = {string2DArrV1, string2DArrV2};\r
-        rep.setValue(string3DK, string3DArrV);\r
-        String[][][] string3DArrVa = rep.getValue(string3DK);\r
-        assertEquals(string3DArrV.length, string3DArrVa.length);\r
-        for (int i = 0; i < string3DArrV.length; i++) {\r
-            String[][] string2DT = string3DArrV[i];\r
-            String[][] string2DTa = string3DArrVa[i];\r
-            assertEquals(string2DT.length, string2DTa.length);\r
-            for (int j = 0; j < string2DT.length; j++) {\r
-                assertTrue(Arrays.equals(string2DT[j], string2DTa[j]));\r
-            }\r
-        }\r
-        String[][][] string3DArrVEmpty = {};\r
-        rep.setValue(string3DK, string3DArrVEmpty);\r
-        String[][][] string3DArrVEmptyA = rep.getValue(string3DK);\r
-        assertEquals(string3DArrVEmpty.length, string3DArrVEmptyA.length);\r
-        for (int i = 0; i < string3DArrVEmpty.length; i++) {\r
-            String[][] string2DT = string3DArrVEmpty[i];\r
-            String[][] string2DTa = string3DArrVEmptyA[i];\r
-            assertEquals(string2DT.length, string2DTa.length);\r
-            for (int j = 0; j < string2DT.length; j++) {\r
-                assertTrue(Arrays.equals(string2DT[j], string2DTa[j]));\r
-            }\r
-        }\r
-\r
-        //OcRepresentation\r
-        String intK = "intK";\r
-        String representation3DK = "representation3DK";\r
-        OcRepresentation[] representation2DArrV1 = {\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation()};\r
-        representation2DArrV1[0].setValue(intK, 0);\r
-        representation2DArrV1[1].setValue(intK, 1);\r
-        representation2DArrV1[2].setValue(intK, 2);\r
-        representation2DArrV1[3].setValue(intK, 3);\r
-\r
-        OcRepresentation[] representation2DArrV2 = {\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation(),\r
-                new OcRepresentation()};\r
-        representation2DArrV2[0].setValue(intK, 4);\r
-        representation2DArrV2[1].setValue(intK, 5);\r
-        representation2DArrV2[2].setValue(intK, 6);\r
-        representation2DArrV2[3].setValue(intK, 7);\r
-\r
-        OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2};\r
-        OcRepresentation[][][] representation3DArrV = {representation2DArrV, representation2DArrV};\r
-\r
-        rep.setValue(representation3DK, representation3DArrV);\r
-        OcRepresentation[][][] representation3DArrVa = rep.getValue(representation3DK);\r
-        assertEquals(representation3DArrV.length, representation3DArrVa.length);\r
-        for (int i = 0; i < representation3DArrV.length; ++i) {\r
-            OcRepresentation[][] repArr2V = representation3DArrV[i];\r
-            OcRepresentation[][] repArr2Va = representation3DArrVa[i];\r
-            assertEquals(repArr2V.length, repArr2Va.length);\r
-            for (int j = 0; j < repArr2V.length; ++j) {\r
-                OcRepresentation[] repArrV = repArr2V[j];\r
-                OcRepresentation[] repArrVa = repArr2Va[j];\r
-                assertEquals(repArrV.length, repArrVa.length);\r
-                for (int k = 0; k < repArrV.length; ++k) {\r
-                    assertEquals(repArrV[k].getValue(intK), repArrVa[k].getValue(intK));\r
-                }\r
-            }\r
-        }\r
-    }\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import android.test.InstrumentationTestCase;
+
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class OcRepresentationTest extends InstrumentationTestCase {
+
+    private static final String TAG = "OcRepresentationTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testChildrenManagement() throws OcException {
+        OcRepresentation representation = new OcRepresentation();
+
+        List<OcRepresentation> emptyList = representation.getChildren();
+        assertTrue(emptyList.isEmpty());
+
+        OcRepresentation child1 = new OcRepresentation();
+        OcRepresentation child2 = new OcRepresentation();
+        String key = "key";
+        int value = 75;
+
+        child1.setValue(key, value);
+        child2.setValue(key, value);
+        representation.addChild(child1);
+        representation.addChild(child2);
+        List<OcRepresentation> twoChildren = representation.getChildren();
+        assertEquals(2, twoChildren.size());
+        for (OcRepresentation rep : twoChildren) {
+            assertEquals(value, rep.getValue(key));
+        }
+
+        representation.clearChildren();
+        emptyList = representation.getChildren();
+        assertTrue(emptyList.isEmpty());
+    }
+
+    public void testUriGetSet() {
+        OcRepresentation representation = new OcRepresentation();
+
+        String emptyUri = representation.getUri();
+        assertTrue(emptyUri.isEmpty());
+
+        String expected = "a/resource/uri";
+        representation.setUri(expected);
+        String actual = representation.getUri();
+        assertEquals(expected, actual);
+    }
+
+    public void testResourceTypesGetSet() {
+        OcRepresentation representation = new OcRepresentation();
+
+        List<String> emptyResourceTypeList = representation.getResourceTypes();
+        assertTrue(emptyResourceTypeList.isEmpty());
+
+        representation.setResourceTypes(emptyResourceTypeList);
+        emptyResourceTypeList = representation.getResourceTypes();
+        assertTrue(emptyResourceTypeList.isEmpty());
+
+        List<String> resourceTypeListExpected = new LinkedList<String>();
+        resourceTypeListExpected.add("type1");
+        resourceTypeListExpected.add("type2");
+        resourceTypeListExpected.add("type3");
+
+        representation.setResourceTypes(resourceTypeListExpected);
+        List<String> resourceTypeListActual = representation.getResourceTypes();
+        assertEquals(resourceTypeListExpected.size(), resourceTypeListActual.size());
+        for (int i = 0; i < resourceTypeListExpected.size(); i++) {
+            assertEquals(resourceTypeListExpected.get(i), resourceTypeListActual.get(i));
+        }
+
+        boolean thrown = false;
+        try {
+            representation.setResourceTypes(null);
+        } catch (InvalidParameterException e) {
+            thrown = true;
+        }
+        assertTrue(thrown);
+    }
+
+    public void testResourceInterfacesGetSet() {
+        OcRepresentation representation = new OcRepresentation();
+
+        List<String> emptyResourceInterfaceList = representation.getResourceInterfaces();
+        assertTrue(emptyResourceInterfaceList.isEmpty());
+
+        representation.setResourceInterfaces(emptyResourceInterfaceList);
+        emptyResourceInterfaceList = representation.getResourceInterfaces();
+        assertTrue(emptyResourceInterfaceList.isEmpty());
+
+        List<String> resourceInterfaceListExpected = new LinkedList<String>();
+        resourceInterfaceListExpected.add("Interface1");
+        resourceInterfaceListExpected.add("Interface2");
+        resourceInterfaceListExpected.add("Interface3");
+
+        representation.setResourceInterfaces(resourceInterfaceListExpected);
+        List<String> resourceInterfaceListActual = representation.getResourceInterfaces();
+        assertEquals(resourceInterfaceListExpected.size(), resourceInterfaceListActual.size());
+        for (int i = 0; i < resourceInterfaceListExpected.size(); i++) {
+            assertEquals(resourceInterfaceListExpected.get(i), resourceInterfaceListActual.get(i));
+        }
+
+        boolean thrown = false;
+        try {
+            representation.setResourceInterfaces(null);
+        } catch (InvalidParameterException e) {
+            thrown = true;
+        }
+        assertTrue(thrown);
+    }
+
+    public void testAttributeManagement() {
+        OcRepresentation representation = new OcRepresentation();
+
+        assertTrue(representation.isEmpty());
+        assertEquals(0, representation.size());
+
+        try {
+            String integerKey = "integerKey";
+            int integerValue = 75;
+            representation.setValue(integerKey, integerValue);
+            assertFalse(representation.isEmpty());
+            assertEquals(1, representation.size());
+
+            int actualIntValue = representation.getValue(integerKey);
+            assertEquals(integerValue, actualIntValue);
+
+            String stringKey = "stringKey";
+            String stringValue = "stringValue";
+            representation.setValue(stringKey, stringValue);
+            assertEquals(2, representation.size());
+
+            assertTrue(representation.hasAttribute(integerKey));
+            representation.remove(integerKey);
+            assertFalse(representation.hasAttribute(integerKey));
+            assertEquals(1, representation.size());
+
+            representation.setValue(integerKey, integerValue);
+            assertFalse(representation.isNull(integerKey));
+            representation.setNull(integerKey);
+            assertTrue(representation.isNull(integerKey));
+        } catch (OcException e) {
+            assertTrue(false);
+        }
+
+        String nonexistentKey = "nonexistentKey";
+        assertFalse(representation.hasAttribute(nonexistentKey));
+        representation.setNull(nonexistentKey);
+        assertTrue(representation.isNull(nonexistentKey));
+
+        String nonexistentKey2 = "nonexistentKey2";
+        boolean thrown = false;
+        try {
+            boolean nonexistentValue = representation.getValue(nonexistentKey2);
+        } catch (OcException e) {
+            thrown = true;
+        }
+        assertTrue(thrown);
+    }
+
+    public void testAttributeAccessByType() throws OcException {
+        OcRepresentation rep = new OcRepresentation();
+
+        //integer
+        String intK = "intK";
+        int intV = 4;
+        rep.setValue(intK, intV);
+        int intVa = rep.getValue(intK);
+        assertEquals(intV, intVa);
+
+        //double
+        String doubleK = "doubleK";
+        double doubleV = 4.5;
+        rep.setValue(doubleK, doubleV);
+        double doubleVa = rep.getValue(doubleK);
+        assertEquals(doubleV, doubleVa);
+
+        //boolean
+        String booleanK = "booleanK";
+        boolean booleanV = true;
+        rep.setValue(booleanK, booleanV);
+        boolean booleanVa = rep.getValue(booleanK);
+        assertEquals(booleanV, booleanVa);
+
+        //String
+        String stringK = "stringK";
+        String stringV = "stringV";
+        rep.setValue(stringK, stringV);
+        String stringVa = rep.getValue(stringK);
+        assertEquals(stringV, stringVa);
+
+        //OcRepresentation
+        String repK = "repK";
+        OcRepresentation repV = new OcRepresentation();
+        repV.setValue(intK, intV);
+        rep.setValue(repK, repV);
+        OcRepresentation repVa = rep.getValue(repK);
+        assertEquals(intV, repVa.getValue(intK));
+    }
+
+    public void testAttributeAccessBySequenceType() throws OcException {
+        OcRepresentation rep = new OcRepresentation();
+
+        //integer
+        String intK = "intK";
+        int[] intArrV = {1, 2, 3, 4};
+        rep.setValue(intK, intArrV);
+        int[] intArrVa = rep.getValue(intK);
+        assertTrue(Arrays.equals(intArrV, intArrVa));
+
+        int[] intArrVEmpty = {};
+        rep.setValue(intK, intArrVEmpty);
+        int[] intArrVEmptyA = rep.getValue(intK);
+        assertTrue(Arrays.equals(intArrVEmpty, intArrVEmptyA));
+
+        //double
+        String doubleK = "doubleK";
+        double[] doubleArrV = {1.1, 2.2, 3.3, 4.4};
+        rep.setValue(doubleK, doubleArrV);
+        double[] doubleArrVa = rep.getValue(doubleK);
+        assertTrue(Arrays.equals(doubleArrV, doubleArrVa));
+
+        double[] doubleArrVEmpty = {};
+        rep.setValue(doubleK, doubleArrVEmpty);
+        double[] doubleArrVEmptyA = rep.getValue(doubleK);
+        assertTrue(Arrays.equals(doubleArrVEmpty, doubleArrVEmptyA));
+
+        //boolean
+        String booleanK = "booleanK";
+        boolean[] booleanArrV = {true, false, true, false};
+        rep.setValue(booleanK, booleanArrV);
+        boolean[] booleanArrVa = rep.getValue(booleanK);
+        assertTrue(Arrays.equals(booleanArrV, booleanArrVa));
+
+        boolean[] booleanArrVEmpty = {};
+        rep.setValue(booleanK, booleanArrVEmpty);
+        boolean[] booleanArrVEmptyA = rep.getValue(booleanK);
+        assertTrue(Arrays.equals(booleanArrVEmpty, booleanArrVEmptyA));
+
+        //String
+        String stringK = "stringK";
+        String[] stringArrV = {"aaa", "bbb", "ccc", "ddd"};
+        rep.setValue(stringK, stringArrV);
+        String[] stringArrVa = rep.getValue(stringK);
+        assertTrue(Arrays.equals(stringArrV, stringArrVa));
+
+        String[] stringArrVEmpty = {};
+        rep.setValue(stringK, stringArrVEmpty);
+        String[] stringArrVEmptyA = rep.getValue(stringK);
+        assertTrue(Arrays.equals(stringArrVEmpty, stringArrVEmptyA));
+
+        //OcRepresentation
+        String representationK = "representationK";
+        OcRepresentation[] representationArrV = {
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation()};
+        representationArrV[0].setValue(intK, 0);
+        representationArrV[1].setValue(intK, 1);
+        representationArrV[2].setValue(intK, 2);
+        representationArrV[3].setValue(intK, 3);
+
+        rep.setValue(representationK, representationArrV);
+        OcRepresentation[] representationArrVa = rep.getValue(representationK);
+
+        assertEquals(representationArrV.length, representationArrVa.length);
+        for (int i = 0; i < representationArrV.length; ++i) {
+            assertEquals(representationArrV[i].getValue(intK),
+                    representationArrVa[i].getValue(intK));
+        }
+
+        OcRepresentation[] representationArrVEmpty = {};
+        rep.setValue(representationK, representationArrVEmpty);
+        OcRepresentation[] representationArrVEmptyA = rep.getValue(representationK);
+        assertEquals(representationArrVEmpty.length, representationArrVEmptyA.length);
+    }
+
+    public void testAttributeAccessBy2DType() throws OcException {
+        OcRepresentation rep = new OcRepresentation();
+        //integer
+        String int2DK = "int2DK";
+        int[] intArrV1 = {1, 2, 3, 4};
+        int[] intArrV2 = {5, 6, 7, 8};
+        int[][] int2DArrV = {intArrV1, intArrV2};
+        rep.setValue(int2DK, int2DArrV);
+        int[][] int2DArrVa = rep.getValue(int2DK);
+        for (int i = 0; i < int2DArrV.length; i++) {
+            assertTrue(Arrays.equals(int2DArrV[i], int2DArrVa[i]));
+        }
+        //double
+        String double2DK = "double2DK";
+        double[] doubleArrV1 = {1.1, 2.2, 3.3, 4.4};
+        double[] doubleArrV2 = {5, 6, 7, 8};
+        double[][] double2DArrV = {doubleArrV1, doubleArrV2};
+        rep.setValue(double2DK, double2DArrV);
+        double[][] double2DArrVa = rep.getValue(double2DK);
+        for (int i = 0; i < double2DArrV.length; i++) {
+            assertTrue(Arrays.equals(double2DArrV[i], double2DArrVa[i]));
+        }
+        double[][] double2DArrVEmpty = {{}};
+        rep.setValue(double2DK, double2DArrVEmpty);
+        double[][] double2DArrVEmptyA = rep.getValue(double2DK);
+        for (int i = 0; i < double2DArrVEmpty.length; i++) {
+            assertTrue(Arrays.equals(double2DArrVEmpty[i], double2DArrVEmptyA[i]));
+        }
+        //boolean
+        String boolean2DK = "boolean2DK";
+        boolean[] booleanArrV1 = {true, true, false};
+        boolean[] booleanArrV2 = {true, false, false, true};
+        boolean[][] boolean2DArrV = {booleanArrV1, booleanArrV2};
+        rep.setValue(boolean2DK, boolean2DArrV);
+        boolean[][] boolean2DArrVa = rep.getValue(boolean2DK);
+        for (int i = 0; i < boolean2DArrV.length; i++) {
+            assertTrue(Arrays.equals(boolean2DArrV[i], boolean2DArrVa[i]));
+        }
+        boolean[][] boolean2DArrVEmpty = {{}};
+        rep.setValue(boolean2DK, boolean2DArrVEmpty);
+        boolean[][] boolean2DArrVEmptyA = rep.getValue(boolean2DK);
+        for (int i = 0; i < boolean2DArrVEmpty.length; i++) {
+            assertTrue(Arrays.equals(boolean2DArrVEmpty[i], boolean2DArrVEmptyA[i]));
+        }
+
+        //String
+        String string2DK = "string2DK";
+        String[] stringArrV1 = {"aaa", "bbb", "ccc"};
+        String[] stringArrV2 = {"111", "222", "333", "444"};
+        String[][] string2DArrV = {stringArrV1, stringArrV2};
+        rep.setValue(string2DK, string2DArrV);
+        String[][] string2DArrVa = rep.getValue(string2DK);
+        for (int i = 0; i < string2DArrV.length; i++) {
+            assertTrue(Arrays.equals(string2DArrV[i], string2DArrVa[i]));
+        }
+        String[][] string2DArrVEmpty = {{}};
+        rep.setValue(string2DK, string2DArrVEmpty);
+        String[][] string2DArrVEmptyA = rep.getValue(string2DK);
+        for (int i = 0; i < string2DArrVEmpty.length; i++) {
+            assertTrue(Arrays.equals(string2DArrVEmpty[i], string2DArrVEmptyA[i]));
+        }
+
+        //OcRepresentation
+        String intK = "intK";
+        String representation2DK = "representation2DK";
+        OcRepresentation[] representation2DArrV1 = {
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation()};
+        representation2DArrV1[0].setValue(intK, 0);
+        representation2DArrV1[1].setValue(intK, 1);
+        representation2DArrV1[2].setValue(intK, 2);
+        representation2DArrV1[3].setValue(intK, 3);
+
+        OcRepresentation[] representation2DArrV2 = {
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation()};
+        representation2DArrV2[0].setValue(intK, 4);
+        representation2DArrV2[1].setValue(intK, 5);
+        representation2DArrV2[2].setValue(intK, 6);
+        representation2DArrV2[3].setValue(intK, 7);
+
+        OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2};
+        rep.setValue(representation2DK, representation2DArrV);
+        OcRepresentation[][] representation2DArrVa = rep.getValue(representation2DK);
+        assertEquals(representation2DArrV.length, representation2DArrVa.length);
+        for (int i = 0; i < representation2DArrV.length; ++i) {
+            OcRepresentation[] repArrV = representation2DArrV[i];
+            OcRepresentation[] repArrVa = representation2DArrVa[i];
+            assertEquals(repArrV.length, repArrVa.length);
+            for (int j = 0; j < representation2DArrV.length; ++j) {
+                assertEquals(repArrV[j].getValue(intK),
+                        repArrVa[j].getValue(intK));
+            }
+        }
+
+        OcRepresentation[][] representation2DArrVEmpty = {{}};
+        rep.setValue(representation2DK, representation2DArrVEmpty);
+        OcRepresentation[][] representation2DArrVEmptyA = rep.getValue(representation2DK);
+        assertEquals(representation2DArrVEmpty.length, representation2DArrVEmptyA.length);
+    }
+
+    public void testAttributeAccessBy3DType() throws OcException {
+        OcRepresentation rep = new OcRepresentation();
+        //integer
+        String int3DK = "int3DK";
+        int[] intArrV1 = {0, 1, 2, 3, 4};
+        int[] intArrV2 = {5, 6, 7, 8};
+        int[][] int2DArrV1 = {intArrV1, intArrV2};
+        int[] intArrV3 = {9, 10};
+        int[] intArrV4 = {11};
+        int[][] int2DArrV2 = {intArrV3, intArrV4};
+        int[][][] int3DArrV = {int2DArrV1, int2DArrV2};
+        rep.setValue(int3DK, int3DArrV);
+        int[][][] int3DArrVa = rep.getValue(int3DK);
+        assertEquals(int3DArrV.length, int3DArrVa.length);
+        for (int i = 0; i < int3DArrV.length; i++) {
+            int[][] int2DT = int3DArrV[i];
+            int[][] int2DTa = int3DArrVa[i];
+            assertEquals(int2DT.length, int2DTa.length);
+            for (int j = 0; j < int2DT.length; j++) {
+                assertTrue(Arrays.equals(int2DT[j], int2DTa[j]));
+            }
+        }
+        //double
+        String double3DK = "double3DK";
+        double[] doubleArrV1 = {0.0, 1.1, 2.2, 3.3, 4.4};
+        double[] doubleArrV2 = {5.5, 6.6, 7.7, 8.8};
+        double[][] double2DArrV1 = {doubleArrV1, doubleArrV2};
+        double[] doubleArrV3 = {9.9, 10.1};
+        double[] doubleArrV4 = {11.1};
+        double[][] double2DArrV2 = {doubleArrV3, doubleArrV4};
+        double[][][] double3DArrV = {double2DArrV1, double2DArrV2};
+        rep.setValue(double3DK, double3DArrV);
+        double[][][] double3DArrVa = rep.getValue(double3DK);
+        assertEquals(double3DArrV.length, double3DArrVa.length);
+        for (int i = 0; i < double3DArrV.length; i++) {
+            double[][] double2DT = double3DArrV[i];
+            double[][] double2DTa = double3DArrVa[i];
+            assertEquals(double2DT.length, double2DTa.length);
+            for (int j = 0; j < double2DT.length; j++) {
+                assertTrue(Arrays.equals(double2DT[j], double2DTa[j]));
+            }
+        }
+        double[][][] double3DArrVEmpty = {};
+        rep.setValue(double3DK, double3DArrVEmpty);
+        double[][][] double3DArrVEmptyA = rep.getValue(double3DK);
+        assertEquals(double3DArrVEmpty.length, double3DArrVEmptyA.length);
+        for (int i = 0; i < double3DArrVEmpty.length; i++) {
+            double[][] double2DT = double3DArrVEmpty[i];
+            double[][] double2DTa = double3DArrVEmptyA[i];
+            assertEquals(double2DT.length, double2DTa.length);
+            for (int j = 0; j < double2DT.length; j++) {
+                assertTrue(Arrays.equals(double2DT[j], double2DTa[j]));
+            }
+        }
+
+        //boolean
+        String boolean3DK = "boolean3DK";
+        boolean[] booleanArrV1 = {true, false, true, true, false};
+        boolean[] booleanArrV2 = {false, false, false, true};
+        boolean[][] boolean2DArrV1 = {booleanArrV1, booleanArrV2};
+        boolean[] booleanArrV3 = {true, true};
+        boolean[] booleanArrV4 = {false};
+        boolean[][] boolean2DArrV2 = {booleanArrV3, booleanArrV4};
+        boolean[][][] boolean3DArrV = {boolean2DArrV1, boolean2DArrV2};
+        rep.setValue(boolean3DK, boolean3DArrV);
+        boolean[][][] boolean3DArrVa = rep.getValue(boolean3DK);
+        assertEquals(boolean3DArrV.length, boolean3DArrVa.length);
+        for (int i = 0; i < boolean3DArrV.length; i++) {
+            boolean[][] boolean2DT = boolean3DArrV[i];
+            boolean[][] boolean2DTa = boolean3DArrVa[i];
+            assertEquals(boolean2DT.length, boolean2DTa.length);
+            for (int j = 0; j < boolean2DT.length; j++) {
+                assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j]));
+            }
+        }
+        boolean[][][] boolean3DArrVEmpty = {};
+        rep.setValue(boolean3DK, boolean3DArrVEmpty);
+        boolean[][][] boolean3DArrVEmptyA = rep.getValue(boolean3DK);
+        assertEquals(boolean3DArrVEmpty.length, boolean3DArrVEmptyA.length);
+        for (int i = 0; i < boolean3DArrVEmpty.length; i++) {
+            boolean[][] boolean2DT = boolean3DArrVEmpty[i];
+            boolean[][] boolean2DTa = boolean3DArrVEmptyA[i];
+            assertEquals(boolean2DT.length, boolean2DTa.length);
+            for (int j = 0; j < boolean2DT.length; j++) {
+                assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j]));
+            }
+        }
+
+        //String
+        String string3DK = "string3DK";
+        String[] stringArrV1 = {"a", "bb", "ccc", "dddd", "eeee"};
+        String[] stringArrV2 = {"f", "gg", "hhh", "ii"};
+        String[][] string2DArrV1 = {stringArrV1, stringArrV2};
+        String[] stringArrV3 = {"j", "jj"};
+        String[] stringArrV4 = {"jjj"};
+        String[][] string2DArrV2 = {stringArrV3, stringArrV4};
+        String[][][] string3DArrV = {string2DArrV1, string2DArrV2};
+        rep.setValue(string3DK, string3DArrV);
+        String[][][] string3DArrVa = rep.getValue(string3DK);
+        assertEquals(string3DArrV.length, string3DArrVa.length);
+        for (int i = 0; i < string3DArrV.length; i++) {
+            String[][] string2DT = string3DArrV[i];
+            String[][] string2DTa = string3DArrVa[i];
+            assertEquals(string2DT.length, string2DTa.length);
+            for (int j = 0; j < string2DT.length; j++) {
+                assertTrue(Arrays.equals(string2DT[j], string2DTa[j]));
+            }
+        }
+        String[][][] string3DArrVEmpty = {};
+        rep.setValue(string3DK, string3DArrVEmpty);
+        String[][][] string3DArrVEmptyA = rep.getValue(string3DK);
+        assertEquals(string3DArrVEmpty.length, string3DArrVEmptyA.length);
+        for (int i = 0; i < string3DArrVEmpty.length; i++) {
+            String[][] string2DT = string3DArrVEmpty[i];
+            String[][] string2DTa = string3DArrVEmptyA[i];
+            assertEquals(string2DT.length, string2DTa.length);
+            for (int j = 0; j < string2DT.length; j++) {
+                assertTrue(Arrays.equals(string2DT[j], string2DTa[j]));
+            }
+        }
+
+        //OcRepresentation
+        String intK = "intK";
+        String representation3DK = "representation3DK";
+        OcRepresentation[] representation2DArrV1 = {
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation()};
+        representation2DArrV1[0].setValue(intK, 0);
+        representation2DArrV1[1].setValue(intK, 1);
+        representation2DArrV1[2].setValue(intK, 2);
+        representation2DArrV1[3].setValue(intK, 3);
+
+        OcRepresentation[] representation2DArrV2 = {
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation(),
+                new OcRepresentation()};
+        representation2DArrV2[0].setValue(intK, 4);
+        representation2DArrV2[1].setValue(intK, 5);
+        representation2DArrV2[2].setValue(intK, 6);
+        representation2DArrV2[3].setValue(intK, 7);
+
+        OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2};
+        OcRepresentation[][][] representation3DArrV = {representation2DArrV, representation2DArrV};
+
+        rep.setValue(representation3DK, representation3DArrV);
+        OcRepresentation[][][] representation3DArrVa = rep.getValue(representation3DK);
+        assertEquals(representation3DArrV.length, representation3DArrVa.length);
+        for (int i = 0; i < representation3DArrV.length; ++i) {
+            OcRepresentation[][] repArr2V = representation3DArrV[i];
+            OcRepresentation[][] repArr2Va = representation3DArrVa[i];
+            assertEquals(repArr2V.length, repArr2Va.length);
+            for (int j = 0; j < repArr2V.length; ++j) {
+                OcRepresentation[] repArrV = repArr2V[j];
+                OcRepresentation[] repArrVa = repArr2Va[j];
+                assertEquals(repArrV.length, repArrVa.length);
+                for (int k = 0; k < repArrV.length; ++k) {
+                    assertEquals(repArrV[k].getValue(intK), repArrVa[k].getValue(intK));
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
index 490496a..eb981b5 100644 (file)
@@ -78,7 +78,10 @@ public class SmokeTest extends InstrumentationTestCase {
                     public void onResourceFound(OcResource resource) {
                         Log.i(TAG, "Host: " + resource.getHost());
                         Log.i(TAG, "Server ID: " + resource.getServerId());
-                        Log.i(TAG, "Connectivity Type: " + resource.getConnectivityType());
+                        Log.i(TAG, "Connectivity Types: ");
+                        for (OcConnectivityType connectivityType : resource.getConnectivityTypeSet()) {
+                            Log.i(TAG, " " + connectivityType);
+                        }
                         signal.countDown();
                     }
                 };
@@ -96,7 +99,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -109,85 +112,85 @@ public class SmokeTest extends InstrumentationTestCase {
             assertTrue(false);
         }
     }
-
-    public void testStartStopListenForPresence() throws InterruptedException {
-        final String resourceType = "unit.test.resource" +
-                new Date().getTime();
-        final CountDownLatch signal = new CountDownLatch(1);
-
-        OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() {
-            @Override
-            public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {
-                return EntityHandlerResult.OK;
-            }
-        };
-
-        final OcPlatform.OnPresenceListener presenceListener = new OcPlatform.OnPresenceListener() {
-            @Override
-            public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress) {
-                Log.i(TAG, "onPresence status " + ocPresenceStatus.toString() + " nonce " + nonce);
-                signal.countDown();
-            }
-        };
-
-        OcPlatform.OnResourceFoundListener resourceFoundListener =
-                new OcPlatform.OnResourceFoundListener() {
-                    @Override
-                    public void onResourceFound(OcResource resource) {
-                        try {
-                            //client
-                            OcPresenceHandle presenceHandle = OcPlatform.subscribePresence(
-                                    resource.getHost(),
-                                    OcConnectivityType.IPV4,
-                                    presenceListener
-                            );
-
-                            //wait for onPresence event
-                            assertTrue(signal.await(60, TimeUnit.SECONDS));
-
-                            //client
-                            OcPlatform.unsubscribePresence(presenceHandle);
-                        } catch (OcException e) {
-                            assertTrue(false);
-                        } catch (InterruptedException e) {
-                            assertTrue(false);
-                        }
-                    }
-                };
-
-        try {
-            //server
-            OcResourceHandle resourceHandle = OcPlatform.registerResource(
-                    "/a/unittest",
-                    resourceType,
-                    OcPlatform.DEFAULT_INTERFACE,
-                    entityHandler,
-                    EnumSet.of(ResourceProperty.DISCOVERABLE)
-            );
-
-            //client
-            OcPlatform.findResource("",
-                    OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
-                    resourceFoundListener);
-
-            //server
-            OcPlatform.startPresence(OcPlatform.DEFAULT_PRESENCE_TTL);
-
-            //wait for onPresence event
-            assertTrue(signal.await(60, TimeUnit.SECONDS));
-
-            //server
-            OcPlatform.stopPresence();
-
-            //client
-            OcPlatform.unregisterResource(resourceHandle);
-
-        } catch (OcException e) {
-            Log.e(TAG, e.getMessage());
-            assertTrue(false);
-        }
-    }
+//    TODO - this test fails currently
+//    public void testStartStopListenForPresence() throws InterruptedException {
+//        final String resourceType = "unit.test.resource" +
+//                new Date().getTime();
+//        final CountDownLatch signal = new CountDownLatch(1);
+//
+//        OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() {
+//            @Override
+//            public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {
+//                return EntityHandlerResult.OK;
+//            }
+//        };
+//
+//        final OcPlatform.OnPresenceListener presenceListener = new OcPlatform.OnPresenceListener() {
+//            @Override
+//            public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress) {
+//                Log.i(TAG, "onPresence status " + ocPresenceStatus.toString() + " nonce " + nonce);
+//                signal.countDown();
+//            }
+//        };
+//
+//        OcPlatform.OnResourceFoundListener resourceFoundListener =
+//                new OcPlatform.OnResourceFoundListener() {
+//                    @Override
+//                    public void onResourceFound(OcResource resource) {
+//                        try {
+//                            //client
+//                            OcPresenceHandle presenceHandle = OcPlatform.subscribePresence(
+//                                    resource.getHost(),
+//                                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
+//                                    presenceListener
+//                            );
+//
+//                            //wait for onPresence event
+//                            assertTrue(signal.await(60, TimeUnit.SECONDS));
+//
+//                            //client
+//                            OcPlatform.unsubscribePresence(presenceHandle);
+//                        } catch (OcException e) {
+//                            assertTrue(false);
+//                        } catch (InterruptedException e) {
+//                            assertTrue(false);
+//                        }
+//                    }
+//                };
+//
+//        try {
+//            //server
+//            OcResourceHandle resourceHandle = OcPlatform.registerResource(
+//                    "/a/unittest",
+//                    resourceType,
+//                    OcPlatform.DEFAULT_INTERFACE,
+//                    entityHandler,
+//                    EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE)
+//            );
+//
+//            //client
+//            OcPlatform.findResource("",
+//                    OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
+//                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
+//                    resourceFoundListener);
+//
+//            //server
+//            OcPlatform.startPresence(OcPlatform.DEFAULT_PRESENCE_TTL);
+//
+//            //wait for onPresence event
+//            assertTrue(signal.await(60, TimeUnit.SECONDS));
+//
+//            //server
+//            OcPlatform.stopPresence();
+//
+//            //client
+//            OcPlatform.unregisterResource(resourceHandle);
+//
+//        } catch (OcException e) {
+//            Log.e(TAG, e.getMessage());
+//            assertTrue(false);
+//        }
+//    }
 
     public void testHandleGetRequest() throws InterruptedException {
         final String someKey = "SomeKey";
@@ -223,9 +226,14 @@ public class SmokeTest extends InstrumentationTestCase {
                 if (ex instanceof OcException) {
                     OcException ocEx = (OcException) ex;
                     ErrorCode errCode = ocEx.getErrorCode();
+                    if (ErrorCode.NO_RESOURCE != errCode) {
+                        Log.e(TAG, ocEx.getMessage());
+                        assertTrue(false);
+                    }
+                } else {
+                    Log.e(TAG, ex.getMessage());
+                    assertTrue(false);
                 }
-                Log.e(TAG, ex.toString());
-                assertTrue(false);
             }
         };
 
@@ -314,7 +322,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource(null,
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -364,9 +372,14 @@ public class SmokeTest extends InstrumentationTestCase {
                 if (ex instanceof OcException) {
                     OcException ocEx = (OcException) ex;
                     ErrorCode errCode = ocEx.getErrorCode();
+                    if (ErrorCode.NO_RESOURCE != errCode) {
+                        Log.e(TAG, ocEx.getMessage());
+                        assertTrue(false);
+                    }
+                } else {
+                    Log.e(TAG, ex.getMessage());
+                    assertTrue(false);
                 }
-                Log.e(TAG, ex.toString());
-                assertTrue(false);
             }
         };
 
@@ -400,9 +413,14 @@ public class SmokeTest extends InstrumentationTestCase {
                                             if (ex instanceof OcException) {
                                                 OcException ocEx = (OcException) ex;
                                                 ErrorCode errCode = ocEx.getErrorCode();
+                                                if (ErrorCode.NO_RESOURCE != errCode) {
+                                                    Log.e(TAG, ocEx.getMessage());
+                                                    assertTrue(false);
+                                                }
+                                            } else {
+                                                Log.e(TAG, ex.getMessage());
+                                                assertTrue(false);
                                             }
-                                            Log.e(TAG, ex.toString());
-                                            assertTrue(false);
                                         }
                                     });
 
@@ -477,7 +495,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -527,9 +545,14 @@ public class SmokeTest extends InstrumentationTestCase {
                 if (ex instanceof OcException) {
                     OcException ocEx = (OcException) ex;
                     ErrorCode errCode = ocEx.getErrorCode();
+                    if (ErrorCode.NO_RESOURCE != errCode) {
+                        Log.e(TAG, ocEx.getMessage());
+                        assertTrue(false);
+                    }
+                } else {
+                    Log.e(TAG, ex.getMessage());
+                    assertTrue(false);
                 }
-                Log.e(TAG, ex.toString());
-                assertTrue(false);
             }
         };
 
@@ -563,9 +586,14 @@ public class SmokeTest extends InstrumentationTestCase {
                                             if (ex instanceof OcException) {
                                                 OcException ocEx = (OcException) ex;
                                                 ErrorCode errCode = ocEx.getErrorCode();
+                                                if (ErrorCode.NO_RESOURCE != errCode) {
+                                                    Log.e(TAG, ocEx.getMessage());
+                                                    assertTrue(false);
+                                                }
+                                            } else {
+                                                Log.e(TAG, ex.getMessage());
+                                                assertTrue(false);
                                             }
-                                            Log.e(TAG, ex.toString());
-                                            assertTrue(false);
                                         }
                                     });
 
@@ -643,7 +671,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -679,9 +707,14 @@ public class SmokeTest extends InstrumentationTestCase {
                 if (ex instanceof OcException) {
                     OcException ocEx = (OcException) ex;
                     ErrorCode errCode = ocEx.getErrorCode();
+                    if (ErrorCode.NO_RESOURCE != errCode) {
+                        Log.e(TAG, ocEx.getMessage());
+                        assertTrue(false);
+                    }
+                } else {
+                    Log.e(TAG, ex.getMessage());
+                    assertTrue(false);
                 }
-                Log.e(TAG, ex.toString());
-                assertTrue(false);
             }
         };
 
@@ -747,7 +780,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -925,7 +958,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -948,6 +981,56 @@ public class SmokeTest extends InstrumentationTestCase {
         }
     }
 
+    public void testPlatformInfo() throws InterruptedException {
+        final String resourceType = "unit.test.resource" + new Date().getTime();
+        final CountDownLatch signal = new CountDownLatch(1);
+
+        OcPlatform.OnPlatformFoundListener platformFoundListener = new OcPlatform.OnPlatformFoundListener() {
+            @Override
+            public void onPlatformFound(OcRepresentation ocRepresentation) {
+                Log.i(TAG, "Platform Info Received: ");
+                Log.i(TAG, "URI: " + ocRepresentation.getUri());
+                signal.countDown();
+            }
+        };
+
+        OcPlatformInfo platformInfo = null;
+        try {
+            platformInfo = new OcPlatformInfo("myPlatformID", "myManuName", "myManuUrl");
+        } catch (OcException e) {
+            Log.e(TAG, "Could not construct platformInfo. " + e.getMessage());
+            assertTrue(false);
+        }
+
+        platformInfo.setModelNumber("myModelNumber");
+        platformInfo.setDateOfManufacture("myDateOfManufacture");
+        platformInfo.setPlatformVersion("myPlatformVersion");
+        platformInfo.setOperatingSystemVersion("myOperatingSystemVersion");
+        platformInfo.setHardwareVersion("myHardwareVersion");
+        platformInfo.setFirmwareVersion("myFirmwareVersion");
+        platformInfo.setSupportUrl("mySupportUrl");
+        platformInfo.setSystemTime("mySystemTime");
+
+        try {
+            //server
+
+            OcPlatform.registerPlatformInfo(platformInfo);
+
+            //client
+            OcPlatform.getPlatformInfo(
+                    "",
+                    OcPlatform.MULTICAST_PREFIX + "/oic/p",
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
+                    platformFoundListener);
+
+            //wait for onPlatformFound event
+            assertTrue(signal.await(60, TimeUnit.SECONDS));
+        } catch (OcException e) {
+            Log.e(TAG, e.getMessage() + platformInfo.toString());
+            assertTrue(false);
+        }
+    }
+
     public void testRegisterDeviceInfoGetDeviceInfo() throws InterruptedException {
         final String resourceType = "unit.test.resource" + new Date().getTime();
         final CountDownLatch signal = new CountDownLatch(1);
@@ -956,12 +1039,12 @@ public class SmokeTest extends InstrumentationTestCase {
             @Override
             public void onDeviceFound(OcRepresentation ocRepresentation) {
                 try {
-                    Log.i(TAG, "Device Name: " + ocRepresentation.getValue("dn"));
+                    Log.i(TAG, "Device Name: " + ocRepresentation.getValue("n"));
                 } catch (OcException e) {
                     Log.e(TAG, e.toString());
                     assertTrue(false);
                 }
-                boolean hasDeviceNameAtr = ocRepresentation.hasAttribute("dn");
+                boolean hasDeviceNameAtr = ocRepresentation.hasAttribute("n");
                 assertTrue(hasDeviceNameAtr);
                 boolean hasNonExistingAtr = ocRepresentation.hasAttribute("NonExisting");
                 assertFalse(hasNonExistingAtr);
@@ -971,19 +1054,7 @@ public class SmokeTest extends InstrumentationTestCase {
         };
 
         OcDeviceInfo devInfo = new OcDeviceInfo();
-
-        devInfo.setContentType("myContentType");
-        devInfo.setDateOfManufacture("myDateOfManufacture");
         devInfo.setDeviceName("myDeviceName");
-        devInfo.setDeviceUuid("myDeviceUUID");
-        devInfo.setFirmwareVersion("myFirmwareVersion");
-        devInfo.setHostName("myHostName");
-        devInfo.setManufacturerName("myManufacturerNa");
-        devInfo.setManufacturerUrl("myManufacturerUrl");
-        devInfo.setModelNumber("myModelNumber");
-        devInfo.setPlatformVersion("myPlatformVersion");
-        devInfo.setSupportUrl("mySupportUrl");
-        devInfo.setVersion("myVersion");
 
         try {
             //server
@@ -992,8 +1063,8 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.getDeviceInfo(
                     "",
-                    OcPlatform.WELL_KNOWN_QUERY + "/d",
-                    OcConnectivityType.IPV4,
+                    OcPlatform.MULTICAST_PREFIX + OcPlatform.DEVICE_URI,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     deviceFoundListener);
 
             //wait for onDeviceFound event
@@ -1093,7 +1164,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener1);
 
             //wait for onResourceFound event to find 3 registered resources
@@ -1106,7 +1177,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener3);
 
             //wait for onResourceFound event to find 1 collection resources
@@ -1118,7 +1189,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener2);
 
             //wait for onResourceFound event to find 2 resources
@@ -1130,7 +1201,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener4);
 
             //wait for onResourceFound event to find 3 registered resources
@@ -1145,7 +1216,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener6);
 
             //wait for onResourceFound event to find 1 collection resources
@@ -1156,7 +1227,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener5);
 
             //wait for onResourceFound event to find 1 collection resources
@@ -1240,12 +1311,12 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType1,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType2,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -1289,7 +1360,7 @@ public class SmokeTest extends InstrumentationTestCase {
                             OcResource resourceProxy = OcPlatform.constructResourceObject(
                                     resource.getHost(),
                                     resource.getUri(),
-                                    OcConnectivityType.IPV4,
+                                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                                     resource.isObservable(),
                                     resource.getResourceTypes(),
                                     resource.getResourceInterfaces());
@@ -1319,7 +1390,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -1346,7 +1417,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
@@ -1518,7 +1589,7 @@ public class SmokeTest extends InstrumentationTestCase {
             //client
             OcPlatform.findResource("",
                     OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType,
-                    OcConnectivityType.IPV4,
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
                     resourceFoundListener);
 
             //wait for onResourceFound event
index d1862e0..b83e4b3 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-public enum ErrorCode {\r
-    /* Success status code - START HERE */\r
-    OK("OK", ""),\r
-    RESOURCE_CREATED("RESOURCE_CREATED", ""),\r
-    RESOURCE_DELETED("RESOURCE_DELETED", ""),\r
-    CONTINUE("CONTINUE", ""),\r
-    /* Success status code - END HERE */\r
-        /* Error status code - START HERE */\r
-    INVALID_URI("INVALID_URI", ""),\r
-    INVALID_QUERY("INVALID_QUERY", ""),\r
-    INVALID_IP("INVALID_IP", ""),\r
-    INVALID_PORT("INVALID_PORT", ""),\r
-    INVALID_CALLBACK("INVALID_CALLBACK", ""),\r
-    INVALID_METHOD("INVALID_METHOD", ""),\r
-    INVALID_PARAM("INVALID_PARAM", ""),\r
-    INVALID_OBSERVE_PARAM("INVALID_OBSERVE_PARAM", ""),\r
-    NO_MEMORY("NO_MEMORY", ""),\r
-    COMM_ERROR("COMM_ERROR", ""),\r
-    NOT_IMPL("NOTIMPL", ""),\r
-    NO_RESOURCE("NO_RESOURCE", "Resource not found"),\r
-    RESOURCE_ERROR("RESOURCE_ERROR", "Not supported method or interface"),\r
-    SLOW_RESOURCE("SLOW_RESOURCE", ""),\r
-    NO_OBSERVERS("NO_OBSERVERS", "Resource has no registered observers"),\r
-    OBSERVER_NOT_FOUND("OBSERVER_NOT_FOUND", ""),\r
-    PRESENCE_STOPPED("PRESENCE_STOPPED", ""),\r
-    PRESENCE_TIMEOUT("PRESENCE_TIMEOUT", ""),\r
-    PRESENCE_DO_NOT_HANDLE("PRESENCE_DO_NOT_HANDLE", ""),\r
-    VIRTUAL_DO_NOT_HANDLE("VIRTUAL_DO_NOT_HANDLE", ""),\r
-    INVALID_OPTION("INVALID_OPTION", ""),\r
-    MALFORMED_RESPONSE("MALFORMED_RESPONSE", "Remote reply contained malformed data"),\r
-    PERSISTENT_BUFFER_REQUIRED("PERSISTENT_BUFFER_REQUIRED", ""),\r
-    INVALID_REQUEST_HANDLE("INVALID_REQUEST_HANDLE", ""),\r
-    INVALID_DEVICE_INFO("INVALID_DEVICE_INFO", ""),\r
-    ERROR("ERROR", "Generic error"),\r
-\r
-    JNI_EXCEPTION("JNI_EXCEPTION", "Generic Java binder error"),\r
-    JNI_NO_NATIVE_OBJECT("JNI_NO_NATIVE_OBJECT", ""),\r
-    JNI_INVALID_VALUE("JNI_INVALID_VALUE", ""),\r
-\r
-    INVALID_CLASS_CAST("INVALID_CLASS_CAST", ""),;\r
-\r
-    private String error;\r
-    private String description;\r
-\r
-    private ErrorCode(String error, String description) {\r
-        this.error = error;\r
-        this.description = description;\r
-    }\r
-\r
-    public String getError() {\r
-        return error;\r
-    }\r
-\r
-    public String getDescription() {\r
-        return description;\r
-    }\r
-\r
-    public static ErrorCode get(String errorCode) {\r
-        for (ErrorCode eCode : ErrorCode.values()) {\r
-            if (eCode.getError().equals(errorCode)) {\r
-                return eCode;\r
-            }\r
-        }\r
-        throw new IllegalArgumentException("Unexpected ErrorCode value");\r
-    }\r
-\r
-    @Override\r
-    public String toString() {\r
-        return error + (description.isEmpty() ? "" : " : " + description);\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+public enum ErrorCode {
+    /* Success status code - START HERE */
+    OK("OK", ""),
+    RESOURCE_CREATED("RESOURCE_CREATED", ""),
+    RESOURCE_DELETED("RESOURCE_DELETED", ""),
+    CONTINUE("CONTINUE", ""),
+    /* Success status code - END HERE */
+        /* Error status code - START HERE */
+    INVALID_URI("INVALID_URI", ""),
+    INVALID_QUERY("INVALID_QUERY", ""),
+    INVALID_IP("INVALID_IP", ""),
+    INVALID_PORT("INVALID_PORT", ""),
+    INVALID_CALLBACK("INVALID_CALLBACK", ""),
+    INVALID_METHOD("INVALID_METHOD", ""),
+    INVALID_PARAM("INVALID_PARAM", ""),
+    INVALID_OBSERVE_PARAM("INVALID_OBSERVE_PARAM", ""),
+    NO_MEMORY("NO_MEMORY", ""),
+    COMM_ERROR("COMM_ERROR", ""),
+    NOT_IMPL("NOTIMPL", ""),
+    NO_RESOURCE("NO_RESOURCE", "Resource not found"),
+    RESOURCE_ERROR("RESOURCE_ERROR", "Not supported method or interface"),
+    SLOW_RESOURCE("SLOW_RESOURCE", ""),
+    NO_OBSERVERS("NO_OBSERVERS", "Resource has no registered observers"),
+    OBSERVER_NOT_FOUND("OBSERVER_NOT_FOUND", ""),
+    PRESENCE_STOPPED("PRESENCE_STOPPED", ""),
+    PRESENCE_TIMEOUT("PRESENCE_TIMEOUT", ""),
+    PRESENCE_DO_NOT_HANDLE("PRESENCE_DO_NOT_HANDLE", ""),
+    VIRTUAL_DO_NOT_HANDLE("VIRTUAL_DO_NOT_HANDLE", ""),
+    INVALID_OPTION("INVALID_OPTION", ""),
+    MALFORMED_RESPONSE("MALFORMED_RESPONSE", "Remote reply contained malformed data"),
+    PERSISTENT_BUFFER_REQUIRED("PERSISTENT_BUFFER_REQUIRED", ""),
+    INVALID_REQUEST_HANDLE("INVALID_REQUEST_HANDLE", ""),
+    INVALID_DEVICE_INFO("INVALID_DEVICE_INFO", ""),
+    INVALID_PLATFORM_INFO_PLATFORMID("INVALID_PLATFORM_INFO_PLATFORMID",
+            "PlatformID cannot be null or empty"),
+    INVALID_PLATFORM_INFO_MANUFACTURER_NAME("INVALID_PLATFORM_INFO_MANUFACTURER_NAME",
+            "ManufacturerName cannot be null, empty or greater than " +
+                    OcStackConfig.MAX_MANUFACTURER_NAME_LENGTH + " characters long"),
+    INVALID_PLATFORM_INFO_PLATFORMID_MANUFACTURER_URL("INVALID_PLATFORM_INFO_MANUFACTURER_URL",
+            "MANUFACTURER_URL cannot be null, empty or greater than " +
+                    OcStackConfig.MAX_MANUFACTURER_URL_LENGTH + " characters long"),
+    ERROR("ERROR", "Generic error"),
+
+    JNI_EXCEPTION("JNI_EXCEPTION", "Generic Java binder error"),
+    JNI_NO_NATIVE_OBJECT("JNI_NO_NATIVE_OBJECT", ""),
+    JNI_INVALID_VALUE("JNI_INVALID_VALUE", ""),
+
+    INVALID_CLASS_CAST("INVALID_CLASS_CAST", ""),;
+
+    private String error;
+    private String description;
+
+    private ErrorCode(String error, String description) {
+        this.error = error;
+        this.description = description;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static ErrorCode get(String errorCode) {
+        for (ErrorCode eCode : ErrorCode.values()) {
+            if (eCode.getError().equals(errorCode)) {
+                return eCode;
+            }
+        }
+        throw new IllegalArgumentException("Unexpected ErrorCode value");
+    }
+
+    @Override
+    public String toString() {
+        return error + (description.isEmpty() ? "" : " : " + description);
+    }
+}
index db38881..7d42144 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-import java.security.InvalidParameterException;\r
-\r
-public enum OcConnectivityType {\r
-    IPV4    (0),\r
-    IPV6    (1),\r
-    EDR     (2),\r
-    LE      (3),\r
-    ALL     (4),\r
-    ;\r
-\r
-    private int value;\r
-\r
-    private OcConnectivityType(int value) {\r
-        this.value = value;\r
-    }\r
-\r
-    public int getValue() {\r
-        return this.value;\r
-    }\r
-\r
-    public static OcConnectivityType get(int val) {\r
-        for (OcConnectivityType v : OcConnectivityType.values()) {\r
-            if (v.getValue() == val)\r
-                return v;\r
-        }\r
-        throw new InvalidParameterException("Unexpected OcConnectivityType value:" + val);\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.security.InvalidParameterException;
+import java.util.EnumSet;
+
+public enum OcConnectivityType {
+    /** use when defaults are ok. */
+    CT_DEFAULT              (0),
+
+    /** IPv4 and IPv6, including 6LoWPAN.*/
+    CT_ADAPTER_IP           (1 << 16),
+
+    /** GATT over Bluetooth LE.*/
+    CT_ADAPTER_GATT_BTLE    (1 << 17),
+
+    /** RFCOMM over Bluetooth EDR.*/
+    CT_ADAPTER_RFCOMM_BTEDR (1 << 18),
+
+    /** Remote Access over XMPP.*/
+    CT_ADAPTER_REMOTE_ACCESS(1 << 19),
+
+    /** Insecure transport is the default (subject to change).*/
+
+    /** secure the transport path.*/
+    CT_FLAG_SECURE          (1 << 4),
+
+    /** IPv4 & IPv6 autoselection is the default.*/
+
+    /** IP adapter only.*/
+    CT_IP_USE_V6            (1 << 5),
+
+    /** IP adapter only.*/
+    CT_IP_USE_V4            (1 << 6),
+
+    /** Link-Local multicast is the default multicast scope for IPv6.
+     * These are placed here to correspond to the IPv6 address bits.*/
+
+    /** IPv6 Interface-Local scope(loopback).*/
+    CT_SCOPE_INTERFACE      (0x1),
+
+    /** IPv6 Link-Local scope (default).*/
+    CT_SCOPE_LINK           (0x2),
+
+    /** IPv6 Realm-Local scope.*/
+    CT_SCOPE_REALM          (0x3),
+
+    /** IPv6 Admin-Local scope.*/
+    CT_SCOPE_ADMIN          (0x4),
+
+    /** IPv6 Site-Local scope.*/
+    CT_SCOPE_SITE           (0x5),
+
+    /** IPv6 Organization-Local scope.*/
+    CT_SCOPE_ORG            (0x8),
+
+    /** IPv6 Global scope.*/
+    CT_SCOPE_GLOBAL         (0xE),
+    ;
+
+    private int value;
+
+    private OcConnectivityType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    public static EnumSet<OcConnectivityType> convertToEnumSet(int value) {
+        EnumSet<OcConnectivityType> typeSet = null;
+
+        for (OcConnectivityType 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 OcConnectivityType value:" + value);
+        }
+
+        return typeSet;
+    }
+}
index 65e1497..99d8c7c 100644 (file)
@@ -25,153 +25,24 @@ package org.iotivity.base;
 public class OcDeviceInfo {\r
 \r
     private String deviceName;\r
-    private String hostName;\r
-    private String deviceUuid;\r
-    private String contentType;\r
-    private String version;\r
-    private String manufacturerName;\r
-    private String manufacturerUrl;\r
-    private String modelNumber;\r
-    private String dateOfManufacture;\r
-    private String platformVersion;\r
-    private String firmwareVersion;\r
-    private String supportUrl;\r
 \r
     public OcDeviceInfo() {\r
+\r
         deviceName = "";\r
-        hostName = "";\r
-        deviceUuid = "";\r
-        contentType = "";\r
-        version = "";\r
-        manufacturerName = "";\r
-        manufacturerUrl = "";\r
-        modelNumber = "";\r
-        dateOfManufacture = "";\r
-        platformVersion = "";\r
-        firmwareVersion = "";\r
-        supportUrl = "";\r
     }\r
 \r
-    public OcDeviceInfo(\r
-            String deviceName,\r
-            String hostName,\r
-            String deviceUuid,\r
-            String contentType,\r
-            String version,\r
-            String manufacturerName,\r
-            String manufacturerUrl,\r
-            String modelNumber,\r
-            String dateOfManufacture,\r
-            String platformVersion,\r
-            String firmwareVersion,\r
-            String supportUrl) {\r
+    public OcDeviceInfo(String deviceName) {\r
+\r
         this.deviceName = deviceName;\r
-        this.hostName = hostName;\r
-        this.deviceUuid = deviceUuid;\r
-        this.contentType = contentType;\r
-        this.version = version;\r
-        this.manufacturerName = manufacturerName;\r
-        this.manufacturerUrl = manufacturerUrl;\r
-        this.modelNumber = modelNumber;\r
-        this.dateOfManufacture = dateOfManufacture;\r
-        this.platformVersion = platformVersion;\r
-        this.firmwareVersion = firmwareVersion;\r
-        this.supportUrl = supportUrl;\r
     }\r
 \r
     public String getDeviceName() {\r
+\r
         return deviceName;\r
     }\r
 \r
     public void setDeviceName(String deviceName) {\r
-        this.deviceName = deviceName;\r
-    }\r
-\r
-    public String getHostName() {\r
-        return hostName;\r
-    }\r
-\r
-    public void setHostName(String hostName) {\r
-        this.hostName = hostName;\r
-    }\r
-\r
-    public String getDeviceUuid() {\r
-        return deviceUuid;\r
-    }\r
-\r
-    public void setDeviceUuid(String deviceUuid) {\r
-        this.deviceUuid = deviceUuid;\r
-    }\r
-\r
-    public String getContentType() {\r
-        return contentType;\r
-    }\r
-\r
-    public void setContentType(String contentType) {\r
-        this.contentType = contentType;\r
-    }\r
-\r
-    public String getVersion() {\r
-        return version;\r
-    }\r
-\r
-    public void setVersion(String version) {\r
-        this.version = version;\r
-    }\r
-\r
-    public String getManufacturerName() {\r
-        return manufacturerName;\r
-    }\r
-\r
-    public void setManufacturerName(String manufacturerName) {\r
-        this.manufacturerName = manufacturerName;\r
-    }\r
-\r
-    public String getManufacturerUrl() {\r
-        return manufacturerUrl;\r
-    }\r
-\r
-    public void setManufacturerUrl(String manufacturerUrl) {\r
-        this.manufacturerUrl = manufacturerUrl;\r
-    }\r
-\r
-    public String getModelNumber() {\r
-        return modelNumber;\r
-    }\r
-\r
-    public void setModelNumber(String modelNumber) {\r
-        this.modelNumber = modelNumber;\r
-    }\r
-\r
-    public String getDateOfManufacture() {\r
-        return dateOfManufacture;\r
-    }\r
-\r
-    public void setDateOfManufacture(String dateOfManufacture) {\r
-        this.dateOfManufacture = dateOfManufacture;\r
-    }\r
-\r
-    public String getPlatformVersion() {\r
-        return platformVersion;\r
-    }\r
-\r
-    public void setPlatformVersion(String platformVersion) {\r
-        this.platformVersion = platformVersion;\r
-    }\r
-\r
-    public String getFirmwareVersion() {\r
-        return firmwareVersion;\r
-    }\r
-\r
-    public void setFirmwareVersion(String firmwareVersion) {\r
-        this.firmwareVersion = firmwareVersion;\r
-    }\r
 \r
-    public String getSupportUrl() {\r
-        return supportUrl;\r
-    }\r
-\r
-    public void setSupportUrl(String supportUrl) {\r
-        this.supportUrl = supportUrl;\r
+        this.deviceName = deviceName;\r
     }\r
 }\r
index f55269b..d042e9e 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-import org.iotivity.ca.CaInterface;\r
-\r
-import java.util.EnumSet;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-/**\r
- * Contains the main entrance/functionality of the product. To set a custom configuration, the\r
- * implementer must make a call to OcPlatform.Configure before the first usage of a function in this\r
- * class.\r
- */\r
-public final class OcPlatform {\r
-\r
-    static {\r
-        System.loadLibrary("oc_logger");\r
-        System.loadLibrary("octbstack");\r
-        System.loadLibrary("connectivity_abstraction");\r
-        System.loadLibrary("oc");\r
-        System.loadLibrary("ocstack-jni");\r
-    }\r
-\r
-    /**\r
-     * Default interface\r
-     */\r
-    public static final String DEFAULT_INTERFACE = "oc.mi.def";\r
-\r
-    /**\r
-     * Used in discovering (GET) links to other resources of a collection\r
-     */\r
-    public static final String LINK_INTERFACE = "oc.mi.ll";\r
-\r
-    /**\r
-     * Used in GET, PUT, POST, DELETE methods on links to other resources of a collection\r
-     */\r
-    public static final String BATCH_INTERFACE = "oc.mi.b";\r
-\r
-    /**\r
-     * Used in GET, PUT, POST methods on links to other remote resources of a group\r
-     */\r
-    public static final String GROUP_INTERFACE = "oc.mi.grp";\r
-\r
-    public static final String WELL_KNOWN_QUERY = "224.0.1.187:5683/oc/core";\r
-    public static final String MULTICAST_PREFIX = "224.0.1.187:5683";\r
-    public static final String MULTICAST_IP = "224.0.1.187";\r
-    public static final int MULTICAST_PORT = 5683;\r
-    public static final int DEFAULT_PRESENCE_TTL = 60;\r
-    public static final String PRESENCE_URI = "/oc/presence";\r
-\r
-    private static volatile boolean sIsPlatformInitialized = false;\r
-\r
-    private OcPlatform() {\r
-    }\r
-\r
-    /**\r
-     * API for setting the configuration of the OcPlatform.\r
-     * Note: Any calls made to this AFTER the first call to OcPlatform.Configure will have no affect\r
-     *\r
-     * @param platformConfig platform configuration\r
-     */\r
-    public synchronized static void Configure(PlatformConfig platformConfig) {\r
-        if (!sIsPlatformInitialized) {\r
-            CaInterface.initialize(platformConfig.getContext());\r
-\r
-            OcPlatform.configure(\r
-                    platformConfig.getServiceType().getValue(),\r
-                    platformConfig.getModeType().getValue(),\r
-                    platformConfig.getIpAddress(),\r
-                    platformConfig.getPort(),\r
-                    platformConfig.getQualityOfService().getValue()\r
-            );\r
-\r
-            sIsPlatformInitialized = true;\r
-        }\r
-    }\r
-\r
-    private static native void configure(int serviceType,\r
-                                         int modeType,\r
-                                         String ipAddress,\r
-                                         int port,\r
-                                         int qualityOfService);\r
-\r
-    /**\r
-     * API for notifying base that resource's attributes have changed.\r
-     *\r
-     * @param ocResourceHandle resource handle of the resource\r
-     * @throws OcException\r
-     */\r
-    public static void notifyAllObservers(\r
-            OcResourceHandle ocResourceHandle) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.notifyAllObservers0(ocResourceHandle);\r
-    }\r
-\r
-    private static native void notifyAllObservers0(\r
-            OcResourceHandle ocResourceHandle) throws OcException;\r
-\r
-    /**\r
-     * API for notifying base that resource's attributes have changed.\r
-     *\r
-     * @param ocResourceHandle resource handle of the resource\r
-     * @param qualityOfService the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public static void notifyAllObservers(\r
-            OcResourceHandle ocResourceHandle,\r
-            QualityOfService qualityOfService) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.notifyAllObservers1(ocResourceHandle, qualityOfService.getValue());\r
-    }\r
-\r
-    private static native void notifyAllObservers1(\r
-            OcResourceHandle ocResourceHandle,\r
-            int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * API for notifying only specific clients that resource's attributes have changed.\r
-     *\r
-     * @param ocResourceHandle    resource handle of the resource\r
-     * @param ocObservationIdList These set of ids are ones which which will be notified upon\r
-     *                            resource change.\r
-     * @param ocResourceResponse  OcResourceResponse object used by app to fill the response for\r
-     *                            this resource change\r
-     * @throws OcException\r
-     */\r
-    public static void notifyListOfObservers(\r
-            OcResourceHandle ocResourceHandle,\r
-            List<Byte> ocObservationIdList,\r
-            OcResourceResponse ocResourceResponse) throws OcException {\r
-        OcPlatform.initCheck();\r
-\r
-        byte[] idArr = new byte[ocObservationIdList.size()];\r
-        Iterator<Byte> it = ocObservationIdList.iterator();\r
-        int i = 0;\r
-        while (it.hasNext()) {\r
-            idArr[i++] = (byte) it.next();\r
-        }\r
-\r
-        OcPlatform.notifyListOfObservers2(\r
-                ocResourceHandle,\r
-                idArr,\r
-                ocResourceResponse);\r
-    }\r
-\r
-    private static native void notifyListOfObservers2(\r
-            OcResourceHandle ocResourceHandle,\r
-            byte[] ocObservationIdArray,\r
-            OcResourceResponse ocResourceResponse) throws OcException;\r
-\r
-    /**\r
-     * API for notifying only specific clients that resource's attributes have changed.\r
-     *\r
-     * @param ocResourceHandle    resource handle of the resource\r
-     * @param ocObservationIdList These set of ids are ones which which will be notified upon\r
-     *                            resource change.\r
-     * @param ocResourceResponse  OcResourceResponse object used by app to fill the response for\r
-     *                            this resource change\r
-     * @param qualityOfService    the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public static void notifyListOfObservers(\r
-            OcResourceHandle ocResourceHandle,\r
-            List<Byte> ocObservationIdList,\r
-            OcResourceResponse ocResourceResponse,\r
-            QualityOfService qualityOfService) throws OcException {\r
-        OcPlatform.initCheck();\r
-\r
-        byte[] idArr = new byte[ocObservationIdList.size()];\r
-        Iterator<Byte> it = ocObservationIdList.iterator();\r
-        int i = 0;\r
-        while (it.hasNext()) {\r
-            idArr[i++] = (byte) it.next();\r
-        }\r
-\r
-        OcPlatform.notifyListOfObservers3(\r
-                ocResourceHandle,\r
-                idArr,\r
-                ocResourceResponse,\r
-                qualityOfService.getValue()\r
-        );\r
-    }\r
-\r
-    private static native void notifyListOfObservers3(\r
-            OcResourceHandle ocResourceHandle,\r
-            byte[] ocObservationIdArray,\r
-            OcResourceResponse ocResourceResponse,\r
-            int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * API for Service and Resource Discovery. NOTE: This API applies to client side only\r
-     *\r
-     * @param host                    Host IP Address of a service to direct resource discovery query.\r
-     *                                If empty, performs multicast resource discovery query\r
-     * @param resourceUri             name of the resource. If null or empty, performs search for all\r
-     *                                resource names\r
-     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,\r
-     *                                IPV6, ALL\r
-     * @param onResourceFoundListener Handles events, success states and failure states.\r
-     * @throws OcException\r
-     */\r
-    public static void findResource(\r
-            String host,\r
-            String resourceUri,\r
-            OcConnectivityType connectivityType,\r
-            OnResourceFoundListener onResourceFoundListener) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.findResource0(\r
-                host,\r
-                resourceUri,\r
-                connectivityType.getValue(),\r
-                onResourceFoundListener\r
-        );\r
-    }\r
-\r
-    private static native void findResource0(\r
-            String host,\r
-            String resourceUri,\r
-            int connectivityType,\r
-            OnResourceFoundListener onResourceFoundListener) throws OcException;\r
-\r
-    /**\r
-     * API for Service and Resource Discovery. NOTE: This API applies to client side only\r
-     *\r
-     * @param host                    Host IP Address of a service to direct resource discovery query.\r
-     *                                If empty, performs multicast resource discovery query\r
-     * @param resourceUri             name of the resource. If null or empty, performs search for all\r
-     *                                resource names\r
-     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,\r
-     *                                IPV6, ALL\r
-     * @param onResourceFoundListener Handles events, success states and failure states.\r
-     * @param qualityOfService        the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public static void findResource(\r
-            String host,\r
-            String resourceUri,\r
-            OcConnectivityType connectivityType,\r
-            OnResourceFoundListener onResourceFoundListener,\r
-            QualityOfService qualityOfService) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.findResource1(host,\r
-                resourceUri,\r
-                connectivityType.getValue(),\r
-                onResourceFoundListener,\r
-                qualityOfService.getValue()\r
-        );\r
-    }\r
-\r
-    private static native void findResource1(\r
-            String host,\r
-            String resourceUri,\r
-            int connectivityType,\r
-            OnResourceFoundListener onResourceFoundListener,\r
-            int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * API for Device Discovery\r
-     *\r
-     * @param host                  Host IP Address. If null or empty, Multicast is performed.\r
-     * @param deviceUri             Uri containing address to the virtual device\r
-     * @param connectivityType      a type of connectivity indicating the interface. Example: IPV4,\r
-     *                              IPV6, ALL\r
-     * @param onDeviceFoundListener Handles events, success states and failure states.\r
-     * @throws OcException\r
-     */\r
-    public static void getDeviceInfo(\r
-            String host,\r
-            String deviceUri,\r
-            OcConnectivityType connectivityType,\r
-            OnDeviceFoundListener onDeviceFoundListener) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.getDeviceInfo0(\r
-                host,\r
-                deviceUri,\r
-                connectivityType.getValue(),\r
-                onDeviceFoundListener\r
-        );\r
-    }\r
-\r
-    private static native void getDeviceInfo0(\r
-            String host,\r
-            String deviceUri,\r
-            int connectivityType,\r
-            OnDeviceFoundListener onDeviceFoundListener) throws OcException;\r
-\r
-    /**\r
-     * API for Device Discovery\r
-     *\r
-     * @param host                  Host IP Address. If null or empty, Multicast is performed.\r
-     * @param deviceUri             Uri containing address to the virtual device\r
-     * @param connectivityType      a type of connectivity indicating the interface. Example: IPV4,\r
-     *                              IPV6, ALL\r
-     * @param onDeviceFoundListener Handles events, success states and failure states.\r
-     * @param qualityOfService      the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public static void getDeviceInfo(\r
-            String host,\r
-            String deviceUri,\r
-            OcConnectivityType connectivityType,\r
-            OnDeviceFoundListener onDeviceFoundListener,\r
-            QualityOfService qualityOfService) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.getDeviceInfo1(\r
-                host,\r
-                deviceUri,\r
-                connectivityType.getValue(),\r
-                onDeviceFoundListener,\r
-                qualityOfService.getValue()\r
-        );\r
-    }\r
-\r
-    private static native void getDeviceInfo1(\r
-            String host,\r
-            String deviceUri,\r
-            int connectivityType,\r
-            OnDeviceFoundListener onDeviceFoundListener,\r
-            int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * This API registers a resource with the server NOTE: This API applies to server side only.\r
-     *\r
-     * @param ocResource The instance of OcResource with all data filled\r
-     * @return resource handle\r
-     * @throws OcException\r
-     */\r
-    public static OcResourceHandle registerResource(\r
-            OcResource ocResource) throws OcException {\r
-        OcPlatform.initCheck();\r
-        return OcPlatform.registerResource0(ocResource);\r
-    }\r
-\r
-    private static native OcResourceHandle registerResource0(\r
-            OcResource ocResource) throws OcException;\r
-\r
-    /**\r
-     * This API registers a resource with the server NOTE: This API applies to server side only.\r
-     *\r
-     * @param resourceUri         The URI of the resource. Example: "a/light"\r
-     * @param resourceTypeName    The resource type. Example: "light"\r
-     * @param resourceInterface   The resource interface (whether it is collection etc).\r
-     * @param entityHandler       entity handler.\r
-     * @param resourcePropertySet indicates the property of the resource\r
-     * @return resource handle\r
-     * @throws OcException\r
-     */\r
-    public static OcResourceHandle registerResource(\r
-            String resourceUri,\r
-            String resourceTypeName,\r
-            String resourceInterface,\r
-            EntityHandler entityHandler,\r
-            EnumSet<ResourceProperty> resourcePropertySet) throws OcException {\r
-        OcPlatform.initCheck();\r
-\r
-        int resProperty = 0;\r
-\r
-        for (ResourceProperty prop : ResourceProperty.values()) {\r
-            if (resourcePropertySet.contains(prop))\r
-                resProperty |= prop.getValue();\r
-        }\r
-\r
-        return OcPlatform.registerResource1(resourceUri,\r
-                resourceTypeName,\r
-                resourceInterface,\r
-                entityHandler,\r
-                resProperty);\r
-    }\r
-\r
-    private static native OcResourceHandle registerResource1(\r
-            String resourceUri,\r
-            String resourceTypeName,\r
-            String resourceInterface,\r
-            EntityHandler entityHandler,\r
-            int resourceProperty) throws OcException;\r
-\r
-    /**\r
-     * Register Device Info\r
-     *\r
-     * @param ocDeviceInfo object containing all the device specific information\r
-     * @throws OcException\r
-     */\r
-    public static void registerDeviceInfo(\r
-            OcDeviceInfo ocDeviceInfo) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.registerDeviceInfo0(\r
-                ocDeviceInfo.getDeviceName(),\r
-                ocDeviceInfo.getHostName(),\r
-                ocDeviceInfo.getDeviceUuid(),\r
-                ocDeviceInfo.getContentType(),\r
-                ocDeviceInfo.getVersion(),\r
-                ocDeviceInfo.getManufacturerName(),\r
-                ocDeviceInfo.getManufacturerUrl(),\r
-                ocDeviceInfo.getModelNumber(),\r
-                ocDeviceInfo.getDateOfManufacture(),\r
-                ocDeviceInfo.getPlatformVersion(),\r
-                ocDeviceInfo.getFirmwareVersion(),\r
-                ocDeviceInfo.getSupportUrl()\r
-        );\r
-    }\r
-\r
-    private static native void registerDeviceInfo0(\r
-            String deviceName,\r
-            String hostName,\r
-            String deviceUUID,\r
-            String contentType,\r
-            String version,\r
-            String manufacturerName,\r
-            String manufacturerUrl,\r
-            String modelNumber,\r
-            String dateOfManufacture,\r
-            String platformVersion,\r
-            String firmwareVersion,\r
-            String supportUrl) throws OcException;\r
-\r
-    /**\r
-     * This API unregisters a resource with the server NOTE: This API applies to server side only.\r
-     *\r
-     * @param ocResourceHandle This is the resource handle which we which to unregister from the\r
-     *                         server\r
-     * @throws OcException\r
-     */\r
-    public static void unregisterResource(\r
-            OcResourceHandle ocResourceHandle) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.unregisterResource0(ocResourceHandle);\r
-    }\r
-\r
-    private static native void unregisterResource0(\r
-            OcResourceHandle ocResourceHandle) throws OcException;\r
-\r
-\r
-    /**\r
-     * Add a resource to a collection resource\r
-     *\r
-     * @param ocResourceCollectionHandle handle to the collection resource\r
-     * @param ocResourceHandle           handle to resource to be added to the collection resource\r
-     * @throws OcException\r
-     */\r
-    public static void bindResource(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle ocResourceHandle) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.bindResource0(ocResourceCollectionHandle, ocResourceHandle);\r
-    }\r
-\r
-    private static native void bindResource0(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle ocResourceHandle) throws OcException;\r
-\r
-    /**\r
-     * Add multiple resources to a collection resource.\r
-     *\r
-     * @param ocResourceCollectionHandle handle to the collection resource\r
-     * @param ocResourceHandleList       reference to list of resource handles to be added to the\r
-     *                                   collection resource\r
-     * @throws OcException\r
-     */\r
-    public static void bindResources(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            List<OcResourceHandle> ocResourceHandleList) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.bindResources0(\r
-                ocResourceCollectionHandle,\r
-                ocResourceHandleList.toArray(\r
-                        new OcResourceHandle[ocResourceHandleList.size()])\r
-        );\r
-    }\r
-\r
-    private static native void bindResources0(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle[] ocResourceHandleArray) throws OcException;\r
-\r
-    /**\r
-     * Unbind a resource from a collection resource.\r
-     *\r
-     * @param ocResourceCollectionHandle handle to the collection resource\r
-     * @param ocResourceHandle           resource handle to be unbound from the collection resource\r
-     * @throws OcException\r
-     */\r
-    public static void unbindResource(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle ocResourceHandle) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.unbindResource0(ocResourceCollectionHandle, ocResourceHandle);\r
-    }\r
-\r
-    private static native void unbindResource0(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle ocResourceHandle) throws OcException;\r
-\r
-    /**\r
-     * Unbind resources from a collection resource.\r
-     *\r
-     * @param ocResourceCollectionHandle Handle to the collection resource\r
-     * @param ocResourceHandleList       List of resource handles to be unbound from the collection\r
-     *                                   resource\r
-     * @throws OcException\r
-     */\r
-    public static void unbindResources(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            List<OcResourceHandle> ocResourceHandleList) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.unbindResources0(\r
-                ocResourceCollectionHandle,\r
-                ocResourceHandleList.toArray(\r
-                        new OcResourceHandle[ocResourceHandleList.size()])\r
-        );\r
-    }\r
-\r
-    private static native void unbindResources0(\r
-            OcResourceHandle ocResourceCollectionHandle,\r
-            OcResourceHandle[] ocResourceHandleArray) throws OcException;\r
-\r
-    /**\r
-     * Binds a type to a particular resource\r
-     *\r
-     * @param ocResourceHandle handle to the resource\r
-     * @param resourceTypeName new typename to bind to the resource\r
-     * @throws OcException\r
-     */\r
-    public static void bindTypeToResource(\r
-            OcResourceHandle ocResourceHandle,\r
-            String resourceTypeName) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.bindTypeToResource0(ocResourceHandle, resourceTypeName);\r
-    }\r
-\r
-    private static native void bindTypeToResource0(\r
-            OcResourceHandle ocResourceHandle,\r
-            String resourceTypeName) throws OcException;\r
-\r
-    /**\r
-     * Binds an interface to a particular resource\r
-     *\r
-     * @param ocResourceHandle      handle to the resource\r
-     * @param resourceInterfaceName new interface to bind to the resource\r
-     * @throws OcException\r
-     */\r
-    public static void bindInterfaceToResource(\r
-            OcResourceHandle ocResourceHandle,\r
-            String resourceInterfaceName) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.bindInterfaceToResource0(ocResourceHandle, resourceInterfaceName);\r
-    }\r
-\r
-    private static native void bindInterfaceToResource0(\r
-            OcResourceHandle ocResourceHandle,\r
-            String resourceInterfaceName) throws OcException;\r
-\r
-    /**\r
-     * Start Presence announcements.\r
-     *\r
-     * @param ttl time to live in seconds\r
-     * @throws OcException\r
-     */\r
-    public static void startPresence(int ttl) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.startPresence0(ttl);\r
-    }\r
-\r
-    private static native void startPresence0(int ttl) throws OcException;\r
-\r
-    /**\r
-     * Stop Presence announcements.\r
-     *\r
-     * @throws OcException\r
-     */\r
-    public static void stopPresence() throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.stopPresence0();\r
-    }\r
-\r
-    private static native void stopPresence0() throws OcException;\r
-\r
-    /**\r
-     * Subscribes to a server's presence change events. By making this subscription, every time a\r
-     * server adds/removes/alters a resource, starts or is intentionally stopped\r
-     *\r
-     * @param host               The IP address/addressable name of the server to subscribe to\r
-     * @param connectivityType   a type of connectivity indicating the interface. Example: IPV4,\r
-     *                           IPV6, ALL\r
-     * @param onPresenceListener listener that will receive notifications/subscription events\r
-     * @return a handle object that can be used to identify this subscription request. It can be\r
-     * used to unsubscribe from these events in the future\r
-     * @throws OcException\r
-     */\r
-    public static OcPresenceHandle subscribePresence(\r
-            String host,\r
-            OcConnectivityType connectivityType,\r
-            OnPresenceListener onPresenceListener) throws OcException {\r
-        OcPlatform.initCheck();\r
-        return OcPlatform.subscribePresence0(\r
-                host,\r
-                connectivityType.getValue(),\r
-                onPresenceListener\r
-        );\r
-    }\r
-\r
-    private static native OcPresenceHandle subscribePresence0(\r
-            String host,\r
-            int connectivityType,\r
-            OnPresenceListener onPresenceListener) throws OcException;\r
-\r
-    /**\r
-     * Subscribes to a server's presence change events. By making this subscription, every time a\r
-     * server adds/removes/alters a resource, starts or is intentionally stopped\r
-     *\r
-     * @param host               The IP address/addressable name of the server to subscribe to\r
-     * @param resourceType       a resource type specified as a filter for subscription events.\r
-     * @param connectivityType   a type of connectivity indicating the interface. Example: IPV4,\r
-     *                           IPV6, ALL\r
-     * @param onPresenceListener listener that will receive notifications/subscription events\r
-     * @return a handle object that can be used to identify this subscription request. It can be\r
-     * used to unsubscribe from these events in the future\r
-     * @throws OcException\r
-     */\r
-    public static OcPresenceHandle subscribePresence(\r
-            String host,\r
-            String resourceType,\r
-            OcConnectivityType connectivityType,\r
-            OnPresenceListener onPresenceListener) throws OcException {\r
-        OcPlatform.initCheck();\r
-        return OcPlatform.subscribePresence1(\r
-                host,\r
-                resourceType,\r
-                connectivityType.getValue(),\r
-                onPresenceListener);\r
-    }\r
-\r
-    private static native OcPresenceHandle subscribePresence1(\r
-            String host,\r
-            String resourceType,\r
-            int connectivityType,\r
-            OnPresenceListener onPresenceListener) throws OcException;\r
-\r
-    /**\r
-     * Unsubscribes from a previously subscribed server's presence events. Note that you may for\r
-     * a short time still receive events from the server since it may take time for the\r
-     * unsubscribe to take effect.\r
-     *\r
-     * @param ocPresenceHandle the handle object provided by the subscribePresence call that\r
-     *                         identifies this subscription\r
-     * @throws OcException\r
-     */\r
-    public static void unsubscribePresence(\r
-            OcPresenceHandle ocPresenceHandle) throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.unsubscribePresence0(ocPresenceHandle);\r
-    }\r
-\r
-    private static native void unsubscribePresence0(\r
-            OcPresenceHandle ocPresenceHandle) throws OcException;\r
-\r
-    /**\r
-     * Creates a resource proxy object so that get/put/observe functionality can be used without\r
-     * discovering the object in advance. Note that the consumer of this method needs to provide\r
-     * all of the details required to correctly contact and observe the object. If the consumer\r
-     * lacks any of this information, they should discover the resource object normally.\r
-     * Additionally, you can only create this object if OcPlatform was initialized to be a Client\r
-     * or Client/Server.\r
-     *\r
-     * @param host             a string containing a resolvable host address of the server holding\r
-     *                         the resource\r
-     * @param uri              the rest of the resource's URI that will permit messages to be\r
-     *                         properly routed.\r
-     *                         Example: /a/light\r
-     * @param connectivityType a type of connectivity indicating the interface. Example: IPV4,\r
-     *                         IPV6, ALL\r
-     * @param isObservable     a boolean containing whether the resource supports observation\r
-     * @param resourceTypeList a collection of resource types implemented by the resource\r
-     * @param interfaceList    a collection of interfaces that the resource supports/implements\r
-     * @return new resource object\r
-     * @throws OcException\r
-     */\r
-    public static OcResource constructResourceObject(\r
-            String host,\r
-            String uri,\r
-            OcConnectivityType connectivityType,\r
-            boolean isObservable,\r
-            List<String> resourceTypeList,\r
-            List<String> interfaceList) throws OcException {\r
-        OcPlatform.initCheck();\r
-        return OcPlatform.constructResourceObject0(\r
-                host,\r
-                uri,\r
-                connectivityType.getValue(),\r
-                isObservable,\r
-                resourceTypeList.toArray(new String[resourceTypeList.size()]),\r
-                interfaceList.toArray(new String[interfaceList.size()])\r
-        );\r
-    }\r
-\r
-    private static native OcResource constructResourceObject0(\r
-            String host,\r
-            String uri,\r
-            int connectivityType,\r
-            boolean isObservable,\r
-            String[] resourceTypes,\r
-            String[] interfaces) throws OcException;\r
-\r
-    /**\r
-     * Allows application entity handler to send response to an incoming request.\r
-     *\r
-     * @param ocResourceResponse resource response\r
-     * @throws OcException\r
-     */\r
-    public static void sendResponse(OcResourceResponse ocResourceResponse)\r
-            throws OcException {\r
-        OcPlatform.initCheck();\r
-        OcPlatform.sendResponse0(ocResourceResponse);\r
-    }\r
-\r
-    private static native void sendResponse0(OcResourceResponse ocResourceResponse)\r
-            throws OcException;\r
-\r
-    /**\r
-     * An OnResourceFoundListener can be registered via the OcPlatform.findResource call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnResourceFoundListener {\r
-        public void onResourceFound(OcResource resource);\r
-    }\r
-\r
-    /**\r
-     * An OnDeviceFoundListener can be registered via the OcPlatform.getDeviceInfo call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnDeviceFoundListener {\r
-        public void onDeviceFound(OcRepresentation ocRepresentation);\r
-    }\r
-\r
-    /**\r
-     * An OnPresenceListener can be registered via the OcPlatform.subscribePresence call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnPresenceListener {\r
-        public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress);\r
-    }\r
-\r
-    /**\r
-     * An EntityHandler can be registered via the OcPlatform.registerResource call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface EntityHandler {\r
-        public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest);\r
-    }\r
-\r
-    private static void initCheck() {\r
-        if (!sIsPlatformInitialized) {\r
-            throw new IllegalStateException("OcPlatform must be configured by making a call to " +\r
-                    "OcPlatform.Configure before any other API calls are permitted");\r
-        }\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import org.iotivity.ca.CaInterface;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Contains the main entrance/functionality of the product. To set a custom configuration, the
+ * implementer must make a call to OcPlatform.Configure before the first usage of a function in this
+ * class.
+ */
+public final class OcPlatform {
+
+    static {
+        System.loadLibrary("oc_logger");
+        System.loadLibrary("octbstack");
+        System.loadLibrary("connectivity_abstraction");
+        System.loadLibrary("oc");
+        System.loadLibrary("ocstack-jni");
+    }
+
+    /**
+     * Default interface
+     */
+    public static final String DEFAULT_INTERFACE = "oic.if.baseline";
+
+    /**
+     * Used in discovering (GET) links to other resources of a collection
+     */
+    public static final String LINK_INTERFACE = "oic.if.ll";
+
+    /**
+     * Used in GET, PUT, POST, DELETE methods on links to other resources of a collection
+     */
+    public static final String BATCH_INTERFACE = "oic.if.b";
+
+    /**
+     * Used in GET, PUT, POST methods on links to other remote resources of a group
+     */
+    public static final String GROUP_INTERFACE = "oic.mi.grp";
+
+    public static final String WELL_KNOWN_QUERY = "224.0.1.187:5683/oic/res";
+    public static final String MULTICAST_PREFIX = "224.0.1.187:5683";
+    public static final String MULTICAST_IP = "224.0.1.187";
+    public static final int MULTICAST_PORT = 5683;
+    public static final int DEFAULT_PRESENCE_TTL = 60;
+    public static final String DEVICE_URI = "/oic/d";
+    public static final String PRESENCE_URI = "/oic/ad";
+
+    private static volatile boolean sIsPlatformInitialized = false;
+
+    private OcPlatform() {
+    }
+
+    /**
+     * API for setting the configuration of the OcPlatform.
+     * Note: Any calls made to this AFTER the first call to OcPlatform.Configure will have no affect
+     *
+     * @param platformConfig platform configuration
+     */
+    public synchronized static void Configure(PlatformConfig platformConfig) {
+        if (!sIsPlatformInitialized) {
+            CaInterface.initialize(platformConfig.getContext());
+
+            OcPlatform.configure(
+                    platformConfig.getServiceType().getValue(),
+                    platformConfig.getModeType().getValue(),
+                    platformConfig.getIpAddress(),
+                    platformConfig.getPort(),
+                    platformConfig.getQualityOfService().getValue(),
+                    platformConfig.getSvrDbPath()
+            );
+
+            sIsPlatformInitialized = true;
+        }
+    }
+
+    private static native void configure(int serviceType,
+                                         int modeType,
+                                         String ipAddress,
+                                         int port,
+                                         int qualityOfService,
+                                         String dbPath);
+
+    /**
+     * API for notifying base that resource's attributes have changed.
+     *
+     * @param ocResourceHandle resource handle of the resource
+     * @throws OcException
+     */
+    public static void notifyAllObservers(
+            OcResourceHandle ocResourceHandle) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.notifyAllObservers0(ocResourceHandle);
+    }
+
+    private static native void notifyAllObservers0(
+            OcResourceHandle ocResourceHandle) throws OcException;
+
+    /**
+     * API for notifying base that resource's attributes have changed.
+     *
+     * @param ocResourceHandle resource handle of the resource
+     * @param qualityOfService the quality of communication
+     * @throws OcException
+     */
+    public static void notifyAllObservers(
+            OcResourceHandle ocResourceHandle,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.notifyAllObservers1(ocResourceHandle, qualityOfService.getValue());
+    }
+
+    private static native void notifyAllObservers1(
+            OcResourceHandle ocResourceHandle,
+            int qualityOfService) throws OcException;
+
+    /**
+     * API for notifying only specific clients that resource's attributes have changed.
+     *
+     * @param ocResourceHandle    resource handle of the resource
+     * @param ocObservationIdList These set of ids are ones which which will be notified upon
+     *                            resource change.
+     * @param ocResourceResponse  OcResourceResponse object used by app to fill the response for
+     *                            this resource change
+     * @throws OcException
+     */
+    public static void notifyListOfObservers(
+            OcResourceHandle ocResourceHandle,
+            List<Byte> ocObservationIdList,
+            OcResourceResponse ocResourceResponse) throws OcException {
+        OcPlatform.initCheck();
+
+        byte[] idArr = new byte[ocObservationIdList.size()];
+        Iterator<Byte> it = ocObservationIdList.iterator();
+        int i = 0;
+        while (it.hasNext()) {
+            idArr[i++] = (byte) it.next();
+        }
+
+        OcPlatform.notifyListOfObservers2(
+                ocResourceHandle,
+                idArr,
+                ocResourceResponse);
+    }
+
+    private static native void notifyListOfObservers2(
+            OcResourceHandle ocResourceHandle,
+            byte[] ocObservationIdArray,
+            OcResourceResponse ocResourceResponse) throws OcException;
+
+    /**
+     * API for notifying only specific clients that resource's attributes have changed.
+     *
+     * @param ocResourceHandle    resource handle of the resource
+     * @param ocObservationIdList These set of ids are ones which which will be notified upon
+     *                            resource change.
+     * @param ocResourceResponse  OcResourceResponse object used by app to fill the response for
+     *                            this resource change
+     * @param qualityOfService    the quality of communication
+     * @throws OcException
+     */
+    public static void notifyListOfObservers(
+            OcResourceHandle ocResourceHandle,
+            List<Byte> ocObservationIdList,
+            OcResourceResponse ocResourceResponse,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+
+        byte[] idArr = new byte[ocObservationIdList.size()];
+        Iterator<Byte> it = ocObservationIdList.iterator();
+        int i = 0;
+        while (it.hasNext()) {
+            idArr[i++] = (byte) it.next();
+        }
+
+        OcPlatform.notifyListOfObservers3(
+                ocResourceHandle,
+                idArr,
+                ocResourceResponse,
+                qualityOfService.getValue()
+        );
+    }
+
+    private static native void notifyListOfObservers3(
+            OcResourceHandle ocResourceHandle,
+            byte[] ocObservationIdArray,
+            OcResourceResponse ocResourceResponse,
+            int qualityOfService) throws OcException;
+
+    /**
+     * API for Service and Resource Discovery. NOTE: This API applies to client side only
+     *
+     * @param host                    Host IP Address of a service to direct resource discovery query.
+     *                                If empty, performs multicast resource discovery query
+     * @param resourceUri             name of the resource. If null or empty, performs search for all
+     *                                resource names
+     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,
+     *                                IPV6, ALL
+     * @param onResourceFoundListener Handles events, success states and failure states.
+     * @throws OcException
+     */
+    public static void findResource(
+            String host,
+            String resourceUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnResourceFoundListener onResourceFoundListener) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+
+        OcPlatform.findResource0(
+                host,
+                resourceUri,
+                connTypeInt,
+                onResourceFoundListener
+        );
+    }
+
+    private static native void findResource0(
+            String host,
+            String resourceUri,
+            int connectivityType,
+            OnResourceFoundListener onResourceFoundListener) throws OcException;
+
+    /**
+     * API for Service and Resource Discovery. NOTE: This API applies to client side only
+     *
+     * @param host                    Host IP Address of a service to direct resource discovery query.
+     *                                If empty, performs multicast resource discovery query
+     * @param resourceUri             name of the resource. If null or empty, performs search for all
+     *                                resource names
+     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,
+     *                                IPV6, ALL
+     * @param onResourceFoundListener Handles events, success states and failure states.
+     * @param qualityOfService        the quality of communication
+     * @throws OcException
+     */
+    public static void findResource(
+            String host,
+            String resourceUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnResourceFoundListener onResourceFoundListener,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+
+        OcPlatform.findResource1(host,
+                resourceUri,
+                connTypeInt,
+                onResourceFoundListener,
+                qualityOfService.getValue()
+        );
+    }
+
+    private static native void findResource1(
+            String host,
+            String resourceUri,
+            int connectivityType,
+            OnResourceFoundListener onResourceFoundListener,
+            int qualityOfService) throws OcException;
+
+    /**
+     * API for Device Discovery
+     *
+     * @param host                  Host IP Address. If null or empty, Multicast is performed.
+     * @param deviceUri             Uri containing address to the virtual device
+     * @param connectivityType      a type of connectivity indicating the interface. Example: IPV4,
+     *                              IPV6, ALL
+     * @param onDeviceFoundListener Handles events, success states and failure states.
+     * @throws OcException
+     */
+    public static void getDeviceInfo(
+            String host,
+            String deviceUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnDeviceFoundListener onDeviceFoundListener) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        OcPlatform.getDeviceInfo0(
+                host,
+                deviceUri,
+                connTypeInt,
+                onDeviceFoundListener
+        );
+    }
+
+    private static native void getDeviceInfo0(
+            String host,
+            String deviceUri,
+            int connectivityType,
+            OnDeviceFoundListener onDeviceFoundListener) throws OcException;
+
+    /**
+     * API for Device Discovery
+     *
+     * @param host                  Host IP Address. If null or empty, Multicast is performed.
+     * @param deviceUri             Uri containing address to the virtual device
+     * @param connectivityType      a type of connectivity indicating the interface. Example: IPV4,
+     *                              IPV6, ALL
+     * @param onDeviceFoundListener Handles events, success states and failure states.
+     * @param qualityOfService      the quality of communication
+     * @throws OcException
+     */
+    public static void getDeviceInfo(
+            String host,
+            String deviceUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnDeviceFoundListener onDeviceFoundListener,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        OcPlatform.getDeviceInfo1(
+                host,
+                deviceUri,
+                connTypeInt,
+                onDeviceFoundListener,
+                qualityOfService.getValue()
+        );
+    }
+
+    private static native void getDeviceInfo1(
+            String host,
+            String deviceUri,
+            int connectivityType,
+            OnDeviceFoundListener onDeviceFoundListener,
+            int qualityOfService) throws OcException;
+
+    /**
+     * API for Platform Discovery
+     *
+     * @param host                    Host IP Address. If null or empty, Multicast is performed.
+     * @param platformUri             Uri containing address to the platform
+     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,
+     *                                IPV6, ALL
+     * @param onPlatformFoundListener Handles events, success states and failure states.
+     * @throws OcException
+     */
+
+    public static void getPlatformInfo(
+            String host,
+            String platformUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPlatformFoundListener onPlatformFoundListener) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        OcPlatform.getPlatformInfo0(
+                host,
+                platformUri,
+                connTypeInt,
+                onPlatformFoundListener
+        );
+    }
+
+    private static native void getPlatformInfo0(
+            String host,
+            String platformUri,
+            int connectivityType,
+            OnPlatformFoundListener onPlatformInfoFoundListener) throws OcException;
+
+    /**
+     * API for Platform Discovery
+     *
+     * @param host                    Host IP Address. If null or empty, Multicast is performed.
+     * @param platformUri             Uri containing address to the platform
+     * @param connectivityType        a type of connectivity indicating the interface. Example: IPV4,
+     *                                IPV6, ALL
+     * @param onPlatformFoundListener Handles events, success states and failure states.
+     * @param qualityOfService        the quality of communication
+     * @throws OcException
+     */
+
+    public static void getPlatformInfo(
+            String host,
+            String platformUri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPlatformFoundListener onPlatformFoundListener,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        OcPlatform.getPlatformInfo1(
+                host,
+                platformUri,
+                connTypeInt,
+                onPlatformFoundListener,
+                qualityOfService.getValue()
+        );
+    }
+
+    private static native void getPlatformInfo1(
+            String host,
+            String platformUri,
+            int connectivityType,
+            OnPlatformFoundListener onPlatformFoundListener,
+            int qualityOfService) throws OcException;
+
+    /**
+     * This API registers a resource with the server NOTE: This API applies to server side only.
+     *
+     * @param ocResource The instance of OcResource with all data filled
+     * @return resource handle
+     * @throws OcException
+     */
+    public static OcResourceHandle registerResource(
+            OcResource ocResource) throws OcException {
+        OcPlatform.initCheck();
+        return OcPlatform.registerResource0(ocResource);
+    }
+
+    private static native OcResourceHandle registerResource0(
+            OcResource ocResource) throws OcException;
+
+    /**
+     * This API registers a resource with the server NOTE: This API applies to server side only.
+     *
+     * @param resourceUri         The URI of the resource. Example: "a/light"
+     * @param resourceTypeName    The resource type. Example: "light"
+     * @param resourceInterface   The resource interface (whether it is collection etc).
+     * @param entityHandler       entity handler.
+     * @param resourcePropertySet indicates the property of the resource
+     * @return resource handle
+     * @throws OcException
+     */
+    public static OcResourceHandle registerResource(
+            String resourceUri,
+            String resourceTypeName,
+            String resourceInterface,
+            EntityHandler entityHandler,
+            EnumSet<ResourceProperty> resourcePropertySet) throws OcException {
+        OcPlatform.initCheck();
+
+        int resProperty = 0;
+
+        for (ResourceProperty prop : ResourceProperty.values()) {
+            if (resourcePropertySet.contains(prop))
+                resProperty |= prop.getValue();
+        }
+
+        return OcPlatform.registerResource1(resourceUri,
+                resourceTypeName,
+                resourceInterface,
+                entityHandler,
+                resProperty);
+    }
+
+    private static native OcResourceHandle registerResource1(
+            String resourceUri,
+            String resourceTypeName,
+            String resourceInterface,
+            EntityHandler entityHandler,
+            int resourceProperty) throws OcException;
+
+    /**
+     * Register Device Info
+     *
+     * @param ocDeviceInfo object containing all the device specific information
+     * @throws OcException
+     */
+    public static void registerDeviceInfo(
+            OcDeviceInfo ocDeviceInfo) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.registerDeviceInfo0(
+                ocDeviceInfo.getDeviceName()
+        );
+    }
+
+    private static native void registerDeviceInfo0(
+            String deviceName
+    ) throws OcException;
+
+    /**
+     * Register Platform Info
+     *
+     * @param ocPlatformInfo object containing all the platform specific information
+     * @throws OcException
+     */
+    public static void registerPlatformInfo(
+            OcPlatformInfo ocPlatformInfo) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.registerPlatformInfo0(
+                ocPlatformInfo.getPlatformID(),
+                ocPlatformInfo.getManufacturerName(),
+                ocPlatformInfo.getManufacturerUrl(),
+                ocPlatformInfo.getModelNumber(),
+                ocPlatformInfo.getDateOfManufacture(),
+                ocPlatformInfo.getPlatformVersion(),
+                ocPlatformInfo.getOperatingSystemVersion(),
+                ocPlatformInfo.getHardwareVersion(),
+                ocPlatformInfo.getFirmwareVersion(),
+                ocPlatformInfo.getSupportUrl(),
+                ocPlatformInfo.getSystemTime()
+        );
+    }
+
+    private static native void registerPlatformInfo0(
+            String platformId, String manufacturerName, String manufacturerUrl,
+            String modelNumber, String dateOfManufacture, String platformVersion,
+            String operatingSystemVersion, String hardwareVersion, String firmwareVersion,
+            String supportUrl, String systemTime
+    ) throws OcException;
+
+    /**
+     * This API unregisters a resource with the server NOTE: This API applies to server side only.
+     *
+     * @param ocResourceHandle This is the resource handle which we which to unregister from the
+     *                         server
+     * @throws OcException
+     */
+    public static void unregisterResource(
+            OcResourceHandle ocResourceHandle) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.unregisterResource0(ocResourceHandle);
+    }
+
+    private static native void unregisterResource0(
+            OcResourceHandle ocResourceHandle) throws OcException;
+
+
+    /**
+     * Add a resource to a collection resource
+     *
+     * @param ocResourceCollectionHandle handle to the collection resource
+     * @param ocResourceHandle           handle to resource to be added to the collection resource
+     * @throws OcException
+     */
+    public static void bindResource(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle ocResourceHandle) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.bindResource0(ocResourceCollectionHandle, ocResourceHandle);
+    }
+
+    private static native void bindResource0(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle ocResourceHandle) throws OcException;
+
+    /**
+     * Add multiple resources to a collection resource.
+     *
+     * @param ocResourceCollectionHandle handle to the collection resource
+     * @param ocResourceHandleList       reference to list of resource handles to be added to the
+     *                                   collection resource
+     * @throws OcException
+     */
+    public static void bindResources(
+            OcResourceHandle ocResourceCollectionHandle,
+            List<OcResourceHandle> ocResourceHandleList) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.bindResources0(
+                ocResourceCollectionHandle,
+                ocResourceHandleList.toArray(
+                        new OcResourceHandle[ocResourceHandleList.size()])
+        );
+    }
+
+    private static native void bindResources0(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle[] ocResourceHandleArray) throws OcException;
+
+    /**
+     * Unbind a resource from a collection resource.
+     *
+     * @param ocResourceCollectionHandle handle to the collection resource
+     * @param ocResourceHandle           resource handle to be unbound from the collection resource
+     * @throws OcException
+     */
+    public static void unbindResource(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle ocResourceHandle) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.unbindResource0(ocResourceCollectionHandle, ocResourceHandle);
+    }
+
+    private static native void unbindResource0(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle ocResourceHandle) throws OcException;
+
+    /**
+     * Unbind resources from a collection resource.
+     *
+     * @param ocResourceCollectionHandle Handle to the collection resource
+     * @param ocResourceHandleList       List of resource handles to be unbound from the collection
+     *                                   resource
+     * @throws OcException
+     */
+    public static void unbindResources(
+            OcResourceHandle ocResourceCollectionHandle,
+            List<OcResourceHandle> ocResourceHandleList) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.unbindResources0(
+                ocResourceCollectionHandle,
+                ocResourceHandleList.toArray(
+                        new OcResourceHandle[ocResourceHandleList.size()])
+        );
+    }
+
+    private static native void unbindResources0(
+            OcResourceHandle ocResourceCollectionHandle,
+            OcResourceHandle[] ocResourceHandleArray) throws OcException;
+
+    /**
+     * Binds a type to a particular resource
+     *
+     * @param ocResourceHandle handle to the resource
+     * @param resourceTypeName new typename to bind to the resource
+     * @throws OcException
+     */
+    public static void bindTypeToResource(
+            OcResourceHandle ocResourceHandle,
+            String resourceTypeName) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.bindTypeToResource0(ocResourceHandle, resourceTypeName);
+    }
+
+    private static native void bindTypeToResource0(
+            OcResourceHandle ocResourceHandle,
+            String resourceTypeName) throws OcException;
+
+    /**
+     * Binds an interface to a particular resource
+     *
+     * @param ocResourceHandle      handle to the resource
+     * @param resourceInterfaceName new interface to bind to the resource
+     * @throws OcException
+     */
+    public static void bindInterfaceToResource(
+            OcResourceHandle ocResourceHandle,
+            String resourceInterfaceName) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.bindInterfaceToResource0(ocResourceHandle, resourceInterfaceName);
+    }
+
+    private static native void bindInterfaceToResource0(
+            OcResourceHandle ocResourceHandle,
+            String resourceInterfaceName) throws OcException;
+
+    /**
+     * Start Presence announcements.
+     *
+     * @param ttl time to live in seconds
+     * @throws OcException
+     */
+    public static void startPresence(int ttl) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.startPresence0(ttl);
+    }
+
+    private static native void startPresence0(int ttl) throws OcException;
+
+    /**
+     * Stop Presence announcements.
+     *
+     * @throws OcException
+     */
+    public static void stopPresence() throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.stopPresence0();
+    }
+
+    private static native void stopPresence0() throws OcException;
+
+    /**
+     * Subscribes to a server's presence change events. By making this subscription, every time a
+     * server adds/removes/alters a resource, starts or is intentionally stopped
+     *
+     * @param host               The IP address/addressable name of the server to subscribe to
+     * @param connectivityType   a type of connectivity indicating the interface. Example: IPV4,
+     *                           IPV6, ALL
+     * @param onPresenceListener listener that will receive notifications/subscription events
+     * @return a handle object that can be used to identify this subscription request. It can be
+     * used to unsubscribe from these events in the future
+     * @throws OcException
+     */
+    public static OcPresenceHandle subscribePresence(
+            String host,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPresenceListener onPresenceListener) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        return OcPlatform.subscribePresence0(
+                host,
+                connTypeInt,
+                onPresenceListener
+        );
+    }
+
+    private static native OcPresenceHandle subscribePresence0(
+            String host,
+            int connectivityType,
+            OnPresenceListener onPresenceListener) throws OcException;
+
+    /**
+     * Subscribes to a server's presence change events. By making this subscription, every time a
+     * server adds/removes/alters a resource, starts or is intentionally stopped
+     *
+     * @param host               The IP address/addressable name of the server to subscribe to
+     * @param resourceType       a resource type specified as a filter for subscription events.
+     * @param connectivityType   a type of connectivity indicating the interface. Example: IPV4,
+     *                           IPV6, ALL
+     * @param onPresenceListener listener that will receive notifications/subscription events
+     * @return a handle object that can be used to identify this subscription request. It can be
+     * used to unsubscribe from these events in the future
+     * @throws OcException
+     */
+    public static OcPresenceHandle subscribePresence(
+            String host,
+            String resourceType,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPresenceListener onPresenceListener) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        return OcPlatform.subscribePresence1(
+                host,
+                resourceType,
+                connTypeInt,
+                onPresenceListener);
+    }
+
+    private static native OcPresenceHandle subscribePresence1(
+            String host,
+            String resourceType,
+            int connectivityType,
+            OnPresenceListener onPresenceListener) throws OcException;
+
+    /**
+     * Unsubscribes from a previously subscribed server's presence events. Note that you may for
+     * a short time still receive events from the server since it may take time for the
+     * unsubscribe to take effect.
+     *
+     * @param ocPresenceHandle the handle object provided by the subscribePresence call that
+     *                         identifies this subscription
+     * @throws OcException
+     */
+    public static void unsubscribePresence(
+            OcPresenceHandle ocPresenceHandle) throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.unsubscribePresence0(ocPresenceHandle);
+    }
+
+    private static native void unsubscribePresence0(
+            OcPresenceHandle ocPresenceHandle) throws OcException;
+
+    /**
+     * Creates a resource proxy object so that get/put/observe functionality can be used without
+     * discovering the object in advance. Note that the consumer of this method needs to provide
+     * all of the details required to correctly contact and observe the object. If the consumer
+     * lacks any of this information, they should discover the resource object normally.
+     * Additionally, you can only create this object if OcPlatform was initialized to be a Client
+     * or Client/Server.
+     *
+     * @param host             a string containing a resolvable host address of the server holding
+     *                         the resource
+     * @param uri              the rest of the resource's URI that will permit messages to be
+     *                         properly routed.
+     *                         Example: /a/light
+     * @param connectivityType a type of connectivity indicating the interface. Example: IPV4,
+     *                         IPV6, ALL
+     * @param isObservable     a boolean containing whether the resource supports observation
+     * @param resourceTypeList a collection of resource types implemented by the resource
+     * @param interfaceList    a collection of interfaces that the resource supports/implements
+     * @return new resource object
+     * @throws OcException
+     */
+    public static OcResource constructResourceObject(
+            String host,
+            String uri,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            boolean isObservable,
+            List<String> resourceTypeList,
+            List<String> interfaceList) throws OcException {
+        OcPlatform.initCheck();
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType))
+                connTypeInt |= connType.getValue();
+        }
+        return OcPlatform.constructResourceObject0(
+                host,
+                uri,
+                connTypeInt,
+                isObservable,
+                resourceTypeList.toArray(new String[resourceTypeList.size()]),
+                interfaceList.toArray(new String[interfaceList.size()])
+        );
+    }
+
+    private static native OcResource constructResourceObject0(
+            String host,
+            String uri,
+            int connectivityType,
+            boolean isObservable,
+            String[] resourceTypes,
+            String[] interfaces) throws OcException;
+
+    /**
+     * Allows application entity handler to send response to an incoming request.
+     *
+     * @param ocResourceResponse resource response
+     * @throws OcException
+     */
+    public static void sendResponse(OcResourceResponse ocResourceResponse)
+            throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.sendResponse0(ocResourceResponse);
+    }
+
+    private static native void sendResponse0(OcResourceResponse ocResourceResponse)
+            throws OcException;
+
+    /**
+     * An OnResourceFoundListener can be registered via the OcPlatform.findResource call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnResourceFoundListener {
+        public void onResourceFound(OcResource resource);
+    }
+
+    /**
+     * An OnDeviceFoundListener can be registered via the OcPlatform.getDeviceInfo call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnDeviceFoundListener {
+        public void onDeviceFound(OcRepresentation ocRepresentation);
+    }
+
+    /**
+     * An OnPlatformFoundListener can be registered via the OcPlatform.getPlatformInfo call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnPlatformFoundListener {
+        public void onPlatformFound(OcRepresentation ocRepresentation);
+    }
+
+    /**
+     * An OnPresenceListener can be registered via the OcPlatform.subscribePresence call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnPresenceListener {
+        public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress);
+    }
+
+    /**
+     * An EntityHandler can be registered via the OcPlatform.registerResource call.
+     * Event listeners are notified asynchronously
+     */
+    public interface EntityHandler {
+        public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest);
+    }
+
+    private static void initCheck() {
+        if (!sIsPlatformInitialized) {
+            throw new IllegalStateException("OcPlatform must be configured by making a call to " +
+                    "OcPlatform.Configure before any other API calls are permitted");
+        }
+    }
+}
diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcPlatformInfo.java b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatformInfo.java
new file mode 100644 (file)
index 0000000..53d366d
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.lang.Error;
+
+public class OcPlatformInfo {
+
+    private String platformID;
+    private String manufacturerName;
+    private String manufacturerUrl;
+    private String modelNumber;
+    private String dateOfManufacture;
+    private String platformVersion;
+    private String operatingSystemVersion;
+    private String hardwareVersion;
+    private String firmwareVersion;
+    private String supportUrl;
+    private String systemTime;
+
+    // construct OcPlatformInfo with mandatory fields which cannot be null
+    // manufacturerName cannot be > 16 chars
+    // manufacturerUrl cannot be > 32 chars
+    protected OcPlatformInfo(String platformID, String manufacturerName,
+                             String manufacturerUrl) throws OcException {
+        ErrorCode result = validatePlatformInfo(platformID, manufacturerName, manufacturerUrl);
+        if (ErrorCode.OK == result) {
+            this.platformID = platformID;
+            this.manufacturerName = manufacturerName;
+            this.manufacturerUrl = manufacturerUrl;
+        } else {
+            throw new OcException(result, result.getDescription());
+        }
+    }
+
+    public ErrorCode validatePlatformInfo(String platformID, String manufacturerName,
+                                          String manufacturerUrl) {
+        // checks to see if the mandatory fields have non-null values or not
+        if (platformID == null || platformID.isEmpty()) return ErrorCode.INVALID_PLATFORM_INFO_PLATFORMID;
+        if (manufacturerName == null || manufacturerName.isEmpty() ||
+                manufacturerName.length() > OcStackConfig.MAX_MANUFACTURER_NAME_LENGTH)
+            return ErrorCode.INVALID_PLATFORM_INFO_MANUFACTURER_NAME;
+        if (manufacturerUrl == null || manufacturerUrl.isEmpty() ||
+                manufacturerUrl.length() > OcStackConfig.MAX_MANUFACTURER_URL_LENGTH)
+            return ErrorCode.INVALID_PLATFORM_INFO_PLATFORMID_MANUFACTURER_URL;
+        return ErrorCode.OK;
+    }
+
+    public String getPlatformID() {
+        return platformID;
+    }
+
+    public void setPlatformID(String platformID) {
+        this.platformID = platformID;
+    }
+
+    public String getManufacturerName() {
+        return manufacturerName;
+    }
+
+    public void setManufacturerName(String manufacturerName) {
+        this.manufacturerName = manufacturerName;
+    }
+
+    public String getManufacturerUrl() {
+        return manufacturerUrl;
+    }
+
+    public void setManufacturerUrl(String manufacturerUrl) {
+        this.manufacturerUrl = manufacturerUrl;
+    }
+
+    public String getModelNumber() {
+        return modelNumber;
+    }
+
+    public void setModelNumber(String modelNumber) {
+        this.modelNumber = modelNumber;
+    }
+
+    public String getDateOfManufacture() {
+        return dateOfManufacture;
+    }
+
+    public void setDateOfManufacture(String dateOfManufacture) {
+        this.dateOfManufacture = dateOfManufacture;
+    }
+
+    public String getPlatformVersion() {
+        return platformVersion;
+    }
+
+    public void setPlatformVersion(String platformVersion) {
+        this.platformVersion = platformVersion;
+    }
+
+    public String getOperatingSystemVersion() {
+        return operatingSystemVersion;
+    }
+
+    public void setOperatingSystemVersion(String operatingSystemVersion) {
+        this.operatingSystemVersion = operatingSystemVersion;
+    }
+
+    public String getHardwareVersion() {
+        return hardwareVersion;
+    }
+
+    public void setHardwareVersion(String hardwareVersion) {
+        this.hardwareVersion = hardwareVersion;
+    }
+
+    public String getFirmwareVersion() {
+        return firmwareVersion;
+    }
+
+    public void setFirmwareVersion(String firmwareVersion) {
+        this.firmwareVersion = firmwareVersion;
+    }
+
+    public String getSupportUrl() {
+        return supportUrl;
+    }
+
+    public void setSupportUrl(String supportUrl) {
+        this.supportUrl = supportUrl;
+    }
+
+    public String getSystemTime() {
+        return systemTime;
+    }
+
+    public void setSystemTime(String systemTime) {
+        this.systemTime = systemTime;
+    }
+}
index 98ec0bc..eba1001 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-import java.security.InvalidParameterException;\r
-import java.util.Arrays;\r
-import java.util.List;\r
-\r
-/**\r
- *\r
- */\r
-public class OcRepresentation {\r
-\r
-    static {\r
-        System.loadLibrary("oc");\r
-        System.loadLibrary("ocstack-jni");\r
-    }\r
-\r
-    public OcRepresentation() {\r
-        create();\r
-        //Native OCRepresentation object was created using "new" and needs to be deleted\r
-        this.mNativeNeedsDelete = true;\r
-    }\r
-\r
-    private OcRepresentation(long nativeHandle) {\r
-        this.mNativeHandle = nativeHandle;\r
-        this.mNativeNeedsDelete = false;\r
-    }\r
-\r
-    private OcRepresentation(long nativeHandle, boolean nativeNeedsDelete) {\r
-        this.mNativeHandle = nativeHandle;\r
-        this.mNativeNeedsDelete = nativeNeedsDelete;\r
-    }\r
-\r
-    public <T> T getValue(String key) throws OcException {\r
-        Object obj = this.getValueN(key);\r
-        @SuppressWarnings("unchecked")\r
-        T t = (T) obj;\r
-        return t;\r
-    }\r
-\r
-    private native Object getValueN(String key);\r
-\r
-    public void setValue(String key, int value) throws OcException {\r
-        this.setValueInteger(key, value);\r
-    }\r
-\r
-    public void setValue(String key, double value) throws OcException {\r
-        this.setValueDouble(key, value);\r
-    }\r
-\r
-    public void setValue(String key, boolean value) throws OcException {\r
-        this.setValueBoolean(key, value);\r
-    }\r
-\r
-    public void setValue(String key, String value) throws OcException {\r
-        this.setValueStringN(key, value);\r
-    }\r
-\r
-    public void setValue(String key, OcRepresentation value) throws OcException {\r
-        this.setValueRepresentation(key, value);\r
-    }\r
-\r
-    public void setValue(String key, int[] value) throws OcException {\r
-        this.setValueIntegerArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, int[][] value) throws OcException {\r
-        this.setValueInteger2DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, int[][][] value) throws OcException {\r
-        this.setValueInteger3DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, double[] value) throws OcException {\r
-        this.setValueDoubleArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, double[][] value) throws OcException {\r
-        this.setValueDouble2DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, double[][][] value) throws OcException {\r
-        this.setValueDouble3DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, boolean[] value) throws OcException {\r
-        this.setValueBooleanArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, boolean[][] value) throws OcException {\r
-        this.setValueBoolean2DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, boolean[][][] value) throws OcException {\r
-        this.setValueBoolean3DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, String[] value) throws OcException {\r
-        this.setValueStringArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, String[][] value) throws OcException {\r
-        this.setValueString2DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, String[][][] value) throws OcException {\r
-        this.setValueString3DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, OcRepresentation[] value) throws OcException {\r
-        this.setValueRepresentationArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, OcRepresentation[][] value) throws OcException {\r
-        this.setValueRepresentation2DArray(key, value);\r
-    }\r
-\r
-    public void setValue(String key, OcRepresentation[][][] value) throws OcException {\r
-        this.setValueRepresentation3DArray(key, value);\r
-    }\r
-\r
-    private native void setValueInteger(String key, int value) throws OcException;\r
-\r
-    private native void setValueDouble(String key, double value) throws OcException;\r
-\r
-    private native void setValueBoolean(String key, boolean value) throws OcException;\r
-\r
-    private native void setValueStringN(String key, String value) throws OcException;\r
-\r
-    private native void setValueRepresentation(String key, OcRepresentation value) throws OcException;\r
-\r
-    private native void setValueIntegerArray(String key, int[] value) throws OcException;\r
-\r
-    private native void setValueInteger2DArray(String key, int[][] value) throws OcException;\r
-\r
-    private native void setValueInteger3DArray(String key, int[][][] value) throws OcException;\r
-\r
-    private native void setValueDoubleArray(String key, double[] value) throws OcException;\r
-\r
-    private native void setValueDouble2DArray(String key, double[][] value) throws OcException;\r
-\r
-    private native void setValueDouble3DArray(String key, double[][][] value) throws OcException;\r
-\r
-    private native void setValueBooleanArray(String key, boolean[] value) throws OcException;\r
-\r
-    private native void setValueBoolean2DArray(String key, boolean[][] value) throws OcException;\r
-\r
-    private native void setValueBoolean3DArray(String key, boolean[][][] value) throws OcException;\r
-\r
-    private native void setValueStringArray(String key, String[] value) throws OcException;\r
-\r
-    private native void setValueString2DArray(String key, String[][] value) throws OcException;\r
-\r
-    private native void setValueString3DArray(String key, String[][][] value) throws OcException;\r
-\r
-    private native void setValueRepresentationArray(String key, OcRepresentation[] value) throws OcException;\r
-\r
-    private native void setValueRepresentation2DArray(String key, OcRepresentation[][] value) throws OcException;\r
-\r
-    private native void setValueRepresentation3DArray(String key, OcRepresentation[][][] value) throws OcException;\r
-\r
-    /**\r
-     * @deprecated use {@link #getValue(String key)} instead.\r
-     */\r
-    @Deprecated\r
-    public int getValueInt(String key) {\r
-        int value = 0;\r
-        try {\r
-            value = this.getValue(key);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-        return value;\r
-    }\r
-\r
-    /**\r
-     * @deprecated use {@link #getValue(String key)} instead.\r
-     */\r
-    @Deprecated\r
-    public boolean getValueBool(String key) {\r
-        boolean value = false;\r
-        try {\r
-            value = this.getValue(key);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-        return value;\r
-    }\r
-\r
-    /**\r
-     * @deprecated use {@link #getValue(String key)} instead.\r
-     */\r
-    @Deprecated\r
-    public String getValueString(String key) {\r
-        String value = "";\r
-        try {\r
-            value = this.getValue(key);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-        return value;\r
-    }\r
-\r
-    /**\r
-     * @deprecated use {@link #setValue(String key, int value)} instead.\r
-     */\r
-    @Deprecated\r
-    public void setValueInt(String key, int value) {\r
-        try {\r
-            this.setValue(key, value);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @deprecated use {@link #setValue(String key, boolean value)} instead.\r
-     */\r
-    @Deprecated\r
-    public void setValueBool(String key, boolean value) {\r
-        try {\r
-            this.setValue(key, value);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @deprecated use {@link #setValue(String key, String value)} instead.\r
-     */\r
-    @Deprecated\r
-    public void setValueString(String key, String value) {\r
-        try {\r
-            this.setValue(key, value);\r
-        } catch (OcException e) {\r
-            //simply catching here for the deprecated APIs, so the older usages don't have to handle\r
-            //it in the code\r
-        }\r
-    }\r
-\r
-    public native String getJSONRepresentation();\r
-\r
-    public native void addChild(OcRepresentation representation);\r
-\r
-    public native void clearChildren();\r
-\r
-    public List<OcRepresentation> getChildren() {\r
-        return Arrays.asList(\r
-                getChildrenArray());\r
-    }\r
-\r
-    private native OcRepresentation[] getChildrenArray();\r
-\r
-    public native String getUri();\r
-\r
-    public native void setUri(String uri);\r
-\r
-    /**\r
-     * Method to get the list of resource types\r
-     *\r
-     * @return List of resource types\r
-     */\r
-    public native List<String> getResourceTypes();\r
-\r
-    /**\r
-     * Method to set the list of resource types\r
-     *\r
-     * @param resourceTypeList list of resources\r
-     */\r
-    public void setResourceTypes(List<String> resourceTypeList) {\r
-        if (null == resourceTypeList) {\r
-            throw new InvalidParameterException("resourceTypeList cannot be null");\r
-        }\r
-\r
-        this.setResourceTypeArray(\r
-                resourceTypeList.toArray(\r
-                        new String[resourceTypeList.size()]));\r
-    }\r
-\r
-    private native void setResourceTypeArray(String[] resourceTypeArray);\r
-\r
-    /**\r
-     * Method to get the list of resource interfaces\r
-     *\r
-     * @return List of resource interface\r
-     */\r
-    public native List<String> getResourceInterfaces();\r
-\r
-    /**\r
-     * Method to set the list of resource interfaces\r
-     *\r
-     * @param resourceInterfaceList list of interfaces\r
-     */\r
-    public void setResourceInterfaces(List<String> resourceInterfaceList) {\r
-        if (null == resourceInterfaceList) {\r
-            throw new InvalidParameterException("resourceInterfaceList cannot be null");\r
-        }\r
-\r
-        this.setResourceInterfaceArray(\r
-                resourceInterfaceList.toArray(\r
-                        new String[resourceInterfaceList.size()]));\r
-    }\r
-\r
-    private native void setResourceInterfaceArray(String[] resourceInterfaceArray);\r
-\r
-    public native boolean isEmpty();\r
-\r
-    public native int size();\r
-\r
-    public native boolean remove(String key);\r
-\r
-    public native boolean hasAttribute(String key);\r
-\r
-    public native void setNull(String key);\r
-\r
-    public native boolean isNull(String key);\r
-\r
-    @Override\r
-    protected void finalize() throws Throwable {\r
-        super.finalize();\r
-\r
-        dispose(this.mNativeNeedsDelete);\r
-    }\r
-\r
-    private native void create();\r
-\r
-    private native void dispose(boolean needsDelete);\r
-\r
-    private long mNativeHandle;\r
-    private boolean mNativeNeedsDelete;\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ */
+public class OcRepresentation {
+
+    static {
+        System.loadLibrary("oc");
+        System.loadLibrary("ocstack-jni");
+    }
+
+    public OcRepresentation() {
+        create();
+        //Native OCRepresentation object was created using "new" and needs to be deleted
+        this.mNativeNeedsDelete = true;
+    }
+
+    private OcRepresentation(long nativeHandle) {
+        this.mNativeHandle = nativeHandle;
+        this.mNativeNeedsDelete = false;
+    }
+
+    private OcRepresentation(long nativeHandle, boolean nativeNeedsDelete) {
+        this.mNativeHandle = nativeHandle;
+        this.mNativeNeedsDelete = nativeNeedsDelete;
+    }
+
+    public <T> T getValue(String key) throws OcException {
+        Object obj = this.getValueN(key);
+        @SuppressWarnings("unchecked")
+        T t = (T) obj;
+        return t;
+    }
+
+    private native Object getValueN(String key);
+
+    public void setValue(String key, int value) throws OcException {
+        this.setValueInteger(key, value);
+    }
+
+    public void setValue(String key, double value) throws OcException {
+        this.setValueDouble(key, value);
+    }
+
+    public void setValue(String key, boolean value) throws OcException {
+        this.setValueBoolean(key, value);
+    }
+
+    public void setValue(String key, String value) throws OcException {
+        this.setValueStringN(key, value);
+    }
+
+    public void setValue(String key, OcRepresentation value) throws OcException {
+        this.setValueRepresentation(key, value);
+    }
+
+    public void setValue(String key, int[] value) throws OcException {
+        this.setValueIntegerArray(key, value);
+    }
+
+    public void setValue(String key, int[][] value) throws OcException {
+        this.setValueInteger2DArray(key, value);
+    }
+
+    public void setValue(String key, int[][][] value) throws OcException {
+        this.setValueInteger3DArray(key, value);
+    }
+
+    public void setValue(String key, double[] value) throws OcException {
+        this.setValueDoubleArray(key, value);
+    }
+
+    public void setValue(String key, double[][] value) throws OcException {
+        this.setValueDouble2DArray(key, value);
+    }
+
+    public void setValue(String key, double[][][] value) throws OcException {
+        this.setValueDouble3DArray(key, value);
+    }
+
+    public void setValue(String key, boolean[] value) throws OcException {
+        this.setValueBooleanArray(key, value);
+    }
+
+    public void setValue(String key, boolean[][] value) throws OcException {
+        this.setValueBoolean2DArray(key, value);
+    }
+
+    public void setValue(String key, boolean[][][] value) throws OcException {
+        this.setValueBoolean3DArray(key, value);
+    }
+
+    public void setValue(String key, String[] value) throws OcException {
+        this.setValueStringArray(key, value);
+    }
+
+    public void setValue(String key, String[][] value) throws OcException {
+        this.setValueString2DArray(key, value);
+    }
+
+    public void setValue(String key, String[][][] value) throws OcException {
+        this.setValueString3DArray(key, value);
+    }
+
+    public void setValue(String key, OcRepresentation[] value) throws OcException {
+        this.setValueRepresentationArray(key, value);
+    }
+
+    public void setValue(String key, OcRepresentation[][] value) throws OcException {
+        this.setValueRepresentation2DArray(key, value);
+    }
+
+    public void setValue(String key, OcRepresentation[][][] value) throws OcException {
+        this.setValueRepresentation3DArray(key, value);
+    }
+
+    private native void setValueInteger(String key, int value) throws OcException;
+
+    private native void setValueDouble(String key, double value) throws OcException;
+
+    private native void setValueBoolean(String key, boolean value) throws OcException;
+
+    private native void setValueStringN(String key, String value) throws OcException;
+
+    private native void setValueRepresentation(String key, OcRepresentation value) throws OcException;
+
+    private native void setValueIntegerArray(String key, int[] value) throws OcException;
+
+    private native void setValueInteger2DArray(String key, int[][] value) throws OcException;
+
+    private native void setValueInteger3DArray(String key, int[][][] value) throws OcException;
+
+    private native void setValueDoubleArray(String key, double[] value) throws OcException;
+
+    private native void setValueDouble2DArray(String key, double[][] value) throws OcException;
+
+    private native void setValueDouble3DArray(String key, double[][][] value) throws OcException;
+
+    private native void setValueBooleanArray(String key, boolean[] value) throws OcException;
+
+    private native void setValueBoolean2DArray(String key, boolean[][] value) throws OcException;
+
+    private native void setValueBoolean3DArray(String key, boolean[][][] value) throws OcException;
+
+    private native void setValueStringArray(String key, String[] value) throws OcException;
+
+    private native void setValueString2DArray(String key, String[][] value) throws OcException;
+
+    private native void setValueString3DArray(String key, String[][][] value) throws OcException;
+
+    private native void setValueRepresentationArray(String key, OcRepresentation[] value) throws OcException;
+
+    private native void setValueRepresentation2DArray(String key, OcRepresentation[][] value) throws OcException;
+
+    private native void setValueRepresentation3DArray(String key, OcRepresentation[][][] value) throws OcException;
+
+    /**
+     * @deprecated use {@link #getValue(String key)} instead.
+     */
+    @Deprecated
+    public int getValueInt(String key) {
+        Integer value = 0;
+        try {
+            value = this.getValue(key);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+        return value;
+    }
+
+    /**
+     * @deprecated use {@link #getValue(String key)} instead.
+     */
+    @Deprecated
+    public boolean getValueBool(String key) {
+        Boolean value = false;
+        try {
+            value = this.getValue(key);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+        return value;
+    }
+
+    /**
+     * @deprecated use {@link #getValue(String key)} instead.
+     */
+    @Deprecated
+    public String getValueString(String key) {
+        String value = "";
+        try {
+            value = this.getValue(key);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+        return value;
+    }
+
+    /**
+     * @deprecated use {@link #setValue(String key, int value)} instead.
+     */
+    @Deprecated
+    public void setValueInt(String key, int value) {
+        try {
+            this.setValue(key, value);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+    }
+
+    /**
+     * @deprecated use {@link #setValue(String key, boolean value)} instead.
+     */
+    @Deprecated
+    public void setValueBool(String key, boolean value) {
+        try {
+            this.setValue(key, value);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+    }
+
+    /**
+     * @deprecated use {@link #setValue(String key, String value)} instead.
+     */
+    @Deprecated
+    public void setValueString(String key, String value) {
+        try {
+            this.setValue(key, value);
+        } catch (OcException e) {
+            //simply catching here for the deprecated APIs, so the older usages don't have to handle
+            //it in the code
+        }
+    }
+
+    public native void addChild(OcRepresentation representation);
+
+    public native void clearChildren();
+
+    public List<OcRepresentation> getChildren() {
+        return Arrays.asList(
+                getChildrenArray());
+    }
+
+    private native OcRepresentation[] getChildrenArray();
+
+    public native String getUri();
+
+    public native void setUri(String uri);
+
+    /**
+     * Method to get the list of resource types
+     *
+     * @return List of resource types
+     */
+    public native List<String> getResourceTypes();
+
+    /**
+     * Method to set the list of resource types
+     *
+     * @param resourceTypeList list of resources
+     */
+    public void setResourceTypes(List<String> resourceTypeList) {
+        if (null == resourceTypeList) {
+            throw new InvalidParameterException("resourceTypeList cannot be null");
+        }
+
+        this.setResourceTypeArray(
+                resourceTypeList.toArray(
+                        new String[resourceTypeList.size()]));
+    }
+
+    private native void setResourceTypeArray(String[] resourceTypeArray);
+
+    /**
+     * Method to get the list of resource interfaces
+     *
+     * @return List of resource interface
+     */
+    public native List<String> getResourceInterfaces();
+
+    /**
+     * Method to set the list of resource interfaces
+     *
+     * @param resourceInterfaceList list of interfaces
+     */
+    public void setResourceInterfaces(List<String> resourceInterfaceList) {
+        if (null == resourceInterfaceList) {
+            throw new InvalidParameterException("resourceInterfaceList cannot be null");
+        }
+
+        this.setResourceInterfaceArray(
+                resourceInterfaceList.toArray(
+                        new String[resourceInterfaceList.size()]));
+    }
+
+    private native void setResourceInterfaceArray(String[] resourceInterfaceArray);
+
+    public native boolean isEmpty();
+
+    public native int size();
+
+    public native boolean remove(String key);
+
+    public native boolean hasAttribute(String key);
+
+    public native void setNull(String key);
+
+    public native boolean isNull(String key);
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+
+        dispose(this.mNativeNeedsDelete);
+    }
+
+    private native void create();
+
+    private native void dispose(boolean needsDelete);
+
+    private long mNativeHandle;
+    private boolean mNativeNeedsDelete;
 }
\ No newline at end of file
index b3f4b08..92e38e6 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base;\r
-\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-/**\r
- * OcResource represents an OC resource. A resource could be a light controller, temperature sensor,\r
- * smoke detector, etc. A resource comes with a well-defined contract or interface onto which you\r
- * can perform different operations, such as turning on the light, getting the current temperature\r
- * or subscribing for event notifications from the smoke detector. A resource can be composed of\r
- * one or more resources.\r
- */\r
-public class OcResource {\r
-\r
-    private OcResource(long nativeHandle) {\r
-        this.mNativeHandle = nativeHandle;\r
-    }\r
-\r
-    /**\r
-     * Method to get the attributes of a resource.\r
-     *\r
-     * @param queryParamsMap map which can have the query parameter name and value\r
-     * @param onGetListener  The event handler will be invoked with a map of attribute name and\r
-     *                       values. The event handler will also have the result from this Get\r
-     *                       operation This will have error codes\r
-     * @throws OcException\r
-     */\r
-    public native void get(Map<String, String> queryParamsMap,\r
-                           OnGetListener onGetListener) throws OcException;\r
-\r
-    /**\r
-     * Method to get the attributes of a resource.\r
-     *\r
-     * @param queryParamsMap   map which can have the query parameter name and value\r
-     * @param onGetListener    The event handler will be invoked with a map of attribute name and\r
-     *                         values. The event handler will also have the result from this Get\r
-     *                         operation This will have error codes\r
-     * @param qualityOfService the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void get(Map<String, String> queryParamsMap,\r
-                    OnGetListener onGetListener,\r
-                    QualityOfService qualityOfService) throws OcException {\r
-        this.get1(queryParamsMap, onGetListener, qualityOfService.getValue());\r
-    }\r
-\r
-    private native void get1(Map<String, String> queryParamsMap,\r
-                             OnGetListener onGetListener,\r
-                             int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to get the attributes of a resource.\r
-     *\r
-     * @param resourceType      resourceType of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param queryParamsMap    map which can have the query parameter name and value\r
-     * @param onGetListener     The event handler will be invoked with a map of attribute name and\r
-     *                          values. The event handler will also have the result from this Get\r
-     *                          operation This will have error codes\r
-     * @throws OcException\r
-     */\r
-    public void get(String resourceType,\r
-                    String resourceInterface,\r
-                    Map<String, String> queryParamsMap,\r
-                    OnGetListener onGetListener) throws OcException {\r
-        this.get2(\r
-                resourceType,\r
-                resourceInterface,\r
-                queryParamsMap,\r
-                onGetListener);\r
-    }\r
-\r
-    private native void get2(String resourceType,\r
-                             String resourceInterface,\r
-                             Map<String, String> queryParamsMap,\r
-                             OnGetListener onGetListener) throws OcException;\r
-\r
-    /**\r
-     * Method to get the attributes of a resource.\r
-     *\r
-     * @param resourceType      resourceType of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param queryParamsMap    map which can have the query parameter name and value\r
-     * @param onGetListener     The event handler will be invoked with a map of attribute name and\r
-     *                          values. The event handler will also have the result from this Get\r
-     *                          operation This will have error codes\r
-     * @param qualityOfService  the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void get(String resourceType,\r
-                    String resourceInterface,\r
-                    Map<String, String> queryParamsMap,\r
-                    OnGetListener onGetListener,\r
-                    QualityOfService qualityOfService) throws OcException {\r
-        this.get3(\r
-                resourceType,\r
-                resourceInterface,\r
-                queryParamsMap,\r
-                onGetListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void get3(String resourceType,\r
-                             String resourceInterface,\r
-                             Map<String, String> queryParamsMap,\r
-                             OnGetListener onGetListener,\r
-                             int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to set the representation of a resource (via PUT)\r
-     *\r
-     * @param representation representation of the resource\r
-     * @param queryParamsMap Map which can have the query parameter name and value\r
-     * @param onPutListener  event handler The event handler will be invoked with a map of attribute\r
-     *                       name and values.\r
-     * @throws OcException\r
-     */\r
-    public native void put(OcRepresentation representation,\r
-                           Map<String, String> queryParamsMap,\r
-                           OnPutListener onPutListener) throws OcException;\r
-\r
-    /**\r
-     * Method to set the representation of a resource (via PUT)\r
-     *\r
-     * @param ocRepresentation representation of the resource\r
-     * @param queryParamsMap   Map which can have the query parameter name and value\r
-     * @param onPutListener    event handler The event handler will be invoked with a map of\r
-     *                         attribute name and values.\r
-     * @param qualityOfService the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void put(OcRepresentation ocRepresentation,\r
-                    Map<String, String> queryParamsMap,\r
-                    OnPutListener onPutListener,\r
-                    QualityOfService qualityOfService) throws OcException {\r
-        this.put1(\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPutListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void put1(OcRepresentation ocRepresentation,\r
-                             Map<String, String> queryParamsMap,\r
-                             OnPutListener onPutListener,\r
-                             int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to set the representation of a resource (via PUT)\r
-     *\r
-     * @param resourceType      resource type of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param ocRepresentation  representation of the resource\r
-     * @param queryParamsMap    Map which can have the query parameter name and value\r
-     * @param onPutListener     event handler The event handler will be invoked with a map of\r
-     *                          attribute name and values.\r
-     * @throws OcException\r
-     */\r
-    public void put(String resourceType,\r
-                    String resourceInterface,\r
-                    OcRepresentation ocRepresentation,\r
-                    Map<String, String> queryParamsMap,\r
-                    OnPutListener onPutListener) throws OcException {\r
-        this.put2(\r
-                resourceType,\r
-                resourceInterface,\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPutListener);\r
-    }\r
-\r
-    private native void put2(String resourceType,\r
-                             String resourceInterface,\r
-                             OcRepresentation ocRepresentation,\r
-                             Map<String, String> queryParamsMap,\r
-                             OnPutListener onPutListener) throws OcException;\r
-\r
-    /**\r
-     * Method to set the representation of a resource (via PUT)\r
-     *\r
-     * @param resourceType      resource type of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param ocRepresentation  representation of the resource\r
-     * @param queryParamsMap    Map which can have the query parameter name and value\r
-     * @param onPutListener     event handler The event handler will be invoked with a map of\r
-     *                          attribute name and values.\r
-     * @param qualityOfService  the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void put(String resourceType,\r
-                    String resourceInterface,\r
-                    OcRepresentation ocRepresentation,\r
-                    Map<String, String> queryParamsMap,\r
-                    OnPutListener onPutListener,\r
-                    QualityOfService qualityOfService) throws OcException {\r
-        this.put3(\r
-                resourceType,\r
-                resourceInterface,\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPutListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void put3(String resourceType,\r
-                             String resourceInterface,\r
-                             OcRepresentation ocRepresentation,\r
-                             Map<String, String> queryParamsMap,\r
-                             OnPutListener onPutListener,\r
-                             int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to POST on a resource\r
-     *\r
-     * @param ocRepresentation representation of the resource\r
-     * @param queryParamsMap   Map which can have the query parameter name and value\r
-     * @param onPostListener   event handler The event handler will be invoked with a map of\r
-     *                         attribute name and values.\r
-     * @throws OcException\r
-     */\r
-    public native void post(OcRepresentation ocRepresentation,\r
-                            Map<String, String> queryParamsMap,\r
-                            OnPostListener onPostListener) throws OcException;\r
-\r
-    /**\r
-     * Method to POST on a resource\r
-     *\r
-     * @param ocRepresentation representation of the resource\r
-     * @param queryParamsMap   Map which can have the query parameter name and value\r
-     * @param onPostListener   event handler The event handler will be invoked with a map of\r
-     *                         attribute name and values.\r
-     * @param qualityOfService the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void post(OcRepresentation ocRepresentation,\r
-                     Map<String, String> queryParamsMap,\r
-                     OnPostListener onPostListener,\r
-                     QualityOfService qualityOfService) throws OcException {\r
-        this.post1(\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPostListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void post1(OcRepresentation ocRepresentation,\r
-                              Map<String, String> queryParamsMap,\r
-                              OnPostListener onPostListener,\r
-                              int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to POST on a resource\r
-     *\r
-     * @param resourceType      resource type of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param ocRepresentation  representation of the resource\r
-     * @param queryParamsMap    Map which can have the query parameter name and value\r
-     * @param onPostListener    event handler The event handler will be invoked with a map of\r
-     *                          attribute name and values.\r
-     * @throws OcException\r
-     */\r
-    public void post(String resourceType,\r
-                     String resourceInterface,\r
-                     OcRepresentation ocRepresentation,\r
-                     Map<String, String> queryParamsMap,\r
-                     OnPostListener onPostListener) throws OcException {\r
-        this.post2(\r
-                resourceType,\r
-                resourceInterface,\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPostListener);\r
-    }\r
-\r
-    private native void post2(String resourceType,\r
-                              String resourceInterface,\r
-                              OcRepresentation ocRepresentation,\r
-                              Map<String, String> queryParamsMap,\r
-                              OnPostListener onPostListener) throws OcException;\r
-\r
-    /**\r
-     * Method to POST on a resource\r
-     *\r
-     * @param resourceType      resource type of the resource to operate on\r
-     * @param resourceInterface interface type of the resource to operate on\r
-     * @param ocRepresentation  representation of the resource\r
-     * @param queryParamsMap    Map which can have the query parameter name and value\r
-     * @param onPostListener    event handler The event handler will be invoked with a map of\r
-     *                          attribute name and values.\r
-     * @param qualityOfService  the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void post(String resourceType,\r
-                     String resourceInterface,\r
-                     OcRepresentation ocRepresentation,\r
-                     Map<String, String> queryParamsMap,\r
-                     OnPostListener onPostListener,\r
-                     QualityOfService qualityOfService) throws OcException {\r
-        this.post3(\r
-                resourceType,\r
-                resourceInterface,\r
-                ocRepresentation,\r
-                queryParamsMap,\r
-                onPostListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void post3(String resourceType,\r
-                              String resourceInterface,\r
-                              OcRepresentation ocRepresentation,\r
-                              Map<String, String> queryParamsMap,\r
-                              OnPostListener onPostListener,\r
-                              int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to perform DELETE operation\r
-     *\r
-     * @param onDeleteListener event handler The event handler will have headerOptionList\r
-     */\r
-    public native void deleteResource(OnDeleteListener onDeleteListener) throws OcException;\r
-\r
-    /**\r
-     * Method to perform DELETE operation\r
-     *\r
-     * @param onDeleteListener event handler The event handler will have headerOptionList\r
-     * @param qualityOfService the quality of communication\r
-     */\r
-    public void deleteResource(OnDeleteListener onDeleteListener,\r
-                               QualityOfService qualityOfService) throws OcException {\r
-        this.deleteResource1(onDeleteListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private native void deleteResource1(OnDeleteListener onDeleteListener,\r
-                                        int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to set observation on the resource\r
-     *\r
-     * @param observeType       allows the client to specify how it wants to observe\r
-     * @param queryParamsMap    map which can have the query parameter name and value\r
-     * @param onObserveListener event handler The handler method will be invoked with a map\r
-     *                          of attribute name and values.\r
-     * @throws OcException\r
-     */\r
-    public void observe(ObserveType observeType,\r
-                        Map<String, String> queryParamsMap,\r
-                        OnObserveListener onObserveListener) throws OcException {\r
-        this.observe(\r
-                observeType.getValue(),\r
-                queryParamsMap,\r
-                onObserveListener);\r
-    }\r
-\r
-    private synchronized native void observe(int observeType,\r
-                                             Map<String, String> queryParamsMap,\r
-                                             OnObserveListener onObserveListener) throws OcException;\r
-\r
-    /**\r
-     * Method to set observation on the resource\r
-     *\r
-     * @param observeType       allows the client to specify how it wants to observe\r
-     * @param queryParamsMap    map which can have the query parameter name and value\r
-     * @param onObserveListener event handler The handler method will be invoked with a map\r
-     *                          of attribute name and values.\r
-     * @param qualityOfService  the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void observe(ObserveType observeType,\r
-                        Map<String, String> queryParamsMap,\r
-                        OnObserveListener onObserveListener,\r
-                        QualityOfService qualityOfService) throws OcException {\r
-        this.observe1(\r
-                observeType.getValue(),\r
-                queryParamsMap,\r
-                onObserveListener,\r
-                qualityOfService.getValue());\r
-    }\r
-\r
-    private synchronized native void observe1(int observeType,\r
-                                              Map<String, String> queryParamsMap,\r
-                                              OnObserveListener onObserveListener,\r
-                                              int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to cancel the observation on the resource\r
-     *\r
-     * @throws OcException\r
-     */\r
-    public native void cancelObserve() throws OcException;\r
-\r
-    /**\r
-     * Method to cancel the observation on the resource\r
-     *\r
-     * @param qualityOfService the quality of communication\r
-     * @throws OcException\r
-     */\r
-    public void cancelObserve(QualityOfService qualityOfService) throws OcException {\r
-        this.cancelObserve1(qualityOfService.getValue());\r
-    }\r
-\r
-    private native void cancelObserve1(int qualityOfService) throws OcException;\r
-\r
-    /**\r
-     * Method to set header options\r
-     *\r
-     * @param headerOptionList List<OcHeaderOption> where header information(header optionID and\r
-     *                         optionData is passed\r
-     */\r
-    public void setHeaderOptions(List<OcHeaderOption> headerOptionList) {\r
-        this.setHeaderOptions(headerOptionList.toArray(\r
-                        new OcHeaderOption[headerOptionList.size()])\r
-        );\r
-    }\r
-\r
-    private native void setHeaderOptions(OcHeaderOption[] headerOptionList);\r
-\r
-    /**\r
-     * Method to unset header options\r
-     */\r
-    public native void unsetHeaderOptions();\r
-\r
-    /**\r
-     * Method to get the host address of this resource\r
-     *\r
-     * @return host address NOTE: This might or might not be exposed in future due to\r
-     * security concerns\r
-     */\r
-    public native String getHost();\r
-\r
-    /**\r
-     * Method to get the URI for this resource\r
-     *\r
-     * @return resource URI\r
-     */\r
-    public native String getUri();\r
-\r
-    /**\r
-     * Method to get the connectivity type of this resource\r
-     *\r
-     * @return OcConnectivityType connectivity type\r
-     */\r
-    public OcConnectivityType getConnectivityType() {\r
-        return OcConnectivityType.get(\r
-                this.getConnectivityTypeN()\r
-        );\r
-    }\r
-\r
-    private native int getConnectivityTypeN();\r
-\r
-    /**\r
-     * Method to provide ability to check if this resource is observable or not\r
-     *\r
-     * @return true indicates resource is observable; false indicates resource is not observable\r
-     */\r
-    public native boolean isObservable();\r
-\r
-    /**\r
-     * Method to get the list of resource types\r
-     *\r
-     * @return List of resource types\r
-     */\r
-    public native List<String> getResourceTypes();\r
-\r
-    /**\r
-     * Method to get the list of resource interfaces\r
-     *\r
-     * @return List of resource interface\r
-     */\r
-    public native List<String> getResourceInterfaces();\r
-\r
-    /**\r
-     * Method to get a unique identifier for this resource across network interfaces.  This will\r
-     * be guaranteed unique for every resource-per-server independent of how this was discovered.\r
-     *\r
-     * @return OcResourceIdentifier object, which can be used for all comparison and hashing\r
-     */\r
-    public native OcResourceIdentifier getUniqueIdentifier();\r
-\r
-    /**\r
-     * Method to get a string representation of the resource's server ID.\r
-     * * This is unique per- server independent on how it was discovered.\r
-     *\r
-     * @return server ID\r
-     */\r
-    public native String getServerId();\r
-\r
-    /**\r
-     * An OnGetListener can be registered via the resource get call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnGetListener {\r
-        public void onGetCompleted(List<OcHeaderOption> headerOptionList,\r
-                                   OcRepresentation ocRepresentation);\r
-\r
-        public void onGetFailed(Throwable ex);\r
-    }\r
-\r
-    /**\r
-     * An OnPutListener can be registered via the resource put call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnPutListener {\r
-        public void onPutCompleted(List<OcHeaderOption> headerOptionList,\r
-                                   OcRepresentation ocRepresentation);\r
-\r
-        public void onPutFailed(Throwable ex);\r
-    }\r
-\r
-    /**\r
-     * An OnPostListener can be registered via the resource post call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnPostListener {\r
-        public void onPostCompleted(List<OcHeaderOption> headerOptionList,\r
-                                    OcRepresentation ocRepresentation);\r
-\r
-        public void onPostFailed(Throwable ex);\r
-    }\r
-\r
-    /**\r
-     * An OnDeleteListener can be registered via the resource delete call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnDeleteListener {\r
-        public void onDeleteCompleted(List<OcHeaderOption> headerOptionList);\r
-\r
-        public void onDeleteFailed(Throwable ex);\r
-    }\r
-\r
-    /**\r
-     * An OnObserveListener can be registered via the resource observe call.\r
-     * Event listeners are notified asynchronously\r
-     */\r
-    public interface OnObserveListener {\r
-        public void onObserveCompleted(List<OcHeaderOption> headerOptionList,\r
-                                       OcRepresentation ocRepresentation,\r
-                                       int sequenceNumber);\r
-\r
-        public void onObserveFailed(Throwable ex);\r
-    }\r
-\r
-    @Override\r
-    protected void finalize() throws Throwable {\r
-        super.finalize();\r
-\r
-        dispose();\r
-    }\r
-\r
-    private native void dispose();\r
-\r
-    private long mNativeHandle;\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OcResource represents an OC resource. A resource could be a light controller, temperature sensor,
+ * smoke detector, etc. A resource comes with a well-defined contract or interface onto which you
+ * can perform different operations, such as turning on the light, getting the current temperature
+ * or subscribing for event notifications from the smoke detector. A resource can be composed of
+ * one or more resources.
+ */
+public class OcResource {
+
+    private OcResource(long nativeHandle) {
+        this.mNativeHandle = nativeHandle;
+    }
+
+    /**
+     * Method to get the attributes of a resource.
+     *
+     * @param queryParamsMap map which can have the query parameter name and value
+     * @param onGetListener  The event handler will be invoked with a map of attribute name and
+     *                       values. The event handler will also have the result from this Get
+     *                       operation This will have error codes
+     * @throws OcException
+     */
+    public native void get(Map<String, String> queryParamsMap,
+                           OnGetListener onGetListener) throws OcException;
+
+    /**
+     * Method to get the attributes of a resource.
+     *
+     * @param queryParamsMap   map which can have the query parameter name and value
+     * @param onGetListener    The event handler will be invoked with a map of attribute name and
+     *                         values. The event handler will also have the result from this Get
+     *                         operation This will have error codes
+     * @param qualityOfService the quality of communication
+     * @throws OcException
+     */
+    public void get(Map<String, String> queryParamsMap,
+                    OnGetListener onGetListener,
+                    QualityOfService qualityOfService) throws OcException {
+        this.get1(queryParamsMap, onGetListener, qualityOfService.getValue());
+    }
+
+    private native void get1(Map<String, String> queryParamsMap,
+                             OnGetListener onGetListener,
+                             int qualityOfService) throws OcException;
+
+    /**
+     * Method to get the attributes of a resource.
+     *
+     * @param resourceType      resourceType of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param queryParamsMap    map which can have the query parameter name and value
+     * @param onGetListener     The event handler will be invoked with a map of attribute name and
+     *                          values. The event handler will also have the result from this Get
+     *                          operation This will have error codes
+     * @throws OcException
+     */
+    public void get(String resourceType,
+                    String resourceInterface,
+                    Map<String, String> queryParamsMap,
+                    OnGetListener onGetListener) throws OcException {
+        this.get2(
+                resourceType,
+                resourceInterface,
+                queryParamsMap,
+                onGetListener);
+    }
+
+    private native void get2(String resourceType,
+                             String resourceInterface,
+                             Map<String, String> queryParamsMap,
+                             OnGetListener onGetListener) throws OcException;
+
+    /**
+     * Method to get the attributes of a resource.
+     *
+     * @param resourceType      resourceType of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param queryParamsMap    map which can have the query parameter name and value
+     * @param onGetListener     The event handler will be invoked with a map of attribute name and
+     *                          values. The event handler will also have the result from this Get
+     *                          operation This will have error codes
+     * @param qualityOfService  the quality of communication
+     * @throws OcException
+     */
+    public void get(String resourceType,
+                    String resourceInterface,
+                    Map<String, String> queryParamsMap,
+                    OnGetListener onGetListener,
+                    QualityOfService qualityOfService) throws OcException {
+        this.get3(
+                resourceType,
+                resourceInterface,
+                queryParamsMap,
+                onGetListener,
+                qualityOfService.getValue());
+    }
+
+    private native void get3(String resourceType,
+                             String resourceInterface,
+                             Map<String, String> queryParamsMap,
+                             OnGetListener onGetListener,
+                             int qualityOfService) throws OcException;
+
+    /**
+     * Method to set the representation of a resource (via PUT)
+     *
+     * @param representation representation of the resource
+     * @param queryParamsMap Map which can have the query parameter name and value
+     * @param onPutListener  event handler The event handler will be invoked with a map of attribute
+     *                       name and values.
+     * @throws OcException
+     */
+    public native void put(OcRepresentation representation,
+                           Map<String, String> queryParamsMap,
+                           OnPutListener onPutListener) throws OcException;
+
+    /**
+     * Method to set the representation of a resource (via PUT)
+     *
+     * @param ocRepresentation representation of the resource
+     * @param queryParamsMap   Map which can have the query parameter name and value
+     * @param onPutListener    event handler The event handler will be invoked with a map of
+     *                         attribute name and values.
+     * @param qualityOfService the quality of communication
+     * @throws OcException
+     */
+    public void put(OcRepresentation ocRepresentation,
+                    Map<String, String> queryParamsMap,
+                    OnPutListener onPutListener,
+                    QualityOfService qualityOfService) throws OcException {
+        this.put1(
+                ocRepresentation,
+                queryParamsMap,
+                onPutListener,
+                qualityOfService.getValue());
+    }
+
+    private native void put1(OcRepresentation ocRepresentation,
+                             Map<String, String> queryParamsMap,
+                             OnPutListener onPutListener,
+                             int qualityOfService) throws OcException;
+
+    /**
+     * Method to set the representation of a resource (via PUT)
+     *
+     * @param resourceType      resource type of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param ocRepresentation  representation of the resource
+     * @param queryParamsMap    Map which can have the query parameter name and value
+     * @param onPutListener     event handler The event handler will be invoked with a map of
+     *                          attribute name and values.
+     * @throws OcException
+     */
+    public void put(String resourceType,
+                    String resourceInterface,
+                    OcRepresentation ocRepresentation,
+                    Map<String, String> queryParamsMap,
+                    OnPutListener onPutListener) throws OcException {
+        this.put2(
+                resourceType,
+                resourceInterface,
+                ocRepresentation,
+                queryParamsMap,
+                onPutListener);
+    }
+
+    private native void put2(String resourceType,
+                             String resourceInterface,
+                             OcRepresentation ocRepresentation,
+                             Map<String, String> queryParamsMap,
+                             OnPutListener onPutListener) throws OcException;
+
+    /**
+     * Method to set the representation of a resource (via PUT)
+     *
+     * @param resourceType      resource type of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param ocRepresentation  representation of the resource
+     * @param queryParamsMap    Map which can have the query parameter name and value
+     * @param onPutListener     event handler The event handler will be invoked with a map of
+     *                          attribute name and values.
+     * @param qualityOfService  the quality of communication
+     * @throws OcException
+     */
+    public void put(String resourceType,
+                    String resourceInterface,
+                    OcRepresentation ocRepresentation,
+                    Map<String, String> queryParamsMap,
+                    OnPutListener onPutListener,
+                    QualityOfService qualityOfService) throws OcException {
+        this.put3(
+                resourceType,
+                resourceInterface,
+                ocRepresentation,
+                queryParamsMap,
+                onPutListener,
+                qualityOfService.getValue());
+    }
+
+    private native void put3(String resourceType,
+                             String resourceInterface,
+                             OcRepresentation ocRepresentation,
+                             Map<String, String> queryParamsMap,
+                             OnPutListener onPutListener,
+                             int qualityOfService) throws OcException;
+
+    /**
+     * Method to POST on a resource
+     *
+     * @param ocRepresentation representation of the resource
+     * @param queryParamsMap   Map which can have the query parameter name and value
+     * @param onPostListener   event handler The event handler will be invoked with a map of
+     *                         attribute name and values.
+     * @throws OcException
+     */
+    public native void post(OcRepresentation ocRepresentation,
+                            Map<String, String> queryParamsMap,
+                            OnPostListener onPostListener) throws OcException;
+
+    /**
+     * Method to POST on a resource
+     *
+     * @param ocRepresentation representation of the resource
+     * @param queryParamsMap   Map which can have the query parameter name and value
+     * @param onPostListener   event handler The event handler will be invoked with a map of
+     *                         attribute name and values.
+     * @param qualityOfService the quality of communication
+     * @throws OcException
+     */
+    public void post(OcRepresentation ocRepresentation,
+                     Map<String, String> queryParamsMap,
+                     OnPostListener onPostListener,
+                     QualityOfService qualityOfService) throws OcException {
+        this.post1(
+                ocRepresentation,
+                queryParamsMap,
+                onPostListener,
+                qualityOfService.getValue());
+    }
+
+    private native void post1(OcRepresentation ocRepresentation,
+                              Map<String, String> queryParamsMap,
+                              OnPostListener onPostListener,
+                              int qualityOfService) throws OcException;
+
+    /**
+     * Method to POST on a resource
+     *
+     * @param resourceType      resource type of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param ocRepresentation  representation of the resource
+     * @param queryParamsMap    Map which can have the query parameter name and value
+     * @param onPostListener    event handler The event handler will be invoked with a map of
+     *                          attribute name and values.
+     * @throws OcException
+     */
+    public void post(String resourceType,
+                     String resourceInterface,
+                     OcRepresentation ocRepresentation,
+                     Map<String, String> queryParamsMap,
+                     OnPostListener onPostListener) throws OcException {
+        this.post2(
+                resourceType,
+                resourceInterface,
+                ocRepresentation,
+                queryParamsMap,
+                onPostListener);
+    }
+
+    private native void post2(String resourceType,
+                              String resourceInterface,
+                              OcRepresentation ocRepresentation,
+                              Map<String, String> queryParamsMap,
+                              OnPostListener onPostListener) throws OcException;
+
+    /**
+     * Method to POST on a resource
+     *
+     * @param resourceType      resource type of the resource to operate on
+     * @param resourceInterface interface type of the resource to operate on
+     * @param ocRepresentation  representation of the resource
+     * @param queryParamsMap    Map which can have the query parameter name and value
+     * @param onPostListener    event handler The event handler will be invoked with a map of
+     *                          attribute name and values.
+     * @param qualityOfService  the quality of communication
+     * @throws OcException
+     */
+    public void post(String resourceType,
+                     String resourceInterface,
+                     OcRepresentation ocRepresentation,
+                     Map<String, String> queryParamsMap,
+                     OnPostListener onPostListener,
+                     QualityOfService qualityOfService) throws OcException {
+        this.post3(
+                resourceType,
+                resourceInterface,
+                ocRepresentation,
+                queryParamsMap,
+                onPostListener,
+                qualityOfService.getValue());
+    }
+
+    private native void post3(String resourceType,
+                              String resourceInterface,
+                              OcRepresentation ocRepresentation,
+                              Map<String, String> queryParamsMap,
+                              OnPostListener onPostListener,
+                              int qualityOfService) throws OcException;
+
+    /**
+     * Method to perform DELETE operation
+     *
+     * @param onDeleteListener event handler The event handler will have headerOptionList
+     */
+    public native void deleteResource(OnDeleteListener onDeleteListener) throws OcException;
+
+    /**
+     * Method to perform DELETE operation
+     *
+     * @param onDeleteListener event handler The event handler will have headerOptionList
+     * @param qualityOfService the quality of communication
+     */
+    public void deleteResource(OnDeleteListener onDeleteListener,
+                               QualityOfService qualityOfService) throws OcException {
+        this.deleteResource1(onDeleteListener,
+                qualityOfService.getValue());
+    }
+
+    private native void deleteResource1(OnDeleteListener onDeleteListener,
+                                        int qualityOfService) throws OcException;
+
+    /**
+     * Method to set observation on the resource
+     *
+     * @param observeType       allows the client to specify how it wants to observe
+     * @param queryParamsMap    map which can have the query parameter name and value
+     * @param onObserveListener event handler The handler method will be invoked with a map
+     *                          of attribute name and values.
+     * @throws OcException
+     */
+    public void observe(ObserveType observeType,
+                        Map<String, String> queryParamsMap,
+                        OnObserveListener onObserveListener) throws OcException {
+        this.observe(
+                observeType.getValue(),
+                queryParamsMap,
+                onObserveListener);
+    }
+
+    private synchronized native void observe(int observeType,
+                                             Map<String, String> queryParamsMap,
+                                             OnObserveListener onObserveListener) throws OcException;
+
+    /**
+     * Method to set observation on the resource
+     *
+     * @param observeType       allows the client to specify how it wants to observe
+     * @param queryParamsMap    map which can have the query parameter name and value
+     * @param onObserveListener event handler The handler method will be invoked with a map
+     *                          of attribute name and values.
+     * @param qualityOfService  the quality of communication
+     * @throws OcException
+     */
+    public void observe(ObserveType observeType,
+                        Map<String, String> queryParamsMap,
+                        OnObserveListener onObserveListener,
+                        QualityOfService qualityOfService) throws OcException {
+        this.observe1(
+                observeType.getValue(),
+                queryParamsMap,
+                onObserveListener,
+                qualityOfService.getValue());
+    }
+
+    private synchronized native void observe1(int observeType,
+                                              Map<String, String> queryParamsMap,
+                                              OnObserveListener onObserveListener,
+                                              int qualityOfService) throws OcException;
+
+    /**
+     * Method to cancel the observation on the resource
+     *
+     * @throws OcException
+     */
+    public native void cancelObserve() throws OcException;
+
+    /**
+     * Method to cancel the observation on the resource
+     *
+     * @param qualityOfService the quality of communication
+     * @throws OcException
+     */
+    public void cancelObserve(QualityOfService qualityOfService) throws OcException {
+        this.cancelObserve1(qualityOfService.getValue());
+    }
+
+    private native void cancelObserve1(int qualityOfService) throws OcException;
+
+    /**
+     * Method to set header options
+     *
+     * @param headerOptionList List<OcHeaderOption> where header information(header optionID and
+     *                         optionData is passed
+     */
+    public void setHeaderOptions(List<OcHeaderOption> headerOptionList) {
+        this.setHeaderOptions(headerOptionList.toArray(
+                        new OcHeaderOption[headerOptionList.size()])
+        );
+    }
+
+    private native void setHeaderOptions(OcHeaderOption[] headerOptionList);
+
+    /**
+     * Method to unset header options
+     */
+    public native void unsetHeaderOptions();
+
+    /**
+     * Method to get the host address of this resource
+     *
+     * @return host address NOTE: This might or might not be exposed in future due to
+     * security concerns
+     */
+    public native String getHost();
+
+    /**
+     * Method to get the URI for this resource
+     *
+     * @return resource URI
+     */
+    public native String getUri();
+
+    /**
+     * Method to get the connectivity type of this resource
+     *
+     * @return EnumSet<OcConnectivityType></OcConnectivityType> connectivity type set
+     */
+    public EnumSet<OcConnectivityType> getConnectivityTypeSet() {
+        return OcConnectivityType.convertToEnumSet(
+                this.getConnectivityTypeN()
+        );
+    }
+
+    private native int getConnectivityTypeN();
+
+    /**
+     * Method to provide ability to check if this resource is observable or not
+     *
+     * @return true indicates resource is observable; false indicates resource is not observable
+     */
+    public native boolean isObservable();
+
+    /**
+     * Method to get the list of resource types
+     *
+     * @return List of resource types
+     */
+    public native List<String> getResourceTypes();
+
+    /**
+     * Method to get the list of resource interfaces
+     *
+     * @return List of resource interface
+     */
+    public native List<String> getResourceInterfaces();
+
+    /**
+     * Method to get a unique identifier for this resource across network interfaces.  This will
+     * be guaranteed unique for every resource-per-server independent of how this was discovered.
+     *
+     * @return OcResourceIdentifier object, which can be used for all comparison and hashing
+     */
+    public native OcResourceIdentifier getUniqueIdentifier();
+
+    /**
+     * Method to get a string representation of the resource's server ID.
+     * * This is unique per- server independent on how it was discovered.
+     *
+     * @return server ID
+     */
+    public native String getServerId();
+
+    /**
+     * An OnGetListener can be registered via the resource get call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnGetListener {
+        public void onGetCompleted(List<OcHeaderOption> headerOptionList,
+                                   OcRepresentation ocRepresentation);
+
+        public void onGetFailed(Throwable ex);
+    }
+
+    /**
+     * An OnPutListener can be registered via the resource put call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnPutListener {
+        public void onPutCompleted(List<OcHeaderOption> headerOptionList,
+                                   OcRepresentation ocRepresentation);
+
+        public void onPutFailed(Throwable ex);
+    }
+
+    /**
+     * An OnPostListener can be registered via the resource post call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnPostListener {
+        public void onPostCompleted(List<OcHeaderOption> headerOptionList,
+                                    OcRepresentation ocRepresentation);
+
+        public void onPostFailed(Throwable ex);
+    }
+
+    /**
+     * An OnDeleteListener can be registered via the resource delete call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnDeleteListener {
+        public void onDeleteCompleted(List<OcHeaderOption> headerOptionList);
+
+        public void onDeleteFailed(Throwable ex);
+    }
+
+    /**
+     * An OnObserveListener can be registered via the resource observe call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnObserveListener {
+        public void onObserveCompleted(List<OcHeaderOption> headerOptionList,
+                                       OcRepresentation ocRepresentation,
+                                       int sequenceNumber);
+
+        public void onObserveFailed(Throwable ex);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+
+        dispose();
+    }
+
+    private native void dispose();
+
+    private long mNativeHandle;
+}
diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcStackConfig.java b/android/android_api/base/src/main/java/org/iotivity/base/OcStackConfig.java
new file mode 100644 (file)
index 0000000..ff48d22
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+// This file contains all the variables which can be configured/modified as
+// per platform or specific product usage scenarios.
+
+package org.iotivity.base;
+
+public interface OcStackConfig {
+    // max manufacturer name length for OcPlatformInfo supported by server
+    public static final int MAX_MANUFACTURER_NAME_LENGTH = 16;
+    // max manufacturer url length for OcPlatformInfo supported by server
+    public static final int MAX_MANUFACTURER_URL_LENGTH = 32;
+}
\ No newline at end of file
index 7fd9ac0..70d9df3 100644 (file)
@@ -35,6 +35,8 @@ public class PlatformConfig {
     private String mIpAddress;\r
     private int mPort;\r
     private QualityOfService mQualityOfService;\r
+    private String mSvrDbPath; //TODO: Instead of SVRDB file, it should be Persistent Storage.
+                              //this is only for 0.9.2
 \r
     /**\r
      * @param context          app context\r
@@ -47,19 +49,44 @@ public class PlatformConfig {
      *                         if you specify 5683 : client discovery can work even if they don't\r
      *                         specify port\r
      * @param qualityOfService quality of service\r
+     * @param dbPath           Persistant storage file for SVR Database.
      */\r
     public PlatformConfig(Context context,\r
                           ServiceType serviceType,\r
                           ModeType modeType,\r
                           String ipAddress,\r
                           int port,\r
-                          QualityOfService qualityOfService) {\r
+                          QualityOfService qualityOfService,
+                          String dbPath) {
         this.mContext = context;\r
         this.mServiceType = serviceType;\r
         this.mModeType = modeType;\r
         this.mIpAddress = ipAddress;\r
         this.mPort = port;\r
         this.mQualityOfService = qualityOfService;\r
+        this.mSvrDbPath = dbPath;
+    }
+
+    /**
+     * @param context          app context
+     * @param serviceType      indicate IN_PROC or OUT_OF_PROC
+     * @param modeType         indicate whether we want to do server, client or both
+     * @param ipAddress        ip address of server
+     *                         if you specify 0.0.0.0 : it listens on any interface
+     * @param port             port of server
+     *                         if you specifiy 0 : next available random port is used
+     *                         if you specify 5683 : client discovery can work even if they don't
+     *                         specify port
+     * @param qualityOfService quality of service
+     */
+    //Avoid breaking building java samples due to persistent storage SVR DB changes.
+    public PlatformConfig(Context context,
+                          ServiceType serviceType,
+                          ModeType modeType,
+                          String ipAddress,
+                          int port,
+                          QualityOfService qualityOfService) {
+        this(context,serviceType,modeType,ipAddress,port,qualityOfService, "");
     }\r
 \r
     public Context getContext() {\r
@@ -84,5 +111,9 @@ public class PlatformConfig {
 \r
     public QualityOfService getQualityOfService() {\r
         return mQualityOfService;\r
+    }
+
+    public String getSvrDbPath() {
+        return mSvrDbPath;
     }\r
 }\r
index 64345db..778543d 100644 (file)
@@ -23,9 +23,9 @@
 package org.iotivity.base;\r
 \r
 public enum ResourceProperty {\r
-    ACTIVE(1 << 0),\r
-    DISCOVERABLE(1 << 1),\r
-    OBSERVABLE(1 << 2),\r
+    DISCOVERABLE(1 << 0),\r
+    OBSERVABLE(1 << 1),\r
+    ACTIVE(1 << 2),\r
     SLOW(1 << 3),\r
     SECURE(1 << 4);\r
 \r
diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaEdrInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaEdrInterface.java
new file mode 100644 (file)
index 0000000..1e4d47c
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************
+ *
+ * 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.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public class CaEdrInterface {
+
+    private CaEdrInterface(Context context) {
+
+        registerIntentFilter(context);
+    }
+
+    private static IntentFilter registerIntentFilter(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        context.registerReceiver(mReceiver, filter);
+        return filter;
+    }
+
+    // Network Monitor
+    private native static void caEdrStateChangedCallback(int state);
+
+    private native static void caEdrBondStateChangedCallback(String addr);
+
+    private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+
+            String action = intent.getAction();
+
+            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+
+                int state =
+                        intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+
+                // STATE_ON:12, STATE_OFF:10
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                {
+                    caEdrStateChangedCallback(state);
+                }
+            }
+
+            if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+
+                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                                   BluetoothDevice.ERROR);
+
+                if (bondState == BluetoothDevice.BOND_NONE) {
+                    if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+                                            BluetoothDevice.ERROR)
+                                                == BluetoothDevice.BOND_BONDED)) {
+                        BluetoothDevice device
+                            = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+                        caEdrBondStateChangedCallback(device.getAddress());
+                    }
+                }
+            }
+        }
+    };
+}
index 43d0ace..1e807d1 100644 (file)
@@ -1,24 +1,22 @@
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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
+ *\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
@@ -50,21 +48,21 @@ public class CaIpInterface {
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
             if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,\r
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {\r
-                stateDisabled();\r
+                WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {\r
+                caIpStateDisabled();\r
             } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {\r
                 ConnectivityManager manager = (ConnectivityManager)\r
                         mContext.getSystemService(Context.CONNECTIVITY_SERVICE);\r
                 NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);\r
 \r
                 if(nwInfo.isConnected()) {\r
-                    stateEnabled();\r
+                    caIpStateEnabled();\r
                 }\r
             }\r
         }\r
     };\r
 \r
-    private native static void stateEnabled();\r
+    private native static void caIpStateEnabled();\r
 \r
-    private native static void stateDisabled();\r
-}
\ No newline at end of file
+    private native static void caIpStateDisabled();\r
+}\r
diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java
new file mode 100644 (file)
index 0000000..891cb40
--- /dev/null
@@ -0,0 +1,295 @@
+/******************************************************************
+ *
+ * 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 java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+public class CaLeClientInterface {
+
+    private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
+    private static String TAG          = "Sample_Service : CaLeClientInterface";
+
+    private CaLeClientInterface(Context context) {
+
+        caLeRegisterLeScanCallback(mLeScanCallback);
+        caLeRegisterGattCallback(mGattCallback);
+
+        registerIntentFilter(context);
+    }
+
+    public static void getLeScanCallback() {
+        caLeRegisterLeScanCallback(mLeScanCallback);
+    }
+
+    public static void getLeGattCallback() {
+        caLeRegisterGattCallback(mGattCallback);
+    }
+
+    private static IntentFilter registerIntentFilter(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        context.registerReceiver(mReceiver, filter);
+        return filter;
+    }
+
+    private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
+
+    private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
+
+    // BluetoothAdapter.LeScanCallback
+    private native static void caLeScanCallback(BluetoothDevice device,
+                                                int rssi, byte[] scanRecord);
+
+    // BluetoothGattCallback
+    private native static void caLeGattConnectionStateChangeCallback(
+            BluetoothGatt gatt, int status, int newState);
+
+    private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
+
+    private native static void caLeGattCharacteristicReadCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+            byte[] data, int status);
+
+    private native static void caLeGattCharacteristicWriteCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+            byte[] data, int status);
+
+    private native static void caLeGattCharacteristicChangedCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data);
+
+    private native static void caLeGattDescriptorReadCallback(BluetoothGatt gatt,
+                                                             BluetoothGattDescriptor descriptor,
+                                                             int status);
+
+    private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt,
+                                                              BluetoothGattDescriptor descriptor,
+                                                              int status);
+
+    private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
+                                                                     int status);
+
+    private native static void caLeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi,
+                                                             int status);
+
+    // Network Monitor
+    private native static void caLeStateChangedCallback(int state);
+
+    // bond state
+    private native static void caLeBondStateChangedCallback(String address);
+
+    // Callback
+    private static BluetoothAdapter.LeScanCallback mLeScanCallback =
+                   new BluetoothAdapter.LeScanCallback() {
+
+        @Override
+        public void onLeScan(BluetoothDevice device, int rssi, byte[] 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");
+                        caLeScanCallback(device, rssi, scanRecord);
+                    }
+                }
+            } catch(UnsatisfiedLinkError e) {
+
+            }
+        }
+    };
+
+    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)
+                break;
+
+            int type = scanRecord[offset++];
+
+            switch (type) {
+            case 0x02:
+            case 0x03:
+                while (len > 1) {
+                    int uuid16 = scanRecord[offset++];
+                    uuid16 += (scanRecord[offset++] << 8);
+                    len -= 2;
+                    uuids.add(UUID.fromString(String.format(
+                            "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
+                }
+                break;
+            case 0x06:
+            case 0x07:
+                while (len >= 16) {
+                    try {
+                        ByteBuffer buffer = ByteBuffer.wrap(scanRecord, offset++, 16).
+                                                            order(ByteOrder.LITTLE_ENDIAN);
+                        long mostSigBits = buffer.getLong();
+                        long leastSigBits = buffer.getLong();
+                        uuids.add(new UUID(leastSigBits, mostSigBits));
+                    } catch (IndexOutOfBoundsException e) {
+                        Log.e(TAG, e.toString());
+                        continue;
+                    } finally {
+                        offset += 15;
+                        len -= 16;
+                    }
+                }
+                break;
+            default:
+                offset += (len - 1);
+                break;
+            }
+        }
+        return uuids;
+    }
+
+    private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+            super.onConnectionStateChange(gatt, status, newState);
+
+            caLeGattConnectionStateChangeCallback(gatt, status, newState);
+        }
+
+        @Override
+        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+            super.onServicesDiscovered(gatt, status);
+
+            caLeGattServicesDiscoveredCallback(gatt, status);
+        }
+
+        @Override
+        public void onCharacteristicRead(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicRead(gatt, characteristic, status);
+
+            caLeGattCharacteristicReadCallback(gatt, characteristic,
+                                               characteristic.getValue(), status);
+        }
+
+        @Override
+        public void onCharacteristicWrite(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicWrite(gatt, characteristic, status);
+
+            caLeGattCharacteristicWriteCallback(gatt, characteristic,
+                                                characteristic.getValue(), status);
+        }
+
+        @Override
+        public void onCharacteristicChanged(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicChanged(gatt, characteristic);
+
+            caLeGattCharacteristicChangedCallback(gatt, characteristic,
+                                                  characteristic.getValue());
+        }
+
+        @Override
+        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorRead(gatt, descriptor, status);
+
+            caLeGattDescriptorReadCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorWrite(gatt, descriptor, status);
+
+            caLeGattDescriptorWriteCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+            super.onReliableWriteCompleted(gatt, status);
+
+            caLeGattReliableWriteCompletedCallback(gatt, status);
+        }
+
+        @Override
+        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+            super.onReadRemoteRssi(gatt, rssi, status);
+
+            caLeGattReadRemoteRssiCallback(gatt, rssi, status);
+        }
+    };
+
+    private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+
+            String action = intent.getAction();
+
+            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                               BluetoothAdapter.ERROR);
+
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                {
+                    caLeStateChangedCallback(state);
+                }
+            }
+
+            if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+
+                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                                   BluetoothDevice.ERROR);
+
+                if (bondState == BluetoothDevice.BOND_NONE) {
+                    if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+                            BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED)) {
+                            BluetoothDevice device = intent
+                                .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+                        caLeBondStateChangedCallback(device.getAddress());
+                    }
+                }
+            }
+        }
+    };
+}
+
diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaLeServerInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaLeServerInterface.java
new file mode 100644 (file)
index 0000000..18ac49f
--- /dev/null
@@ -0,0 +1,181 @@
+/******************************************************************
+ *
+ * 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.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattServerCallback;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseSettings;
+
+public class CaLeServerInterface {
+
+    private CaLeServerInterface() {
+
+        caLeRegisterGattServerCallback(mGattServerCallback);
+        caLeRegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+    }
+
+    public static void getLeGattServerCallback() {
+        caLeRegisterGattServerCallback(mGattServerCallback);
+    }
+
+    public static void getBluetoothLeAdvertiseCallback() {
+        caLeRegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+    }
+
+    private native static void caLeRegisterGattServerCallback(BluetoothGattServerCallback callback);
+
+    private native static void caLeRegisterBluetoothLeAdvertiseCallback(AdvertiseCallback callback);
+
+    // BluetoothGattServerCallback
+    private native static void caLeGattServerConnectionStateChangeCallback(
+            BluetoothDevice device, int status, int newState);
+
+    private native static void caLeGattServerServiceAddedCallback(int status,
+                                                                  BluetoothGattService service);
+
+    private native static void caLeGattServerCharacteristicReadRequestCallback(
+            BluetoothDevice device,
+            int requestId, int offset, BluetoothGattCharacteristic characteristic, byte[] data);
+
+    private native static void caLeGattServerCharacteristicWriteRequestCallback(
+            BluetoothDevice device, int requestId,
+            BluetoothGattCharacteristic characteristic, byte[] data, boolean preparedWrite,
+            boolean responseNeeded, int offset, byte[] value);
+
+    private native static void caLeGattServerDescriptorReadRequestCallback(
+            BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor);
+
+    public native static void caLeGattServerDescriptorWriteRequestCallback(
+            BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor,
+            boolean preparedWrite, boolean responseNeeded, int offset, byte[] value);
+
+    private native static void caLeGattServerExecuteWriteCallback(BluetoothDevice device,
+                                                                 int requestId, boolean execute);
+
+    private native static void caLeGattServerNotificationSentCallback(BluetoothDevice device,
+                                                                     int status);
+
+    // AdvertiseCallback
+    private native static void caLeAdvertiseStartSuccessCallback(
+            AdvertiseSettings settingsInEffect);
+
+    private native static void caLeAdvertiseStartFailureCallback(int errorCode);
+
+    private static final BluetoothGattServerCallback mGattServerCallback =
+                         new BluetoothGattServerCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothDevice device, int status,
+                int newState) {
+            super.onConnectionStateChange(device, status, newState);
+
+            caLeGattServerConnectionStateChangeCallback(device, status, newState);
+        }
+
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            super.onServiceAdded(status, service);
+
+            caLeGattServerServiceAddedCallback(status, service);
+        }
+
+        @Override
+        public void onCharacteristicReadRequest(
+                BluetoothDevice device, int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
+
+            caLeGattServerCharacteristicReadRequestCallback(device, requestId, offset,
+                                                            characteristic,
+                                                            characteristic.getValue());
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(
+                BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic,
+                boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
+            super.onCharacteristicWriteRequest(device, requestId, characteristic,
+                    preparedWrite, responseNeeded, offset, value);
+
+            caLeGattServerCharacteristicWriteRequestCallback(device, requestId, characteristic,
+                                                             value, preparedWrite, responseNeeded,
+                                                             offset, value);
+        }
+
+        @Override
+        public void onDescriptorReadRequest(
+                BluetoothDevice device,
+                int requestId, int offset, BluetoothGattDescriptor descriptor) {
+            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
+
+            caLeGattServerDescriptorReadRequestCallback(device, requestId, offset, descriptor);
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(
+                BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor,
+                boolean preparedWrite, boolean responseNeeded, int offset,
+                byte[] value) {
+            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite,
+                                           responseNeeded, offset, value);
+
+            caLeGattServerDescriptorWriteRequestCallback(device, requestId, descriptor,
+                                                         preparedWrite, responseNeeded, offset,
+                                                         value);
+        }
+
+        @Override
+        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
+            super.onExecuteWrite(device, requestId, execute);
+
+            caLeGattServerExecuteWriteCallback(device, requestId, execute);
+        }
+
+        @Override
+        public void onNotificationSent(BluetoothDevice device, int status) {
+            super.onNotificationSent(device, status);
+
+            caLeGattServerNotificationSentCallback(device, status);
+        }
+    };
+
+    private static final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
+
+        @Override
+        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+            super.onStartSuccess(settingsInEffect);
+
+            caLeAdvertiseStartSuccessCallback(settingsInEffect);
+        }
+
+        @Override
+        public void onStartFailure(int errorCode) {
+            super.onStartFailure(errorCode);
+
+            caLeAdvertiseStartFailureCallback(errorCode);
+        }
+    };
+}
+
diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java
deleted file mode 100644 (file)
index 15cac58..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 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
-\r
-public class CaWiFiInterface {\r
-\r
-    private static Context mContext;\r
-\r
-    private CaWiFiInterface(Context context) {\r
-        mContext = context;\r
-        registerWiFiStateReceiver();\r
-    }\r
-\r
-    private void registerWiFiStateReceiver() {\r
-        IntentFilter intentFilter = new IntentFilter();\r
-        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);\r
-        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);\r
-\r
-        mContext.registerReceiver(mReceiver, intentFilter);\r
-    }\r
-\r
-    private static BroadcastReceiver mReceiver = new BroadcastReceiver() {\r
-\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,\r
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {\r
-                CAWiFiStateDisabled();\r
-            } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {\r
-                ConnectivityManager manager = (ConnectivityManager)\r
-                        mContext.getSystemService(Context.CONNECTIVITY_SERVICE);\r
-                NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);\r
-\r
-                if (nwInfo.isConnected()) {\r
-                    CAWiFiStateEnabled();\r
-                }\r
-            }\r
-        }\r
-    };\r
-\r
-    private native static void CAWiFiStateEnabled();\r
-\r
-    private native static void CAWiFiStateDisabled();\r
-}
\ No newline at end of file
index d560e70..fba408a 100755 (executable)
@@ -1,22 +1,33 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
-    xmlns:tools="http://schemas.android.com/tools"\r
-    package="org.iotivity.base.examples.fridgeclient" >\r
-    <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
-\r
-    <application\r
-        android:allowBackup="true"\r
-        android:icon="@drawable/ic_launcher"\r
-        android:label="@string/app_name"\r
-        android:theme="@style/AppTheme">\r
-        <activity\r
-            android:name=".FridgeClient"\r
-            android:label="@string/app_name" >\r
-            <intent-filter>\r
-                <action android:name="android.intent.action.MAIN" />\r
-\r
-                <category android:name="android.intent.category.LAUNCHER" />\r
-            </intent-filter>\r
-        </activity>\r
-    </application>\r
-</manifest>\r
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="org.iotivity.base.examples.fridgeclient" >
+    <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".FridgeClient"
+            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>
index a004c87..b2109e8 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base.examples.fridgeclient;\r
-\r
-import android.app.Activity;\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.os.Bundle;\r
-import android.os.Message;\r
-import android.support.v4.content.LocalBroadcastManager;\r
-import android.text.method.ScrollingMovementMethod;\r
-import android.util.Log;\r
-import android.view.Menu;\r
-import android.view.MenuItem;\r
-import android.widget.LinearLayout;\r
-import android.widget.TextView;\r
-\r
-import org.iotivity.base.ErrorCode;\r
-import org.iotivity.base.ModeType;\r
-import org.iotivity.base.OcConnectivityType;\r
-import org.iotivity.base.OcException;\r
-import org.iotivity.base.OcHeaderOption;\r
-import org.iotivity.base.OcPlatform;\r
-import org.iotivity.base.OcRepresentation;\r
-import org.iotivity.base.OcResource;\r
-import org.iotivity.base.PlatformConfig;\r
-import org.iotivity.base.QualityOfService;\r
-import org.iotivity.base.ServiceType;\r
-\r
-import java.util.HashMap;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-\r
-import base.iotivity.org.examples.message.IMessageLogger;\r
-\r
-/**\r
- * FridgeClient\r
- * <p/>\r
- * FridgeClient is a sample client app which should be started after the fridgeServer is started.\r
- * It creates DeviceResource, DoorResource, LightResource and performs a get operation on them.\r
- * This implements IMessageLogger to display messages on the screen\r
- */\r
-public class FridgeClient extends Activity implements\r
-        OcPlatform.OnResourceFoundListener, IMessageLogger {\r
-    private static String TAG = "FridgeClient: ";\r
-\r
-    private MessageReceiver mMessageReceiver = new MessageReceiver();\r
-    private TextView mEventsTextView;\r
-    private String mDeviceName;\r
-    private int mDeviceCode;\r
-    private List<String> ifaces;\r
-    private final List<OcResource> resourceList = new LinkedList<OcResource>();\r
-\r
-    /**\r
-     * configure OIC platform and call findResource\r
-     */\r
-    private void initOICStack() {\r
-        PlatformConfig cfg = new PlatformConfig(\r
-                this,\r
-                ServiceType.IN_PROC,\r
-                ModeType.CLIENT,\r
-                "0.0.0.0", // bind to all available interfaces\r
-                0,\r
-                QualityOfService.LOW);\r
-\r
-        OcPlatform.Configure(cfg);\r
-        try {\r
-            OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "intel.fridge",\r
-                    OcConnectivityType.WIFI, this);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + " init Error. " + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * prints out the appropriate messages depending on the device code\r
-     *\r
-     * @param representation representation of the OcResource\r
-     * @param value          clientDeviceCode\r
-     */\r
-    private void getResponse(OcRepresentation representation, int value) {\r
-        switch (value) {\r
-            case 0:\r
-                // Get on device\r
-                try {\r
-                    logMessage(TAG + "Name of device: " +\r
-                            representation.getValue(StringConstants.DEVICE_NAME));\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                break;\r
-            case 1:\r
-                // get on fridge light\r
-                try {\r
-                    boolean lightOn = representation.getValue(StringConstants.ON);\r
-                    logMessage(TAG + "The fridge light is " +\r
-                            (lightOn ? "" : "not " + "on"));\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                break;\r
-            case 2:\r
-            case 3:\r
-                // get on fridge door(s)\r
-                try {\r
-                    boolean doorOpen = representation.getValue(StringConstants.OPEN);\r
-                    logMessage(TAG + "Door is " + (doorOpen ?\r
-                            "open" : "not open") + " and is on the " +\r
-                            representation.getValue(StringConstants.SIDE) + " side");\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                break;\r
-            case 4:\r
-                // get on fridge random door\r
-                try {\r
-                    logMessage("Name of fridge: " +\r
-                            representation.getValue(StringConstants.DEVICE_NAME));\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                break;\r
-            default:\r
-                logMessage("Unexpected State");\r
-                break;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * this method is used to wait for 1 second between calls to different resources.\r
-     * It is added for better readability\r
-     */\r
-    private void doWait() {\r
-        try {\r
-            Thread.sleep(StringConstants.WAIT_TIME);\r
-        } catch (InterruptedException e) {\r
-            logMessage(TAG + "doWait exception: " + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    @Override\r
-    /**\r
-     *  callback when a resource is found. This method calls getResponse with the correct code\r
-     */\r
-    synchronized public void onResourceFound(OcResource ocResource) {\r
-        // eventHandler for onGetListener\r
-        resourceList.add(ocResource);\r
-        OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() {\r
-            @Override\r
-            public void onGetCompleted(List<OcHeaderOption> headerOptionList, OcRepresentation rep) {\r
-                logMessage(TAG + " Got a response from " + getClientDeviceName());\r
-                getResponse(rep, getClientDeviceCode());\r
-            }\r
-\r
-            @Override\r
-            public void onGetFailed(Throwable throwable) {\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-\r
-        if (ocResource.getUri().equals(StringConstants.RESOURCE_URI)) {\r
-            logMessage(TAG + "Discovered a device with \nHost: " + ocResource.getHost() +\r
-                    ", Uri: " + ocResource.getUri());\r
-        }\r
-        List<String> lightTypes = new LinkedList<>();\r
-        lightTypes.add("intel.fridge.light");\r
-        try {\r
-            OcResource light = OcPlatform.constructResourceObject(ocResource.getHost(),\r
-                    StringConstants.LIGHT, OcConnectivityType.WIFI, false, lightTypes, ifaces);\r
-\r
-            List<String> doorTypes = new LinkedList<>();\r
-            doorTypes.add("intel.fridge.door");\r
-            OcResource leftDoor = OcPlatform.constructResourceObject(ocResource.getHost(),\r
-                    StringConstants.LEFT_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces);\r
-\r
-            OcResource rightDoor = OcPlatform.constructResourceObject(ocResource.getHost(),\r
-                    StringConstants.RIGHT_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces);\r
-\r
-            OcResource randomDoor = OcPlatform.constructResourceObject(ocResource.getHost(),\r
-                    StringConstants.RANDOM_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces);\r
-\r
-            List<OcHeaderOption> headerOptions = new LinkedList<>();\r
-            OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY,\r
-                    StringConstants.API_VERSION);\r
-            OcHeaderOption clientToken = new OcHeaderOption(StringConstants.CLIENT_VERSION_KEY,\r
-                    StringConstants.CLIENT_TOKEN);\r
-            headerOptions.add(apiVersion);\r
-            headerOptions.add(clientToken);\r
-            ocResource.setHeaderOptions(headerOptions);\r
-            /**\r
-             *  wait for 1 second before calling get on different resources.\r
-             *  It is done for better readability.\r
-             *  doWait() is called before each call to get\r
-             */\r
-            doWait();\r
-\r
-            setupClientOptions("Device", 0);\r
-            ocResource.get(new HashMap<String, String>(), onGetListener);\r
-            doWait();\r
-\r
-            setupClientOptions("Fridge Light", 1);\r
-            light.get(new HashMap<String, String>(), onGetListener);\r
-            doWait();\r
-\r
-            setupClientOptions("Left Door", 2);\r
-            leftDoor.get(new HashMap<String, String>(), onGetListener);\r
-            doWait();\r
-\r
-            setupClientOptions("Right Door", 3);\r
-            rightDoor.get(new HashMap<String, String>(), onGetListener);\r
-            doWait();\r
-\r
-            setupClientOptions("Random Door", 4);\r
-            randomDoor.get(new HashMap<String, String>(), onGetListener);\r
-            doWait();\r
-\r
-            resourceList.add(leftDoor);\r
-            leftDoor.deleteResource(new OcResource.OnDeleteListener() {\r
-                @Override\r
-                public void onDeleteCompleted(List<OcHeaderOption> ocHeaderOptions) {\r
-                    logMessage(TAG + "Delete resource successful");\r
-                }\r
-\r
-                @Override\r
-                public void onDeleteFailed(Throwable throwable) {\r
-                    if (throwable instanceof OcException) {\r
-                        OcException ocEx = (OcException) throwable;\r
-                        ErrorCode errCode = ocEx.getErrorCode();\r
-                        //do something based on errorCode\r
-                    }\r
-                    Log.e(TAG, throwable.toString());\r
-                }\r
-            });\r
-        } catch (OcException e) {\r
-            logMessage(TAG + "onResourceFound Error. " + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        setContentView(R.layout.activity_fridge_client);\r
-        registerReceiver(mMessageReceiver, new IntentFilter(StringConstants.INTENT));\r
-\r
-        mEventsTextView = new TextView(this);\r
-        mEventsTextView.setMovementMethod(new ScrollingMovementMethod());\r
-        LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);\r
-        layout.addView(mEventsTextView, new LinearLayout.LayoutParams\r
-                (LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f));\r
-        ifaces = new LinkedList<>();\r
-        ifaces.add(StringConstants.RESOURCE_INTERFACE);\r
-        mDeviceCode = -1;\r
-        mDeviceName = "";\r
-\r
-        initOICStack();\r
-    }\r
-\r
-    public class MessageReceiver extends BroadcastReceiver {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            final String message = intent.getStringExtra(StringConstants.MESSAGE);\r
-            logMessage(message);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void logMessage(final String text) {\r
-        if (StringConstants.ENABLE_PRINTING) {\r
-            runOnUiThread(new Runnable() {\r
-                public void run() {\r
-                    final Message msg = new Message();\r
-                    msg.obj = text;\r
-                    mEventsTextView.append("\n");\r
-                    mEventsTextView.append(text);\r
-                }\r
-            });\r
-            Log.i(TAG, text);\r
-        }\r
-    }\r
-\r
-\r
-    private void setupClientOptions(String name, int value) {\r
-        mDeviceName = name;\r
-        mDeviceCode = value;\r
-    }\r
-\r
-    private String getClientDeviceName() {\r
-        return mDeviceName;\r
-    }\r
-\r
-    private int getClientDeviceCode() {\r
-        return mDeviceCode;\r
-    }\r
-\r
-\r
-    //method to print the headerOptions received from the server\r
-    void printHeaderOptions(List<OcHeaderOption> headerOptions) {\r
-        for (OcHeaderOption headerOption : headerOptions) {\r
-            if (StringConstants.API_VERSION_KEY == headerOption.getOptionId()) {\r
-                logMessage(TAG + "Server API version in GET response: " +\r
-                        headerOption.getOptionData());\r
-            }\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public boolean onCreateOptionsMenu(Menu menu) {\r
-        getMenuInflater().inflate(R.menu.menu_fridge_client, menu);\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean onOptionsItemSelected(MenuItem item) {\r
-        int id = item.getItemId();\r
-        if (id == R.id.action_settings) {\r
-            return true;\r
-        }\r
-        return super.onOptionsItemSelected(item);\r
-    }\r
-\r
-    @Override\r
-    public void onDestroy() {\r
-        super.onDestroy();\r
-        onStop();\r
-    }\r
-\r
-    @Override\r
-    protected void onStop() {\r
-        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);\r
-        super.onStop();\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples.fridgeclient;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Message;
+import android.support.v4.content.LocalBroadcastManager;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcConnectivityType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcHeaderOption;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.base.OcResource;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import base.iotivity.org.examples.message.IMessageLogger;
+
+/**
+ * FridgeClient
+ * <p/>
+ * FridgeClient is a sample client app which should be started after the fridgeServer is started.
+ * It creates DeviceResource, DoorResource, LightResource and performs a get operation on them.
+ * This implements IMessageLogger to display messages on the screen
+ */
+public class FridgeClient extends Activity implements
+        OcPlatform.OnResourceFoundListener, IMessageLogger {
+    private static String TAG = "FridgeClient: ";
+
+    private MessageReceiver mMessageReceiver = new MessageReceiver();
+    private TextView mEventsTextView;
+    private String mDeviceName;
+    private int mDeviceCode;
+    private List<String> ifaces;
+    private final List<OcResource> resourceList = new LinkedList<OcResource>();
+
+    /**
+     * configure OIC platform and call findResource
+     */
+    private void initOICStack() {
+        PlatformConfig cfg = new PlatformConfig(
+                this,
+                ServiceType.IN_PROC,
+                ModeType.CLIENT,
+                "0.0.0.0", // bind to all available interfaces
+                0,
+                QualityOfService.LOW);
+
+        OcPlatform.Configure(cfg);
+        try {
+            OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "intel.fridge",
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT), this);
+        } catch (OcException e) {
+            logMessage(TAG + " init Error. " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * prints out the appropriate messages depending on the device code
+     *
+     * @param representation representation of the OcResource
+     * @param value          clientDeviceCode
+     */
+    private void getResponse(OcRepresentation representation, int value) {
+        switch (value) {
+            case 0:
+                // Get on device
+                try {
+                    logMessage(TAG + "Name of device: " +
+                            representation.getValue(StringConstants.DEVICE_NAME));
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                break;
+            case 1:
+                // get on fridge light
+                try {
+                    boolean lightOn = representation.getValue(StringConstants.ON);
+                    logMessage(TAG + "The fridge light is " +
+                            (lightOn ? "" : "not " + "on"));
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                break;
+            case 2:
+            case 3:
+                // get on fridge door(s)
+                try {
+                    boolean doorOpen = representation.getValue(StringConstants.OPEN);
+                    logMessage(TAG + "Door is " + (doorOpen ?
+                            "open" : "not open") + " and is on the " +
+                            representation.getValue(StringConstants.SIDE) + " side");
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                break;
+            case 4:
+                // get on fridge random door
+                try {
+                    logMessage("Name of fridge: " +
+                            representation.getValue(StringConstants.DEVICE_NAME));
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                break;
+            default:
+                logMessage("Unexpected State");
+                break;
+        }
+    }
+
+    /**
+     * this method is used to wait for 1 second between calls to different resources.
+     * It is added for better readability
+     */
+    private void doWait() {
+        try {
+            Thread.sleep(StringConstants.WAIT_TIME);
+        } catch (InterruptedException e) {
+            logMessage(TAG + "doWait exception: " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    @Override
+    /**
+     *  callback when a resource is found. This method calls getResponse with the correct code
+     */
+    synchronized public void onResourceFound(OcResource ocResource) {
+        // eventHandler for onGetListener
+        resourceList.add(ocResource);
+        OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() {
+            @Override
+            public void onGetCompleted(List<OcHeaderOption> headerOptionList, OcRepresentation rep) {
+                logMessage(TAG + " Got a response from " + getClientDeviceName());
+                getResponse(rep, getClientDeviceCode());
+            }
+
+            @Override
+            public void onGetFailed(Throwable throwable) {
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+
+        if (ocResource.getUri().equals(StringConstants.RESOURCE_URI)) {
+            logMessage(TAG + "Discovered a device with \nHost: " + ocResource.getHost() +
+                    ", Uri: " + ocResource.getUri());
+        }
+        List<String> lightTypes = new LinkedList<>();
+        lightTypes.add("intel.fridge.light");
+        try {
+            OcResource light = OcPlatform.constructResourceObject(ocResource.getHost(),
+                    StringConstants.LIGHT, EnumSet.of(OcConnectivityType.CT_DEFAULT), false, lightTypes, ifaces);
+
+            List<String> doorTypes = new LinkedList<>();
+            doorTypes.add("intel.fridge.door");
+            OcResource leftDoor = OcPlatform.constructResourceObject(ocResource.getHost(),
+                    StringConstants.LEFT_DOOR, EnumSet.of(OcConnectivityType.CT_DEFAULT), false, doorTypes, ifaces);
+
+            OcResource rightDoor = OcPlatform.constructResourceObject(ocResource.getHost(),
+                    StringConstants.RIGHT_DOOR, EnumSet.of(OcConnectivityType.CT_DEFAULT), false, doorTypes, ifaces);
+
+            OcResource randomDoor = OcPlatform.constructResourceObject(ocResource.getHost(),
+                    StringConstants.RANDOM_DOOR, EnumSet.of(OcConnectivityType.CT_DEFAULT), false, doorTypes, ifaces);
+
+            List<OcHeaderOption> headerOptions = new LinkedList<>();
+            OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY,
+                    StringConstants.API_VERSION);
+            OcHeaderOption clientToken = new OcHeaderOption(StringConstants.CLIENT_TOKEN_KEY,
+                    StringConstants.CLIENT_TOKEN);
+            headerOptions.add(apiVersion);
+            headerOptions.add(clientToken);
+            ocResource.setHeaderOptions(headerOptions);
+            /**
+             *  wait for 1 second before calling get on different resources.
+             *  It is done for better readability.
+             *  doWait() is called before each call to get
+             */
+            doWait();
+
+            setupClientOptions("Device", 0);
+            ocResource.get(new HashMap<String, String>(), onGetListener);
+            doWait();
+
+            setupClientOptions("Fridge Light", 1);
+            light.get(new HashMap<String, String>(), onGetListener);
+            doWait();
+
+            setupClientOptions("Left Door", 2);
+            leftDoor.get(new HashMap<String, String>(), onGetListener);
+            doWait();
+
+            setupClientOptions("Right Door", 3);
+            rightDoor.get(new HashMap<String, String>(), onGetListener);
+            doWait();
+
+            setupClientOptions("Random Door", 4);
+            randomDoor.get(new HashMap<String, String>(), onGetListener);
+            doWait();
+
+            resourceList.add(leftDoor);
+            leftDoor.deleteResource(new OcResource.OnDeleteListener() {
+                @Override
+                public void onDeleteCompleted(List<OcHeaderOption> ocHeaderOptions) {
+                    logMessage(TAG + "Delete resource successful");
+                }
+
+                @Override
+                public void onDeleteFailed(Throwable throwable) {
+                    if (throwable instanceof OcException) {
+                        OcException ocEx = (OcException) throwable;
+                        ErrorCode errCode = ocEx.getErrorCode();
+                        //do something based on errorCode
+                    }
+                    Log.e(TAG, throwable.toString());
+                }
+            });
+        } catch (OcException e) {
+            logMessage(TAG + "onResourceFound Error. " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_fridge_client);
+        registerReceiver(mMessageReceiver, new IntentFilter(StringConstants.INTENT));
+
+        mEventsTextView = new TextView(this);
+        mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
+        LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
+        layout.addView(mEventsTextView, new LinearLayout.LayoutParams
+                (LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f));
+        ifaces = new LinkedList<>();
+        ifaces.add(StringConstants.RESOURCE_INTERFACE);
+        mDeviceCode = -1;
+        mDeviceName = "";
+
+        initOICStack();
+    }
+
+    public class MessageReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String message = intent.getStringExtra(StringConstants.MESSAGE);
+            logMessage(message);
+        }
+    }
+
+    @Override
+    public void logMessage(final String text) {
+        if (StringConstants.ENABLE_PRINTING) {
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    final Message msg = new Message();
+                    msg.obj = text;
+                    mEventsTextView.append("\n");
+                    mEventsTextView.append(text);
+                }
+            });
+            Log.i(TAG, text);
+        }
+    }
+
+
+    private void setupClientOptions(String name, int value) {
+        mDeviceName = name;
+        mDeviceCode = value;
+    }
+
+    private String getClientDeviceName() {
+        return mDeviceName;
+    }
+
+    private int getClientDeviceCode() {
+        return mDeviceCode;
+    }
+
+
+    //method to print the headerOptions received from the server
+    void printHeaderOptions(List<OcHeaderOption> headerOptions) {
+        for (OcHeaderOption headerOption : headerOptions) {
+            if (StringConstants.API_VERSION_KEY == headerOption.getOptionId()) {
+                logMessage(TAG + "Server API version in GET response: " +
+                        headerOption.getOptionData());
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.menu_fridge_client, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int id = item.getItemId();
+        if (id == R.id.action_settings) {
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        onStop();
+    }
+
+    @Override
+    protected void onStop() {
+        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
+        super.onStop();
+    }
+}
index da88e4d..4c2f197 100644 (file)
@@ -1,33 +1,33 @@
-package org.iotivity.base.examples.fridgeclient;\r
-\r
-import org.iotivity.base.OcPlatform;\r
-\r
-/**\r
- * StringConstant contains the fridgeclient specific constant values.  To add another supported\r
- * Resource or Interface type to this app, begin by adding the new strings here, and then\r
- * find the places throughout the app where Resource-specific case switches occur, and add\r
- * the newly-supported type there.\r
- */\r
-public interface StringConstants {\r
-    public static final String RESOURCE_URI = "/device";\r
-    public static final String DEVICE_NAME = "device_name";\r
-    public static final String LIGHT = "/light";\r
-    public static final String LEFT_DOOR = "/door/left";\r
-    public static final String RIGHT_DOOR = "/door/right";\r
-    public static final String RANDOM_DOOR = "/door/random";\r
-    public static final String MESSAGE = "message";\r
-    public static final String API_VERSION = "v.1.2";\r
-    public static final String CLIENT_TOKEN = "AaBbYyZz";\r
-    public static final String ON = "on";\r
-    public static final String OPEN = "open";\r
-    public static final String SIDE = "side";\r
-    public static final String INTENT = "org.iotivity.base.examples.fridgeclient";\r
-    public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE;\r
-\r
-    public static final int WAIT_TIME = 1000;\r
-    public static final int API_VERSION_KEY = 2048;\r
-    public static final int CLIENT_VERSION_KEY = 3000;\r
-\r
-    public static final boolean ENABLE_PRINTING = true; // change to false to disable printing\r
-                                                        // of messages on the console and the screen\r
-}\r
+package org.iotivity.base.examples.fridgeclient;
+
+import org.iotivity.base.OcPlatform;
+
+/**
+ * StringConstant contains the fridgeclient specific constant values.  To add another supported
+ * Resource or Interface type to this app, begin by adding the new strings here, and then
+ * find the places throughout the app where Resource-specific case switches occur, and add
+ * the newly-supported type there.
+ */
+public interface StringConstants {
+    public static final String RESOURCE_URI = "/device";
+    public static final String DEVICE_NAME = "device_name";
+    public static final String LIGHT = "/light";
+    public static final String LEFT_DOOR = "/door/left";
+    public static final String RIGHT_DOOR = "/door/right";
+    public static final String RANDOM_DOOR = "/door/random";
+    public static final String MESSAGE = "message";
+    public static final String API_VERSION = "v.1.2";
+    public static final String CLIENT_TOKEN = "AaBbYyZz";
+    public static final String ON = "on";
+    public static final String OPEN = "open";
+    public static final String SIDE = "side";
+    public static final String INTENT = "org.iotivity.base.examples.fridgeclient";
+    public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE;
+
+    public static final int WAIT_TIME = 1000;
+    public static final int API_VERSION_KEY = 2048;
+    public static final int CLIENT_TOKEN_KEY = 3000;
+
+    public static final boolean ENABLE_PRINTING = true; // change to false to disable printing
+                                                        // of messages on the console and the screen
+}
index cbcffd9..b8c36d7 100755 (executable)
@@ -5,6 +5,17 @@
 \r
     <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
 \r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.BLUETOOTH"/>\r
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>\r
+    <uses-permission android:name="android.permission.INTERNET"/>\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>\r
+\r
     <application\r
         android:allowBackup="true"\r
         android:icon="@drawable/ic_launcher"\r
index fc33258..9868f32 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base.examples.fridgeserver;\r
-\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.util.Log;\r
-\r
-import org.iotivity.base.EntityHandlerResult;\r
-import org.iotivity.base.OcException;\r
-import org.iotivity.base.OcHeaderOption;\r
-import org.iotivity.base.OcPlatform;\r
-import org.iotivity.base.OcResourceRequest;\r
-import org.iotivity.base.OcResourceResponse;\r
-import org.iotivity.base.RequestHandlerFlag;\r
-import org.iotivity.base.ResourceProperty;\r
-\r
-import java.util.EnumSet;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-\r
-import base.iotivity.org.examples.message.IMessageLogger;\r
-\r
-/**\r
- * DeviceResource\r
- * <p/>\r
- * Creates a device resource and performs action based on client requests\r
- */\r
-public class DeviceResource extends Resource implements IMessageLogger {\r
-    private Context mContext;\r
-\r
-    private static String TAG = "DeviceResource: ";\r
-\r
-    /**\r
-     * constructor\r
-     *\r
-     * @param context to enable sending of broadcast messages to be displayed on the user screen\r
-     */\r
-    DeviceResource(Context context) {\r
-        mContext = context;\r
-\r
-        // eventHandler for register deviceResource\r
-        OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() {\r
-            @Override\r
-            public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {\r
-                // this is where the main logic of DeviceResource is handled\r
-                return entityHandler(ocResourceRequest);\r
-            }\r
-        };\r
-\r
-        try {\r
-            logMessage(TAG + "RegisterDeviceResource " + StringConstants.DEVICE_URI + " : " +\r
-                    StringConstants.RESOURCE_TYPENAME + " : " + StringConstants.RESOURCE_INTERFACE);\r
-            mResourceHandle = OcPlatform.registerResource(StringConstants.DEVICE_URI,\r
-                    StringConstants.RESOURCE_TYPENAME, StringConstants.RESOURCE_INTERFACE,\r
-                    eh, EnumSet.of(ResourceProperty.DISCOVERABLE));\r
-        } catch (OcException e) {\r
-            logMessage(TAG + "registerResource error: " + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * update current state of device\r
-     *\r
-     * @return device representation\r
-     */\r
-    private void updateRepresentationValues() {\r
-        try {\r
-            mRepresentation.setValue(StringConstants.DEVICE_NAME,\r
-                    "Intel Powered 2 door, 1 light refrigerator");\r
-        } catch (OcException e) {\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * unregister the resource\r
-     */\r
-    private void deleteDeviceResource() {\r
-        try {\r
-            OcPlatform.unregisterResource(mResourceHandle);\r
-            logMessage(TAG + "Unregister DeviceResource successful");\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * this is the main method which handles different incoming requests appropriately.\r
-     *\r
-     * @param request OcResourceRequest from the client\r
-     * @return EntityHandlerResult depending on whether the request was handled successfully or not\r
-     */\r
-    private EntityHandlerResult entityHandler(OcResourceRequest request) {\r
-        EntityHandlerResult result = EntityHandlerResult.ERROR;\r
-        if (null != request) {\r
-            List<OcHeaderOption> headerOptions = request.getHeaderOptions();\r
-            String clientAPIVersion = "";\r
-            String clientToken = "";\r
-\r
-            // search for header options map and look for API version and client token\r
-            for (OcHeaderOption headerOption : headerOptions) {\r
-                int optionId = headerOption.getOptionId();\r
-                if (StringConstants.API_VERSION_KEY == optionId) {\r
-                    clientAPIVersion = headerOption.getOptionData();\r
-                    logMessage(TAG + " Client API Version: " + clientAPIVersion);\r
-                } else if (StringConstants.CLIENT_VERSION_KEY == optionId) {\r
-                    clientToken = headerOption.getOptionData();\r
-                    logMessage(TAG + " Client Token: " + clientToken);\r
-                }\r
-            }\r
-            if (clientAPIVersion.equals(StringConstants.API_VERSION) &&\r
-                    clientToken.equals(StringConstants.CLIENT_TOKEN)) {\r
-                List<OcHeaderOption> serverHeaderOptions = new LinkedList<>();\r
-                OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY,\r
-                        StringConstants.API_VERSION);\r
-                serverHeaderOptions.add(apiVersion);\r
-                try {\r
-                    if (request.getRequestHandlerFlagSet().contains(RequestHandlerFlag.REQUEST)) {\r
-                        OcResourceResponse response = new OcResourceResponse();\r
-                        response.setRequestHandle(request.getRequestHandle());\r
-                        response.setResourceHandle(request.getResourceHandle());\r
-                        response.setHeaderOptions(serverHeaderOptions);\r
-\r
-                        switch (request.getRequestType()) {\r
-                            case GET:\r
-                                response.setErrorCode(StringConstants.OK);\r
-                                response.setResponseResult(EntityHandlerResult.OK);\r
-                                updateRepresentationValues();\r
-                                response.setResourceRepresentation(mRepresentation);\r
-                                OcPlatform.sendResponse(response);\r
-                                break;\r
-                            case DELETE:\r
-                                deleteDeviceResource();\r
-                                response.setErrorCode(StringConstants.OK);\r
-                                response.setResponseResult(EntityHandlerResult.OK);\r
-                                break;\r
-                            case POST:\r
-                                response.setResponseResult(EntityHandlerResult.ERROR);\r
-                                OcPlatform.sendResponse(response);\r
-                                break;\r
-                        }\r
-                        result = EntityHandlerResult.OK;\r
-                    }\r
-                } catch (OcException e) {\r
-                    logMessage(TAG + e.getMessage());\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    @Override\r
-    public void logMessage(String msg) {\r
-        logMsg(msg);\r
-        if (StringConstants.ENABLE_PRINTING) {\r
-            Log.i(TAG, msg);\r
-        }\r
-    }\r
-\r
-    public void logMsg(final String text) {\r
-        Intent intent = new Intent(StringConstants.INTENT);\r
-        intent.putExtra("message", text);\r
-        mContext.sendBroadcast(intent);\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples.fridgeserver;
+
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import org.iotivity.base.EntityHandlerResult;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcHeaderOption;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcResourceRequest;
+import org.iotivity.base.OcResourceResponse;
+import org.iotivity.base.RequestHandlerFlag;
+import org.iotivity.base.ResourceProperty;
+
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import base.iotivity.org.examples.message.IMessageLogger;
+
+/**
+ * DeviceResource
+ * <p/>
+ * Creates a device resource and performs action based on client requests
+ */
+public class DeviceResource extends Resource implements IMessageLogger {
+    private Context mContext;
+
+    private static String TAG = "DeviceResource: ";
+
+    /**
+     * constructor
+     *
+     * @param context to enable sending of broadcast messages to be displayed on the user screen
+     */
+    DeviceResource(Context context) {
+        mContext = context;
+
+        // eventHandler for register deviceResource
+        OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() {
+            @Override
+            public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {
+                // this is where the main logic of DeviceResource is handled
+                return entityHandler(ocResourceRequest);
+            }
+        };
+
+        try {
+            logMessage(TAG + "RegisterDeviceResource " + StringConstants.DEVICE_URI + " : " +
+                    StringConstants.RESOURCE_TYPENAME + " : " + StringConstants.RESOURCE_INTERFACE);
+            mResourceHandle = OcPlatform.registerResource(StringConstants.DEVICE_URI,
+                    StringConstants.RESOURCE_TYPENAME, StringConstants.RESOURCE_INTERFACE,
+                    eh, EnumSet.of(ResourceProperty.DISCOVERABLE));
+        } catch (OcException e) {
+            logMessage(TAG + "registerResource error: " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * update current state of device
+     *
+     * @return device representation
+     */
+    private void updateRepresentationValues() {
+        try {
+            mRepresentation.setValue(StringConstants.DEVICE_NAME,
+                    "Intel Powered 2 door, 1 light refrigerator");
+        } catch (OcException e) {
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * unregister the resource
+     */
+    private void deleteDeviceResource() {
+        try {
+            OcPlatform.unregisterResource(mResourceHandle);
+            logMessage(TAG + "Unregister DeviceResource successful");
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * this is the main method which handles different incoming requests appropriately.
+     *
+     * @param request OcResourceRequest from the client
+     * @return EntityHandlerResult depending on whether the request was handled successfully or not
+     */
+    private EntityHandlerResult entityHandler(OcResourceRequest request) {
+        EntityHandlerResult result = EntityHandlerResult.ERROR;
+        if (null != request) {
+            List<OcHeaderOption> headerOptions = request.getHeaderOptions();
+            String clientAPIVersion = "";
+            String clientToken = "";
+
+            // search for header options map and look for API version and client token
+            for (OcHeaderOption headerOption : headerOptions) {
+                int optionId = headerOption.getOptionId();
+                if (StringConstants.API_VERSION_KEY == optionId) {
+                    clientAPIVersion = headerOption.getOptionData();
+                    logMessage(TAG + " Client API Version: " + clientAPIVersion);
+                } else if (StringConstants.CLIENT_VERSION_KEY == optionId) {
+                    clientToken = headerOption.getOptionData();
+                    logMessage(TAG + " Client Token: " + clientToken);
+                }
+            }
+
+            if (clientAPIVersion.equals(StringConstants.API_VERSION) &&
+                    clientToken.equals(StringConstants.CLIENT_TOKEN)) {
+                List<OcHeaderOption> serverHeaderOptions = new LinkedList<>();
+                OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY,
+                        StringConstants.API_VERSION);
+                serverHeaderOptions.add(apiVersion);
+                try {
+                    if (request.getRequestHandlerFlagSet().contains(RequestHandlerFlag.REQUEST)) {
+                        OcResourceResponse response = new OcResourceResponse();
+                        response.setRequestHandle(request.getRequestHandle());
+                        response.setResourceHandle(request.getResourceHandle());
+                        response.setHeaderOptions(serverHeaderOptions);
+
+                        switch (request.getRequestType()) {
+                            case GET:
+                                response.setErrorCode(StringConstants.OK);
+                                response.setResponseResult(EntityHandlerResult.OK);
+                                updateRepresentationValues();
+                                response.setResourceRepresentation(mRepresentation);
+                                OcPlatform.sendResponse(response);
+                                break;
+                            case DELETE:
+                                deleteDeviceResource();
+                                response.setErrorCode(StringConstants.OK);
+                                response.setResponseResult(EntityHandlerResult.OK);
+                                break;
+                        }
+                        result = EntityHandlerResult.OK;
+                    }
+                } catch (OcException e) {
+                    logMessage(TAG + e.getMessage());
+                    Log.e(TAG, e.getMessage());
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void logMessage(String msg) {
+        logMsg(msg);
+        if (StringConstants.ENABLE_PRINTING) {
+            Log.i(TAG, msg);
+        }
+    }
+
+    public void logMsg(final String text) {
+        Intent intent = new Intent(StringConstants.INTENT);
+        intent.putExtra("message", text);
+        mContext.sendBroadcast(intent);
+    }
+}
diff --git a/android/examples/guiclient/.gitignore b/android/examples/guiclient/.gitignore
new file mode 100644 (file)
index 0000000..c795b05
--- /dev/null
@@ -0,0 +1 @@
+build
\ No newline at end of file
diff --git a/android/examples/guiclient/build.gradle b/android/examples/guiclient/build.gradle
new file mode 100644 (file)
index 0000000..d1326c9
--- /dev/null
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'\r
+\r
+android {\r
+    compileSdkVersion 21\r
+    buildToolsVersion "21.1.1"\r
+\r
+    defaultConfig {\r
+        applicationId "org.iotivity.guiclient"\r
+        minSdkVersion 19\r
+        targetSdkVersion 21\r
+        versionCode 1\r
+        versionName "1.0"\r
+    }\r
+    buildTypes {\r
+        release {\r
+            minifyEnabled false\r
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\r
+        }\r
+    }\r
+}\r
+\r
+dependencies {\r
+    compile fileTree(dir: 'libs', include: ['*.jar'])\r
+    compile 'com.android.support:appcompat-v7:21.0.2'\r
+}\r
diff --git a/android/examples/guiclient/guiclient.iml b/android/examples/guiclient/guiclient.iml
new file mode 100644 (file)
index 0000000..668427c
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">\r
+  <component name="FacetManager">\r
+    <facet type="android-gradle" name="Android-Gradle">\r
+      <configuration>\r
+        <option name="GRADLE_PROJECT_PATH" value=":guiclient" />\r
+      </configuration>\r
+    </facet>\r
+    <facet type="android" name="Android">\r
+      <configuration>\r
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />\r
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />\r
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />\r
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />\r
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />\r
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />\r
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />\r
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />\r
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />\r
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />\r
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />\r
+      </configuration>\r
+    </facet>\r
+  </component>\r
+  <component name="NewModuleRootManager" inherit-compiler-output="false">\r
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />\r
+    <exclude-output />\r
+    <content url="file://$MODULE_DIR$">\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />\r
+    </content>\r
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />\r
+    <orderEntry type="sourceFolder" forTests="false" />\r
+    <orderEntry type="library" exported="" name="support-annotations-21.0.2" level="project" />\r
+    <orderEntry type="library" exported="" name="support-v4-21.0.2" level="project" />\r
+    <orderEntry type="library" exported="" name="iotivity-armeabi-base-release-unspecified" level="project" />\r
+    <orderEntry type="library" exported="" name="appcompat-v7-21.0.2" level="project" />\r
+  </component>\r
+</module>\r
+\r
@@ -1,11 +1,8 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
 # Add project specific ProGuard rules here.
 # By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
+# in /opt/android-dev/adt-bundle-linux-x86_64-20140702/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
@@ -18,4 +15,3 @@
 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 #   public *;
 #}
-
diff --git a/android/examples/guiclient/src/main/AndroidManifest.xml b/android/examples/guiclient/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..60e7486
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.guiclient"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name"
+            android:screenOrientation="portrait" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/ExpandableResourceListAdapter.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/ExpandableResourceListAdapter.java
new file mode 100644 (file)
index 0000000..000913d
--- /dev/null
@@ -0,0 +1,382 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.content.Context;
+import android.media.Image;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import java.util.List;
+
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE;
+import static org.iotivity.guiclient.OcProtocolStrings.AMBIENT_LIGHT_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.PLATFORM_LED_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.ROOM_TEMPERATURE_RESOURCE_URI;
+
+/**
+ * ExpandableResourceListAdapter knows how to render an ExpandableListView, using a
+ * List of OcResourceInfo objects as the parents of the ExpandableListView,
+ * and OcAttributeInfo objects as the children.
+ *
+ * @see org.iotivity.guiclient.OcAttributeInfo
+ */
+public class ExpandableResourceListAdapter extends BaseExpandableListAdapter {
+    /**
+     * Hardcoded TAG... if project never uses proguard then
+     * MyOcClient.class.getName() is the better way.
+     */
+    private static final String TAG = "ExpandableResourceListAdapter";
+
+    private static final boolean LOCAL_LOGV = true; // set to false to compile out verbose logging
+
+    private List<OcResourceInfo> resourceList;
+    private Context ctx;
+
+    public ExpandableResourceListAdapter(List<OcResourceInfo> resourceList, Context ctx) {
+        this.resourceList = resourceList;
+        this.ctx = ctx;
+    }
+
+    @Override
+    public Object getChild(int groupPosition, int childPosition) {
+        return resourceList.get(groupPosition).getAttributes().get(childPosition);
+    }
+
+    @Override
+    public int getChildrenCount(int groupPosition) {
+        return resourceList.get(groupPosition).getAttributes().size();
+    }
+
+    @Override
+    public long getChildId(int groupPosition, int childPosition) {
+        return resourceList.get(groupPosition).getAttributes().get(childPosition).hashCode();
+    }
+
+    @Override
+    public int getChildType(int groupPosition, int childPosition) {
+        return this.resourceList.get(groupPosition).getAttributes().get(childPosition)
+                .getType().ordinal();
+    }
+
+    @Override
+    public int getChildTypeCount() {
+        return OC_ATTRIBUTE_TYPE.values().length;
+    }
+
+    @Override
+    public View getChildView(final int groupPosition, int childPosition,
+                             boolean isLastChild, View convertView, ViewGroup parent) {
+        View v = convertView;
+        if (v == null) {
+            LayoutInflater inflater = (LayoutInflater)ctx.getSystemService
+                    (Context.LAYOUT_INFLATER_SERVICE);
+            switch(OC_ATTRIBUTE_TYPE.fromInt(getChildType(groupPosition, childPosition))) {
+                case AMBIENT_LIGHT_SENSOR_READING:
+                case ROOM_TEMPERATURE_SENSOR_READING:
+                    v = inflater.inflate(R.layout.attribute_layout_progress_bar, parent, false);
+                    break;
+                case LIGHT_DIMMER:
+                    v = inflater.inflate(R.layout.attribute_layout_slider, parent, false);
+                    break;
+                case LIGHT_SWITCH:
+                case PLATFORM_LED_SWITCH:
+                    v = inflater.inflate(R.layout.attribute_layout_on_off_switch, parent, false);
+                    break;
+            }
+        }
+
+        OcAttributeInfo attribute =
+                resourceList.get(groupPosition).getAttributes().get(childPosition);
+
+        // All attribute icons and names are currently treated the same so we handle them outside
+        // the type-specific inflater functions
+        ImageView attributeIcon = (ImageView) v.findViewById(R.id.attribute_icon_id);
+        attributeIcon.setVisibility(View.VISIBLE);
+        TextView attributeName = (TextView) v.findViewById(R.id.attribute_name_id);
+        attributeName.setText(getAttributeLabelFromType(attribute.getType()));
+        attributeName.setVisibility(View.VISIBLE);
+
+        // Now inflate the rest of the layout in a type-specific way
+        switch(attribute.getType()){
+            case AMBIENT_LIGHT_SENSOR_READING:
+                this.renderAmbientLightSensorReading(v, groupPosition, attribute);
+                break;
+            case LIGHT_DIMMER:
+                this.renderLightDimmer(v, groupPosition, attribute);
+                break;
+            case LIGHT_SWITCH:
+                this.renderLightSwitch(v, groupPosition, attribute);
+                break;
+            case PLATFORM_LED_SWITCH:
+                this.renderPlatformLedSwitch(v, groupPosition, attribute);
+                break;
+            case ROOM_TEMPERATURE_SENSOR_READING:
+                this.renderRoomTemperatureSensorReading(v, groupPosition, attribute);
+                break;
+        }
+
+        return v;
+    }
+
+    @Override
+    public Object getGroup(int groupPosition) {
+        return resourceList.get(groupPosition);
+    }
+
+    @Override
+    public int getGroupCount() {
+        return resourceList.size();
+    }
+
+    @Override
+    public long getGroupId(int groupPosition) {
+        return resourceList.get(groupPosition).hashCode();
+    }
+
+    @Override
+    public View getGroupView(int groupPosition, boolean isExpanded,
+                             View convertView, ViewGroup parent) {
+
+        View v = convertView;
+
+        if (v == null) {
+            LayoutInflater inflater = (LayoutInflater)ctx.getSystemService
+                    (Context.LAYOUT_INFLATER_SERVICE);
+            v = inflater.inflate(R.layout.resource_list_item_layout, parent, false);
+        }
+
+        TextView resourceName = (TextView) v.findViewById(R.id.resource_name_id);
+        TextView resourceDescription = (TextView) v.findViewById(R.id.resource_description_id);
+        ImageView resourceIcon = (ImageView) v.findViewById(R.id.resource_icon_id);
+
+        OcResourceInfo resource = resourceList.get(groupPosition);
+
+        resourceName.setText(this.getResourceLabelFromType(resource.getType()));
+        resourceDescription.setText(resource.getHost()+resource.getUri());
+        switch (resource.getType()) {
+            case AMBIENT_LIGHT_SENSOR:
+                resourceIcon.setImageResource(R.drawable.iotivity_hex_icon);
+                break;
+            case LIGHT:
+                resourceIcon.setImageResource(R.drawable.light_icon);
+                break;
+            case PLATFORM_LED:
+                resourceIcon.setImageResource(R.drawable.led_icon);
+                break;
+            case ROOM_TEMPERATURE_SENSOR:
+                resourceIcon.setImageResource(R.drawable.thermometer_icon);
+                break;
+            default:
+                resourceIcon.setImageResource(R.drawable.iotivity_hex_icon);
+                break;
+        }
+
+        return v;
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    @Override
+    public boolean isChildSelectable(int groupPosition, int childPosition) {
+        return true;
+    }
+
+    /**
+     * Type-specific layout render for Ambient Light Sensor reading attribute.
+     */
+    private void renderAmbientLightSensorReading(final View view,
+                                                  final int groupPosition,
+                                                  final OcAttributeInfo attribute) {
+        // Render attributeValue
+        TextView attributeValue = (TextView) view.findViewById(R.id.attribute_value_id);
+        attributeValue.setText(String.valueOf(attribute.getValueInt()));
+        attributeValue.setVisibility(View.VISIBLE);
+
+        // Render progressBar
+        ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.attribute_progress_bar);
+        progressBar.setMax(100); // display as percent from 0-100
+        progressBar.setProgress(attribute.getValueAsPercentOfMax());
+        progressBar.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * Type-specific layout render for Light Dimmer attribute.
+     */
+    private void renderLightDimmer(final View view,
+                                    final int groupPosition,
+                                    final OcAttributeInfo attribute) {
+        // Render attributeValue
+        TextView attributeValue = (TextView) view.findViewById(R.id.attribute_value_id);
+        attributeValue.setText(String.valueOf(attribute.getValueInt()));
+        attributeValue.setVisibility(View.VISIBLE);
+
+        // Render SeekBar
+        SeekBar slider = (SeekBar) view.findViewById(R.id.attribute_slider);
+        slider.setMax(attribute.getValueMax());
+        slider.setProgress(attribute.getValueInt());
+        slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            private int mSliderVal;
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                if (LOCAL_LOGV) Log.v(TAG, String.format("onProgressChanged(%s)", progress));
+                this.mSliderVal = progress;
+            }
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {}
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+                if (LOCAL_LOGV) Log.v(TAG, "onStopTrackingTouch()");
+                if(ctx instanceof MainActivity) {
+                    // call MainActivity
+                    ((MainActivity) ctx).setLightDimmerLevel(resourceList.get(groupPosition),
+                            this.mSliderVal);
+                }
+            }
+        });
+        slider.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * Type-specific layout render for Light Switch attribute.
+     */
+    private void renderLightSwitch(final View view,
+                                    final int groupPosition,
+                                    final OcAttributeInfo attribute) {
+        // Render attributeValue
+        TextView attributeValue = (TextView) view.findViewById(R.id.attribute_value_id);
+        if(false == attribute.getValueBool()) {
+            attributeValue.setText("off");
+        } else {
+            attributeValue.setText("on");
+        }
+        attributeValue.setVisibility(View.VISIBLE);
+
+        // Render Switch
+        Switch toggleSwitch = (Switch) view.findViewById(R.id.attribute_switch);
+        toggleSwitch.setText(this.ctx.getString(R.string.oc_light_switch_toggle_text));
+        toggleSwitch.setChecked(attribute.getValueBool());
+        toggleSwitch.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (LOCAL_LOGV) Log.v(TAG, String.format("onCheckedChanged(%s)", isChecked));
+                if(ctx instanceof MainActivity) {
+                    // call MainActivity
+                    ((MainActivity) ctx).toggleLightSwitch(resourceList.get(groupPosition),
+                            isChecked);
+                }
+            }
+        });
+        toggleSwitch.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * Type-specific layout render for LED Switch attribute.
+     */
+    private void renderPlatformLedSwitch(final View view,
+                                          final int groupPosition,
+                                          final OcAttributeInfo attribute) {
+        // Render attributeValue
+        TextView attributeValue = (TextView) view.findViewById(R.id.attribute_value_id);
+        if(1 == attribute.getValueInt()) {
+            attributeValue.setText("on");
+        } else {
+            attributeValue.setText("off");
+        }
+        attributeValue.setVisibility(View.VISIBLE);
+
+        // Render Switch
+        Switch toggleSwitch = (Switch) view.findViewById(R.id.attribute_switch);
+        toggleSwitch.setText(this.ctx.getString(R.string.oc_led_switch_toggle_text));
+        toggleSwitch.setChecked(1 == attribute.getValueInt());
+        toggleSwitch.setOnCheckedChangeListener( new Switch.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (LOCAL_LOGV) Log.v(TAG, String.format("onCheckedChanged(%s)", isChecked));
+                if(ctx instanceof MainActivity) {
+                    // call MainActivity
+                    ((MainActivity) ctx).toggleLedSwitch(resourceList.get(groupPosition),
+                            isChecked);
+                }
+            }
+        });
+        toggleSwitch.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * Type-specific layout render for Room Temperature Sensor Reading attribute.
+     */
+    private void renderRoomTemperatureSensorReading(final View view,
+                                                     final int groupPosition,
+                                                     final OcAttributeInfo attribute) {
+        // this happens to have the same behavior as ambient light sensor, so just re-use
+        this.renderAmbientLightSensorReading(view, groupPosition, attribute);
+    }
+
+    private String getAttributeLabelFromType(OC_ATTRIBUTE_TYPE type) {
+        switch (type) {
+            case AMBIENT_LIGHT_SENSOR_READING:
+                return ctx.getString(R.string.ui_attribute_label_ambient_light_sensor_reading);
+            case LIGHT_DIMMER:
+                return ctx.getString(R.string.ui_attribute_label_light_dimmer);
+            case LIGHT_SWITCH:
+                return ctx.getString(R.string.ui_attribute_label_light_switch);
+            case PLATFORM_LED_SWITCH:
+                return ctx.getString(R.string.ui_attribute_label_led_switch);
+            case ROOM_TEMPERATURE_SENSOR_READING:
+                return ctx.getString(R.string.ui_attribute_label_room_temperature_sensor_reading);
+            default:
+                Log.w(TAG, "getAttributeLabelFromType(): unrecognized attribute type.");
+                return "Attribute:";
+        }
+    }
+
+    private String getResourceLabelFromType(OcResourceInfo.OC_RESOURCE_TYPE type) {
+        if (LOCAL_LOGV) Log.v(TAG, "getResourceLabelFromType()");
+
+        switch(type) {
+            case AMBIENT_LIGHT_SENSOR:
+                return ctx.getString(R.string.ui_resource_label_ambient_light_sensor);
+            case LIGHT:
+                return ctx.getString(R.string.ui_resource_label_light);
+            case PLATFORM_LED:
+                return ctx.getString(R.string.ui_resource_label_platform_led);
+            case ROOM_TEMPERATURE_SENSOR:
+                return ctx.getString(R.string.ui_resource_label_room_temperature_sensor);
+            default:
+                Log.w(TAG, "getResourceLabelFromType(): unrecognized resource type.");
+                return "Resource:";
+        }
+    }
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/MainActivity.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/MainActivity.java
new file mode 100644 (file)
index 0000000..a2ebdda
--- /dev/null
@@ -0,0 +1,336 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ExpandableListView;
+import android.widget.ProgressBar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_DIMMER;
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_SWITCH;
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.PLATFORM_LED_SWITCH;
+import static org.iotivity.guiclient.R.id.expandableResourceListView;
+
+/**
+ * MainActivity instantiates a ExpandableListView of type ExpandableResourceListView, and
+ * also creates and starts a OcWorker object to handle the IoTivity specific work.
+ *
+ * @see org.iotivity.guiclient.OcWorker
+ * @see org.iotivity.guiclient.OcWorkerListener
+ * @see org.iotivity.guiclient.ExpandableResourceListAdapter
+ */
+public class MainActivity
+        extends ActionBarActivity
+        implements OcWorkerListener, View.OnClickListener, ExpandableListView.OnChildClickListener {
+    /**
+     * Hardcoded TAG... if project never uses proguard then
+     * MyOcClient.class.getName() is the better way.
+     */
+    private static final String TAG = "MainActivity";
+
+    private static final boolean LOCAL_LOGV = true; // set to false to compile out verbose logging
+
+    /**
+     * The data structure behind the displayed List of resources and attributes.
+     */
+    private List<OcResourceInfo> mResourceList;
+
+    /**
+     * The custom adapter for displaying the ResourceListItem List 
+     */
+    private ExpandableResourceListAdapter mResourceListAdapter;
+
+    /**
+     * The OIC-aware worker class which does all the OIC API interaction
+     * and handles the results, notifying MainActivity whenever an event
+     * requires a UI update.
+     */
+    private OcWorker mOcWorker;
+
+    /**
+     * Preserve a ref to Action Bar Menu for changing progress icon
+     */
+    private Menu optionsMenu;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        if (LOCAL_LOGV) Log.v(TAG, "onCreate()");
+
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_main);
+
+        // start the OcWorker thread and register as a listener
+        if(null == this.mOcWorker) {
+            this.mOcWorker = new OcWorker(this);
+            this.mOcWorker.start(); // configures the OIC platform and wait for further calls
+            this.mOcWorker.registerListener(this);
+        }
+
+        // init the Resource display list
+        if(null == this.mResourceList) {
+            this.mResourceList = new ArrayList<>();
+        }
+
+        // init the ListView Adapter
+        if(null == this.mResourceListAdapter) {
+            this.mResourceListAdapter = new ExpandableResourceListAdapter(this.mResourceList,
+                    this);
+        }
+
+        // init the Expandable List View
+        ExpandableListView exListView =
+                (ExpandableListView) findViewById(expandableResourceListView);
+        exListView.setIndicatorBounds(5, 5);
+        exListView.setIndicatorBounds(0, 20);
+        exListView.setAdapter(this.mResourceListAdapter);
+        exListView.setOnChildClickListener(this);
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        if (LOCAL_LOGV) Log.v(TAG, "onRestoreInstanceState()");
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        if (LOCAL_LOGV) Log.v(TAG, "onSaveInstanceState()");
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (LOCAL_LOGV) Log.v(TAG, "onClick()");
+
+        this.setRefreshActionButtonState(false);
+    }
+
+    @Override
+    public boolean onChildClick(ExpandableListView parent,
+                                View v,
+                                int groupPosition,
+                                int childPosition,
+                                long id) {
+        if (LOCAL_LOGV) Log.v(TAG, "onChildClick()");
+
+        this.mOcWorker.doGetResource(mResourceList.get(groupPosition));
+
+        return false;
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        if (LOCAL_LOGV) Log.v(TAG, "onCreateOptionsMenu()");
+
+        // save a reference for use in controlling refresh icon later
+        this.optionsMenu = menu;
+
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.menu_main, menu);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (LOCAL_LOGV) Log.v(TAG, String.format("onOptionsItemSelected(%s)", item.toString()));
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+
+        // Handle the "settings" icon/text click
+        if (id == R.id.action_settings) {
+            return true;
+        }
+
+        // Handle the "developer test" icon/text click
+        if (id == R.id.action_test) {
+            return true;
+        }
+
+        // Handle the trash can "discard" icon click
+        if (id == R.id.action_discard) {
+            AlertDialog diaBox = confirmDiscard();
+            diaBox.show();
+        }
+
+        // Handle the refresh/progress icon click
+        if (id == R.id.action_refresh) {
+            // show the indeterminate progress bar
+            this.setRefreshActionButtonState(true);
+            // use OcWorker to discover resources
+            this.mOcWorker.doDiscoverResources();
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * Handle a resource changed callback from OcWorker by posting a runnable to our
+     * own UI-safe looper/handler
+     */
+    @Override
+    public void onResourceChanged(final OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "onResourceChanged()");
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // in case we were waiting for a refresh, hide the indeterminate progress bar
+                setRefreshActionButtonState(false);
+
+                mResourceListAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    /**
+     * Handle a new resource found callback from OcWorker by posting a runnable to our
+     * own UI-safe looper/handler
+     */
+    @Override
+    public void onResourceFound(final OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "onResourceFound()");
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // in case we were waiting for a refresh, hide the indeterminate progress bar
+                setRefreshActionButtonState(false);
+
+                // if resource not already in list, add it
+                if(!mResourceList.contains(resourceInfo)) {
+                    mResourceList.add(resourceInfo);
+                }
+
+                mResourceListAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public void toggleLedSwitch(OcResourceInfo resourceInfo, boolean onOff) {
+        if (LOCAL_LOGV) Log.d(TAG, String.format("toggleLedSwitch(%s, %s)",
+                resourceInfo.getHost() + resourceInfo.getUri(), String.valueOf(onOff)));
+
+        // send a msg to OcWorker to put the switch value
+        for(OcAttributeInfo ai : resourceInfo.getAttributes()) {
+            if(ai.getType() == PLATFORM_LED_SWITCH) {
+                if(onOff) {
+                    ai.setValueInt(1);
+                } else {
+                    ai.setValueInt(0);
+                }
+            }
+        }
+        this.mOcWorker.doPutResource(resourceInfo);
+    }
+
+    public void toggleLightSwitch(OcResourceInfo resourceInfo, boolean onOff) {
+        if (LOCAL_LOGV) Log.d(TAG, String.format("toggleLightSwitch(%s, %s)",
+                resourceInfo.getHost() + resourceInfo.getUri(), String.valueOf(onOff)));
+
+        // send a msg to OcWorker to put the switch value
+        for(OcAttributeInfo ai : resourceInfo.getAttributes()) {
+            if(ai.getType() == LIGHT_SWITCH) {
+                ai.setValueBool(onOff);
+            }
+        }
+        this.mOcWorker.doPutResource(resourceInfo);
+    }
+
+    public void setLightDimmerLevel(OcResourceInfo resourceInfo, int value) {
+        if (LOCAL_LOGV) Log.d(TAG, String.format("setLightDimmerLevel(%s, %s)",
+                resourceInfo.getHost() + resourceInfo.getUri(), String.valueOf(value)));
+
+        // send a msg to OcWorker to put the switch value
+        for(OcAttributeInfo ai : resourceInfo.getAttributes()) {
+            if(ai.getType() == LIGHT_DIMMER) {
+                ai.setValueInt(value);
+            }
+        }
+        this.mOcWorker.doPutResource(resourceInfo);
+    }
+
+    /**
+     * Sets the Action Bar icon to "progress" (spinning circle), or returns it to refresh icon
+     *
+     * @param refreshing true sets icon to animated "progress" spinner; false to static
+     *                   refresh icon
+     */
+    private void setRefreshActionButtonState(final boolean refreshing) {
+        if (this.optionsMenu != null) {
+            final MenuItem refreshItem
+         = this.optionsMenu
+                    .findItem(R.id.action_refresh);
+            if (refreshItem != null) {
+                if (refreshing) {
+                    refreshItem.setActionView(R.layout.actionbar_indeterminate_progress);
+                    ProgressBar progressBar =
+                            (ProgressBar) findViewById(R.id.find_resource_progress_bar);
+                    progressBar.setOnClickListener(this);
+
+                } else {
+                    refreshItem.setActionView(null);
+                }
+            }
+        }
+    }
+
+    private AlertDialog confirmDiscard()
+    {
+        if (LOCAL_LOGV) Log.v(TAG, "confirmDiscard()");
+
+        return new AlertDialog.Builder(this)
+                .setTitle("Clear Resource List?")
+                .setIcon(R.drawable.ic_action_discard_dark)
+                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                        // clear OcWorker's list
+                        mOcWorker.doClearResources();
+                        // in case its running, hide the indeterminate progress bar
+                        setRefreshActionButtonState(false);
+                        // clear our local data model list
+                        mResourceList.clear();
+                        mResourceListAdapter.notifyDataSetChanged();
+                        dialog.dismiss();
+                    }
+                })
+
+                .setNegativeButton("No", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        dialog.dismiss();
+                    }
+                })
+
+                .create();
+    }
+
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcAttributeInfo.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcAttributeInfo.java
new file mode 100644 (file)
index 0000000..d3ad18e
--- /dev/null
@@ -0,0 +1,176 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.util.Log;
+
+import java.io.Serializable;
+
+/**
+ * Created by nathanhs on 12/28/15.
+ */
+public class OcAttributeInfo implements Serializable {
+    /**
+     * Hardcoded TAG... if project never uses proguard then
+     * MyOcClient.class.getName() is the better way.
+     */
+    private static final String TAG = "OcAttributeInfo";
+
+    private static final boolean LOCAL_LOGV = true; // set to false to compile out verbose logging
+
+    private static final int AMBIENT_LIGHT_SENSOR_READING_MAX = 4096;
+    private static final int LIGHT_DIMMER_MAX = 100;
+    private static final int LIGHT_SWITCH_MAX = 1;
+    private static final int PLATFORM_LED_SWITCH_MAX = 1;
+    // TODO: once the temp getValueInt works, figure out how to scale this properly
+    private static final int ROOM_TEMPERATURE_SENSOR_READING_MAX = 4096;
+
+    /**
+     * These are the resource types supported by OcResourceInfo.
+     */
+    public enum OC_ATTRIBUTE_TYPE {
+        AMBIENT_LIGHT_SENSOR_READING,
+        LIGHT_DIMMER,
+        LIGHT_SWITCH,
+        PLATFORM_LED_SWITCH,
+        ROOM_TEMPERATURE_SENSOR_READING;
+
+        private static final OC_ATTRIBUTE_TYPE[] values = OC_ATTRIBUTE_TYPE.values();
+
+        public static OC_ATTRIBUTE_TYPE fromInt(int i) {
+            return values[i];
+        }
+    }
+
+    private boolean mCurrentlyObserved;
+    private final int mId;
+    private static int mIdInitializer = 0;
+    private final boolean mObservable = true; //TODO BROKEN fix when implementing observe
+    private final OcResourceInfo mParentResource;
+    private final boolean mReadOnly;
+    private final OC_ATTRIBUTE_TYPE mType;
+    private boolean mValueBool; // used if attribute has a boolean value
+    private int mValueInt; // used if attribute has an int value
+    private String mValueString; // used if attribute has a String value
+    private final int mValueMax;
+
+    public OcAttributeInfo(OC_ATTRIBUTE_TYPE type, OcResourceInfo parent) {
+        if (LOCAL_LOGV) Log.v(TAG, "OcAttributeInfo() constructor");
+
+        this.mId = OcAttributeInfo.mIdInitializer++; // give a unique Id from other OcResourceInfos
+        this.mParentResource = parent;
+        this.mReadOnly = this.getReadOnlyBasedOnType(type);
+        this.mType = type;
+        this.mValueBool = false;
+        this.mValueInt = 0;
+        this.mValueString = "error";
+        this.mValueMax = this.getMaxAttributeValueBasedOnType(type);
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public OC_ATTRIBUTE_TYPE getType() {
+        return mType;
+    }
+
+    public boolean getValueBool() {
+        return this.mValueBool;
+    }
+
+    public int getValueInt() {
+        return this.mValueInt;
+    }
+
+    public int getValueMax() {
+        return mValueMax;
+    }
+
+    public String getValueString() {
+        return this.mValueString;
+    }
+
+    public int getValueAsPercentOfMax() {
+        return (this.mValueInt*100)/this.mValueMax;
+    }
+
+    public boolean isCurrentlyObserved() {
+        return this.mCurrentlyObserved;
+    }
+
+    public boolean isObservable() {
+        return this.mObservable;
+    }
+
+    public boolean isReadOnly() {
+        return mReadOnly;
+    }
+
+    public void setCurrentlyObserved(boolean currentlyObserved) {
+        this.mCurrentlyObserved = currentlyObserved;
+    }
+
+    public void setValueBool(boolean value) {
+        this.mValueBool = value;
+    }
+
+    public void setValueInt(int value) {
+        this.mValueInt = value;
+    }
+
+    public void setValueString(String value) {
+        this.mValueString = value;
+    }
+
+    private int getMaxAttributeValueBasedOnType(OC_ATTRIBUTE_TYPE type) {
+        switch(type) {
+            case AMBIENT_LIGHT_SENSOR_READING:
+                return AMBIENT_LIGHT_SENSOR_READING_MAX;
+            case LIGHT_DIMMER:
+                return LIGHT_DIMMER_MAX;
+            case LIGHT_SWITCH:
+                return LIGHT_SWITCH_MAX;
+            case PLATFORM_LED_SWITCH:
+                return PLATFORM_LED_SWITCH_MAX;
+            case ROOM_TEMPERATURE_SENSOR_READING:
+                return ROOM_TEMPERATURE_SENSOR_READING_MAX;
+            default:
+                Log.w(TAG, "getMaxAttributeValueBasedOnType(): unrecognized attribute type.");
+                return 0;
+        }
+    }
+
+    private boolean getReadOnlyBasedOnType(OC_ATTRIBUTE_TYPE type) {
+        switch(type) {
+            case AMBIENT_LIGHT_SENSOR_READING:
+            case ROOM_TEMPERATURE_SENSOR_READING:
+                return true;
+            case LIGHT_DIMMER:
+            case LIGHT_SWITCH:
+            case PLATFORM_LED_SWITCH:
+                return false;
+            default:
+                Log.w(TAG, "getReadOnlyBasedOnType(): unrecognized attribute type.");
+                return false;
+        }
+    }
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcProtocolStrings.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcProtocolStrings.java
new file mode 100644 (file)
index 0000000..5afc2f7
--- /dev/null
@@ -0,0 +1,50 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+/**
+ * OcProtocolStrings contains the IoTivity-specific constant values.  To add another supported
+ * Resource or Interface type to this app, begin by adding the new strings here, and then
+ * find the places throughout the app where Resource-specific case switches occur, and add
+ * the newly-supported type there.
+ */
+public interface OcProtocolStrings {
+    // OIC core protocol strings
+    public static final String COAP_CORE = "coap://224.0.1.187/oic/res";
+    public static final String RESOURCE_TYPE_QUERY = "?rt=";
+    public static final String INTERFACE_QUERY = "?if=";
+    // find resource queries
+    public static final String CORE_LIGHT = "core.light";
+    public static final String CORE_EDISON_RESOURCES = "core.edison.resources";
+    // resource URIs
+    public static final String LIGHT_RESOURCE_URI = "/a/light";
+    public static final String LIGHT_RESOURCE_URI2 = "/light0";
+    public static final String LIGHT_RESOURCE_URI3 = "/a/light1";
+    public static final String ROOM_TEMPERATURE_RESOURCE_URI = "/temperature";
+    public static final String AMBIENT_LIGHT_RESOURCE_URI = "/ambientlight";
+    public static final String PLATFORM_LED_RESOURCE_URI = "/led";
+    // attribute keys for set() calls
+    public static final String LIGHT_SWITCH_RESOURCE_KEY = "state";
+    public static final String LIGHT_DIMMER_RESOURCE_KEY = "power";
+    public static final String ROOM_TEMPERATURE_RESOURCE_KEY = "temperature";
+    public static final String AMBIENT_LIGHT_RESOURCE_KEY = "ambientlight";
+    public static final String PLATFORM_LED_RESOURCE_KEY = "switch";
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcResourceInfo.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcResourceInfo.java
new file mode 100644 (file)
index 0000000..c603e2f
--- /dev/null
@@ -0,0 +1,375 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.util.Log;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcHeaderOption;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.base.OcResource;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.AMBIENT_LIGHT_SENSOR_READING;
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_DIMMER;
+import static org.iotivity.guiclient.OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_SWITCH;
+import static org.iotivity.guiclient.OcProtocolStrings.AMBIENT_LIGHT_RESOURCE_KEY;
+import static org.iotivity.guiclient.OcProtocolStrings.AMBIENT_LIGHT_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_DIMMER_RESOURCE_KEY;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_RESOURCE_URI2;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_RESOURCE_URI3;
+import static org.iotivity.guiclient.OcProtocolStrings.LIGHT_SWITCH_RESOURCE_KEY;
+import static org.iotivity.guiclient.OcProtocolStrings.PLATFORM_LED_RESOURCE_KEY;
+import static org.iotivity.guiclient.OcProtocolStrings.PLATFORM_LED_RESOURCE_URI;
+import static org.iotivity.guiclient.OcProtocolStrings.ROOM_TEMPERATURE_RESOURCE_URI;
+
+/**
+ * OcResourceInfo is a wrapper object for the OcResource object. It implements the Resource-
+ * specific callbacks, and abstracts the IoTivity implementation details from the application.
+ *
+ * In order to use OcResourceInfo, an application should implement the OcResourceInfoListener
+ * interface, which is called when the OcResourceInfo changes in any meaningful way.
+ */
+public class OcResourceInfo
+        implements OcResource.OnGetListener, OcResource.OnPutListener, Serializable {
+    /**
+     * Hardcoded TAG... if project never uses proguard then
+     * MyOcClient.class.getName() is the better way.
+     */
+    private static final String TAG = "OcResourceInfo";
+
+    private static final boolean LOCAL_LOGV = true; // set to false to compile out verbose logging
+
+    /**
+     * These are the resource types supported by OcResourceInfo.  They should have corresponding
+     * URI strings in the OcProtocolStrings interface.
+     */
+    public enum OC_RESOURCE_TYPE {
+        AMBIENT_LIGHT_SENSOR,
+        LIGHT,
+        PLATFORM_LED,
+        ROOM_TEMPERATURE_SENSOR;
+
+        private static final OC_RESOURCE_TYPE[] values = OC_RESOURCE_TYPE.values();
+
+        public static OC_RESOURCE_TYPE fromInt(int i) {
+            return values[i];
+        }
+    }
+
+    private List<OcAttributeInfo> mAttributes;
+    private final String mHost;
+    private final int mId;
+    private static int mIdInitializer = 0;
+    private List<OcResourceInfoListener> mListeners;
+    private final OcResource mResource;
+    private final OC_RESOURCE_TYPE mType;
+    private final String mUri;
+
+    public interface OcResourceInfoListener {
+        public void onResourceInfoChanged(OcResourceInfo resourceInfo);
+    }
+
+
+    public OcResourceInfo(OcResource resource, OcResourceInfoListener changeListener) {
+        if (LOCAL_LOGV) Log.v(TAG, "OcResourceInfo() constructor");
+
+        this.mAttributes = new ArrayList<>();
+        this.mHost = resource.getHost();
+        this.mId = OcResourceInfo.mIdInitializer++; // give a unique Id from other OcResourceInfos
+        this.mListeners = new ArrayList<>();
+        this.mListeners.add(changeListener);
+        this.mResource = resource;
+        this.mType = this.getResourceTypeFromUri(resource.getUri());
+        this.mUri = resource.getUri();
+
+    }
+
+    public void registerListener(OcResourceInfoListener changeListener) {
+        if(null == this.mListeners) {
+            Log.e(TAG, "registerListener(): null mListeners List");
+        } else {
+            boolean alreadyRegistered = false;
+            for(OcResourceInfoListener rl : this.mListeners) {
+                if(changeListener == rl) {
+                    alreadyRegistered = true;
+                }
+            }
+            if(!alreadyRegistered) {
+                this.mListeners.add(changeListener);
+            }
+        }
+    }
+
+    public OC_RESOURCE_TYPE getType() {
+        return this.mType;
+    }
+
+    public String getHost() {
+        return this.mHost;
+    }
+
+    public String getUri() {
+        return this.mUri;
+    }
+
+    @Override
+    public void onGetFailed(Throwable throwable) {
+        if (throwable instanceof OcException) {
+            OcException ocEx = (OcException) throwable;
+            ErrorCode errCode = ocEx.getErrorCode();
+            //do something based on errorCode
+        }
+        Log.e(TAG, throwable.toString());
+    }
+
+    @Override
+    public void onPutFailed(Throwable throwable) {
+        if (throwable instanceof OcException) {
+            OcException ocEx = (OcException) throwable;
+            ErrorCode errCode = ocEx.getErrorCode();
+            //do something based on errorCode
+        }
+        Log.e(TAG, throwable.toString());
+    }
+
+    public List<OcAttributeInfo> getAttributes() {
+        return this.mAttributes;
+    }
+
+    public void doOcGet() {
+        if(null != this.mResource) {
+            try {
+                this.mResource.get(new HashMap<String, String>(), this);
+            } catch (OcException e) {
+                e.printStackTrace();
+                Log.e(TAG, e.getMessage());
+            }
+        } else {
+            Log.e(TAG, "doOcGet(): null mResource");
+        }
+    }
+
+    public void doOcPut(OcAttributeInfo attribute) {
+        if (LOCAL_LOGV) Log.v(TAG, "doOcPut()");
+
+        if(attribute.isReadOnly()) {
+            Log.w(TAG, String.format("doOcPut(): %s attribute is read only; skipping put!",
+                    attribute.getType()));
+        } else {
+            if (null != this.mResource) {
+                try {
+                    OcRepresentation representation = new OcRepresentation();
+                    switch (attribute.getType()) {
+                        case AMBIENT_LIGHT_SENSOR_READING:
+                            break;
+                        case LIGHT_DIMMER:
+                            representation.setValueInt(LIGHT_DIMMER_RESOURCE_KEY,
+                                    attribute.getValueInt());
+                            // This 'sw' logic is here because the current IoTivity Light forces
+                            // the switch to "false" if the switch val is not specified.
+                            boolean sw = true;
+                            for(OcAttributeInfo ai : this.mAttributes) {
+                                if(ai.getType() == LIGHT_SWITCH) {
+                                    sw = ai.getValueBool();
+                                }
+                            }
+                            representation.setValueBool(LIGHT_SWITCH_RESOURCE_KEY, sw);
+                            break;
+                        case LIGHT_SWITCH:
+                            representation.setValueBool(LIGHT_SWITCH_RESOURCE_KEY,
+                                    attribute.getValueBool());
+                            break;
+                        case PLATFORM_LED_SWITCH:
+                            representation.setValueInt(PLATFORM_LED_RESOURCE_KEY,
+                                    attribute.getValueInt());
+                            break;
+                        case ROOM_TEMPERATURE_SENSOR_READING:
+                            break;
+                        default:
+                            break;
+                    }
+                    this.mResource.put(representation, new HashMap<String, String>(), this);
+                } catch (OcException e) {
+                    e.printStackTrace();
+                    Log.e(TAG, e.getMessage());
+                }
+            } else {
+                Log.e(TAG, "doOcGet(): null mResource");
+            }
+        }
+    }
+
+    private static Object onGetCompletedLock = new Object();
+    @Override
+//    public void onGetCompleted(HeaderOptions headerOptions, OcRepresentation ocRepresentation) {
+    public void onGetCompleted(List<OcHeaderOption> headerOptionList,
+                               OcRepresentation ocRepresentation) {
+        synchronized (onGetCompletedLock) {
+            if (LOCAL_LOGV) Log.v(TAG, "enter -> onGetCompleted()");
+            if (LOCAL_LOGV) Log.v(TAG, String.format("\tthis = %s", this.toString()));
+            if (LOCAL_LOGV) Log.v(TAG, String.format("\tthis.mType = %s", this.mType));
+
+            this.mAttributes.clear();
+            switch(this.mType) {
+                case AMBIENT_LIGHT_SENSOR:
+                    int ambientLightVal = ocRepresentation.getValueInt(AMBIENT_LIGHT_RESOURCE_KEY);
+                    if (LOCAL_LOGV) Log.v(TAG,
+                            String.format("%s int value of %s attribute = %d",
+                                    mType, AMBIENT_LIGHT_RESOURCE_KEY, ambientLightVal));
+                    OcAttributeInfo ambientAttribute = new OcAttributeInfo(
+                            AMBIENT_LIGHT_SENSOR_READING, this);
+                    ambientAttribute.setValueInt(ambientLightVal);
+                    this.mAttributes.add(ambientAttribute);
+                    break;
+                case LIGHT:
+                    // do switch first
+                    boolean lightSwitchVal = ocRepresentation.getValueBool(LIGHT_SWITCH_RESOURCE_KEY);
+                    OcAttributeInfo lightSwitchAttribute = new OcAttributeInfo(
+                            LIGHT_SWITCH, this);
+                    lightSwitchAttribute.setValueBool(lightSwitchVal);
+                    this.mAttributes.add(lightSwitchAttribute);
+                    // then dimmer
+                    int dimmerVal = ocRepresentation.getValueInt(LIGHT_DIMMER_RESOURCE_KEY);
+                    OcAttributeInfo dimmerAttribute = new OcAttributeInfo(
+                            LIGHT_DIMMER, this);
+                    dimmerAttribute.setValueInt(dimmerVal);
+                    this.mAttributes.add(dimmerAttribute);
+                    break;
+                case PLATFORM_LED:
+                    int ledVal = ocRepresentation.getValueInt(PLATFORM_LED_RESOURCE_KEY);
+                    if (LOCAL_LOGV) Log.v(TAG,
+                            String.format("%s int value of %s attribute = %d",
+                                    mType, PLATFORM_LED_RESOURCE_KEY, ledVal));
+                    OcAttributeInfo ledAttribute = new OcAttributeInfo(
+                            OcAttributeInfo.OC_ATTRIBUTE_TYPE.PLATFORM_LED_SWITCH, this);
+                    ledAttribute.setValueInt(ledVal);
+                    this.mAttributes.add(ledAttribute);
+                    break;
+                case ROOM_TEMPERATURE_SENSOR:
+                    int temperatureVal = 98;
+                    Log.w(TAG, "getting 'temperature' value is causing crash;" +
+                            " skipping and using 98.");
+                    // TODO This call crashes in the native JNI code.  The example .cpp
+                    //      app receives a double for the Room Temp key, but the Java API
+                    //      doesn't support getValueDouble yet.
+                    //      Debug crash when API fixed?
+//                    temperatureVal = ocRepresentation.getValueInt(ROOM_TEMPERATURE_RESOURCE_KEY);
+                    if (LOCAL_LOGV) Log.v(TAG,
+                            String.format("%s int value of 'temperature' attribute = %d",
+                                    mType, temperatureVal));
+                    OcAttributeInfo temperatureAttribute = new OcAttributeInfo(
+                            OcAttributeInfo.OC_ATTRIBUTE_TYPE.ROOM_TEMPERATURE_SENSOR_READING,
+                            this);
+                    temperatureAttribute.setValueInt(temperatureVal);
+                    this.mAttributes.add(temperatureAttribute);
+                    break;
+            }
+            this.notifyListeners();
+            if (LOCAL_LOGV) Log.v(TAG, "exit <- onGetCompleted()");
+        }
+    }
+
+    /**
+     * Should be called whenever any Resource or Attribute values change on this object.
+     */
+    private void notifyListeners() {
+        if (LOCAL_LOGV) Log.v(TAG, "notifyListeners()");
+
+        for(OcResourceInfoListener l : this.mListeners) {
+            l.onResourceInfoChanged(this);
+        }
+    }
+
+    private Object onPutCompletedLock = new Object();
+    @Override
+    public void onPutCompleted(List<OcHeaderOption> headerOptionList,
+                               OcRepresentation ocRepresentation) {
+        synchronized (onPutCompletedLock) {
+            if (LOCAL_LOGV) Log.v(TAG, "enter -> onPutCompleted()");
+            if (LOCAL_LOGV) Log.v(TAG, String.format("\tthis = %s", this.toString()));
+            if (LOCAL_LOGV) Log.v(TAG, String.format("\tthis.mType = %s", this.mType));
+
+            switch(this.mType) {
+                case AMBIENT_LIGHT_SENSOR:
+                    Log.w(TAG, String.format("onPutCompleted(): %s is a readonly attribute type.",
+                            this.mType));
+                    break;
+                case LIGHT:
+                    // do switch first
+                    boolean lightSwitchVal = ocRepresentation.getValueBool(LIGHT_SWITCH_RESOURCE_KEY);
+                    for(OcAttributeInfo ai : this.mAttributes) {
+                        if (ai.getType() == OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_SWITCH) {
+                            ai.setValueBool(lightSwitchVal);
+                        }
+                    }
+                    // then dimmer
+                    int dimmerVal = ocRepresentation.getValueInt(LIGHT_DIMMER_RESOURCE_KEY);
+                    for(OcAttributeInfo ai : this.mAttributes) {
+                        if (ai.getType() == OcAttributeInfo.OC_ATTRIBUTE_TYPE.LIGHT_DIMMER) {
+                            ai.setValueInt(dimmerVal);
+                        }
+                    }
+                    break;
+                case PLATFORM_LED:
+                    int value = ocRepresentation.getValueInt(PLATFORM_LED_RESOURCE_KEY);
+                    for(OcAttributeInfo ai : this.mAttributes) {
+                        if (ai.getType() == OcAttributeInfo.OC_ATTRIBUTE_TYPE.PLATFORM_LED_SWITCH) {
+                            ai.setValueInt(value);
+                        }
+                    }
+                    break;
+                case ROOM_TEMPERATURE_SENSOR:
+                    Log.w(TAG, String.format("onPutCompleted(): %s is a readonly attribute type.",
+                            this.mType));
+                    break;
+            }
+            this.notifyListeners();
+            if (LOCAL_LOGV) Log.v(TAG, "exit <- onPutCompleted()");
+        }
+    }
+
+    private OC_RESOURCE_TYPE getResourceTypeFromUri(String uri) {
+        if (LOCAL_LOGV) Log.v(TAG, "getResourceTypeFromUri()");
+
+        switch(uri) {
+            case LIGHT_RESOURCE_URI:
+            case LIGHT_RESOURCE_URI2:
+            case LIGHT_RESOURCE_URI3:
+                return OC_RESOURCE_TYPE.LIGHT;
+            case AMBIENT_LIGHT_RESOURCE_URI:
+                return OC_RESOURCE_TYPE.AMBIENT_LIGHT_SENSOR;
+            case PLATFORM_LED_RESOURCE_URI:
+                return OC_RESOURCE_TYPE.PLATFORM_LED;
+            case ROOM_TEMPERATURE_RESOURCE_URI:
+                return OC_RESOURCE_TYPE.ROOM_TEMPERATURE_SENSOR;
+            default:
+                Log.w(TAG, "getResourceTypeFromUri(): unsupported resource '" + uri + "'" );
+        }
+        return null;
+    }
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorker.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorker.java
new file mode 100644 (file)
index 0000000..cb049a6
--- /dev/null
@@ -0,0 +1,524 @@
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcConnectivityType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcResource;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.iotivity.guiclient.OcProtocolStrings.COAP_CORE;
+import static org.iotivity.guiclient.OcProtocolStrings.CORE_EDISON_RESOURCES;
+import static org.iotivity.guiclient.OcProtocolStrings.CORE_LIGHT;
+import static org.iotivity.guiclient.OcProtocolStrings.INTERFACE_QUERY;
+import static org.iotivity.guiclient.OcProtocolStrings.RESOURCE_TYPE_QUERY;
+import static org.iotivity.guiclient.OcWorker.OCW_IN_MSG.DO_CLEAR_RESOURCES;
+import static org.iotivity.guiclient.OcWorker.OCW_IN_MSG.DO_DISCOVER_RESOURCES;
+import static org.iotivity.guiclient.OcWorker.OCW_IN_MSG.DO_GET_RESOURCE;
+import static org.iotivity.guiclient.OcWorker.OCW_IN_MSG.DO_PUT_RESOURCE;
+import static org.iotivity.guiclient.OcWorker.OCW_IN_MSG.fromInt;
+
+/**
+ * OcWorker
+ *
+ * A class designed to encapsulate the OIC API functionality.  OcWorker has its own
+ * thread which is used to call all OIC APIs.  To get results back from OcWorker,
+ * implement the interface OcWorkerListener, and call registerListener().
+ *
+ * @see org.iotivity.guiclient.OcWorkerListener
+ *
+ * Created by nathanhs on 12/22/15.
+ */
+public class OcWorker extends Thread
+        implements OcPlatform.OnResourceFoundListener, OcResourceInfo.OcResourceInfoListener  {
+    /**
+     * Hardcoded TAG... if project never uses proguard then
+     * MyOcClient.class.getName() is the better way.
+     */
+    private static final String TAG = "OcWorker";
+    private Context mContext;
+
+    private static final boolean LOCAL_LOGV = true; // set to false to compile out verbose logging
+
+    /**
+     * NOTE: DO NOT assign non-default values to these enums!
+     * The correctness of "fromInt()" depends on the enum values not being
+     * overridden.  For example DO_TEST = 100, RESULT_TEST = 101.. would BREAK the
+     * fromInt() function.  There are designs which can account for arbitrary enum
+     * values, but they are less desirable for other reasons and since we do not
+     * need to use any specific value, this design is the best for this case.
+     */
+
+    /**
+     * These "IN" message types are for posting API-generated request actions
+     * to our OcWorker queue.
+     */
+    public enum OCW_IN_MSG {
+        DO_TEST,  // developer testing only
+        DO_DISCOVER_RESOURCES,
+        DO_CLEAR_RESOURCES,
+        DO_GET_RESOURCE,
+        DO_PUT_RESOURCE,
+        DO_OBSERVE_RESOURCE,
+        DO_STOP_OBSERVING_RESOURCE;
+
+        private static final OCW_IN_MSG[] values = values();
+
+        public static OCW_IN_MSG fromInt(int i) {
+            return values[i];
+        }
+    }
+
+    /**
+     * These events are for internally putting work on our thread's looper
+     * queue, usually in a callback where we don't want to do work on the
+     * callback thread.
+     */
+    private enum OC_EVENT {
+        OIC_RESOURCE_FOUND,
+        OIC_RESOURCE_CHANGED;
+
+        private static final OC_EVENT[] values = OC_EVENT.values();
+
+        public static OC_EVENT fromInt(int i) {
+            return values[i];
+        }
+    }
+
+    private Handler mDoMsgHandler;
+
+    private Handler mOcEventHandler;
+
+    /**
+     * The OcResourceInfo List
+     */
+    private ArrayList<OcResourceInfo> mOcResourceInfoList;
+
+    /**
+     * The types of OIC Resources included in "FindResource" calls by this object.
+     */
+    private final String[] mOcFindQueries = {
+            COAP_CORE + RESOURCE_TYPE_QUERY + CORE_LIGHT,
+            COAP_CORE + INTERFACE_QUERY + CORE_EDISON_RESOURCES
+    };
+
+    private List<OcWorkerListener> mListeners;
+
+    public OcWorker(Context context) {
+        if (LOCAL_LOGV) Log.v(TAG, "OcWorker() constructor");
+
+        mContext = context;
+        this.mListeners = new ArrayList<>();
+    }
+
+    /**
+     * Set up our Handler and Looper, then initialize the OIC platform and
+     * start processing messages as they arrive.
+     */
+    public void run() {
+        if (LOCAL_LOGV) Log.v(TAG, "run()");
+
+        Looper.prepare();
+        this.initHandlers(); // set up our message handler
+        this.ocInit(); // init the OIC layer including calling ConfigurePlatform
+        Looper.loop();
+    }
+
+    /**
+     * Registers a listener for OcWorker events.
+     *
+     * @see org.iotivity.guiclient.OcWorkerListener
+     */
+    public void registerListener(OcWorkerListener listener) {
+        if (LOCAL_LOGV) Log.v(TAG, "registerListener()");
+
+        if(null != this.mListeners) {
+            this.mListeners.add(listener);
+        } else {
+            Log.e(TAG, "registerListener(): null mListeners list; not adding listener!");
+            Log.e(TAG, "OcWorker.run() must be called before using public methods.");
+        }
+    }
+
+    /**
+     * The Resource discovery external API
+     */
+    public void doDiscoverResources() {
+        if (LOCAL_LOGV) Log.v(TAG, "doDiscoverResources()");
+
+        if(null != this.mDoMsgHandler) {
+            this.mDoMsgHandler.obtainMessage(
+                    DO_DISCOVER_RESOURCES.ordinal()).sendToTarget();
+        } else {
+            Log.e(TAG, "doDiscoverResources(): null mDoMsgHandler; not discovering resources!");
+            Log.e(TAG, "OcWorker.run() must be called before using public methods.");
+        }
+    }
+
+    /**
+     * The GetResource external API
+     */
+    public void doGetResource(OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "doGetResource()");
+
+        if(null != this.mDoMsgHandler) {
+            this.mDoMsgHandler.obtainMessage(
+                    DO_GET_RESOURCE.ordinal(), resourceInfo).sendToTarget();
+        } else {
+            Log.e(TAG, "doPutResource(): null mDoMsgHandler; not putting resource!");
+            Log.e(TAG, "OcWorker.run() must be called before using public methods.");
+        }
+    }
+
+    /**
+     * The PutResource external API
+     */
+    public void doPutResource(OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "doPutResource()");
+
+        if(null != this.mDoMsgHandler) {
+            this.mDoMsgHandler.obtainMessage(
+                    DO_PUT_RESOURCE.ordinal(), resourceInfo).sendToTarget();
+        } else {
+            Log.e(TAG, "doPutResource(): null mDoMsgHandler; not putting resource!");
+            Log.e(TAG, "OcWorker.run() must be called before using public methods.");
+        }
+    }
+
+    /**
+     * The Clear Resources external API
+     */
+    public void doClearResources() {
+        if (LOCAL_LOGV) Log.v(TAG, "doClearResources()");
+
+        if(null != this.mDoMsgHandler) {
+            this.mDoMsgHandler.obtainMessage(
+                    DO_CLEAR_RESOURCES.ordinal()).sendToTarget();
+        } else {
+            Log.e(TAG, "doClearResources(): null mDoMsgHandler; not clearing resources!");
+            Log.e(TAG, "OcWorker.run() must be called before using public methods.");
+        }
+    }
+
+    /**
+     * Set up handlers
+     */
+    private void initHandlers() {
+        if (LOCAL_LOGV) Log.v(TAG, "initHandler()");
+
+        this.mDoMsgHandler = new Handler() {
+            public void handleMessage(Message msg) {
+                Log.d(TAG, String.format("mDoMsgHandler.handleMessage(%s)", msg.toString()));
+                // process incoming messages here
+                OCW_IN_MSG type = fromInt(msg.what);
+                switch(type) {
+                    case DO_TEST:
+                        break;
+                    case DO_DISCOVER_RESOURCES:
+                        discoverResources();
+                        break;
+                    case DO_CLEAR_RESOURCES:
+                        clearResourceInfoList();
+                        break;
+                    case DO_GET_RESOURCE:
+                        getResourceAttributes((OcResourceInfo)msg.obj);
+                        break;
+                    case DO_PUT_RESOURCE:
+                        putResourceAttributes((OcResourceInfo)msg.obj);
+                        break;
+                    case DO_OBSERVE_RESOURCE:
+                        break;
+                    case DO_STOP_OBSERVING_RESOURCE:
+                        break;
+                    default:
+                        Log.e(TAG, "unknown msg.what in handler");
+                        break;
+                }
+            }
+        };
+
+        this.mOcEventHandler = new Handler() {
+            public void handleMessage(Message msg) {
+                Log.d(TAG, String.format("mOcEventHandler.handleMessage(%s)", msg.toString()));
+                // process incoming messages here
+                OC_EVENT type = OC_EVENT.fromInt(msg.what);
+                switch(type) {
+                    case OIC_RESOURCE_FOUND:
+                        handleNewResourceFound((OcResource)msg.obj);
+                        break;
+                    case OIC_RESOURCE_CHANGED:
+                        handleResourceInfoChange((OcResourceInfo)msg.obj);
+                        break;
+                }
+            }
+        };
+    }
+
+    /**
+     * Get the attributes on resourceInfo.
+     *
+     * @param resourceInfo
+     */
+    private void getResourceAttributes(OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "getResourceAttributes()");
+
+        // find the matching resource in our resourceList
+        OcResourceInfo existingResource = this.selectResourceInfoByHostAndUri(
+                resourceInfo.getHost() + resourceInfo.getUri());
+        if(null != existingResource) {
+            existingResource.doOcGet();
+        } else {
+            Log.e(TAG, "getResourceAttributes(): could not find target resource.");
+        }
+        // Done.  Later, the onGet listener in the OcResourceInfo object will notify us of a change
+        // via our onResourceChanged() method
+    }
+
+    /**
+     * For each attribute in the resourceInfo.mAttributes, put the attribute value to the
+     * Resource.
+     *
+     * @param resourceInfo
+     */
+    private void putResourceAttributes(OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "putResourceAttributes()");
+
+        // find the matching resource in our resourceList
+        OcResourceInfo existingResource = this.selectResourceInfoByHostAndUri(
+                resourceInfo.getHost() + resourceInfo.getUri());
+        if(null != existingResource) {
+            // for each attribute in resourceInfo, put that attribute to the resource
+            for(OcAttributeInfo attribute : resourceInfo.getAttributes()) {
+                if(false == attribute.isReadOnly()) {
+                    existingResource.doOcPut(attribute);
+                }
+            }
+        } else {
+            Log.e(TAG, "putResourceAttributes(): could not find target resource.");
+        }
+        // Done. later, the onPut listener in the OcResourceInfo object will notify us of a change
+        // via our onResourceChanged() method
+    }
+
+    /**
+     * Because this callback is called on a JNI layer thread, don't do work here.
+     * Instead, create a "found resource" message and send to OcWorker's message queue,
+     * Our looper/handler then calls handleNewResource on our own worker thread.
+     *
+     * Also note that this method must be thread safe because it can be called by
+     * multiple concurrent native threads.
+     *
+     * @param resource
+     */
+    private Object onResourceFoundLock = new Object(); // not strictly necessary with this impl.,
+                                                       // but clears up Log message readability.
+    @Override
+    public void onResourceFound(OcResource resource) {
+        synchronized (onResourceFoundLock) {
+            if (LOCAL_LOGV) Log.v(TAG, "onResourceFound()");
+            if (LOCAL_LOGV) Log.v(TAG, "host: " + resource.getHost());
+            if (LOCAL_LOGV) Log.v(TAG, "uri: " + resource.getUri());
+            if (LOCAL_LOGV) Log.v(TAG, "is observable: " + resource.isObservable());
+
+            this.mOcEventHandler.obtainMessage(OC_EVENT.OIC_RESOURCE_FOUND.ordinal(),
+                    resource).sendToTarget();
+        }
+    }
+
+    /**
+     * Handles the internal NEW_RESOURCE_FOUND event, typically engueued on "onResourceFound".
+     * Creates a new OcResourceInfo object to wrap the new OcResource and store other info.
+     *
+     * @param resource the OcResource object
+     */
+    private void handleNewResourceFound(OcResource resource) {
+        if (LOCAL_LOGV) Log.v(TAG, String.format("handleNewResourceFound(%s)",
+                resource.toString()));
+
+        OcResourceInfo ri =
+                this.selectResourceInfoByHostAndUri(resource.getHost() + resource.getUri());
+
+        // before notifying listeners, update our own internal OcResourceInfo list
+        if(null != mOcResourceInfoList) {
+            // check for pre-existing duplicate before adding
+            if(null == ri) {
+                if (LOCAL_LOGV) Log.v(TAG, "handleNewResourceFound(): ri is new; adding.");
+                // if not found, create new info object
+                ri = new OcResourceInfo(resource, this);
+                // register as a listener to the newly created OcResourceInfo
+                ri.registerListener(this);
+                // kick off a get to fill in attributes
+                ri.doOcGet();
+                // add the info object to our list
+                mOcResourceInfoList.add(ri);
+            }
+        }
+        // notify listeners
+        for(OcWorkerListener l : this.mListeners) {
+            l.onResourceFound(ri);
+        }
+    }
+
+    /**
+     * The "listener" callback from the OcResourceInfo class.
+     * Called by the OcResourceInfo object using the native callback thread.
+     * We use this callback to post an event to our queue so that the work
+     * is serialized with other incoming events, and executed on our worker thread.
+     *
+     * Also note that this method must be thread safe because it could be called by
+     * one of many OcResourceInfo objects on separate native threads.
+     *
+     * @param resourceInfo
+     */
+    private Object onResourceInfoChangedLock = new Object();
+    @Override
+    public void onResourceInfoChanged(OcResourceInfo resourceInfo) {
+
+        synchronized (onResourceInfoChangedLock) {
+            if (LOCAL_LOGV) Log.v(TAG, String.format("resourceInfoChanged(%s)",
+                    resourceInfo.toString()));
+
+            // this is a result of a callback (i.e. onGetCompleted, onPut, onObserve)
+            // so we post a message to our queue to transfer the work to our own thread
+            this.mOcEventHandler.obtainMessage(OC_EVENT.OIC_RESOURCE_CHANGED.ordinal(),
+                    resourceInfo).sendToTarget();
+        }
+    }
+
+    /**
+     * Handle our internal event that is enqueued when a resource is found.
+     *
+     * @param resourceInfo
+     */
+    private void handleResourceInfoChange(OcResourceInfo resourceInfo) {
+        if (LOCAL_LOGV) Log.v(TAG, "handleResourceInfoChange()");
+
+        // notify listeners
+        for(OcWorkerListener l : this.mListeners) {
+            l.onResourceChanged(resourceInfo);
+        }
+    }
+
+    /**
+     * Complete OIC-related initialization, including configuring the platform
+     */
+    private void ocInit() {
+        if (LOCAL_LOGV) Log.v(TAG, "ocInit()");
+
+        // OIC initialization
+        mOcResourceInfoList = new ArrayList<>();
+
+        this.configurePlatform();
+    }
+
+    /**
+     * Configures the OIC platform.
+     */
+    private void configurePlatform() {
+        if (LOCAL_LOGV) Log.v(TAG, "configurePlatform()");
+
+        PlatformConfig cfg = new PlatformConfig(
+                mContext,
+                ServiceType.IN_PROC,
+                ModeType.CLIENT_SERVER,
+                "0.0.0.0", // bind to all available interfaces
+                0,
+                QualityOfService.LOW);
+
+        Log.d(TAG, "configurePlatform(): calling OcPlatform.Configure()");
+        OcPlatform.Configure(cfg);
+    }
+
+    /**
+     * Search mOcResourceInfo list for a resource whose Host and Uri concatenated
+     * matches the param passed, and return it.
+     *
+     * @param resourceHostAndUri
+     * @return OcResourceInfo with Host and Uri matching resourceHostAndUri, or null if
+     * no such OcResourceInfo exists in mOcResourceInfoList
+     */
+    private OcResourceInfo selectResourceInfoByHostAndUri(String resourceHostAndUri) {
+        if (LOCAL_LOGV) Log.v(TAG, "selectResourceByHostAndUri()");
+
+        boolean found = false;
+        OcResourceInfo retVal = null;
+
+        for(OcResourceInfo ri : mOcResourceInfoList) {
+            if(!found) {
+                String s = ri.getHost() + ri.getUri();
+                if (resourceHostAndUri.equalsIgnoreCase(s)) {
+                    retVal = ri;
+                    found = true;
+                }
+            }
+        }
+        if(!found) {
+            Log.v(TAG, "selectResourceByHostAndUri(): no resource found matching HostAndUri "
+                    + resourceHostAndUri);
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Finds OIC Resources matching known patterns.
+     *
+     * @see org.iotivity.guiclient.OcProtocolStrings
+     */
+    private void discoverResources() {
+        if (LOCAL_LOGV) Log.v(TAG, "discoverResources()");
+
+        try {
+            for (String s : mOcFindQueries) {
+                Log.d(TAG, String.format("discoverResources(): Calling OcPlatform.findResource(%s)", s));
+                OcPlatform.findResource("",
+                        OcPlatform.WELL_KNOWN_QUERY + "?rt=" + s,
+                        EnumSet.of(OcConnectivityType.CT_DEFAULT),
+                        this);
+            }
+        } catch (OcException e) {
+            e.printStackTrace();
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * Clear the ResourceInfoList
+     */
+    private void clearResourceInfoList() {
+        if (LOCAL_LOGV) Log.v(TAG, "clearResourceInfoList()");
+
+        this.mOcResourceInfoList.clear();
+    }
+}
diff --git a/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorkerListener.java b/android/examples/guiclient/src/main/java/org/iotivity/guiclient/OcWorkerListener.java
new file mode 100644 (file)
index 0000000..d78949b
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.guiclient;
+
+import android.os.Handler;
+
+import java.util.List;
+
+/**
+ * Applications wishing to use the OcWorker object must implement this interface to
+ * receive notification of OcWorker's ResourceFound and ResourceChanged events.
+ *
+ * @see org.iotivity.guiclient.OcWorker
+ */
+public interface OcWorkerListener {
+
+    /**
+     * Called whenever a new Resource is discovered.
+     *
+     * Note that the calling thread for this callback is not a UI thread.  OcWorkerListeners
+     * with UI functionality should post a message to their own UI thread, or similar action.
+     *
+     * @param resourceInfo
+     */
+    public void onResourceFound(final OcResourceInfo resourceInfo);
+
+    /**
+     * Called whenever a previously-discovered Resource changes, e.g. as a result of Put,
+     * or Observe callbacks.
+     *
+     * Note that the calling thread for this callback is not a UI thread.  OcWorkerListeners
+     * with UI functionality should post a message to their own UI thread, or similar action.
+     *
+     * @param resourceInfo
+     */
+    public void onResourceChanged(final OcResourceInfo resourceInfo);
+
+}
diff --git a/android/examples/guiclient/src/main/res/drawable-hdpi/ic_launcher.png b/android/examples/guiclient/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..96a442e
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable-mdpi/ic_launcher.png b/android/examples/guiclient/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..359047d
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable-xhdpi/ic_launcher.png b/android/examples/guiclient/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..71c6d76
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/examples/guiclient/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..4df1894
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/android_resource_icon.png b/android/examples/guiclient/src/main/res/drawable/android_resource_icon.png
new file mode 100644 (file)
index 0000000..5f8329b
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/android_resource_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/attribute_icon.png b/android/examples/guiclient/src/main/res/drawable/attribute_icon.png
new file mode 100644 (file)
index 0000000..4227bc5
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/attribute_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/ic_action_discard.png b/android/examples/guiclient/src/main/res/drawable/ic_action_discard.png
new file mode 100644 (file)
index 0000000..703b31f
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/ic_action_discard.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/ic_action_discard_dark.png b/android/examples/guiclient/src/main/res/drawable/ic_action_discard_dark.png
new file mode 100644 (file)
index 0000000..9c717dd
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/ic_action_discard_dark.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/ic_action_refresh.png b/android/examples/guiclient/src/main/res/drawable/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..dae2790
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/ic_action_refresh.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/iotivity_hex_icon.png b/android/examples/guiclient/src/main/res/drawable/iotivity_hex_icon.png
new file mode 100644 (file)
index 0000000..10ddd49
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/iotivity_hex_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/led_icon.png b/android/examples/guiclient/src/main/res/drawable/led_icon.png
new file mode 100644 (file)
index 0000000..90472ee
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/led_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/light_icon.png b/android/examples/guiclient/src/main/res/drawable/light_icon.png
new file mode 100644 (file)
index 0000000..399b20c
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/light_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/drawable/thermometer_icon.png b/android/examples/guiclient/src/main/res/drawable/thermometer_icon.png
new file mode 100644 (file)
index 0000000..346e95d
Binary files /dev/null and b/android/examples/guiclient/src/main/res/drawable/thermometer_icon.png differ
diff --git a/android/examples/guiclient/src/main/res/layout/actionbar_indeterminate_progress.xml b/android/examples/guiclient/src/main/res/layout/actionbar_indeterminate_progress.xml
new file mode 100644 (file)
index 0000000..d1af0eb
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="56dp"
+    android:minWidth="56dp"
+    android:clickable="true">
+    <ProgressBar android:id="@+id/find_resource_progress_bar"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_gravity="center"
+        android:clickable="true"/>
+</FrameLayout>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/layout/activity_main.xml b/android/examples/guiclient/src/main/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..dd9e997
--- /dev/null
@@ -0,0 +1,30 @@
+<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:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_horizontal_margin"
+    android:paddingBottom="@dimen/activity_horizontal_margin"
+    tools:context=".MainActivity">
+
+    <ExpandableListView
+        android:id="@+id/expandableResourceListView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="10dp"
+        >
+
+    </ExpandableListView>
+
+</RelativeLayout>
+
+
+    <!--<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"-->
+    <!--xmlns:tools="http://schemas.android.com/tools"-->
+    <!--android:id="@+id/container"-->
+    <!--android:layout_width="match_parent"-->
+    <!--android:layout_height="match_parent"-->
+    <!--tools:context=".MainActivity"-->
+    <!--tools:ignore="MergeRootFrame" />-->
diff --git a/android/examples/guiclient/src/main/res/layout/attribute_layout_on_off_switch.xml b/android/examples/guiclient/src/main/res/layout/attribute_layout_on_off_switch.xml
new file mode 100644 (file)
index 0000000..f74cd82
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView android:id="@+id/attribute_icon_id"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:layout_marginLeft="40dp"
+        android:src="@drawable/attribute_icon"/>
+
+    <TextView android:id="@+id/attribute_name_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_name_not_set"
+        android:textSize="14dp"
+        android:clickable="true"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_icon_id"
+        />
+
+    <TextView android:id="@+id/attribute_value_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="10dp"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_value_not_set"
+        android:textSize="14dp"
+        android:clickable="false"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_name_id"
+        />
+
+    <LinearLayout android:id="@+id/attribute_specific_view"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/attribute_name_id"
+        android:layout_alignParentRight="true"
+        android:layout_below="@+id/attribute_name_id"
+        android:layout_toRightOf="@+id/attribute_icon_id">
+
+        <Switch android:id="@+id/attribute_switch"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:text="@string/unnamed_switch"
+            android:textSize="12dp"
+            />
+
+    </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/layout/attribute_layout_progress_bar.xml b/android/examples/guiclient/src/main/res/layout/attribute_layout_progress_bar.xml
new file mode 100644 (file)
index 0000000..1811f1b
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView android:id="@+id/attribute_icon_id"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:layout_marginLeft="40dp"
+        android:src="@drawable/attribute_icon"/>
+
+    <TextView android:id="@+id/attribute_name_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_name_not_set"
+        android:textSize="14dp"
+        android:clickable="true"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_icon_id"
+        />
+
+    <TextView android:id="@+id/attribute_value_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="10dp"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_value_not_set"
+        android:textSize="14dp"
+        android:clickable="false"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_name_id"
+        />
+
+    <LinearLayout android:id="@+id/attribute_specific_view"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/attribute_name_id"
+        android:layout_alignParentRight="true"
+        android:layout_below="@+id/attribute_name_id"
+        android:layout_toRightOf="@+id/attribute_icon_id">
+
+        <ProgressBar android:id="@+id/attribute_progress_bar"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+
+    </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/layout/attribute_layout_slider.xml b/android/examples/guiclient/src/main/res/layout/attribute_layout_slider.xml
new file mode 100644 (file)
index 0000000..8a2027f
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView android:id="@+id/attribute_icon_id"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:layout_marginLeft="40dp"
+        android:src="@drawable/attribute_icon"/>
+
+    <TextView android:id="@+id/attribute_name_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_name_not_set"
+        android:textSize="14dp"
+        android:clickable="true"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_icon_id"
+        />
+
+    <TextView android:id="@+id/attribute_value_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="10dp"
+        android:inputType="textNoSuggestions"
+        android:text="@string/attribute_value_not_set"
+        android:textSize="14dp"
+        android:clickable="false"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/attribute_name_id"
+        />
+
+    <LinearLayout android:id="@+id/attribute_specific_view"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/attribute_name_id"
+        android:layout_alignParentRight="true"
+        android:layout_below="@+id/attribute_name_id"
+        android:layout_toRightOf="@+id/attribute_icon_id">
+
+        <SeekBar android:id="@+id/attribute_slider"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:text="@string/unnamed_slider"
+            android:textSize="12dp"
+            />
+
+    </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/layout/resource_list_item_layout.xml b/android/examples/guiclient/src/main/res/layout/resource_list_item_layout.xml
new file mode 100644 (file)
index 0000000..7063acb
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView android:id="@+id/resource_icon_id"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:layout_marginLeft="20dp"/>
+
+    <TextView android:id="@+id/resource_name_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textNoSuggestions"
+        android:text="@string/resource_name_not_set"
+        android:textSize="16dp"
+        android:clickable="true"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_toRightOf="@+id/resource_icon_id"
+        />
+
+    <TextView android:id="@+id/resource_description_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="10dp"
+        android:inputType="textNoSuggestions"
+        android:text="@string/resource_description_not_set"
+        android:textSize="14dp"
+        android:clickable="false"
+        android:cursorVisible="false"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:layout_below="@+id/resource_name_id"
+        android:layout_toRightOf="@+id/resource_icon_id"
+        />
+
+    <ImageView android:id="@+id/observing_icon_id"
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        android:layout_alignParentRight="true"
+        />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/menu/menu_main.xml b/android/examples/guiclient/src/main/res/menu/menu_main.xml
new file mode 100644 (file)
index 0000000..6bc3850
--- /dev/null
@@ -0,0 +1,18 @@
+<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=".MainActivity">
+    <item android:id="@+id/action_settings" android:title="@string/action_settings"
+        android:orderInCategory="100" app:showAsAction="never" />
+    <item android:id="@+id/action_test" android:title="@string/action_test"
+        android:orderInCategory="100" app:showAsAction="never" />
+    <item android:id="@+id/action_refresh"
+        android:icon="@drawable/ic_action_refresh"
+        android:title="@string/discover_resources"
+        android:alphabeticShortcut="r"
+        app:showAsAction="always" />
+    <item android:id="@+id/action_discard"
+        android:icon="@drawable/ic_action_discard"
+        android:title="@string/action_discard"
+        android:alphabeticShortcut="d"
+        app:showAsAction="always"/>
+</menu>
diff --git a/android/examples/guiclient/src/main/res/values-large/refs.xml b/android/examples/guiclient/src/main/res/values-large/refs.xml
new file mode 100644 (file)
index 0000000..91cab11
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--
+    Layout alias to replace the single-pane version of the layout with a
+    two-pane version on Large screens.
+
+    For more on layout aliases, see:
+    http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
+    -->
+
+</resources>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/values-sw600dp/refs.xml b/android/examples/guiclient/src/main/res/values-sw600dp/refs.xml
new file mode 100644 (file)
index 0000000..91cab11
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--
+    Layout alias to replace the single-pane version of the layout with a
+    two-pane version on Large screens.
+
+    For more on layout aliases, see:
+    http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
+    -->
+
+</resources>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/values-w820dp/dimens.xml b/android/examples/guiclient/src/main/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..63fc816
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/android/examples/guiclient/src/main/res/values/dimens.xml b/android/examples/guiclient/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..d913436
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">8dp</dimen>
+</resources>
diff --git a/android/examples/guiclient/src/main/res/values/refs.xml b/android/examples/guiclient/src/main/res/values/refs.xml
new file mode 100644 (file)
index 0000000..91cab11
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--
+    Layout alias to replace the single-pane version of the layout with a
+    two-pane version on Large screens.
+
+    For more on layout aliases, see:
+    http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
+    -->
+
+</resources>
\ No newline at end of file
diff --git a/android/examples/guiclient/src/main/res/values/strings.xml b/android/examples/guiclient/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..89984c5
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">IoTivity Client Demo</string>
+    <string name="action_settings">Settings</string>
+    <string name="action_discard">Clear Items</string>
+    <string name="action_test">Developer Test Action</string>
+    <string name="edit_input">default-string-from-xml</string>
+    <string name="ok">OK</string>
+    <string name="cancel">Cancel</string>
+    <string name="attribute_name_not_set">Attribute Name not set</string>
+    <string name="attribute_value_not_set">Attribute Value not set</string>
+    <string name="resource_name_not_set">Resource Name not set</string>
+    <string name="resource_description_not_set">Resource Description not set</string>
+    <string name="unnamed_switch">Unnamed Switch</string>
+    <string name="unnamed_slider">Unnamed Slider</string>
+    <string name="oc_light_switch_toggle_text">Turn Light On/Off:</string>
+    <string name="discover_resources">Discover Resources</string>
+    <string name="no_resource_selected">No Resource Selected</string>
+    <string name="oc_led_switch_toggle_text">Turn LED on/off</string>
+    <string name="ui_resource_label_light">SimpleServer Light</string>
+    <string name="ui_resource_label_ambient_light_sensor">Edison Ambient Light Sensor</string>
+    <string name="ui_resource_label_platform_led">Edison Platform LED</string>
+    <string name="ui_resource_label_room_temperature_sensor">Edison Room Temp Sensor</string>
+    <string name="ui_attribute_label_ambient_light_sensor_reading">Ambient Light Level:</string>
+    <string name="ui_attribute_label_light_dimmer">Light Dimmer:</string>
+    <string name="ui_attribute_label_light_switch">Light Switch:</string>
+    <string name="ui_attribute_label_led_switch">LED switch:</string>
+    <string name="ui_attribute_label_room_temperature_sensor_reading">Temperature Reading:</string>
+</resources>
diff --git a/android/examples/guiclient/src/main/res/values/styles.xml b/android/examples/guiclient/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..766ab99
--- /dev/null
@@ -0,0 +1,8 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+</resources>
index bf2b78b..4cd41ac 100755 (executable)
@@ -1 +1 @@
-include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient'
\ No newline at end of file
+include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient', ':guiclient'
index 0345054..5d91543 100755 (executable)
@@ -4,6 +4,16 @@
     xmlns:tools="http://schemas.android.com/tools">\r
 \r
     <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.BLUETOOTH"/>\r
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>\r
+    <uses-permission android:name="android.permission.INTERNET"/>\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>\r
 \r
     <application\r
         android:allowBackup="true"\r
diff --git a/android/examples/simpleclient/src/main/assets/oic_svr_db_client.json b/android/examples/simpleclient/src/main/assets/oic_svr_db_client.json
new file mode 100755 (executable)
index 0000000..17dc43f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MjIyMjIyMjIyMjIyMjIyMg==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MTExMTExMTExMTExMTExMQ==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index b747c5a..d20794e 100644 (file)
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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 org.iotivity.base.examples.simpleclient;\r
-\r
-import android.app.Activity;\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.os.Bundle;\r
-import android.os.Message;\r
-import android.text.method.ScrollingMovementMethod;\r
-import android.util.Log;\r
-import android.widget.LinearLayout;\r
-import android.widget.TextView;\r
-\r
-import org.iotivity.base.ErrorCode;\r
-import org.iotivity.base.ModeType;\r
-import org.iotivity.base.ObserveType;\r
-import org.iotivity.base.OcConnectivityType;\r
-import org.iotivity.base.OcException;\r
-import org.iotivity.base.OcHeaderOption;\r
-import org.iotivity.base.OcPlatform;\r
-import org.iotivity.base.OcRepresentation;\r
-import org.iotivity.base.OcResource;\r
-import org.iotivity.base.PlatformConfig;\r
-import org.iotivity.base.QualityOfService;\r
-import org.iotivity.base.ServiceType;\r
-\r
-import java.util.HashMap;\r
-import java.util.List;\r
-\r
-import base.iotivity.org.examples.message.IMessageLogger;\r
-\r
-/**\r
- * SimpleClient\r
- * <p/>\r
- * SimpleClient is a sample client app which should be started after the simpleServer is started.\r
- * It finds resources advertised by the server and calls different operations on it (GET, PUT,\r
- * POST and OBSERVE).\r
- * This implements IMessageLogger to display messages on the screen\r
- */\r
-public class SimpleClient extends Activity implements OcPlatform.OnResourceFoundListener,\r
-        IMessageLogger {\r
-    private static final String TAG = "SimpleClient: ";\r
-\r
-    private Light myLight;\r
-    private OcResource curResource;\r
-\r
-    //for display\r
-    private TextView mEventsTextView;\r
-    private static boolean printOnce = true;\r
-\r
-    /**\r
-     * configure OIC platform and call findResource\r
-     */\r
-    private void initOICStack() {\r
-        //create platform config\r
-        PlatformConfig cfg = new PlatformConfig(\r
-                this,\r
-                ServiceType.IN_PROC,\r
-                ModeType.CLIENT,\r
-                "0.0.0.0", // bind to all available interfaces\r
-                0,\r
-                QualityOfService.LOW);\r
-        OcPlatform.Configure(cfg);\r
-        try {\r
-            /**\r
-             * find all resources\r
-             */\r
-            OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "core.light",\r
-                    OcConnectivityType.WIFI, this);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + "findResource error: " + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    @Override\r
-    /**\r
-     *  callback when a resource is found. This method calls doGetLightRepresentation to get the\r
-     *  current values of myLight\r
-     */\r
-    synchronized public void onResourceFound(OcResource ocResource) {\r
-        /**\r
-         *  this may potentially be called by multiple threads at the same time\r
-         */\r
-        synchronized (this) {\r
-            String resourceUri;\r
-            String hostAddress;\r
-            resourceUri = ocResource.getUri();\r
-            hostAddress = ocResource.getHost();\r
-            logMessage(TAG + "Discovered Resource\nUri: " + resourceUri + " \n Host: " + hostAddress);\r
-            // get the resource types\r
-            if (resourceUri.equals(StringConstants.RESOURCE_URI0)) {\r
-                curResource = ocResource;\r
-                doGetLightRepresentation();\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * get myLight values after observe\r
-     */\r
-    private void doObserveLightRepresentation() {\r
-        // eventhandler for observe()\r
-        OcResource.OnObserveListener onObserveListener = new OcResource.OnObserveListener() {\r
-            @Override\r
-            public void onObserveCompleted(List<OcHeaderOption> ocHeaderOptions,\r
-                                           OcRepresentation ocRepresentation, int seqNum) {\r
-                if (printOnce) {\r
-                    logMessage(TAG + "OBSERVE request was successful");\r
-                    printOnce = false;\r
-                }\r
-                try {\r
-                    boolean state = ocRepresentation.getValue(StringConstants.STATE);\r
-                    int power = ocRepresentation.getValue(StringConstants.POWER);\r
-                    String name = ocRepresentation.getValue(StringConstants.NAME);\r
-                    myLight.setState(state);\r
-                    myLight.setPower(power);\r
-                    myLight.setName(name);\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                logMessage(TAG + "onObserve: Power: " + myLight.getPower());\r
-                if (seqNum > 20) {\r
-                    try {\r
-                        curResource.cancelObserve();\r
-                        logMessage(TAG + "Successfully cancelled observe");\r
-                   } catch (OcException e) {\r
-                        logMessage(TAG + "cancelObserve error. " + e.getMessage());\r
-                        Log.e(TAG, e.getMessage());\r
-                    }\r
-                }\r
-\r
-            }\r
-\r
-            @Override\r
-            public void onObserveFailed(Throwable throwable) {\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-        try {\r
-            curResource.observe(ObserveType.OBSERVE, new HashMap<String, String>(), onObserveListener);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * get the current value of myLight after POST and call doObserveLightRepresentation\r
-     *\r
-     * @param ocRepresentation needed to invoke post()\r
-     */\r
-    private void doOnPost2(OcRepresentation ocRepresentation) {\r
-        // eventhandler for post()\r
-        OcResource.OnPostListener onPostListener2 = new OcResource.OnPostListener() {\r
-            @Override\r
-            public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions, OcRepresentation rep) {\r
-                logMessage(TAG + "POST request was successful");\r
-                String createdUri = rep.getUri();\r
-                if (createdUri.equals(StringConstants.RESOURCE_URI1)) {\r
-                    logMessage(TAG + "Uri of the created resource: " + createdUri);\r
-                } else {\r
-                    try {\r
-                        boolean state = rep.getValue(StringConstants.STATE);\r
-                        int power = rep.getValue(StringConstants.POWER);\r
-                        String name = rep.getValue(StringConstants.NAME);\r
-                        myLight.setState(state);\r
-                        myLight.setPower(power);\r
-                        myLight.setName(name);\r
-                    } catch (OcException e) {\r
-                        Log.e(TAG, e.getMessage());\r
-                    }\r
-                    logMessage(TAG + "onPost\nState: " + myLight.getState() + "\nPower: " +\r
-                            myLight.getPower() + "\nName: " + myLight.getName());\r
-                }\r
-                doObserveLightRepresentation();\r
-            }\r
-\r
-            @Override\r
-            public void onPostFailed(Throwable throwable) {\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-        try {\r
-            curResource.post(ocRepresentation, new HashMap<String, String>(), onPostListener2);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * create a new resource and update its value.\r
-     */\r
-    private void doPostLightRepresentation() {\r
-        // eventhandler for post()\r
-        OcResource.OnPostListener onPostListener = new OcResource.OnPostListener() {\r
-            @Override\r
-            public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions,\r
-                                        OcRepresentation ocRepresentation) {\r
-                String createdUri = "";\r
-                try {\r
-                    createdUri = ocRepresentation.getValue(StringConstants.CREATED_URI);\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                if (createdUri.equals(StringConstants.RESOURCE_URI1)) {\r
-                    logMessage(TAG + "Uri of the created resource: " + createdUri);\r
-                } else {\r
-                    boolean state = false;\r
-                    try {\r
-                        state = ocRepresentation.getValue(StringConstants.STATE);\r
-                        int power = ocRepresentation.getValue(StringConstants.POWER);\r
-                        String name = ocRepresentation.getValue(StringConstants.NAME);\r
-                        myLight.setState(state);\r
-                        myLight.setPower(power);\r
-                        myLight.setName(name);\r
-                    } catch (OcException e) {\r
-                        Log.e(TAG, e.getMessage());\r
-                    }\r
-                }\r
-                OcRepresentation rep = new OcRepresentation();\r
-                myLight.setState(true);\r
-                myLight.setPower(55);\r
-                try {\r
-                    rep.setValue(StringConstants.POWER, myLight.getPower());\r
-                    rep.setValue(StringConstants.STATE, myLight.getState());\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                doOnPost2(rep);\r
-            }\r
-\r
-            @Override\r
-            public void onPostFailed(Throwable throwable) {\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-\r
-        OcRepresentation rep = new OcRepresentation();\r
-        myLight.setState(false);\r
-        myLight.setPower(105);\r
-        try {\r
-            rep.setValue(StringConstants.STATE, myLight.getState());\r
-            rep.setValue(StringConstants.POWER, myLight.getPower());\r
-        } catch (OcException e) {\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-        try {\r
-            curResource.post(rep, new HashMap<String, String>(), onPostListener);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * modify the current value of myLight and call doPostLightRepresentation\r
-     */\r
-    private void doPutLightRepresentation() {\r
-        // eventhandler for put()\r
-        OcResource.OnPutListener onPutListener = new OcResource.OnPutListener() {\r
-            @Override\r
-            public void onPutCompleted(List<OcHeaderOption> ocHeaderOptions,\r
-                                       OcRepresentation ocRepresentation) {\r
-                logMessage(TAG + "PUT resource was successful");\r
-                try {\r
-                    boolean state = ocRepresentation.getValue(StringConstants.STATE);\r
-                    int power = ocRepresentation.getValue(StringConstants.POWER);\r
-                    String name = ocRepresentation.getValue(StringConstants.NAME);\r
-                    myLight.setState(state);\r
-                    myLight.setPower(power);\r
-                    myLight.setName(name);\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-\r
-                logMessage(TAG + "onPutCompleted:\nState:" + myLight.getState() + "\nPower: " +\r
-                        myLight.getPower() + "\nName: " + myLight.getName());\r
-                doPostLightRepresentation();\r
-            }\r
-\r
-            @Override\r
-            public void onPutFailed(Throwable throwable) {\r
-\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-\r
-        OcRepresentation rep = new OcRepresentation();\r
-        Log.d(TAG, "myLight settings: power = 15");\r
-        myLight.setState(true);\r
-        myLight.setPower(15);\r
-        try {\r
-            rep.setValue(StringConstants.STATE, myLight.getState());\r
-            rep.setValue(StringConstants.POWER, myLight.getPower());\r
-            rep.setValue(StringConstants.NAME, myLight.getName());\r
-        } catch (OcException e) {\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-        try {\r
-            Log.d(TAG, "before calling put");\r
-            curResource.put(rep, new HashMap<String, String>(), onPutListener);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-        Log.d(TAG, "end of put call");\r
-    }\r
-\r
-    /**\r
-     * get the existing value of myLight and call doPutLightRepresentation() to modify the current values\r
-     */\r
-    private void doGetLightRepresentation() {\r
-        // eventhandler for get()\r
-        OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() {\r
-            @Override\r
-            public void onGetCompleted(List<OcHeaderOption> headerOptionList,\r
-                                       OcRepresentation ocRepresentation) {\r
-                logMessage(TAG + "GET resource was successful " + StringConstants.STATE);\r
-                try {\r
-                    boolean state = ocRepresentation.getValue(StringConstants.STATE);\r
-                    int power = ocRepresentation.getValue(StringConstants.POWER);\r
-                    String name = ocRepresentation.getValue(StringConstants.NAME);\r
-                    myLight.setState(state);\r
-                    myLight.setPower(power);\r
-                    myLight.setName(name);\r
-                } catch (OcException e) {\r
-                    Log.e(TAG, e.getMessage());\r
-                }\r
-                logMessage(TAG + "onGetCompleted\nState: " + myLight.getState() + "\nPower: " +\r
-                        myLight.getPower() + "\nName: " + myLight.getName());\r
-                doPutLightRepresentation();\r
-            }\r
-\r
-            @Override\r
-            public void onGetFailed(Throwable throwable) {\r
-                if (throwable instanceof OcException) {\r
-                    OcException ocEx = (OcException) throwable;\r
-                    ErrorCode errCode = ocEx.getErrorCode();\r
-                    //do something based on errorCode\r
-                }\r
-                Log.e(TAG, throwable.toString());\r
-            }\r
-        };\r
-\r
-        try {\r
-            curResource.get(new HashMap<String, String>(), onGetListener);\r
-        } catch (OcException e) {\r
-            logMessage(TAG + e.getMessage());\r
-            Log.e(TAG, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * to display on SimpleClient screen\r
-     */\r
-    public class MessageReceiver extends BroadcastReceiver {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            final String message = intent.getStringExtra(StringConstants.MESSAGE);\r
-            logMessage(message);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        setContentView(R.layout.activity_main);\r
-        mEventsTextView = new TextView(this);\r
-        mEventsTextView.setMovementMethod(new ScrollingMovementMethod());\r
-        LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);\r
-        layout.addView(mEventsTextView, new LinearLayout.LayoutParams(\r
-                LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)\r
-        );\r
-        myLight = new Light();\r
-\r
-        initOICStack();\r
-    }\r
-\r
-    @Override\r
-    public void logMessage(String text) {\r
-        logMsg(text);\r
-    }\r
-\r
-    public void logMsg(final String text) {\r
-        runOnUiThread(new Runnable() {\r
-            public void run() {\r
-                Message msg = new Message();\r
-                msg.obj = text;\r
-                mEventsTextView.append("\n");\r
-                mEventsTextView.append(text);\r
-            }\r
-        });\r
-        Log.i(TAG, text);\r
-        //to print on SimpleServer screen\r
-        Intent intent = new Intent("org.iotivity.base.examples.simpleclient");\r
-        intent.putExtra(StringConstants.MESSAGE, text);\r
-        sendBroadcast(intent);\r
-    }\r
-}\r
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples.simpleclient;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.AssetManager;
+import android.os.Bundle;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.ModeType;
+import org.iotivity.base.ObserveType;
+import org.iotivity.base.OcConnectivityType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcHeaderOption;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.base.OcResource;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.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.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+
+import base.iotivity.org.examples.message.IMessageLogger;
+
+/**
+ * SimpleClient
+ * <p/>
+ * SimpleClient is a sample client app which should be started after the simpleServer is started.
+ * It finds resources advertised by the server and calls different operations on it (GET, PUT,
+ * POST and OBSERVE).
+ * This implements IMessageLogger to display messages on the screen
+ */
+public class SimpleClient extends Activity implements OcPlatform.OnResourceFoundListener,
+        IMessageLogger {
+    private static final String TAG = "SimpleClient: ";
+
+    private static final int BUFFER_SIZE = 1024;
+    private String filePath = "";
+    private Light myLight;
+    private OcResource curResource;
+
+    //for display
+    private TextView mEventsTextView;
+    private static boolean printOnce = true;
+
+    /**
+     * configure OIC platform and call findResource
+     */
+    private void initOICStack() {
+        //create platform config
+        PlatformConfig cfg = new PlatformConfig(
+                this,
+                ServiceType.IN_PROC,
+                ModeType.CLIENT_SERVER,
+                "0.0.0.0", // bind to all available interfaces
+                0,
+                QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+        OcPlatform.Configure(cfg);
+        try {
+            /**
+             * find all resources
+             */
+            OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "core.light",
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT), this);
+        } catch (OcException e) {
+            logMessage(TAG + "findResource error: " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    @Override
+    /**
+     *  callback when a resource is found. This method calls doGetLightRepresentation to get the
+     *  current values of myLight
+     */
+    synchronized public void onResourceFound(OcResource ocResource) {
+        /**
+         *  this may potentially be called by multiple threads at the same time
+         */
+        synchronized (this) {
+            String resourceUri;
+            String hostAddress;
+            resourceUri = ocResource.getUri();
+            hostAddress = ocResource.getHost();
+            logMessage(TAG + "Discovered Resource\nUri: " + resourceUri + " \n Host: " + hostAddress);
+            // get the resource types
+            if (resourceUri.contains("light")) {
+                curResource = ocResource;
+                doGetLightRepresentation();
+            }
+        }
+    }
+
+    /**
+     * get myLight values after observe
+     */
+    private void doObserveLightRepresentation() {
+        // eventhandler for observe()
+        OcResource.OnObserveListener onObserveListener = new OcResource.OnObserveListener() {
+            @Override
+            public void onObserveCompleted(List<OcHeaderOption> ocHeaderOptions,
+                                           OcRepresentation ocRepresentation, int seqNum) {
+                if (printOnce) {
+                    logMessage(TAG + "OBSERVE request was successful");
+                    printOnce = false;
+                }
+                try {
+                    boolean state = ocRepresentation.getValue(StringConstants.STATE);
+                    int power = ocRepresentation.getValue(StringConstants.POWER);
+                    String name = ocRepresentation.getValue(StringConstants.NAME);
+                    myLight.setState(state);
+                    myLight.setPower(power);
+                    myLight.setName(name);
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                logMessage(TAG + "onObserve: Power: " + myLight.getPower());
+                if (seqNum > 20) {
+                    try {
+                        curResource.cancelObserve();
+                        logMessage(TAG + "Successfully cancelled observe");
+                   } catch (OcException e) {
+                        logMessage(TAG + "cancelObserve error. " + e.getMessage());
+                        Log.e(TAG, e.getMessage());
+                    }
+                }
+
+            }
+
+            @Override
+            public void onObserveFailed(Throwable throwable) {
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+        try {
+            curResource.observe(ObserveType.OBSERVE, new HashMap<String, String>(), onObserveListener);
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * get the current value of myLight after POST and call doObserveLightRepresentation
+     *
+     * @param ocRepresentation needed to invoke post()
+     */
+    private void doOnPost2(OcRepresentation ocRepresentation) {
+        // eventhandler for post()
+        OcResource.OnPostListener onPostListener2 = new OcResource.OnPostListener() {
+            @Override
+            public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions, OcRepresentation rep) {
+                logMessage(TAG + "POST request was successful");
+                String createdUri = rep.getUri();
+                if (createdUri.equals(StringConstants.RESOURCE_URI1)) {
+                    logMessage(TAG + "Uri of the created resource: " + createdUri);
+                } else {
+                    try {
+                        boolean state = rep.getValue(StringConstants.STATE);
+                        int power = rep.getValue(StringConstants.POWER);
+                        String name = rep.getValue(StringConstants.NAME);
+                        myLight.setState(state);
+                        myLight.setPower(power);
+                        myLight.setName(name);
+                    } catch (OcException e) {
+                        Log.e(TAG, e.getMessage());
+                    }
+                    logMessage(TAG + "onPost\nState: " + myLight.getState() + "\nPower: " +
+                            myLight.getPower() + "\nName: " + myLight.getName());
+                }
+                doObserveLightRepresentation();
+            }
+
+            @Override
+            public void onPostFailed(Throwable throwable) {
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+        try {
+            curResource.post(ocRepresentation, new HashMap<String, String>(), onPostListener2);
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * create a new resource and update its value.
+     */
+    private void doPostLightRepresentation() {
+        // eventhandler for post()
+        OcResource.OnPostListener onPostListener = new OcResource.OnPostListener() {
+            @Override
+            public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions,
+                                        OcRepresentation ocRepresentation) {
+                String createdUri = "";
+                try {
+                    createdUri = ocRepresentation.getValue(StringConstants.CREATED_URI);
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                if (createdUri.equals(StringConstants.RESOURCE_URI1)) {
+                    logMessage(TAG + "Uri of the created resource: " + createdUri);
+                } else {
+                    boolean state = false;
+                    try {
+                        state = ocRepresentation.getValue(StringConstants.STATE);
+                        int power = ocRepresentation.getValue(StringConstants.POWER);
+                        String name = ocRepresentation.getValue(StringConstants.NAME);
+                        myLight.setState(state);
+                        myLight.setPower(power);
+                        myLight.setName(name);
+                    } catch (OcException e) {
+                        Log.e(TAG, e.getMessage());
+                    }
+                }
+                OcRepresentation rep = new OcRepresentation();
+                myLight.setState(true);
+                myLight.setPower(55);
+                try {
+                    rep.setValue(StringConstants.POWER, myLight.getPower());
+                    rep.setValue(StringConstants.STATE, myLight.getState());
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                doOnPost2(rep);
+            }
+
+            @Override
+            public void onPostFailed(Throwable throwable) {
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+
+        OcRepresentation rep = new OcRepresentation();
+        myLight.setState(false);
+        myLight.setPower(105);
+        try {
+            rep.setValue(StringConstants.STATE, myLight.getState());
+            rep.setValue(StringConstants.POWER, myLight.getPower());
+        } catch (OcException e) {
+            Log.e(TAG, e.getMessage());
+        }
+        try {
+            curResource.post(rep, new HashMap<String, String>(), onPostListener);
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * modify the current value of myLight and call doPostLightRepresentation
+     */
+    private void doPutLightRepresentation() {
+        // eventhandler for put()
+        OcResource.OnPutListener onPutListener = new OcResource.OnPutListener() {
+            @Override
+            public void onPutCompleted(List<OcHeaderOption> ocHeaderOptions,
+                                       OcRepresentation ocRepresentation) {
+                logMessage(TAG + "PUT resource was successful");
+                try {
+                    boolean state = ocRepresentation.getValue(StringConstants.STATE);
+                    int power = ocRepresentation.getValue(StringConstants.POWER);
+                    String name = ocRepresentation.getValue(StringConstants.NAME);
+                    myLight.setState(state);
+                    myLight.setPower(power);
+                    myLight.setName(name);
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+
+                logMessage(TAG + "onPutCompleted:\nState:" + myLight.getState() + "\nPower: " +
+                        myLight.getPower() + "\nName: " + myLight.getName());
+                doPostLightRepresentation();
+            }
+
+            @Override
+            public void onPutFailed(Throwable throwable) {
+
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+
+        OcRepresentation rep = new OcRepresentation();
+        Log.d(TAG, "myLight settings: power = 15");
+        myLight.setState(true);
+        myLight.setPower(15);
+        try {
+            rep.setValue(StringConstants.STATE, myLight.getState());
+            rep.setValue(StringConstants.POWER, myLight.getPower());
+            rep.setValue(StringConstants.NAME, myLight.getName());
+        } catch (OcException e) {
+            Log.e(TAG, e.getMessage());
+        }
+        try {
+            Log.d(TAG, "before calling put");
+            curResource.put(rep, new HashMap<String, String>(), onPutListener);
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+        Log.d(TAG, "end of put call");
+    }
+
+    /**
+     * get the existing value of myLight and call doPutLightRepresentation() to modify the current values
+     */
+    private void doGetLightRepresentation() {
+        // eventhandler for get()
+        OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() {
+            @Override
+            public void onGetCompleted(List<OcHeaderOption> headerOptionList,
+                                       OcRepresentation ocRepresentation) {
+                logMessage(TAG + "GET resource was successful " + StringConstants.STATE);
+                try {
+                    boolean state = ocRepresentation.getValue(StringConstants.STATE);
+                    int power = ocRepresentation.getValue(StringConstants.POWER);
+                    String name = ocRepresentation.getValue(StringConstants.NAME);
+                    myLight.setState(state);
+                    myLight.setPower(power);
+                    myLight.setName(name);
+                } catch (OcException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+                logMessage(TAG + "onGetCompleted\nState: " + myLight.getState() + "\nPower: " +
+                        myLight.getPower() + "\nName: " + myLight.getName());
+                doPutLightRepresentation();
+            }
+
+            @Override
+            public void onGetFailed(Throwable throwable) {
+                if (throwable instanceof OcException) {
+                    OcException ocEx = (OcException) throwable;
+                    ErrorCode errCode = ocEx.getErrorCode();
+                    //do something based on errorCode
+                }
+                Log.e(TAG, throwable.toString());
+            }
+        };
+
+        try {
+            curResource.get(new HashMap<String, String>(), onGetListener);
+        } catch (OcException e) {
+            logMessage(TAG + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * to display on SimpleClient screen
+     */
+    public class MessageReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String message = intent.getStringExtra(StringConstants.MESSAGE);
+            logMessage(message);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        mEventsTextView = new TextView(this);
+        mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
+        LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
+        layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
+        );
+        myLight = new Light();
+        filePath = getFilesDir().getPath() + "/"; //  data/data/<package>/files/
+        //copy json when application runs first time
+        SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
+        boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
+        if (isFirstRun) {
+            copyJsonFromAsset();
+            SharedPreferences.Editor editor = wmbPreference.edit();
+            editor.putBoolean("FIRSTRUN", false);
+            editor.commit();
+        }
+
+
+        initOICStack();
+    }
+/**
+     * Copy svr db json file from assets folder to app data files dir
+     */
+    private void copyJsonFromAsset() {
+        AssetManager assetManager = getAssets();
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = assetManager.open(StringConstants.OIC_CLIENT_JSON_DB_FILE);
+            File file = new File(filePath);
+            //check files directory exists
+            if (!(file.exists() && file.isDirectory())) {
+                file.mkdirs();
+            }
+            out = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+            copyFile(in, out);
+        } catch (NullPointerException e) {
+            logMessage(TAG + "Null pointer exception " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        } catch (FileNotFoundException e) {
+            logMessage(TAG + "Json svr db file not found " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+        } catch (IOException e) {
+            logMessage(TAG + StringConstants.OIC_CLIENT_JSON_DB_FILE+ " file copy failed");
+            Log.e(TAG, e.getMessage());
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+            }
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+            }
+        }
+    }
+
+    private void copyFile(InputStream in, OutputStream out) throws IOException {
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int read;
+        while ((read = in.read(buffer)) != -1) {
+            out.write(buffer, 0, read);
+        }
+    }
+    @Override
+    public void logMessage(String text) {
+        logMsg(text);
+    }
+
+    public void logMsg(final String text) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                Message msg = new Message();
+                msg.obj = text;
+                mEventsTextView.append("\n");
+                mEventsTextView.append(text);
+            }
+        });
+        Log.i(TAG, text);
+        //to print on SimpleServer screen
+        Intent intent = new Intent("org.iotivity.base.examples.simpleclient");
+        intent.putExtra(StringConstants.MESSAGE, text);
+        sendBroadcast(intent);
+    }
+}
index f87c387..54336f8 100644 (file)
@@ -1,5 +1,4 @@
 package org.iotivity.base.examples.simpleclient;\r
-\r
 /**\r
  * StringConstant contains the simpleclient specific constant values.  To add another supported\r
  * Resource or Interface type to this app, begin by adding the new strings here, and then\r
@@ -7,8 +6,9 @@ package org.iotivity.base.examples.simpleclient;
  * the newly-supported type there.\r
  */\r
 public interface StringConstants {\r
-    public static final String RESOURCE_URI0 = "/light0";\r
-    public static final String RESOURCE_URI1 = "/light1";\r
+    public static final String RESOURCE_URI0 = "/a/light";\r
+    public static final String RESOURCE_URI1 = "/a/light2";\r
+    public static final String OIC_CLIENT_JSON_DB_FILE =  "oic_svr_db_client.json";\r
     public static final String CREATED_URI = "createduri";\r
     public static final String STATE = "state";\r
     public static final String NAME = "name";\r
index 43352f4..45535e8 100755 (executable)
@@ -4,6 +4,16 @@
     xmlns:tools="http://schemas.android.com/tools">\r
 \r
     <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.BLUETOOTH"/>\r
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>\r
+    <uses-permission android:name="android.permission.INTERNET"/>\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>\r
 \r
     <application\r
         android:allowBackup="true"\r
diff --git a/android/examples/simpleserver/src/main/assets/oic_svr_db_server.json b/android/examples/simpleserver/src/main/assets/oic_svr_db_server.json
new file mode 100755 (executable)
index 0000000..6c8c4e4
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        },
+        {
+            "sub": "Kg==",
+            "rsrc": ["/light0", "/light1", "/a/light"],
+            "perms": 6,
+            "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MTExMTExMTExMTExMTExMQ==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index e8414a0..a658663 100644 (file)
@@ -305,4 +305,4 @@ public class LightResource implements IMessageLogger {
         intent.putExtra(StringConstants.MESSAGE, text);\r
         mContext.sendBroadcast(intent);\r
     }\r
-}
\ No newline at end of file
+}\r
index 31b5c6a..b48a9f5 100644 (file)
@@ -36,6 +36,9 @@ import android.view.Menu;
 import android.view.MenuItem;\r
 import android.widget.LinearLayout;\r
 import android.widget.TextView;\r
+import android.content.SharedPreferences;\r
+import android.content.res.AssetManager;\r
+import android.preference.PreferenceManager;\r
 \r
 import org.iotivity.base.ModeType;\r
 import org.iotivity.base.OcPlatform;\r
@@ -44,6 +47,13 @@ import org.iotivity.base.PlatformConfig;
 import org.iotivity.base.QualityOfService;\r
 import org.iotivity.base.ServiceType;\r
 \r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+\r
 import base.iotivity.org.examples.message.IMessageLogger;\r
 \r
 /**\r
@@ -56,6 +66,8 @@ import base.iotivity.org.examples.message.IMessageLogger;
 \r
 public class SimpleServer extends Activity implements IMessageLogger {\r
     private final static String TAG = "SimpleServer: ";\r
+    private static final int BUFFER_SIZE = 1024;
+    private String filePath = "";\r
     private TextView mEventsTextView;\r
     private MessageReceiver mMessageReceiver = new MessageReceiver();\r
 \r
@@ -73,10 +85,72 @@ public class SimpleServer extends Activity implements IMessageLogger {
         OcRepresentation rep = new OcRepresentation();\r
         rep.setValueBool("test", false);\r
         boolean result = rep.getValueBool("test");\r
+        filePath = getFilesDir().getPath() + "/";//  data/data/<package>/files/\r
+        //copy json when application runs first time\r
+        SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);\r
+        boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);\r
+        if (isFirstRun) {\r
+            copyJsonFromAsset();\r
+            SharedPreferences.Editor editor = wmbPreference.edit();\r
+            editor.putBoolean("FIRSTRUN", false);\r
+            editor.commit();\r
+        }
 \r
         initOICStack();\r
     }\r
+
+    /**\r
+     * Copy svr db json file from assets folder to app data files dir\r
+     */\r
+    private void copyJsonFromAsset() {\r
+        AssetManager assetManager = getAssets();\r
+\r
+        InputStream in = null;\r
+        OutputStream out = null;\r
+        try {\r
+\r
+            in = assetManager.open(StringConstants.OIC_SERVER_JSON_DB_FILE);\r
+            File file = new File(filePath);\r
+            //check files directory exists\r
+            if (!(file.exists() && file.isDirectory())) {\r
+                file.mkdirs();\r
+            }\r
+            out = new FileOutputStream(filePath + StringConstants.OIC_SERVER_JSON_DB_FILE);\r
+            copyFile(in, out);\r
+        } catch (NullPointerException e) {\r
+            logMessage(TAG + "Null pointer exception " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (FileNotFoundException e) {\r
+            logMessage(TAG + "Json svr db file not found " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (IOException e) {\r
+            logMessage(TAG + StringConstants.OIC_SERVER_JSON_DB_FILE + " file copy failed");\r
+            Log.e(TAG, e.getMessage());\r
+        } finally {\r
+            if (in != null) {\r
+                try {\r
+                    in.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+            if (out != null) {\r
+                try {\r
+                    out.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+        }\r
+    }\r
 \r
+    private void copyFile(InputStream in, OutputStream out) throws IOException {\r
+        byte[] buffer = new byte[BUFFER_SIZE];\r
+        int read;\r
+        while ((read = in.read(buffer)) != -1) {\r
+            out.write(buffer, 0, read);\r
+        }\r
+    }\r
     /**\r
      * configure OIC platform and call findResource\r
      */\r
@@ -88,14 +162,15 @@ public class SimpleServer extends Activity implements IMessageLogger {
                 ModeType.SERVER,\r
                 "0.0.0.0", // bind to all available interfaces\r
                 0,\r
-                QualityOfService.LOW);\r
+                QualityOfService.LOW,\r
+                filePath + StringConstants.OIC_SERVER_JSON_DB_FILE);\r
         OcPlatform.Configure(cfg);\r
         // Create instance of lightResource\r
         LightResource myLight = new LightResource(this);\r
         // create and register a resource\r
         myLight.createResource0();\r
     }\r
-\r
+
     public class MessageReceiver extends BroadcastReceiver {\r
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
index 98f33d0..46b5c2d 100644 (file)
@@ -8,9 +8,10 @@ import org.iotivity.base.OcPlatform;
  * the newly-supported type there.\r
  */\r
 public interface StringConstants {\r
-    public static final String RESOURCE_URI0 = "/light0";\r
-    public static final String RESOURCE_URI1 = "/light1";\r
+    public static final String RESOURCE_URI0 = "/a/light";\r
+    public static final String RESOURCE_URI1 = "/a/light2";\r
     public static final String RESOURCE_TYPENAME = "core.light";\r
+    public static final String OIC_SERVER_JSON_DB_FILE =  "oic_svr_db_server.json";\r
     public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE; //resource interface\r
     public static final String CREATED_URI = "createduri";\r
     public static final String STATE = "state";\r
index 2f40e74..ae3b53f 100644 (file)
@@ -45,5 +45,7 @@ if 'RBL_NRF8001' in env.get('SHIELD'):
 env.ImportLib('Time/Time')
 # we have variety of macros for arduino!!
 env.AppendUnique(CPPDEFINES = ['WITH_ARDUINO', '__ARDUINO__'])
+# Set device name to __OIC_DEVICE_NAME__
+env.AppendUnique(CPPDEFINES = ['-D__OIC_DEVICE_NAME__=' + "\'\"" + env.get('DEVICE_NAME') + "\"\'"])
 if env.get('LOGGING'):
        env.AppendUnique(CPPDEFINES = ['TB_LOG'])
index 19c3440..c1b7904 100755 (executable)
@@ -4,24 +4,62 @@
 # the build script.  For now, use set -e and fail the build at first failure.
 set -e
 
-function clean()
-{
-       echo "*********** Clean build *************"
-       scons -c
-       rm -rf out
-}
-
-function build()
+function build_all()
 {
        if [ $(uname -s) = "Linux" ]
         then
-               echo "*********** Build for linux *************"
-               scons RELEASE=$3
+               build_linux_unsecured $1 $2
+               build_linux_secured $1 $2
+               build_linux_unsecured_with_ra $1 $2
+               build_linux_secured_with_ra $1 $2
+       fi
 
-               echo "*********** Build for linux with Security*************"
-               scons RELEASE=$3 SECURED=1
+       build_android $1 $2
+
+       build_arduino $1 $2
+
+       build_tizen $1 $2
+
+       if [ $(uname -s) = "Darwin" ]
+       then
+               build_darwin $1 $2
        fi
+}
+
+function build_linux()
+{
+       build_linux_unsecured $1 $2
 
+       build_linux_secured $1 $2
+}
+
+function build_linux_unsecured()
+{
+       echo "*********** Build for linux ************"
+       scons RELEASE=$1 $2
+}
+
+function build_linux_secured()
+{
+       echo "*********** Build for linux with Security *************"
+       scons RELEASE=$1 SECURED=1 $2
+}
+
+function build_linux_unsecured_with_ra()
+{
+
+       echo "*********** Build for linux With Remote Access *************"
+       scons RELEASE=$1 WITH_RA=1 $2
+}
+
+function build_linux_secured_with_ra()
+{
+       echo "*********** Build for linux With Remote Access & Security ************"
+       scons RELEASE=$1 WITH_RA=1 SECURED=1 $2
+}
+
+function build_android()
+{
        # Note: for android, as oic-resource uses C++11 feature stoi and to_string,
        # it requires gcc-4.9, currently only android-ndk-r10(for linux)
        # and windows android-ndk-r10(64bit target version) support these features.
@@ -30,77 +68,145 @@ function build()
        export SCONSFLAGS="-Q"
 
        echo "*********** Build for android x86 *************"
-       scons TARGET_OS=android TARGET_ARCH=x86 RELEASE=$3 TARGET_TRANSPORT=IP
+       scons TARGET_OS=android TARGET_ARCH=x86 RELEASE=$1 TARGET_TRANSPORT=IP $2
 
        echo "*********** Build for android armeabi *************"
-       scons TARGET_OS=android TARGET_ARCH=armeabi RELEASE=$3 TARGET_TRANSPORT=IP
+       scons TARGET_OS=android TARGET_ARCH=armeabi RELEASE=$1 TARGET_TRANSPORT=IP $2
 
        # enable parallel build
        export SCONSFLAGS="-Q -j 4"
+}
 
+function build_arduino()
+{
        echo "*********** Build for arduino avr *************"
-       scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$3
-       scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$3
+       scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$1 $2
+       scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$1 $2
 
        echo "*********** Build for arduino arm *************"
-       scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$3
-       scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$3
+       scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$1 $2
+       scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$1 $2
+}
 
+function build_tizen()
+{
+       echo "*********** Build for Tizen CA lib and sample *************"
+       scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true RELEASE=$1 $2
 
-       if [ $(uname -s) = "Darwin" ]
-       then
-               echo "*********** Build for OSX *************"
-               scons TARGET_OS=darwin SYS_VERSION=10.9 RELEASE=$3
+       echo "*********** Build for Tizen CA lib and sample with Security *************"
+       scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP LOGGING=true SECURED=1 RELEASE=$1 $2
+}
+
+function build_darwin() # Mac OSx and iOS
+{
+       echo "*********** Build for OSX *************"
+       scons TARGET_OS=darwin SYS_VERSION=10.9 RELEASE=$1 $2
 
-               echo "*********** Build for IOS i386 *************"
-               scons TARGET_OS=ios TARGET_ARCH=i386 SYS_VERSION=7.0 RELEASE=$3
+       echo "*********** Build for IOS i386 *************"
+       scons TARGET_OS=ios TARGET_ARCH=i386 SYS_VERSION=7.0 RELEASE=$1 $2
 
-               echo "*********** Build for IOS x86_64 *************"
-               scons TARGET_OS=ios TARGET_ARCH=x86_64 SYS_VERSION=7.0 RELEASE=$3
+       echo "*********** Build for IOS x86_64 *************"
+       scons TARGET_OS=ios TARGET_ARCH=x86_64 SYS_VERSION=7.0 RELEASE=$1 $2
 
-               echo "*********** Build for IOS armv7 *************"
-               scons TARGET_OS=ios TARGET_ARCH=armv7 SYS_VERSION=7.0 RELEASE=$3
+       echo "*********** Build for IOS armv7 *************"
+       scons TARGET_OS=ios TARGET_ARCH=armv7 SYS_VERSION=7.0 RELEASE=$1 $2
 
-               echo "*********** Build for IOS armv7s *************"
-               scons TARGET_OS=ios TARGET_ARCH=armv7s SYS_VERSION=7.0 RELEASE=$3
+       echo "*********** Build for IOS armv7s *************"
+       scons TARGET_OS=ios TARGET_ARCH=armv7s SYS_VERSION=7.0 RELEASE=$1 $2
 
-               echo "*********** Build for IOS arm64 *************"
-               scons TARGET_OS=ios TARGET_ARCH=arm64 SYS_VERSION=7.0 RELEASE=$3
-       fi
+       echo "*********** Build for IOS arm64 *************"
+       scons TARGET_OS=ios TARGET_ARCH=arm64 SYS_VERSION=7.0 RELEASE=$1 $2
+}
+
+function unit_tests()
+{
+       scons resource RELEASE=false -c
+       scons resource LOGGING=false RELEASE=false
+       scons resource TEST=1 RELEASE=false
 }
 
 function  help()
 {
        echo "Usage:"
         echo "  build:"
-        echo "     `basename $0` <path-to-android-ndk>"
+        echo "     `basename $0` <target_build>"
+       echo "      Allowed values for <target_build>: all, linux_unsecured, linux_secured, linux_unsecured_with_ra, linux_secured_with_ra, android, arduino, tizen, darwin"
+       echo "      Note: \"linux\" will build \"linux_unsecured\", \"linux_secured\", \"linux_unsecured_with_ra\" & \"linux_secured_with_ra\"."
+       echo "      Any selection will build both debug and release versions of all available targets in the scope you've"
+       echo "      selected. To choose any specific command, please use the SCons commandline directly. Please refer"
+       echo "      to [IOTIVITY_REPO]/Readme.scons.txt."
         echo "  clean:"
         echo "     `basename $0` -c"
 }
 
+# Suppress "Reading ..." message and enable parallel build
+export SCONSFLAGS="-Q -j 4"
+
 if [ $# -eq 1 ]
 then
        if [ $1 = '-c' ]
        then
-               clean
+               build_all true $1
+               build_all false $1
                exit 0
+       elif [ $1 = 'all' ]
+       then
+               build_all true
+               build_all false
+               unit_tests
+       elif [ $1 = 'linux' ]
+       then
+               build_linux true
+               build_linux false
+       elif [ $1 = 'linux_unsecured' ]
+       then
+               build_linux_unsecured true
+               build_linux_unsecured false
+       elif [ $1 = 'linux_secured' ]
+       then
+               build_linux_secured true
+               build_linux_secured false
+       elif [ $1 = 'linux_unsecured_with_ra' ]
+       then
+               build_linux_unsecured_with_ra true
+               build_linux_unsecured_with_ra false
+       elif [ $1 = 'linux_secured_with_ra' ]
+       then
+               build_linux_secured_with_ra true
+               build_linux_secured_with_ra false
+       elif [ $1 = 'android' ]
+       then
+               build_android true
+               build_android false
+       elif [ $1 = 'arduino' ]
+       then
+               build_arduino true
+               build_arduino false
+       elif [ $1 = 'tizen' ]
+       then
+               build_tizen true
+               build_tizen false
+       elif [ $1 = 'darwin' ]
+       then
+               build_darwin true
+               build_darwin false
+       elif [ $1 = 'unit_tests' ]
+       then
+               unit_tests
        else
                help
                exit -1
        fi
-elif [ $# -ne 2 ]
+elif [ $# -eq 0 ]
 then
+       build_all true
+       build_all false
+       unit_tests
+else
        help
        exit -1
 fi
 
-# Suppress "Reading ..." message and enable parallel build
-export SCONSFLAGS="-Q -j 4"
-build $1 $2 true
-build $1 $2 false
-scons resource RELEASE=false -c
-scons resource LOGGING=false RELEASE=false
-scons resource TEST=1 RELEASE=false
 echo "===================== done ====================="
 
 
index 16a81f9..575288c 100644 (file)
@@ -40,7 +40,11 @@ if target_os not in host_target_map[host]:
        print "\nError: Unknown target os: %s (Allow values: %s)\n" % (target_os, host_target_map[host])
        Exit(1)
 
-default_arch = platform.machine()
+if target_os == 'android':
+       default_arch = 'x86'
+else:
+       default_arch = platform.machine()
+
 if default_arch not in os_arch_map[target_os]:
        default_arch = os_arch_map[target_os][0].lower()
 
@@ -50,27 +54,36 @@ target_arch = ARGUMENTS.get('TARGET_ARCH', default_arch) # target arch
 # set to 'no', 'false' or 0 for only compilation
 require_upload = ARGUMENTS.get('UPLOAD', False)
 
+# Get the device name. This name can be used as network display name wherever possible
+device_name = ARGUMENTS.get('DEVICE_NAME', "OIC-DEVICE")
+
 if ARGUMENTS.get('TEST'):
        logging_default = False
 else:
-       logging_default = (ARGUMENTS.get('RELEASE', True) == 'false')
+       release_mode = False
+       if ARGUMENTS.get('RELEASE', True) in ['y', 'yes', 'true', 't', '1', 'on', 'all', True]:
+               release_mode = True
+       logging_default = (release_mode == False)
 
 
 
 ######################################################################
 # Common build options (release, target os, target arch)
 ######################################################################
-targets_disallow_multitransport = ['arduino']
+targets_disallow_multitransport = ['arduino', 'android']
 
 help_vars = Variables()
 help_vars.Add(BoolVariable('VERBOSE', 'Show compilation', False))
 help_vars.Add(BoolVariable('RELEASE', 'Build for release?', True)) # set to 'no', 'false' or 0 for debug
 help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map[host]))
 
+
+help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
+
 if target_os in targets_disallow_multitransport:
-    help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
+       help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
 else:
-    help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP']))
+       help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP']))
 
 help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os]))
 help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1')))
@@ -78,6 +91,16 @@ help_vars.Add(EnumVariable('TEST', 'Run unit tests', '0', allowed_values=('0', '
 help_vars.Add(BoolVariable('LOGGING', 'Enable stack logging', logging_default))
 help_vars.Add(BoolVariable('UPLOAD', 'Upload binary ? (For Arduino)', require_upload))
 help_vars.Add(EnumVariable('BUILD_SAMPLE', 'Build with sample', 'ON', allowed_values=('ON', 'OFF')))
+help_vars.AddVariables(('DEVICE_NAME', 'Network display name for device (For Arduino)', device_name, None, None),)
+
+AddOption('--prefix',
+                  dest='prefix',
+                  type='string',
+                  nargs=1,
+                  action='store',
+                  metavar='DIR',
+                  help='installation prefix')
+
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
 ######################################################################
@@ -95,7 +118,7 @@ if target_os in ['android', 'arduino']: # Android/Arduino always uses GNU compil
                        tools = ['gnulink', 'gcc', 'g++', 'ar', 'as']
                        )
 else:
-       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os)
+       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os, PREFIX = GetOption('prefix'))
 
 Help(help_vars.GenerateHelpText(env))
 
@@ -108,8 +131,11 @@ tc_set_msg = '''
 '''
 if env.get('VERBOSE') == False:
        env['CCCOMSTR'] = "Compiling $TARGET"
+       env['SHCCCOMSTR'] = "Compiling $TARGET"
        env['CXXCOMSTR'] = "Compiling $TARGET"
+       env['SHCXXCOMSTR'] = "Compiling $TARGET"
        env['LINKCOMSTR'] = "Linking $TARGET"
+       env['SHLINKCOMSTR'] = "Linking $TARGET"
        env['ARCOMSTR'] = "Archiving $TARGET"
        env['RANLIBCOMSTR'] = "Indexing Archive $TARGET"
 
@@ -117,12 +143,11 @@ if target_os in targets_support_cc:
        prefix = env.get('TC_PREFIX')
        tc_path = env.get('TC_PATH')
        if prefix:
-               env.Replace(CC = prefix + 'gcc')
-               env.Replace(CXX = prefix + 'g++')
-               env.Replace(AR = prefix + 'ar')
-               env.Replace(AS = prefix + 'as')
-               env.Replace(LINK = prefix + 'ld')
-               env.Replace(RANLIB = prefix + 'ranlib')
+               env.Replace(CC = prefix + env.get('CC', 'gcc'))
+               env.Replace(CXX = prefix + env.get('CXX', 'g++'))
+               env.Replace(AR = prefix + env.get('AR', 'ar'))
+               env.Replace(AS = prefix + env.get('AS', 'as'))
+               env.Replace(RANLIB = prefix + env.get('RANLIB', 'ranlib'))
 
        if tc_path:
                env.PrependENVPath('PATH', tc_path)
@@ -174,6 +199,22 @@ def __install(ienv, targets, name):
        Alias(name, i_n)
        env.AppendUnique(TS = [name])
 
+def __installlib(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/lib', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
+def __installbin(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/bin', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
 def __append_target(ienv, name, targets = None):
        if targets:
                env.Alias(name, targets)
@@ -197,6 +238,8 @@ env.AddMethod(__print_targets, 'PrintTargets')
 env.AddMethod(__src_to_obj, 'SrcToObj')
 env.AddMethod(__append_target, 'AppendTarget')
 env.AddMethod(__install, 'InstallTarget')
+env.AddMethod(__installlib, 'UserInstallTargetLib')
+env.AddMethod(__installbin, 'UserInstallTargetBin')
 env.SetDir(env.GetLaunchDir())
 env['ROOT_DIR']=env.GetLaunchDir()+'/..'
 
@@ -261,6 +304,7 @@ if target_os == "yocto":
     env.AppendUnique(CFLAGS = ['-std=gnu99'])
     env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
     env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread'])
+    env.AppendUnique(LIBS = ['uuid'])
     Export('env')
 else:
     '''
index b90beb0..ca96af6 100644 (file)
@@ -202,7 +202,7 @@ else:
        env.AppendUnique(CCFLAGS = ['-g'])
 
 if env.get('LOGGING'):
-        env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+        env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 
 env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__'])
index 65c0a3b..a086177 100644 (file)
@@ -70,8 +70,15 @@ def __search_files(path, pattern, ondisk=True, source=True, strings=False, recur
 
        matches = []
        for root, dirnames, filenames in os.walk(path):
-               matches.extend(Glob(root + '/' + pattern, ondisk, source, strings))
-
+               # This is a helper function to build Arduino libraries. Scripts are using this function
+               # to add all the files in a folder as compilation targets rather than specifying each
+               # file to compile from a Arduino library folder.
+
+               # Since the function is recursive, it adds even "/library/<library-name>/examples" to the
+               # compilation list. This is an extra overhead as stack is never going to use ".o" generated
+               # for these examples.
+               if 'examples' not in root:
+                       matches.extend(Glob(root + '/' + pattern, ondisk, source, strings))
        return matches
 
 # To make sure the src is built in 'BUILD_DIR' (by default it will be built at
@@ -427,7 +434,11 @@ else:
                env.AppendUnique(LIBS = 'm')
        env.Replace(ARCOM = '$AR ' + platform_info.get('compiler.ar.flags') + ' $TARGET $SOURCES')
 
-
+# Make sure the .d files are removed when clean the build
+if env.GetOption('clean'):
+       dfs = __search_files(env.get('BUILD_DIR'), '*.d')
+       for df in dfs:
+               Execute(Delete(df))
 __build_core(env)
 
 env.AddMethod(__import_lib, "ImportLib") #import arduino library
index 2b0386a..4cbb981 100644 (file)
@@ -4,33 +4,52 @@
 ##
 import os
 import platform
+import commands
+from distutils.version import StrictVersion
 
 Import('env')
 
+target_arch = env.get('TARGET_ARCH')
+target_os = env.get('TARGET_OS')
+
+tc_path=commands.getoutput('xcode-select -p')
+
+tc_sdks=commands.getoutput('xcodebuild -showsdks')
+
+#Find the SDK's that are installed
+sdks=[]
+for line in tc_sdks.split('\n'):
+    if (line == ''):
+        bIn=False
+    if (line[:10] == 'OS X SDKs:'):
+        bIn=(target_os == 'darwin')
+    elif (line[:9] == 'iOS SDKs:'):
+        bIn=(target_os == 'ios')
+    elif bIn:
+        sdks.append(line[:14].strip())
+
+#find the latest
+maxsdk='0.0'
+if len(sdks) > 0:
+    for sdk in sdks:
+        p = sdk.rsplit(' ',1)[1]
+        if (StrictVersion(p)) > StrictVersion(maxsdk):
+            maxsdk=p
+
 # SYS_VERSION build option
 help_vars = Variables()
-help_vars.Add('SYS_VERSION', 'MAC OS X version / IOS version', os.environ.get('SYS_VERSION'))
+help_vars.Add('SYS_VERSION', 'MAC OS X SDK version / IOS SDK version', os.environ.get('SYS_VERSION'))
 help_vars.Update(env)
 Help(help_vars.GenerateHelpText(env))
 
 sys_version = env.get('SYS_VERSION')
 
+#if they didn't explictly set it use the auto-detected one
 if sys_version is None:
-       print '''
-*********************************** Error *************************************
-*   MAC OSX/IOS version isn't set, please set it in command line as :         *
-*      # scons TARGET_ARCH=<arch> TARGET_OS=<os> SYS_VERSION=<version> ...    *
-*   To get the version, please see:                                                              *
-* /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/   *
-* /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ *
-*   <arch> is 'armv7','armv7s','arm64','i386', 'x86_64'
-*   <os> is 'darwin','ios'
-*******************************************************************************
-'''
-       Exit(1)
+    sys_version=maxsdk
+
+env['SYS_VERSION']=sys_version
 
-target_arch = env.get('TARGET_ARCH')
-target_os = env.get('TARGET_OS')
 # Set release/debug flags
 if env.get('RELEASE'):
        env.AppendUnique(CCFLAGS = ['-Os'])
@@ -40,12 +59,12 @@ else:
        env.AppendUnique(LINKFLAGS = ['-g'])
 
 if target_os == 'darwin':
-       sys_root = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX' + sys_version + '.sdk/'
+       sys_root = tc_path + '/Platforms/MacOSX.platform/Developer/SDKs/MacOSX' + sys_version + '.sdk/'
 else:
        if target_arch in ['i386', 'x86_64']:
-               sys_root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator' + sys_version + '.sdk/'
+               sys_root = tc_path + '/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator' + sys_version + '.sdk/'
        else:
-               sys_root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS' + sys_version + '.sdk/'
+               sys_root = tc_path + '/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS' + sys_version + '.sdk/'
 
 # Set arch flags
 env.AppendUnique(CCFLAGS = ['-arch', target_arch, '-isysroot', sys_root])
index 432bbe5..52f0546 100644 (file)
@@ -121,6 +121,14 @@ def __install_lib(ienv, lib):
 
 SConscript('tools/UnpackAll.py')
 
+# tinycbor build/fetch
+SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'tinycbor', 'SConscript'))
+
+with_ra = env.get('WITH_RA')
+if with_ra:
+       SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'raxmpp', 'SConscript'))
+
+
 env.AddMethod(__prepare_lib, "PrepareLib")
 env.AddMethod(__configure, "Configure")
 env.AddMethod(__download, "Download")
index 81be23a..cc3b535 100644 (file)
@@ -8,13 +8,13 @@ print "Reading linux configuration script"
 
 # Set release/debug flags
 if env.get('RELEASE'):
-    env.AppendUnique(CCFLAGS = ['-Os'])
-    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
 else:
-    env.AppendUnique(CCFLAGS = ['-g'])
+       env.AppendUnique(CCFLAGS = ['-g'])
 
 if env.get('LOGGING'):
-    env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+       env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
 
 env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__'])
 env.AppendUnique(CFLAGS = ['-std=gnu99'])
@@ -28,19 +28,19 @@ if env.get('TARGET_OS') == 'tizen':
 # Set arch flags
 target_arch = env.get('TARGET_ARCH')
 if target_arch in ['x86']:
-    env.AppendUnique(CCFLAGS = ['-m32'])
-    env.AppendUnique(LINKFLAGS = ['-m32'])
+       env.AppendUnique(CCFLAGS = ['-m32'])
+       env.AppendUnique(LINKFLAGS = ['-m32'])
 elif target_arch in ['x86_64']:
-    env.AppendUnique(CCFLAGS = ['-m64'])
-    env.AppendUnique(LINKFLAGS = ['-m64'])
+       env.AppendUnique(CCFLAGS = ['-m64'])
+       env.AppendUnique(LINKFLAGS = ['-m64'])
 elif target_arch.find('v7a-hard') > 0:
-    env.AppendUnique(CPPFLAGS = ['-march=armv7-a'])
-    env.AppendUnique(CPPFLAGS = ['-mfloat-abi=hard'])
-    env.AppendUnique(CCFLAGS = ['-mfloat-abi=hard'])
-    env.AppendUnique(LINKFLAGS = ['-mfloat-abi=hard'])
+       env.AppendUnique(CPPFLAGS = ['-march=armv7-a'])
+       env.AppendUnique(CPPFLAGS = ['-mfloat-abi=hard'])
+       env.AppendUnique(CCFLAGS = ['-mfloat-abi=hard'])
+       env.AppendUnique(LINKFLAGS = ['-mfloat-abi=hard'])
 elif target_arch.find('v7a') > 0:
-    env.AppendUnique(CPPFLAGS = ['-march=armv7-a'])
+       env.AppendUnique(CPPFLAGS = ['-march=armv7-a'])
 elif target_arch.find('arm64') >= 0:
-    env.AppendUnique(CPPFLAGS = ['-march=armv8-a'])
+       env.AppendUnique(CPPFLAGS = ['-march=armv8-a'])
 else:
-    env.AppendUnique(CPPFLAGS = ['-march=armv5te'])
+       env.AppendUnique(CPPFLAGS = ['-march=armv5te'])
diff --git a/build_docs.sh b/build_docs.sh
new file mode 100755 (executable)
index 0000000..7c0bdbc
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# Fail script on any failure
+set -e
+
+# Move to script direotory
+pushd `dirname $0` > /dev/null
+
+rm -rf docs
+
+# JavaDoc now... from Uze's script
+ANDROID_JAR="$ANDROID_HOME/platforms/android-21/android.jar"
+
+if [ ! -e "$ANDROID_JAR" ]; then
+    echo "Android platform not found. Expected '$ANDROID_JAR'"
+    exit 1
+fi
+
+BASE_PATH="android/android_api/base/src/main/java/"
+BASE_PKG="org.iotivity.base"
+
+TM_PATH="service/things-manager/sdk/java/src/"
+TM_PKG="org.iotivity.service.tm"
+
+SSM_PATH="service/soft-sensor-manager/SDK/java/"
+SSM_PKG="org.iotivity.service.ssm"
+
+PPM_PATH="service/protocol-plugin/plugin-manager/src/Android/src"
+PPM_PKG="service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/PluginManager.java service/protocol-plugin/plugin-manager/src/Android/src/org/iotivity/service/ppm/Plugin.java"
+# PPM_PKG="org.iotivity.service.ppm"
+
+javadoc -splitindex \
+        -d ./docs/java \
+        -sourcepath $BASE_PATH:$TM_PATH:$SSM_PATH $BASE_PKG $TM_PKG $SSM_PKG $PPM_PKG \
+        -classpath $ANDROID_JAR
+
+# Doxygen now...
+# NOTE: For now this is a workaround since I am ready to modify the doxygen setup
+pushd resource/docs > /dev/null
+doxygen
+
+# Check for warnings or errors
+if [ -s doxygen.log ]; then
+    echo "Errors running doxygen. Review doxygen.log"
+    exit 2
+fi
+
+popd > /dev/null
+rm -rf docs/cxx
+mv resource/docs/docs/html docs/cxx
+
+popd > /dev/null
index b753b94..6acab49 100644 (file)
@@ -39,7 +39,7 @@ void MiddleClient::findResources()
 {
     m_resourceMap.clear();
 
-    OC::OCPlatform::findResource("", OC_WELL_KNOWN_QUERY, OC_ALL, m_findCB);
+    OC::OCPlatform::findResource("", OC_RSRVD_WELL_KNOWN_URI, CT_DEFAULT, m_findCB);
 }
 
 void MiddleClient::foundOCResource(shared_ptr<OCResource> resource)
index 685d33a..5fac3ed 100644 (file)
@@ -235,7 +235,7 @@ LineResult LineInput::processGet(elements_t& elems, stringstream& ss)
         return LR_Timeout;
     }
 
-    std::string jsonRep = wreq->m_rep.getJSONRepresentation();
+    std::string jsonRep ;//= wreq->m_rep.getJSONRepresentation();
     //ss << jsonRep << endl;
     printJSONAsTable(jsonRep);
         return LR_OK;
@@ -356,7 +356,7 @@ void LineInput::obsCB(token_t token, const HeaderOptions& headerOptions, const O
     if (!m_observer)
         return;
     cout << "cb " << eCode << " " << sequenceNumber << '\n';
-    cout << rep.getJSONRepresentation() << "\n";
+    //cout << rep.getJSONRepresentation() << "\n";
 }
 
 ParseState LineInput::finishElem(char*& e, elements_t& elems)
index 0da4145..0fed217 100644 (file)
@@ -44,6 +44,14 @@ Middle::Middle() :
 {
 }
 
+Middle::~Middle()
+{
+    delete m_client;
+    delete m_server;
+    delete m_lineInput;
+    delete m_restInput;
+}
+
 void Middle::init()
 {
 
index 457b7a8..d9d2564 100644 (file)
@@ -65,6 +65,7 @@ class Middle
 {
 public:
     Middle();
+    ~Middle();
     void init();
     void run(int argc, char* argv[]);
 
index b6e240f..b922ebe 100644 (file)
@@ -26,7 +26,6 @@
 using namespace std;
 
 #define BUFLEN 10000
-#define MAX_CONNS 5
 
 static bool enableDebug = false; // set to true to print debug messages
 
@@ -40,10 +39,15 @@ void printDebugMessage(std::string message)
 RestInput::RestInput(LineInput *lineInput) : m_lineInput(lineInput)
 {
     m_data = (char*)malloc(BUFLEN);
-    m_thread = new std::thread[MAX_CONNS];
     m_threadCount = 0;
 }
 
+RestInput::~RestInput()
+{
+    free(m_data);
+    close(m_sockfd);
+}
+
 bool RestInput::init()
 {
     m_sockfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -81,6 +85,7 @@ void RestInput::startAccept(int &sockfd)
                 return;
             }
             int n = read(connfd, m_data, BUFLEN);
+            close(connfd);
             if (n < 0) {
                 cerr << "Failed to read from socket" << endl;
                 return;
index 2e1cad6..56ec3ff 100644 (file)
@@ -28,8 +28,10 @@ class Connection;
 
 class RestInput
 {
+    static const int MAX_CONNS = 5;
 public:
     RestInput(LineInput *lineInput);
+    ~RestInput();
     bool init();
     void startAccept(int &sockfd);
     void startThread();
@@ -43,7 +45,7 @@ protected:
     int m_sockfd, m_port, m_threadCount;
     struct sockaddr_in m_serverAddr;
     char *m_data;
-    std::thread *m_thread;
+    std::thread m_thread[MAX_CONNS];
 };
 
 #endif // RESTINPUT_H
diff --git a/examples/OICMiddle/SConstruct b/examples/OICMiddle/SConstruct
deleted file mode 100644 (file)
index 02a2d8e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#For Yocto builds, set OS=yocto as a command-line argument to scons once
-#the Yocto toolchain is installed and configured.
-
-#For Linux builds, set the following two variables:
-#Set OIC_RESOURCE_PATH to the root of oic-resource on Ubuntu.
-
-OIC_RESOURCE_PATH = '../..'
-
-#Set OIC_LIBS_PATH to path on Ubuntu that contains liboc.so, liboctbstack.so,
-#liboc_logger.so and libcoap.so.
-
-OIC_LIBS_PATH = '../../out/linux/x86_64/release'
-
-env = DefaultEnvironment()
-target_os = ARGUMENTS.get("OS", "linux").lower()
-output_dir = env.GetLaunchDir() + "/out/" + target_os
-env.VariantDir(output_dir, env.GetLaunchDir(), duplicate=0)
-env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
-env.AppendUnique(LINKFLAGS = ['-pthread'])
-env.AppendUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'coap'])
-env.Program(output_dir + '/OICMiddle', [output_dir + '/OICMiddle.cpp',
-                          output_dir + '/Client.cpp',
-                          output_dir + '/Server.cpp',
-                          output_dir + '/WrapResource.cpp',
-                          output_dir + '/LineInput.cpp',
-                          output_dir + '/RestInput.cpp'])
-
-if target_os == "yocto":
-    '''
-    This code injects Yocto cross-compilation flags into scons' default environment
-    in order to invoke the relevant tools while performing a build.
-    '''
-    import os.path, re
-    sdk_root = ''
-    try:
-        CC = os.environ['CC']
-        sdk_root = re.search(r'--sysroot=\S+', CC).group().split('=')[1]
-        target_prefix = CC.split()[0]
-        target_prefix = target_prefix[:len(target_prefix)-3]
-        tools = {"CC" : target_prefix+"gcc",
-                 "CXX" : target_prefix+"g++",
-                 "AS" : target_prefix+"as",
-                 "LD" : target_prefix+"ld",
-                 "GDB" : target_prefix+"gdb",
-                 "STRIP" : target_prefix+"strip",
-                 "RANLIB" : target_prefix+"ranlib",
-                 "OBJCOPY" : target_prefix+"objcopy",
-                 "OBJDUMP" : target_prefix+"objdump",
-                 "AR" : target_prefix+"ar",
-                 "NM" : target_prefix+"nm",
-                 "M4" : "m4",
-                 "STRINGS": target_prefix+"strings"}
-        PATH = os.environ['PATH'].split(os.pathsep)
-        for tool in tools:
-            if tool in os.environ:
-                for path in PATH:
-                   if os.path.isfile(os.path.join(path, tools[tool])):
-                       env[tool] = os.path.join(path, os.environ[tool])
-        env.AppendUnique(CPPPATH = [
-                sdk_root + '/usr/include/oic/',
-                sdk_root + '/usr/include/oic/stack/',
-                sdk_root + '/usr/include/oic/ocsocket/',
-                sdk_root + '/usr/include/oic/oc_logger/',
-                ])
-    except:
-        print "ERROR configuring Yocto cross-toolchain environment."
-        Exit(1)
-elif target_os == "linux":
-    if OIC_RESOURCE_PATH == '' or OIC_LIBS_PATH == '':
-        print "ERROR Please set both OIC_RESOURCE_PATH and OIC_LIBS_PATH in SConstruct"
-        Exit(1)
-    env.AppendUnique(CPPPATH = [
-                OIC_RESOURCE_PATH + '/resource/include',
-                OIC_RESOURCE_PATH + '/resource/csdk/stack/include',
-                OIC_RESOURCE_PATH + '/resource/csdk/ocsocket/include',
-                OIC_RESOURCE_PATH + '/resource/oc_logger/include',
-                ])
-    env.AppendUnique(LIBPATH = [OIC_LIBS_PATH])
-else:
-    print "ERROR ", target_os, " is an unsupported target"
-    Exit(1)
index 3cadb7d..a064d28 100644 (file)
@@ -164,7 +164,7 @@ void WrapResource::parseJSON(WrapRequest *wreq)
 {
     string sep = "\":";
     string anchor = "\"rep\":{";
-    string json = wreq->m_rep.getJSONRepresentation();
+    string json;// = wreq->m_rep.getJSONRepresentation();
     string name, type, value, next;
     size_t r, e, e1, s, c;
 
diff --git a/examples/OICSensorBoard/Makefile b/examples/OICSensorBoard/Makefile
new file mode 100644 (file)
index 0000000..ce6b173
--- /dev/null
@@ -0,0 +1,34 @@
+#Set the two variables below for the client build. 
+CLIENTARCH=x86
+BUILDTYPE=release
+##
+
+YOCTOCXXFLAGS=-I$(SDKTARGETSYSROOT)/usr/include/iotivity/resource/ -I$(SDKTARGETSYSROOT)/usr/include/iotivity/resource/stack -I$(SDKTARGETSYSROOT)/usr/include/iotivity/resource/ocrandom -I$(SDKTARGETSYSROOT)/usr/include/iotivity/resource/logger -I$(SDKTARGETSYSROOT)/usr/include/iotivity/resource/oc_logger
+
+YOCTOLDFLAGS=-loc -loctbstack -loc_logger -lmraa
+
+CXXFLAGS=-I../../resource/include -I../../resource/csdk/stack/include -I../../resource/csdk/ocrandom/include -I../../resource/csdk/logger/include -I../../resource/oc_logger/include
+
+LDFLAGS=-L../../out/linux/$(CLIENTARCH)/$(BUILDTYPE) -loc -loctbstack -loc_logger
+
+client: client.o
+       g++ -o client client.o $(LDFLAGS)
+
+client.o: client.cpp
+       g++ -std=c++0x -c -o $@ $< $(CXXFLAGS)
+
+observer.o: observer.cpp
+       $(CXX) -std=c++0x -c -o $@ $< $(YOCTOCXXFLAGS)
+
+server.o: server.cpp
+ifeq ($(SDKTARGETSYSROOT),)
+       echo "Error: Yocto cross-toolchain environment not initialized"
+       exit 1 
+endif
+       $(CXX) -std=c++0x -c -o $@ $< $(YOCTOCXXFLAGS)
+
+server: server.o observer.o
+       $(CXX) -o server server.o observer.o $(YOCTOLDFLAGS)
+
+clean:
+       rm -rf server client *.o
diff --git a/examples/OICSensorBoard/OICSensorBoardREADME.pdf b/examples/OICSensorBoard/OICSensorBoardREADME.pdf
deleted file mode 100644 (file)
index d5f9f2d..0000000
Binary files a/examples/OICSensorBoard/OICSensorBoardREADME.pdf and /dev/null differ
diff --git a/examples/OICSensorBoard/README b/examples/OICSensorBoard/README
new file mode 100644 (file)
index 0000000..c941e9a
--- /dev/null
@@ -0,0 +1,14 @@
+//******************************************************************
+//
+// This example includes
+// - Server application for Edison which demonstrates Iotivity server
+//   capabilities through the integration of an add-on breadboard that
+//   hosts temperature, ambient light and LED resources.
+// - Client application to test server functionality, discovering and
+//   communicating with these resources.
+//
+// See complete documentation at
+//        https://wiki.iotivity.org/_media/oicsensorboardreadme.pdf
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
diff --git a/examples/OICSensorBoard/SConstruct b/examples/OICSensorBoard/SConstruct
deleted file mode 100644 (file)
index 2a468aa..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#******************************************************************
-#
-# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-#
-#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#This script builds edisonclient for Ubuntu and edisonserver for Yocto.
-
-#Client build for Ubuntu
-#Set IOTIVITY_ROOT to the root of oic-resource on Ubuntu.
-IOTIVITY_ROOT = ''
-#Set IOTIVITY_LIBS_PATH to path on Ubuntu that contains liboc.so, liboctbstack.so, liboc_logger.so and libcoap.so.
-IOTIVITY_LIBS_PATH = ''
-
-env = DefaultEnvironment()
-env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
-env.AppendUnique(LINKFLAGS = ['-pthread'])
-env.AppendUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'coap'])
-
-envClient = env.Clone()
-envClient.AppendUnique(CPPPATH = [
-                IOTIVITY_ROOT + '/resource/include',
-                IOTIVITY_ROOT + '/resource/csdk/stack/include',
-                IOTIVITY_ROOT + '/resource/oc_logger/include',
-                ])
-envClient.AppendUnique(LIBPATH = [IOTIVITY_LIBS_PATH])
-envClient.Program('edisonclient', 'client.cpp')
-
-#Server build
-envServer = env.Clone()
-'''
-This code injects Yocto cross-compilation flags into scons' default environment
-in order to invoke the relevant tools while performing a build.
-'''
-import os.path, re
-sdk_root = ''
-try:
-    CC = os.environ['CC']
-    sdk_root = re.search(r'--sysroot=\S+', CC).group().split('=')[1]
-    target_prefix = CC.split()[0]
-    target_prefix = target_prefix[:len(target_prefix)-3]
-    tools = {"CC" : target_prefix+"gcc",
-             "CXX" : target_prefix+"g++",
-             "AS" : target_prefix+"as",
-             "LD" : target_prefix+"ld",
-             "GDB" : target_prefix+"gdb",
-             "STRIP" : target_prefix+"strip",
-             "RANLIB" : target_prefix+"ranlib",
-             "OBJCOPY" : target_prefix+"objcopy",
-             "OBJDUMP" : target_prefix+"objdump",
-             "AR" : target_prefix+"ar",
-             "NM" : target_prefix+"nm",
-             "M4" : "m4",
-             "STRINGS": target_prefix+"strings"}
-    PATH = os.environ['PATH'].split(os.pathsep)
-    for tool in tools:
-        if tool in os.environ:
-            for path in PATH:
-                   if os.path.isfile(os.path.join(path, tools[tool])):
-                       envServer[tool] = os.path.join(path, os.environ[tool])
-    envServer.Program('edisonserver', ['server.cpp', 'observer.cpp'])
-    envServer.AppendUnique(LIBS = ['mraa'])
-    envServer.AppendUnique(CPPPATH = [
-                sdk_root + '/usr/include/iotivity/',
-                sdk_root + '/usr/include/iotivity/stack/',
-                sdk_root + '/usr/include/iotivity/oc_logger/',
-                ])
-except:
-    print "ERROR configuring Yocto cross-toolchain environment. This is required for building the server"
-
index 4b7fe85..724735f 100644 (file)
@@ -42,8 +42,8 @@ void IoTClient::initializePlatform()
 
 void IoTClient::findResource()
 {
-    string coap_multicast_discovery = string(OC_WELL_KNOWN_QUERY "?if=" EDISON_RESOURCE_INTERFACE);
-    OCPlatform::findResource("", coap_multicast_discovery.c_str(), m_resourceDiscoveryCallback,
+    string coap_multicast_discovery = string(OC_RSRVD_WELL_KNOWN_URI "?if=" EDISON_RESOURCE_INTERFACE);
+    OCPlatform::findResource("", coap_multicast_discovery.c_str(),  CT_DEFAULT, m_resourceDiscoveryCallback,
                              OC::QualityOfService::LowQos);
 }
 
@@ -148,7 +148,7 @@ void TemperatureSensor::onObserve(const HeaderOptions headerOptions, const OCRep
     {
         double value;
         rep.getValue(TEMPERATURE_RESOURCE_KEY, value);
-        cout << "Observing TemperatureSensor: Current temperature reading is " << value << endl;
+        cout << "Observing TemperatureSensor: Current temperature reading in Celsius is " << value << endl;
         cout << "Sequence number: " << sequenceNumber << endl;
     }
     else
@@ -170,7 +170,7 @@ void TemperatureSensor::onGet(const HeaderOptions& headerOptions,
     {
         double value;
         representation.getValue(TEMPERATURE_RESOURCE_KEY, value);
-        cout << endl << endl << "Current temperature reading: " << value << endl;
+        cout << endl << endl << "Current temperature reading in Celsius: " << value << endl;
     }
     else {
         cerr << endl << endl << "Error in GET response from temperature sensor resource" << endl;
index 44ad441..aecbf4c 100644 (file)
@@ -25,6 +25,7 @@
 #define ONBOARD_LED_PIN 13
 #define TEMPERATURE_AIO_PIN 0
 #define LIGHT_SENSOR_AIO_PIN 2
+#define SAMPLE_NUM 5
 
 namespace Sensors
 {
@@ -60,20 +61,40 @@ inline void SetOnboardLed(int on)
         mraa_gpio_write(led_gpio, on); // Writes into GPIO
 }
 
-inline float GetTemperatureInC()
+inline float GetAverageTemperatureRaw()
 {
-    float ret = 0;
     if (tmp_aio == NULL)
     {
         tmp_aio = mraa_aio_init(TEMPERATURE_AIO_PIN); // initialize pin 0
     }
-    if (tmp_aio != NULL)
-    {
-        uint16_t adc_value = mraa_aio_read(tmp_aio); // read the raw value
-        //convert reading to temperature
-        float beta = 4090.0; //the beta of the thermistor, magic number
-        ret = beta / (log((4095.0 * 10 / adc_value - 10) / 10) + beta / 298.0) - 273.0;
-    }
+    
+    uint16_t adc_value = 0;
+    for (int i=0; i< SAMPLE_NUM; i++)
+        adc_value += mraa_aio_read(tmp_aio);           // read the raw value
+    
+    float average = (float)adc_value/SAMPLE_NUM;
+    cout << "Temperature reading raw ..."  << average << endl;
+    
+    return average;
+}
+
+inline float GetTemperatureInC()
+{
+    // Temperature calculation using simpilfy Steinhart-Hart equation
+    //
+    //          1/T = 1/T0 + 1/beta*ln (R/R0)
+    //
+    // where T0 = 25C room temp, R0 = 10000 ohms
+    //
+    float beta = 4090.0;            //the beta of the thermistor, magic number
+    float t_raw = GetAverageTemperatureRaw();
+    float R = 1023.0/t_raw -1;      // 
+    R = 10000.0/R;                  // 10K resistor divider circuit
+        
+    float T1 = log(R/10000.0)/beta; // natural log 
+    float T2 = T1 + 1.0/298.15;     // room temp 25C= 298.15K
+    float ret = 1.0/T2 - 273.0;
     return ret;
 }
 
index 598e370..a8b7a23 100644 (file)
@@ -20,6 +20,7 @@
 #include <signal.h>
 #include <thread>
 #include <functional>
+
 #include "server.h"
 #include "sensors.h"
 #include "namedefs.h"
index aa268e6..17331bd 100644 (file)
@@ -45,7 +45,7 @@ if target_os == 'android':
                        print 'Unzipping android lib...'
                        env.UnpackAll(androidlib_dir, androidlib_zip)
                        print 'Unzipping android lib complete'
-    
+
                        # Remove downloaded file
 #                      os.remove(androidlib_zip_file)
        else:
index 268c061..ede704f 100644 (file)
@@ -69,85 +69,112 @@ if target_os == 'arduino':
        timelib_dir         = arduinolib_dir + '/libraries/Time'
 
        if not os.path.exists(timelib_dir):
-               timelib_zip_file    = src_dir + '/extlibs/arduino/Time.zip'
-               timelib_url         = 'http://playground.arduino.cc/uploads/Code/Time.zip'
-               # Install Arduino Time library
-               # If the zip file is not already present, download it
-               os.mkdir(timelib_dir)
-               os.chdir(timelib_dir)
-               if not os.path.exists(timelib_zip_file):
-                       timelib_zip = env.Download(timelib_zip_file, timelib_url)
-               else:
-                       timelib_zip = timelib_zip_file
+               if WhereIs('dos2unix') is not None:
+                       timelib_zip_file    = src_dir + '/extlibs/arduino/Time.zip'
+                       timelib_url         = 'http://playground.arduino.cc/uploads/Code/Time.zip'
+                       # Install Arduino Time library
+                       # If the zip file is not already present, download it
+                       os.mkdir(timelib_dir)
+                       os.chdir(timelib_dir)
+                       if not os.path.exists(timelib_zip_file):
+                               timelib_zip = env.Download(timelib_zip_file, timelib_url)
+                       else:
+                               timelib_zip = timelib_zip_file
 
-               # Unzip the lib
-               print 'Unzipping Arduino Time lib...'
-               env.UnpackAll(timelib_dir + '/Time', timelib_zip)
+                       # Unzip the lib
+                       print 'Unzipping Arduino Time lib...'
+                       env.UnpackAll(timelib_dir + '/Time', timelib_zip)
 
-               # Apply patches to ARDUINO_HOME directory.
-               os.chdir(arduinolib_dir)
-               print 'Patching Arduino libraries...'
-               os.system("find ./libraries/Time/Time/DateStrings.cpp -type f -exec dos2unix {} \;")
-               os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch --directory=" + arduinolib_dir)
+                       # Apply patches to ARDUINO_HOME directory.
+                       os.chdir(arduinolib_dir)
+                       print 'Patching Arduino libraries...'
 
-               # Remove downloaded file
-               os.remove(timelib_zip_file)
+                       os.system("find ./libraries/Time/Time/DateStrings.cpp -type f -exec dos2unix {} \;")
+                       os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch --directory=" + arduinolib_dir)
+
+                       # Remove downloaded file
+                       os.remove(timelib_zip_file)
+               else:
+                       print 'Please manually install package dos2unix. The build process will end now. Your Action Required: Install package manually, then restart build process.'
+                       print 'You may likely retrieve this package as follows:'
+                       print '      sudo apt-get install dos2unix'
+                       print '               or'
+                       print '      sudo yum install dos2unix'
+                       exit(1)
 
        redbearlib_dir         = arduinolib_dir + '/libraries/RBL_nRF8001'
 
        if not os.path.exists(redbearlib_dir):
-               redbearlib_zip_file    = src_dir + '/extlibs/arduino/25643e7b1b7da3740406325a471e3faa4b948747.zip'
-               redbearlib_url         = 'https://github.com/RedBearLab/nRF8001/archive/25643e7b1b7da3740406325a471e3faa4b948747.zip'
-               if not os.path.exists(redbearlib_zip_file):
-                       redbearlib_zip = env.Download(redbearlib_zip_file, redbearlib_url)
-               else:
-                       redbearlib_zip = redbearlib_zip_file
+               if WhereIs('dos2unix') is not None:
+                       redbearlib_zip_file    = src_dir + '/extlibs/arduino/25643e7b1b7da3740406325a471e3faa4b948747.zip'
+                       redbearlib_url         = 'https://github.com/RedBearLab/nRF8001/archive/25643e7b1b7da3740406325a471e3faa4b948747.zip'
+                       if not os.path.exists(redbearlib_zip_file):
+                               redbearlib_zip = env.Download(redbearlib_zip_file, redbearlib_url)
+                       else:
+                               redbearlib_zip = redbearlib_zip_file
+
+                       # Unzip the lib
+                       print 'Unzipping Red Bear lib...'
+                       os.chdir(arduinolib_dir + '/libraries')
+                       env.UnpackAll(redbearlib_dir, redbearlib_zip)
 
-               # Unzip the lib
-               print 'Unzipping Red Bear lib...'
-               os.chdir(arduinolib_dir + '/libraries')
-               env.UnpackAll(redbearlib_dir, redbearlib_zip)
+                       # Because the way Red Bear lib is distributed... All Red Bear source files must be moved up a few directories.
+                       shutil.move('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747/Arduino/libraries/RBL_nRF8001/', '.')
+                       shutil.rmtree('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747')
 
-               # Because the way Red Bear lib is distributed... All Red Bear source files must be moved up a few directories.
-               shutil.move('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747/Arduino/libraries/RBL_nRF8001/', '.')
-               shutil.rmtree('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747')
+                       # Apply Red Bear patches
+                       print 'Patching Red Bear library...'
+                       os.chdir(arduinolib_dir + '/libraries/RBL_nRF8001/')
 
-               # Apply Red Bear patches
-               print 'Patching Red Bear library...'
-               os.chdir(arduinolib_dir + '/libraries/RBL_nRF8001/')
-               os.system("find . -type f -exec dos2unix {} \;")
-               os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch")
+                       os.system("find . -type f -exec dos2unix {} \;")
+                       os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch")
 
-               # Remove downloaded file
-               os.remove(redbearlib_zip_file)
+                       # Remove downloaded file
+                       os.remove(redbearlib_zip_file)
+               else:
+                       print 'Please manually install package dos2unix. The build process will end now. Your Action Required: Install package manually, then restart build process.'
+                       print 'You may likely retrieve this package as follows:'
+                       print '      sudo apt-get install dos2unix'
+                       print '               or'
+                       print '      sudo yum install dos2unix'
+                       exit(1)
 
        nordiclib_dir           = arduinolib_dir + '/libraries/BLE'
 
        if not os.path.exists(nordiclib_dir):
-               nordiclib_zip_file    = src_dir + '/extlibs/arduino/ble-sdk-arduino-0.9.5.beta.zip'
-                nordiclib_url         = 'https://github.com/NordicSemiconductor/ble-sdk-arduino/archive/0.9.5.beta.zip'
-               if not os.path.exists(nordiclib_zip_file):
-                       nordiclib_zip = env.Download(nordiclib_zip_file, nordiclib_url)
-               else:
-                       nordiclib_zip = nordiclib_zip_file
-
-               # Unzip the lib
-               print 'Unzipping Nordic lib...'
-               os.chdir(arduinolib_dir + '/libraries')
-               env.UnpackAll(nordiclib_dir, nordiclib_zip)
-
-               # Because the way Nordic lib is distributed... All Nordic source files must be moved up a few directories.
-               shutil.move('ble-sdk-arduino-0.9.5.beta/libraries/BLE/', '.')
-               shutil.rmtree('ble-sdk-arduino-0.9.5.beta')
-
-               # Apply Nordic lib patches
-               print 'Patching Nordic library...'
-               os.chdir(arduinolib_dir + '/libraries/BLE/')
-               os.system("find . -type f -exec dos2unix {} \;")
-               os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch")
+               if WhereIs('dos2unix') is not None:
+                       nordiclib_zip_file    = src_dir + '/extlibs/arduino/ble-sdk-arduino-0.9.5.beta.zip'
+                       nordiclib_url         = 'https://github.com/NordicSemiconductor/ble-sdk-arduino/archive/0.9.5.beta.zip'
+                       if not os.path.exists(nordiclib_zip_file):
+                               nordiclib_zip = env.Download(nordiclib_zip_file, nordiclib_url)
+                       else:
+                               nordiclib_zip = nordiclib_zip_file
+
+                       # Unzip the lib
+                       print 'Unzipping Nordic lib...'
+                       os.chdir(arduinolib_dir + '/libraries')
+                       env.UnpackAll(nordiclib_dir, nordiclib_zip)
+
+                       # Because the way Nordic lib is distributed... All Nordic source files must be moved up a few directories.
+                       shutil.move('ble-sdk-arduino-0.9.5.beta/libraries/BLE/', '.')
+                       shutil.rmtree('ble-sdk-arduino-0.9.5.beta')
+
+                       # Apply Nordic lib patches
+                       print 'Patching Nordic library...'
+                       os.chdir(arduinolib_dir + '/libraries/BLE/')
+
+                       os.system("find . -type f -exec dos2unix {} \;")
+                       os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch")
                
-               # Remove downloaded file
-               os.remove(nordiclib_zip_file)
+                       # Remove downloaded file
+                       os.remove(nordiclib_zip_file)
+               else:
+                       print 'Please manually install package dos2unix. The build process will end now. Your Action Required: Install package manually, then restart build process.'
+                       print 'You may likely retrieve this package as follows:'
+                       print '      sudo apt-get install dos2unix'
+                       print '               or'
+                       print '      sudo yum install dos2unix'
+                       exit(1)
 
 # Set the ARDUINO_HOME
 env.Replace(ARDUINO_HOME = arduinolib_dir)
index 0fe0662..26f0c1e 100644 (file)
@@ -23,20 +23,24 @@ if 'android' == target_os :
     boost_version   = '1.58.0'
     boost_base_name  = 'boost_'+string.replace(boost_version,'.','_')
     boost_arch_name  = boost_base_name+'.zip'
+    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'
 
     host_os = sys.platform
 
     if host_os == 'linux2' :
         boost_bootstrap = boost_base_name+os.sep+'bootstrap.sh'
-        boost_b2_name    = boost_base_name+os.sep+'b2'
     else :
         msg="Host platform (%s) is currently not supported for boost builds" % host_os
         raise SCons.Errors.EnvironmentError(msg)
 
-    boost_zip = env.URLDownload(boost_arch_name, boost_url)
-    boost_dir = env.UnpackAll(boost_bootstrap, boost_zip)
-    boost_b2  = env.BoostBootstrap(boost_b2_name, boost_dir)
+    if not os.path.exists(boost_arch_name) and not os.path.exists(boost_base_name):
+        boost_arch_name = env.URLDownload(boost_arch_name, boost_url)
+
+    if not os.path.exists(boost_base_name):
+       boost_arch_name = env.UnpackAll(boost_bootstrap, boost_arch_name)
+
+    boost_b2  = env.BoostBootstrap(boost_b2_name, boost_arch_name)
 
     dep_sys_root = env['DEP_SYS_ROOT']
     dep_src_dir =  dep_sys_root + os.sep + 'include'
index 4ebe318..acd236e 100755 (executable)
@@ -7,15 +7,6 @@ cd "$(dirname "$0")"
 
 EXTDIR=$(pwd)
 
-# Check for cereal existence
-if [ ! -d "cereal" ]; then
-    git clone https://github.com/USCiLab/cereal.git cereal
-    pushd cereal
-    git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
-    git apply ../../resource/patches/cereal_gcc46.patch
-    popd
-fi
-
 # Pick the preferred version of boost to use
 BOOST_MAJOR=1
 BOOST_MINOR=57
@@ -44,8 +35,8 @@ function buildBoost {
     if [ ! -d "boost" ]; then
         cloneBoost
     fi
-    
-    # Determine the 
+
+    # Determine the
     TOOLCHAIN=${ANDROID_NDK}/toolchains/${TOOLSET}-${VERSION}/prebuilt/${HOST_ARCH}/bin
 
     OLDPATH=$PATH
diff --git a/extlibs/cereal/SConscript b/extlibs/cereal/SConscript
deleted file mode 100644 (file)
index 946a483..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-######################################################################
-# Cereal library build script
-#
-# Only 'hpp' is used by Iotivity, it's unnecessary to build it
-######################################################################
-import os
-
-Import('env')
-
-src_dir = env.get('SRC_DIR')
-
-# In the pass, cereal library is in extlibs/cereal, according to external
-# library management rule, cereal should be put in extlibs/cereal/cereal.
-# jenkins of gerrit server, still follow the old, to avoid jenkins fail
-# both places are handled.
-old = os.path.join(src_dir, 'extlibs', 'cereal', 'include')
-cur = os.path.join(src_dir, 'extlibs', 'cereal', 'cereal', 'include')
-
-# check 'cereal' library, if it doesn't exits, ask user to download it
-if not os.path.exists(old) and not os.path.exists(cur):
-       cereal_env = Environment(ENV = os.environ)
-       c = cereal_env.Action(['git clone https://github.com/USCiLab/cereal.git cereal',
-               'cd cereal && git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 && git apply ../../../resource/patches/cereal_gcc46.patch',
-               ])
-
-       print 'Downloading cereal library ...'
-       if cereal_env.Execute(c):
-               print '''
-*********************************** Error: ************************************
-* Please download cereal and apply the patch as following:                    *
-*     $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal *
-*     $ cd  extlibs/cereal/cereal                                             *
-*     $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245             *
-*     $ git apply ../../../resource/patches/cereal_gcc46.patch                *
-*******************************************************************************
-'''
-               Exit(1)
-       else:
-               print 'Download cereal library complete'
-
-env.AppendUnique(CPPPATH = [old, cur])
index 396e4f3..4dfa7ea 100644 (file)
@@ -37,29 +37,30 @@ if target_os == 'darwin':
                gtest_lib_dir = gtest_dir + '/lib'
                gtest_dotlib_dir = gtest_lib_dir + '/.libs'
 
-               if not os.path.exists(gtest_lib_dir):
-                       print 'Create a directory'
-                       os.mkdir(gtest_lib_dir)
+        if not os.path.exists(gtest_lib_dir):
+#                      print 'Create a directory'
+#                      os.mkdir(gtest_lib_dir)
 
-                       print 'Change to a directory'
-                       os.chdir(gtest_lib_dir)
 
                        print 'Invoke cmake command to generate appropriate make files'
-                       env.Configure(gtest_lib_dir, 'cmake -G"Unix Makefiles" ..')
+                       env.Configure(gtest_dir, './configure')
 
                        # Run make on gtest
                        print 'Making google unit test'
-                       env.Configure(gtest_lib_dir, 'make')
+                       env.Configure(gtest_dir, 'make')
 
-                       print 'Create a directory'
-                       os.mkdir(gtest_dotlib_dir)
+#                      print 'Create a directory'
+#                      os.mkdir(gtest_dotlib_dir)
 
                        print 'Change to a directory'
                        os.chdir(gtest_dotlib_dir)
 
+##                     print 'Change to a directory'
+#                      os.chdir(gtest_lib_dir)
+
                        print 'Create hard links pointing to gtest libraries'
-                       os.link('../' + 'libgtest.a', 'libgtest.a')
-                       os.link('../' + 'libgtest_main.a', 'libgtest_main.a')
+                       os.link('libgtest.a', gtest_lib_dir + 'libgtest.a')
+                       os.link('libgtest_main.a', gtest_lib_dir +  'libgtest_main.a')
                        print 'Create hard links pointing to gtest libraries - DONE'
 
 
diff --git a/extlibs/raxmpp/SConscript b/extlibs/raxmpp/SConscript
new file mode 100644 (file)
index 0000000..29d5cad
--- /dev/null
@@ -0,0 +1,60 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+######################################################################
+# raxmpp library build script
+#
+######################################################################
+import os
+import commands
+
+Import('env')
+
+src_dir = env.get('SRC_DIR')
+target_os = env.get('TARGET_OS')
+target_arch = env.get('TARGET_ARCH')
+with_ra = env.get('WITH_RA')
+if with_ra:
+       # check 'raxmppl' library, if it doesn't exits, ask user to download it
+       if not os.path.exists('raxmpp'):
+               print '''
+       *********************************** Error: ***********************************************
+       * Please download ra_xmpp as following :
+       *     $ git clone https://gerrit.iotivity.org/gerrit/iotivity-xmpp extlibs/raxmpp/raxmpp
+       ******************************************************************************************
+       '''
+               Exit(1)
+
+       print 'building with ra_xmpp'
+       if env.get('RELEASE'):
+               print src_dir
+               build_dir = os.path.join(src_dir, 'extlibs/raxmpp/raxmpp/out', target_os, target_arch, 'release/')
+       else:
+               build_dir = os.path.join(src_dir, 'extlibs/raxmpp/raxmpp/out/', target_os, target_arch, 'debug/')
+       os.chdir('raxmpp')
+       sconsflags = ' RELEASE=true' if  env['RELEASE'] else ' RELEASE=false'
+       foo=commands.getoutput('scons external' + sconsflags )
+       print foo
+       foo=commands.getoutput('scons' + sconsflags )
+       print foo
+
+       env.AppendUnique(CPPPATH = src_dir+'/extlibs/raxmpp/raxmpp/ra_xmpp/',
+                               LIBPATH=build_dir,
+                               RPATH = build_dir)
diff --git a/extlibs/tinycbor/SConscript b/extlibs/tinycbor/SConscript
new file mode 100644 (file)
index 0000000..fc12833
--- /dev/null
@@ -0,0 +1,46 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+import os
+
+Import('env')
+
+src_dir = env.get('SRC_DIR')
+
+cborDir = os.path.join(src_dir, 'extlibs','tinycbor','tinycbor')
+
+if not os.path.exists(cborDir):
+    print '''
+*********************************** Error: ****************************************
+* Please download cbor using the following command:                               *
+*     $ git clone https://github.com/01org/tinycbor.git extlibs/tinycbor/tinycbor *
+***********************************************************************************
+'''
+    Exit(1)
+
+cbor_src = [
+    os.path.join(cborDir,'src/cborparser.c'),
+    os.path.join(cborDir,'src/cborencoder.c')
+    ]
+
+env['cbor_files'] = cbor_src
+env.AppendUnique(CPPPATH  = [os.path.join(cborDir, 'src')])
+
+
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
new file mode 100644 (file)
index 0000000..ba75317
--- /dev/null
@@ -0,0 +1,1164 @@
+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
+
index e547991..ead7ad3 100644 (file)
@@ -62,8 +62,10 @@ tinydtls_src = [
 env.AppendUnique(TINYDTLS_SRC = tinydtls_src)
 
 if not env.get('RELEASE'):
-       if(target_os) not in ['android', 'arduino']:
+       if(target_os) not in ['arduino']:
                env.AppendUnique(TINYDTLS_SRC = ['debug.c'])
+       else:
+               env.AppendUnique(CPPDEFINES = ['NDEBUG'])
 else:
        env.AppendUnique(CPPDEFINES = ['NDEBUG'])
 
@@ -95,4 +97,5 @@ if not env.get('RELEASE'):
        samples_env.AppendTarget('samples')
 
 env.InstallTarget(libtinydtls, 'libtinydtls');
+env.UserInstallTargetLib(libtinydtls, 'libtinydtls');
 
index 60e9bef..712798b 100644 (file)
@@ -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 */
index 0113342..5082535 100644 (file)
@@ -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,
@@ -505,21 +596,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 +638,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();
index 972a174..dd13ffa 100644 (file)
@@ -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 */
 
index a923386..41e68a5 100644 (file)
@@ -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;
@@ -1754,8 +1803,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);
 
@@ -1867,7 +1916,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;
@@ -1957,7 +2006,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 */
@@ -1968,9 +2017,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;
@@ -1999,18 +2050,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));
 
@@ -2108,6 +2161,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);
 
@@ -2116,9 +2171,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) {
@@ -2145,7 +2211,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;
       }
     }
@@ -2234,7 +2300,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;
 
@@ -2250,7 +2317,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);
 
@@ -2271,7 +2338,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 */
@@ -2343,16 +2410,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");
@@ -2394,14 +2477,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);
@@ -2612,18 +2699,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;
@@ -2683,13 +2770,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) {
@@ -2698,8 +2785,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,
@@ -2712,6 +2799,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
@@ -2839,7 +2984,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;
@@ -2849,7 +2994,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) {
@@ -2875,7 +3020,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);
 
@@ -2962,12 +3107,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);
@@ -3072,9 +3218,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;
@@ -3110,6 +3258,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)) {
@@ -3219,9 +3374,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
@@ -3342,9 +3497,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),
@@ -4030,6 +4185,44 @@ dtls_check_retransmit(dtls_context_t *context, clock_time_t *next) {
     *next = node->t;
 }
 
+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 */
index 7ebde6b..a2ab86e 100644 (file)
@@ -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
@@ -415,6 +437,30 @@ int dtls_handle_message(dtls_context_t *ctx, session_t *session,
 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_ */
 
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/extlibs/tinydtls/ecc/test_helper.c b/extlibs/tinydtls/ecc/test_helper.c
deleted file mode 100644 (file)
index bda44ba..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2009 Chris K Cockrum <ckc@cockrum.net>
- *
- * Copyright (c) 2013 Jens Trillmann <jtrillma@tzi.de>
- * Copyright (c) 2013 Marc Müller-Weinhardt <muewei@tzi.de>
- * Copyright (c) 2013 Lars Schmertmann <lars@tzi.de>
- * 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.
- *
- *
- * This implementation is based in part on the paper Implementation of an
- * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by
- * Chris K Cockrum <ckc@cockrum.net>.
- *
- * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf
- *
- * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU
- * architectures. It provides basic operations on the secp256r1 curve and support
- * for ECDH and ECDSA.
- */
-#include "test_helper.h"
-#include "ecc.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-void ecc_printNumber(const uint32_t *x, int numberLength){ //here the values are turned to MSB!
-       int n;
-
-       for(n = numberLength - 1; n >= 0; n--){
-               printf("%08x", x[n]);
-       }
-       printf("\n");
-}
-
-void ecc_setRandom(uint32_t *secret){
-       int i;
-
-       for (i = 0; i < arrayLength; ++i)
-       {
-               secret[i] = rand();
-       }
-}
-const uint32_t ecc_prime_m[8] = {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
-                                0x00000000, 0x00000000, 0x00000001, 0xffffffff};
-
-                                                       
-/* This is added after an static byte addition if the answer has a carry in MSB*/
-const uint32_t ecc_prime_r[8] = {0x00000001, 0x00000000, 0x00000000, 0xffffffff,
-                                0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000};
-
-#ifdef CONTIKI
-void
-test_assert(const char *file, int lineno)
-{
-  printf("Assertion failed: file %s, line %d.\n", file, lineno);
-  /*
-   * loop for a while;
-   * call _reset_vector__();
-   */
-}
-#endif
diff --git a/extlibs/tinydtls/ecc/test_helper.h b/extlibs/tinydtls/ecc/test_helper.h
deleted file mode 100644 (file)
index 38a194e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2009 Chris K Cockrum <ckc@cockrum.net>
- *
- * Copyright (c) 2013 Jens Trillmann <jtrillma@tzi.de>
- * Copyright (c) 2013 Marc Müller-Weinhardt <muewei@tzi.de>
- * Copyright (c) 2013 Lars Schmertmann <lars@tzi.de>
- * 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.
- *
- *
- * This implementation is based in part on the paper Implementation of an
- * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by
- * Chris K Cockrum <ckc@cockrum.net>.
- *
- * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf
- *
- * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU
- * architectures. It provides basic operations on the secp256r1 curve and support
- * for ECDH and ECDSA.
- */
-#include <inttypes.h>
-
-extern const uint32_t ecc_prime_m[8];
-extern const uint32_t ecc_prime_r[8];
-
-//debug function to print long numbers
-void ecc_printNumber(const uint32_t *x, int numberLength);
-void ecc_setRandom(uint32_t *secret);
-
-#ifdef CONTIKI
-#undef assert
-#define assert(e) ((e) ? (void)0 : test_assert(__FILE__, __LINE__))
-void test_assert(const char *, int);
-#endif
diff --git a/extlibs/tinydtls/ecc/testecc.c b/extlibs/tinydtls/ecc/testecc.c
deleted file mode 100644 (file)
index b36d46b..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2009 Chris K Cockrum <ckc@cockrum.net>
- *
- * Copyright (c) 2013 Jens Trillmann <jtrillma@tzi.de>
- * Copyright (c) 2013 Marc Müller-Weinhardt <muewei@tzi.de>
- * Copyright (c) 2013 Lars Schmertmann <lars@tzi.de>
- * 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.
- *
- *
- * This implementation is based in part on the paper Implementation of an
- * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by
- * Chris K Cockrum <ckc@cockrum.net>.
- *
- * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf
- *
- * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU
- * architectures. It provides basic operations on the secp256r1 curve and support
- * for ECDH and ECDSA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "ecc.h"
-#include "test_helper.h"
-
-#ifdef CONTIKI
-#include "contiki.h"
-#else
-#include <time.h>
-#endif /* CONTIKI */
-
-//These are testvalues taken from the NIST P-256 definition
-//6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296
-uint32_t BasePointx[8] = {     0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81,
-                                                       0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2};
-
-//4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5
-uint32_t BasePointy[8] = {     0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357,
-                                                       0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2};
-
-//de2444be bc8d36e6 82edd27e 0f271508 617519b3 221a8fa0 b77cab39 89da97c9
-uint32_t Sx[8] = {     0x89da97c9, 0xb77cab39, 0x221a8fa0, 0x617519b3, 
-                                       0x0f271508, 0x82edd27e, 0xbc8d36e6, 0xde2444be};
-
-//c093ae7f f36e5380 fc01a5aa d1e66659 702de80f 53cec576 b6350b24 3042a256
-uint32_t Sy[8] = {     0x3042a256, 0xb6350b24, 0x53cec576, 0x702de80f,
-                                       0xd1e66659, 0xfc01a5aa, 0xf36e5380, 0xc093ae7f};
-
-//55a8b00f 8da1d44e 62f6b3b2 5316212e 39540dc8 61c89575 bb8cf92e 35e0986b
-uint32_t Tx[8] = {     0x35e0986b, 0xbb8cf92e, 0x61c89575, 0x39540dc8,
-                                       0x5316212e, 0x62f6b3b2, 0x8da1d44e, 0x55a8b00f};
-
-//5421c320 9c2d6c70 4835d82a c4c3dd90 f61a8a52 598b9e7a b656e9d8 c8b24316
-uint32_t Ty[8] = {     0xc8b24316, 0xb656e9d8, 0x598b9e7a, 0xf61a8a52,
-                                       0xc4c3dd90, 0x4835d82a, 0x9c2d6c70, 0x5421c320};
-
-//c51e4753 afdec1e6 b6c6a5b9 92f43f8d d0c7a893 3072708b 6522468b 2ffb06fd
-uint32_t secret[8] = { 0x2ffb06fd, 0x6522468b, 0x3072708b, 0xd0c7a893,
-                                               0x92f43f8d, 0xb6c6a5b9, 0xafdec1e6, 0xc51e4753};
-                                                       
-//72b13dd4 354b6b81 745195e9 8cc5ba69 70349191 ac476bd4 553cf35a 545a067e
-uint32_t resultAddx[8] = {     0x545a067e, 0x553cf35a, 0xac476bd4, 0x70349191,
-                                                       0x8cc5ba69, 0x745195e9, 0x354b6b81, 0x72b13dd4};
-
-//8d585cbb 2e1327d7 5241a8a1 22d7620d c33b1331 5aa5c9d4 6d013011 744ac264
-uint32_t resultAddy[8] = {     0x744ac264, 0x6d013011, 0x5aa5c9d4, 0xc33b1331,
-                                                       0x22d7620d, 0x5241a8a1, 0x2e1327d7, 0x8d585cbb};
-
-//7669e690 1606ee3b a1a8eef1 e0024c33 df6c22f3 b17481b8 2a860ffc db6127b0
-uint32_t resultDoublex[8] = {  0xdb6127b0, 0x2a860ffc, 0xb17481b8, 0xdf6c22f3,
-                                                               0xe0024c33, 0xa1a8eef1, 0x1606ee3b, 0x7669e690};
-
-//fa878162 187a54f6 c39f6ee0 072f33de 389ef3ee cd03023d e10ca2c1 db61d0c7
-uint32_t resultDoubley[8] = {  0xdb61d0c7, 0xe10ca2c1, 0xcd03023d, 0x389ef3ee,
-                                                               0x072f33de, 0xc39f6ee0, 0x187a54f6, 0xfa878162};
-
-//51d08d5f 2d427888 2946d88d 83c97d11 e62becc3 cfc18bed acc89ba3 4eeca03f
-uint32_t resultMultx[8] = {    0x4eeca03f, 0xacc89ba3, 0xcfc18bed, 0xe62becc3,
-                                                       0x83c97d11, 0x2946d88d, 0x2d427888, 0x51d08d5f};
-
-//75ee68eb 8bf626aa 5b673ab5 1f6e744e 06f8fcf8 a6c0cf30 35beca95 6a7b41d5
-uint32_t resultMulty[8] = {    0x6a7b41d5, 0x35beca95, 0xa6c0cf30, 0x06f8fcf8,
-                                                       0x1f6e744e, 0x5b673ab5, 0x8bf626aa, 0x75ee68eb};
-
-static const uint32_t ecdsaTestMessage[] = { 0x65637572, 0x20612073, 0x68206F66, 0x20686173, 0x69732061, 0x68697320, 0x6F2C2054, 0x48616C6C};
-
-static const uint32_t ecdsaTestSecret[] = {0x94A949FA, 0x401455A1, 0xAD7294CA, 0x896A33BB, 0x7A80E714, 0x4321435B, 0x51247A14, 0x41C1CB6B};
-
-static const uint32_t ecdsaTestRand1[] = { 0x1D1E1F20, 0x191A1B1C, 0x15161718, 0x11121314, 0x0D0E0F10, 0x090A0B0C, 0x05060708, 0x01020304};
-static const uint32_t ecdsaTestresultR1[] = { 0xC3B4035F, 0x515AD0A6, 0xBF375DCA, 0x0CC1E997, 0x7F54FDCD, 0x04D3FECA, 0xB9E396B9, 0x515C3D6E};
-static const uint32_t ecdsaTestresultS1[] = { 0x5366B1AB, 0x0F1DBF46, 0xB0C8D3C4, 0xDB755B6F, 0xB9BF9243, 0xE644A8BE, 0x55159A59, 0x6F9E52A6};
-
-static const uint32_t ecdsaTestRand2[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01FFFFFF};
-static const uint32_t ecdsaTestresultR2[] = { 0x14146C91, 0xE878724D, 0xCD4FF928, 0xCC24BC04, 0xAC403390, 0x650C0060, 0x4A30B3F1, 0x9C69B726};
-static const uint32_t ecdsaTestresultS2[] = { 0x433AAB6F, 0x808250B1, 0xE46F90F4, 0xB342E972, 0x18B2F7E4, 0x2DB981A2, 0x6A288FA4, 0x41CF59DB};
-
-void addTest(){
-       uint32_t tempx[8];
-       uint32_t tempy[8];
-
-       ecc_ec_add(Tx, Ty, Sx, Sy, tempx, tempy);
-       assert(ecc_isSame(tempx, resultAddx, arrayLength));
-       assert(ecc_isSame(tempy, resultAddy, arrayLength));
-}
-
-void doubleTest(){
-       uint32_t tempx[8];
-       uint32_t tempy[8];
-
-       ecc_ec_double(Sx, Sy, tempx, tempy);
-       assert(ecc_isSame(tempx, resultDoublex, arrayLength));
-       assert(ecc_isSame(tempy, resultDoubley, arrayLength));
-}
-
-void multTest(){
-       uint32_t tempx[8];
-       uint32_t tempy[8];
-
-       ecc_ec_mult(Sx, Sy, secret, tempx, tempy);
-       assert(ecc_isSame(tempx, resultMultx, arrayLength));
-       assert(ecc_isSame(tempy, resultMulty, arrayLength));
-}
-
-void eccdhTest(){
-       uint32_t tempx[8];
-       uint32_t tempy[8];
-       uint32_t tempAx2[8];
-       uint32_t tempAy2[8];
-       uint32_t tempBx1[8];
-       uint32_t tempBy1[8];
-       uint32_t tempBx2[8];
-       uint32_t tempBy2[8];    
-       uint32_t secretA[8];
-       uint32_t secretB[8];
-       ecc_setRandom(secretA);
-       ecc_printNumber(secretA, 8);
-       ecc_setRandom(secretB);
-       ecc_printNumber(secretB, 8);
-       ecc_ec_mult(BasePointx, BasePointy, secretA, tempx, tempy);
-       ecc_ec_mult(BasePointx, BasePointy, secretB, tempBx1, tempBy1);
-       //public key exchange
-       ecc_ec_mult(tempBx1, tempBy1, secretA, tempAx2, tempAy2);
-       ecc_ec_mult(tempx, tempy, secretB, tempBx2, tempBy2);
-       assert(ecc_isSame(tempAx2, tempBx2, arrayLength));
-       assert(ecc_isSame(tempAy2, tempBy2, arrayLength));
-
-}
-
-void ecdsaTest() {
-       int ret __attribute__((unused));
-       uint32_t tempx[9];
-       uint32_t tempy[9];
-       uint32_t pub_x[8];
-       uint32_t pub_y[8];
-
-       ecc_ec_mult(BasePointx, BasePointy, ecdsaTestSecret, pub_x, pub_y);
-
-       ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand1, tempx, tempy);
-       assert(ecc_isSame(tempx, ecdsaTestresultR1, arrayLength));
-       assert(ecc_isSame(tempy, ecdsaTestresultS1, arrayLength));
-       assert(ret == 0);
-
-       ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy);
-       assert(!ret);
-
-
-       ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand2, tempx, tempy);
-       assert(ecc_isSame(tempx, ecdsaTestresultR2, arrayLength));
-       assert(ecc_isSame(tempy, ecdsaTestresultS2, arrayLength));
-       assert(ret == 0);
-
-       ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy);
-       assert(!ret);
-}
-
-#ifdef CONTIKI
-PROCESS(ecc_filed_test, "ECC test");
-AUTOSTART_PROCESSES(&ecc_filed_test);
-PROCESS_THREAD(ecc_filed_test, ev, d)
-{
-       PROCESS_BEGIN();
-
-       srand(1234);
-       addTest();
-       doubleTest();
-       multTest();
-       eccdhTest();
-       ecdsaTest();
-       printf("%s\n", "All Tests successful.");
-
-       PROCESS_END();
-}
-#else /* CONTIKI */
-int main(int argc, char const *argv[])
-{
-       srand(time(NULL));
-       addTest();
-       doubleTest();
-       multTest();
-       eccdhTest();
-       ecdsaTest();
-       printf("%s\n", "All Tests successful.");
-       return 0;
-}
-#endif /* CONTIKI */
diff --git a/extlibs/tinydtls/ecc/testfield.c b/extlibs/tinydtls/ecc/testfield.c
deleted file mode 100644 (file)
index 30a690e..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 2009 Chris K Cockrum <ckc@cockrum.net>
- *
- * Copyright (c) 2013 Jens Trillmann <jtrillma@tzi.de>
- * Copyright (c) 2013 Marc Müller-Weinhardt <muewei@tzi.de>
- * Copyright (c) 2013 Lars Schmertmann <lars@tzi.de>
- * 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.
- *
- *
- * This implementation is based in part on the paper Implementation of an
- * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by
- * Chris K Cockrum <ckc@cockrum.net>.
- *
- * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf
- *
- * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU
- * architectures. It provides basic operations on the secp256r1 curve and support
- * for ECDH and ECDSA.
- */
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include "ecc.h"
-#include "test_helper.h"
-
-#ifdef CONTIKI
-#include "contiki.h"
-#endif /* CONTIKI */
-
-//arbitrary test values and results
-uint32_t null[8] = {   0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t null64[16] = {        0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t one[8] = {    0x00000001,0x00000000,0x00000000,0x00000000,
-                                       0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t one64[16] = { 0x00000001,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t two[8] = {    0x00000002,0x00000000,0x00000000,0x00000000,
-                                       0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t two64[16] = { 0x00000002,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t three[8] = {  0x00000003,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t four[8] = {0x00000004,0x00000000,0x00000000,0x00000000,
-                                       0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t four64[16] = {        0x00000004,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t six[8] = {    0x00000006,0x00000000,0x00000000,0x00000000,
-                                       0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t eight[8] = {  0x00000008,0x00000000,0x00000000,0x00000000,
-                                               0x00000000,0x00000000,0x00000000,0x00000000};
-uint32_t full[8] = {   0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-                                               0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
-//00000000fffffffeffffffffffffffffffffffff000000000000000000000001_16
-uint32_t resultFullAdd[8] = {  0x00000001,0x00000000,0x00000000,0xFFFFFFFF,
-                                                               0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000000};
-uint32_t primeMinusOne[8]=     {       0xfffffffe,0xffffffff,0xffffffff,0x00000000,
-                                                               0x00000000,0x00000000,0x00000001,0xffffffff};
-uint32_t resultDoubleMod[8] = { 0xfffffffd,0xffffffff,0xffffffff,0x00000000,
-                                                               0x00000000,0x00000000,0x00000001,0xffffffff};
-//fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffc00000003fffffffcfffffffffffffffffffffffc000000000000000000000004_16
-uint32_t resultQuadMod[16] = { 0x00000004,0x00000000,0x00000000,0xFFFFFFFC,
-                                                               0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFC,0x00000003,
-                                                               0xFFFFFFFC,0x00000001,0xFFFFFFFE,0x00000001,
-                                                               0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE};
-//00000002fffffffffffffffffffffffefffffffdffffffff0000000000000002_16
-uint32_t resultFullMod[8] = {  0x00000002,0x00000000,0xFFFFFFFF,0xFFFFFFFD,
-                                                               0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000002};
-
-static const uint32_t orderMinusOne[8] = {0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD,
-                                       0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF};
-static const uint32_t orderResultDoubleMod[8] = {0xFC63254F, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF};
-
-uint32_t temp[8];
-uint32_t temp2[16];
-
-void nullEverything(){
-       memset(temp, 0, sizeof(temp));
-       memset(temp2, 0, sizeof(temp));
-}
-
-void fieldAddTest(){
-       assert(ecc_isSame(one, one, arrayLength));
-       ecc_fieldAdd(one, null, ecc_prime_r, temp);
-       assert(ecc_isSame(temp, one, arrayLength));
-       nullEverything();
-       ecc_fieldAdd(one, one, ecc_prime_r, temp);
-       assert(ecc_isSame(temp, two, arrayLength));
-       nullEverything();
-       ecc_add(full, one, temp, 32);
-       assert(ecc_isSame(null, temp, arrayLength));
-       nullEverything();
-       ecc_fieldAdd(full, one, ecc_prime_r, temp);
-       assert(ecc_isSame(temp, resultFullAdd, arrayLength));
-}
-
-void fieldSubTest(){
-       assert(ecc_isSame(one, one, arrayLength));
-       ecc_fieldSub(one, null, ecc_prime_m, temp);
-       assert(ecc_isSame(one, temp, arrayLength));
-       nullEverything();
-       ecc_fieldSub(one, one, ecc_prime_m, temp);
-       assert(ecc_isSame(null, temp, arrayLength));
-       nullEverything();
-       ecc_fieldSub(null, one, ecc_prime_m, temp);
-       assert(ecc_isSame(primeMinusOne, temp, arrayLength));
-}
-
-void fieldMultTest(){
-       ecc_fieldMult(one, null, temp2, arrayLength);
-       assert(ecc_isSame(temp2, null64, arrayLength * 2));
-       nullEverything();
-       ecc_fieldMult(one, two, temp2, arrayLength);
-       assert(ecc_isSame(temp2, two64, arrayLength * 2));
-       nullEverything();
-       ecc_fieldMult(two, two, temp2, arrayLength);
-       assert(ecc_isSame(temp2, four64, arrayLength * 2));
-       nullEverything();
-       ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength);
-       assert(ecc_isSame(temp2, resultQuadMod, arrayLength * 2));
-       nullEverything();
-       ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, two, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(temp, one, arrayLength));
-}
-
-void fieldModPTest(){
-       ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(temp, one, arrayLength));
-       nullEverything();
-       ecc_fieldModP(temp, one64);
-       assert(ecc_isSame(temp, one, arrayLength));
-       nullEverything();
-       ecc_fieldMult(two, primeMinusOne, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(temp, resultDoubleMod, arrayLength));
-       nullEverything();
-       /*fieldMult(full, full, temp2, arrayLength); //not working, maybe because of the number bigger than p^2?
-       fieldModP(temp, temp2);
-       assert(ecc_isSame(temp, resultFullMod, arrayLength));*/
-}
-
-void fieldModOTest(){
-       ecc_fieldMult(orderMinusOne, orderMinusOne, temp2, arrayLength);
-       ecc_fieldModO(temp2, temp, arrayLength * 2);
-       assert(ecc_isSame(temp, one, arrayLength));
-       nullEverything();
-       ecc_fieldModO(one64, temp, arrayLength * 2);
-       assert(ecc_isSame(temp, one, arrayLength));
-       nullEverything();
-       ecc_fieldMult(two, orderMinusOne, temp2, arrayLength);
-       ecc_fieldModO(temp2, temp, arrayLength * 2);
-       assert(ecc_isSame(temp, orderResultDoubleMod, arrayLength));
-       nullEverything();
-}
-
-
-// void rShiftTest(){
-//     printNumber(full, 32);
-//     rshift(full);
-//     printNumber(full, 32);
-//     printNumber(two, 32);
-//     rshift(two);
-//     printNumber(two, 32);
-//     printNumber(four, 32);
-//     rshift(four);
-//     printNumber(four, 32);
-// }
-
-// void isOneTest(){
-//     printf("%d\n", isone(one));
-//     printf("%d\n", isone(two));
-//     printf("%d\n", isone(four));
-//     printf("%d\n", isone(full));
-//     printf("%d\n", isone(null));
-// }
-
-void fieldInvTest(){
-       nullEverything();
-       ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, two, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(one, temp, arrayLength));
-       nullEverything();
-       ecc_fieldInv(eight, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, eight, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(one, temp, arrayLength));
-       nullEverything();
-       ecc_fieldInv(three, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, three, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(one, temp, arrayLength));
-       nullEverything();
-       ecc_fieldInv(six, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, six, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(one, temp, arrayLength));
-       nullEverything();
-       ecc_fieldInv(primeMinusOne, ecc_prime_m, ecc_prime_r, temp);
-       ecc_fieldMult(temp, primeMinusOne, temp2, arrayLength);
-       ecc_fieldModP(temp, temp2);
-       assert(ecc_isSame(one, temp, arrayLength));
-}
-
-// void randomStuff(){
-
-// }
-
-#ifdef CONTIKI
-PROCESS(ecc_filed_test, "ECC field test");
-AUTOSTART_PROCESSES(&ecc_filed_test);
-PROCESS_THREAD(ecc_filed_test, ev, d)
-{
-       PROCESS_BEGIN();
-
-       nullEverything();
-       //randomStuff();
-       nullEverything();
-       fieldAddTest();
-       nullEverything();
-       fieldSubTest();
-       nullEverything();
-       fieldMultTest();
-       nullEverything();
-       fieldModPTest();
-       nullEverything();
-       fieldModOTest();
-       nullEverything();
-       fieldInvTest();
-       nullEverything();
-       //rShiftTest();
-       //isOneTest();
-       printf("%s\n", "All Tests succesfull!");
-
-       PROCESS_END();
-}
-#else /* CONTIKI */
-int main(int argc, char const *argv[])
-{
-       nullEverything();
-       //randomStuff();
-       nullEverything();
-       fieldAddTest();
-       nullEverything();
-       fieldSubTest();
-       nullEverything();
-       fieldMultTest();
-       nullEverything();
-       fieldModPTest();
-       nullEverything();
-       fieldModOTest();
-       nullEverything();
-       fieldInvTest();
-       nullEverything();
-       //rShiftTest();
-       //isOneTest();
-       printf("%s\n", "All Tests succesfull!");
-       return 0;
-}
-#endif /* CONTIKI */
index f0977c8..441710f 100644 (file)
@@ -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 */
index 1c48c1a..35521e9 100644 (file)
@@ -148,8 +148,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,
@@ -296,9 +296,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"
@@ -307,7 +307,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);
 }
 
@@ -333,6 +337,7 @@ static dtls_handler_t cb = {
  * Below command tests this feature.
  */
 #define DTLS_CLIENT_CMD_REHANDSHAKE "client:rehandshake"
+
 int 
 main(int argc, char **argv) {
   fd_set rfds, wfds;
@@ -342,6 +347,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;
 
@@ -357,7 +364,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' : {
@@ -407,6 +414,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);
@@ -472,6 +496,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);
index ae1283e..d3da1a7 100644 (file)
@@ -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) {
index 3fa228a..b1b8cdf 100644 (file)
@@ -34,7 +34,7 @@
 #define _DTLS_TINYDTLS_H_
 
 /** Defined to 1 if tinydtls is built with support for ECC */
-/* #undef DTLS_ECC */
+#define DTLS_ECC 1
 
 /** Defined to 1 if tinydtls is built with support for PSK */
 #define DTLS_PSK 1
index 786c956..5125cc6 100644 (file)
@@ -21,8 +21,8 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef _DTLS_UTHASH_H
-#define _DTLS_UTHASH_H 
+#ifndef UTHASH_H
+#define UTHASH_H
 
 #include <string.h>   /* memcmp,strlen */
 #include <stddef.h>   /* ptrdiff_t */
@@ -48,7 +48,7 @@ do {
   char **_da_dst = (char**)(&(dst));                                             \
   *_da_dst = (char*)(src);                                                       \
 } while(0)
-#else 
+#else
 #define DECLTYPE_ASSIGN(dst,src)                                                 \
 do {                                                                             \
   (dst) = DECLTYPE(dst)(src);                                                    \
@@ -119,9 +119,9 @@ do {
   HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
 
 #else
-#define HASH_BLOOM_MAKE(tbl) 
-#define HASH_BLOOM_FREE(tbl) 
-#define HASH_BLOOM_ADD(tbl,hashv) 
+#define HASH_BLOOM_MAKE(tbl)
+#define HASH_BLOOM_FREE(tbl)
+#define HASH_BLOOM_ADD(tbl,hashv)
 #define HASH_BLOOM_TEST(tbl,hashv) (1)
 #endif
 
@@ -146,7 +146,7 @@ do {
 
 #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;                                                               \
@@ -298,10 +298,10 @@ do {
     }                                                                            \
 } while (0)
 #else
-#define HASH_FSCK(hh,head) 
+#define HASH_FSCK(hh,head)
 #endif
 
-/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to 
+/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
  * the descriptor to which this macro is defined for tuning the hash function.
  * The app can #include <unistd.h> to get the prototype for write(2). */
 #ifdef HASH_EMIT_KEYS
@@ -311,12 +311,12 @@ do {
     write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                \
     write(HASH_EMIT_KEYS, keyptr, fieldlen);                                     \
 } while (0)
-#else 
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                    
+#else
+#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
 #endif
 
 /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
-#ifdef HASH_FUNCTION 
+#ifdef HASH_FUNCTION
 #define HASH_FCN HASH_FUNCTION
 #else
 #define HASH_FCN HASH_JEN
@@ -333,7 +333,7 @@ do {
 } while (0)
 
 
-/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at 
+/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
  * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
 #define HASH_SAX(key,keylen,num_bkts,hashv,bkt)                                  \
 do {                                                                             \
@@ -354,7 +354,7 @@ do {
       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;                                                                \
@@ -484,14 +484,14 @@ do {
 /* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.
  * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
  * So MurmurHash comes in two versions, the faster unaligned one and the slower
- * aligned one. We only use the faster one on CPU's where we know it's safe. 
+ * aligned one. We only use the faster one on CPU's where we know it's safe.
  *
  * Note the preprocessor built-in defines can be emitted using:
  *
  *   gcc -m64 -dM -E - < /dev/null                  (on gcc)
  *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)
  */
-#if (defined(__i386__) || defined(__x86_64__)) 
+#if (defined(__i386__) || defined(__x86_64__))
 #define HASH_MUR HASH_MUR_UNALIGNED
 #else
 #define HASH_MUR HASH_MUR_ALIGNED
@@ -630,7 +630,7 @@ do {
 #endif  /* HASH_USING_NO_STRICT_ALIASING */
 
 /* key comparison function; return 0 if keys equal */
-#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) 
+#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
 
 /* iterate over items in a known bucket to find desired item */
 #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out)                       \
@@ -671,36 +671,36 @@ do {
     }                                                                            \
     if (hh_del->hh_next) {                                                       \
         hh_del->hh_next->hh_prev = hh_del->hh_prev;                              \
-    }                                                                
+    }
 
 /* Bucket expansion has the effect of doubling the number of buckets
  * and redistributing the items into the new buckets. Ideally the
  * items will distribute more or less evenly into the new buckets
  * (the extent to which this is true is a measure of the quality of
- * the hash function as it applies to the key domain). 
- * 
+ * the hash function as it applies to the key domain).
+ *
  * With the items distributed into more buckets, the chain length
  * (item count) in each bucket is reduced. Thus by expanding buckets
- * the hash keeps a bound on the chain length. This bounded chain 
+ * the hash keeps a bound on the chain length. This bounded chain
  * length is the essence of how a hash provides constant time lookup.
- * 
+ *
  * The calculation of tbl->ideal_chain_maxlen below deserves some
  * explanation. First, keep in mind that we're calculating the ideal
  * maximum chain length based on the *new* (doubled) bucket count.
  * In fractions this is just n/b (n=number of items,b=new num buckets).
- * Since the ideal chain length is an integer, we want to calculate 
+ * Since the ideal chain length is an integer, we want to calculate
  * ceil(n/b). We don't depend on floating point arithmetic in this
  * hash, so to calculate ceil(n/b) with integers we could write
- * 
+ *
  *      ceil(n/b) = (n/b) + ((n%b)?1:0)
- * 
+ *
  * and in fact a previous version of this hash did just that.
  * But now we have improved things a bit by recognizing that b is
  * always a power of two. We keep its base 2 log handy (call it lb),
  * so now we can write this with a bit shift and logical AND:
- * 
+ *
  *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
- * 
+ *
  */
 #define HASH_EXPAND_BUCKETS(tbl)                                                 \
 do {                                                                             \
@@ -752,7 +752,7 @@ do {
 
 
 /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
-/* Note that HASH_SORT assumes the hash handle name to be hh. 
+/* Note that HASH_SORT assumes the hash handle name to be hh.
  * HASH_SRT was added to allow the hash handle name to be passed in. */
 #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
 #define HASH_SRT(hh,head,cmpfcn)                                                 \
@@ -834,10 +834,10 @@ do {
  }                                                                               \
 } while (0)
 
-/* This function selects items from one hash into another hash. 
- * The end result is that the selected items have dual presence 
- * in both hashes. There is no copy of the items made; rather 
- * they are added into the new hash through a secondary hash 
+/* This function selects items from one hash into another hash.
+ * The end result is that the selected items have dual presence
+ * in both hashes. There is no copy of the items made; rather
+ * they are added into the new hash through a secondary hash
  * hash handle that must be present in the structure. */
 #define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \
 do {                                                                             \
@@ -890,7 +890,7 @@ do {
 #ifdef NO_DECLTYPE
 #define HASH_ITER(hh,head,el,tmp)                                                \
 for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL);       \
-  el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) 
+  el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
 #else
 #define HASH_ITER(hh,head,el,tmp)                                                \
 for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL);                 \
@@ -898,7 +898,7 @@ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL);
 #endif
 
 /* obtain a count of items in the hash */
-#define HASH_COUNT(head) HASH_CNT(hh,head) 
+#define HASH_COUNT(head) HASH_CNT(hh,head)
 #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
 
 typedef struct UT_hash_bucket {
@@ -907,7 +907,7 @@ typedef struct UT_hash_bucket {
 
    /* expand_mult is normally set to 0. In this situation, the max chain length
     * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
-    * the bucket's chain exceeds this length, bucket expansion is triggered). 
+    * the bucket's chain exceeds this length, bucket expansion is triggered).
     * However, setting expand_mult to a non-zero value delays bucket expansion
     * (that would be triggered by additions to this particular bucket)
     * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
@@ -915,7 +915,7 @@ typedef struct UT_hash_bucket {
     * multiplier is to reduce bucket expansions, since they are expensive, in
     * situations where we know that a particular bucket tends to be overused.
     * It is better to let its chain length grow to a longer yet-still-bounded
-    * value, than to do an O(n) bucket expansion too often. 
+    * value, than to do an O(n) bucket expansion too often.
     */
    unsigned expand_mult;
 
@@ -941,7 +941,7 @@ typedef struct UT_hash_table {
     * hash distribution; reaching them in a chain traversal takes >ideal steps */
    unsigned nonideal_items;
 
-   /* ineffective expands occur when a bucket doubling was performed, but 
+   /* ineffective expands occur when a bucket doubling was performed, but
     * afterward, more than half the items in the hash had nonideal chain
     * positions. If this happens on two consecutive expansions we inhibit any
     * further expansion, as it's not helping; this happens when the hash
index 8b03b6b..9cd4532 100644 (file)
@@ -21,12 +21,12 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef _DTLS_UTLIST_H
-#define _DTLS_UTLIST_H
+#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.
@@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * To use singly-linked lists, your structure must have a "next" pointer.
  * To use doubly-linked lists, your structure must "prev" and "next" pointers.
  * Either way, the pointer to the head of the list must be initialized to NULL.
- * 
+ *
  * ----------------.EXAMPLE -------------------------
  * struct item {
  *      int id;
@@ -83,7 +83,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
 #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
 #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
-#else 
+#else
 #define _SV(elt,list)
 #define _NEXT(elt,list) ((elt)->next)
 #define _NEXTASGN(elt,list,to) ((elt)->next)=(to)
@@ -369,14 +369,14 @@ do {
     LL_FOREACH(head,out) {                                                                     \
       if ((out)->field == (val)) break;                                                        \
     }                                                                                          \
-} while(0) 
+} while(0)
 
 #define LL_SEARCH(head,out,elt,cmp)                                                            \
 do {                                                                                           \
     LL_FOREACH(head,out) {                                                                     \
       if ((cmp(out,elt))==0) break;                                                            \
     }                                                                                          \
-} while(0) 
+} while(0)
 
 /******************************************************************************
  * doubly linked list macros (non-circular)                                   *
@@ -465,7 +465,7 @@ do {
 } while (0);
 
 #define CDL_FOREACH(head,el)                                                                   \
-    for(el=head;el;el=(el->next==head ? 0L : el->next)) 
+    for(el=head;el;el=(el->next==head ? 0L : el->next))
 
 #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2)                                                    \
   for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL);                                        \
@@ -477,14 +477,14 @@ do {
     CDL_FOREACH(head,out) {                                                                    \
       if ((out)->field == (val)) break;                                                        \
     }                                                                                          \
-} while(0) 
+} while(0)
 
 #define CDL_SEARCH(head,out,elt,cmp)                                                           \
 do {                                                                                           \
     CDL_FOREACH(head,out) {                                                                    \
       if ((cmp(out,elt))==0) break;                                                            \
     }                                                                                          \
-} while(0) 
+} while(0)
 
 #endif /* _DTLS_UTLIST_H */
 
index 6cd51b7..c8453c6 100644 (file)
@@ -31,4 +31,3 @@ target_os = env.get('TARGET_OS')
 target_arch = env.get('TARGET_ARCH')
 src_dir = env.get('SRC_DIR')
 
-env.SConscript('extlibs/cereal/SConscript')
index d4542f0..749da0a 100644 (file)
@@ -20,7 +20,7 @@ mkdir ./tmp/extlibs/
 mkdir ./tmp/packaging
 cp -R ./build_common $sourcedir/tmp
 cp -R ./examples $sourcedir/tmp
-cp -R ./extlibs/cereal $sourcedir/tmp/extlibs
+cp -R ./extlibs/tinycbor $sourcedir/tmp/extlibs
 cp -R ./extlibs/cjson $sourcedir/tmp/extlibs
 cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs
 cp -R ./extlibs/timer $sourcedir/tmp/extlibs
@@ -35,7 +35,7 @@ cp ./tools/tizen/.gbs.conf ./tmp
 cd $sourcedir/tmp
 
 echo `pwd`
-rm -rf ./extlibs/cereal/cereal/.git*
+rm -rf ./extlibs/tinycbor/tinycbor/.git*
 
 # Initialize Git repository
 if [ ! -d .git ]; then
index 9f96e77..6a189b2 100644 (file)
@@ -36,20 +36,26 @@ if target_os not in ['arduino', 'darwin', 'ios', 'android']:
 # Build libcoap
 SConscript('csdk/connectivity/lib/libcoap-4.1.1/SConscript')
 
+# Build C Common dependencies
+SConscript('c_common/SConscript')
+
 # Build connectivity
 SConscript('csdk/connectivity/SConscript')
 
+# Build libocsrm
+SConscript('csdk/security/SConscript')
+
 # Build liboctbstack
 SConscript('csdk/SConscript')
 
-if target_os not in ['arduino','darwin']:
+if target_os not in ['arduino','darwin','ios']:
        # Build liboc_logger
        SConscript('oc_logger/SConscript')
 
        # Build liboc
        SConscript('src/SConscript')
 
-if target_os not in ['arduino','darwin', 'android']:
+if target_os not in ['arduino','darwin','ios','android']:
        # Build examples
        SConscript('examples/SConscript')
 
@@ -64,7 +70,8 @@ if target_os == 'linux':
        SConscript('unit_tests.scons')
 
 elif target_os == 'darwin':
-       # Build linux samples for now.
+       env.Command('../../out/darwin/iotivity-csdk.framework',None,src_dir + '/tools/darwin/mkfwk_osx.sh')
+       # Build linux samples for now
        SConscript('csdk/stack/samples/linux/SimpleClientServer/SConscript')
 
        # Build C stack's unit tests.
index d7bce9f..4ce7309 100644 (file)
@@ -23,3 +23,4 @@ compatibilitylib_src = ['OCAndroid.cpp']
 if target_os == 'android':
        static_compatibilitylib = compatibilitylib_env.StaticLibrary('compatibility', compatibilitylib_src)
        compatibilitylib_env.InstallTarget(static_compatibilitylib, 'libcompatibility')
+       compatibilitylib_env.UserInstallTargetLib(static_compatibilitylib, 'libcompatibility')
diff --git a/resource/c_common/SConscript b/resource/c_common/SConscript
new file mode 100644 (file)
index 0000000..f0e140c
--- /dev/null
@@ -0,0 +1,53 @@
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+Import('env')
+import os
+
+env.AppendUnique(CPPPATH = [
+            os.path.join(Dir('.').abspath, 'oic_malloc/include'),
+            os.path.join(Dir('.').abspath, 'oic_string/include')
+        ])
+
+if env.get('TARGET_OS') == 'tizen':
+       env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+else:
+       env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common')])
+
+env.AppendUnique(LIBS = ['c_common'])
+
+common_env = env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+
+######################################################################
+# Source files and Targets
+######################################################################
+common_src = [
+    'oic_string/src/oic_string.c',
+    'oic_malloc/src/oic_malloc.c'
+    ]
+
+commonlib = common_env.StaticLibrary('c_common', common_src)
+common_env.InstallTarget(commonlib, 'c_common')
+common_env.UserInstallTargetLib(commonlib, 'c_common')
@@ -68,6 +68,26 @@ extern "C"
 void *OICMalloc(size_t size);
 
 /**
+ * Re-allocates a block of memory, pointed to by ptr to the size specified
+ * in size.  The returned value contains a pointer to the new location, with
+ * all data copied into it.  If the new size of the memory-object require movement,
+ * the previous space is freed.  If the new size is larger, the newly allocated
+ * area has non-deterministic content. If the space cannot be allocated, the value
+ * ptr is left unchanged.
+ *
+ * @param ptr - Pointer to a block of memory previously allocated by OICCalloc,
+ *              OICMalloc, or a previous call to this function.  If this value is
+ *              NULL, this function will work identically to a call to OICMalloc.
+ *
+ * @param size - Size of the new memory block in bytes, where size > 0
+ *
+ * @return
+ *      on success, a pointer to the newly sized memory block
+ *      on failure, a null pointer is returned, and the memory pointed to by *ptr is untouched
+ */
+void *OICRealloc(void *ptr, size_t size);
+
+/**
  * Allocates a block of memory for an array of num elements, each of them
  * size bytes long and initializes all its bits to zero.
  *
@@ -86,7 +106,7 @@ void *OICCalloc(size_t num, size_t size);
  * NOTE: This function is intended to be used internally by the TB Stack.
  *       It is not intended to be used by applications.
  *
- * @param ptr - Pointer to block of memory previously allocated by OCMalloc.
+ * @param ptr - Pointer to block of memory previously allocated by OICMalloc.
  *              If ptr is a null pointer, the function does nothing.
  */
 void OICFree(void *ptr);
@@ -98,6 +98,29 @@ void *OICCalloc(size_t num, size_t size)
 #endif
 }
 
+void *OICRealloc(void* ptr, size_t size)
+{
+    if(size == 0)
+    {
+        OICFree(ptr);
+        return NULL;
+    }
+
+#ifdef ENABLE_MALLOC_DEBUG
+    if(ptr == NULL)
+    {
+        return OICMalloc(size);
+    }
+
+    void* newptr = NULL;
+    newptr = realloc(ptr, size);
+    OIC_LOG_V(INFO, TAG, "realloc: ptr=%p, newptr=%p, size=%u", ptr, newptr, size);
+    return ptr;
+#else
+    return realloc(ptr, size);
+#endif
+}
+
 void OICFree(void *ptr)
 {
 #ifdef ENABLE_MALLOC_DEBUG
diff --git a/resource/c_common/oic_malloc/test/SConscript b/resource/c_common/oic_malloc/test/SConscript
new file mode 100644 (file)
index 0000000..0b702ec
--- /dev/null
@@ -0,0 +1,55 @@
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+import os
+
+malloctest_env = env.Clone()
+src_dir = malloctest_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+malloctest_env.PrependUnique(CPPPATH = [
+        '../include',
+        '#extlibs/gtest/gtest-1.7.0/include' ])
+
+malloctest_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common')])
+malloctest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
+malloctest_env.PrependUnique(LIBS = ['c_common', 'gtest', 'gtest_main', 'pthread'])
+
+if env.get('LOGGING'):
+       malloctest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+#
+######################################################################
+# Source files and Targets
+######################################################################
+malloctests = malloctest_env.Program('malloctests', ['linux/oic_malloc_tests.cpp'])
+
+Alias("test", [malloctests])
+
+env.AppendTarget('test')
+if env.get('TEST') == '1':
+       target_os = env.get('TARGET_OS')
+       if target_os == 'linux':
+                from tools.scons.RunTest import *
+                run_test(malloctest_env,
+                         'resource_ccommon_malloc_test.memcheck',
+                         'resource/c_common/oic_malloc/test/malloctests')
@@ -20,7 +20,7 @@
 
 
 extern "C" {
-    #include "ocmalloc.h"
+    #include "oic_malloc.h"
 }
 
 #include "gtest/gtest.h"
@@ -51,90 +51,90 @@ static uint8_t *pBuffer;
 //  Tests
 //-----------------------------------------------------------------------------
 
-TEST(OCMalloc, MallocPass1)
+TEST(OICMalloc, MallocPass1)
 {
     // Try to allocate a small buffer
-    pBuffer = (uint8_t *)OCMalloc(1);
+    pBuffer = (uint8_t *)OICMalloc(1);
     EXPECT_TRUE(pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCMalloc, MallocPass2)
+TEST(OICMalloc, MallocPass2)
 {
     // Try to allocate a small buffer
-    pBuffer = (uint8_t *)OCMalloc(128);
+    pBuffer = (uint8_t *)OICMalloc(128);
     EXPECT_TRUE(pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCMalloc, MallocFail1)
+TEST(OICMalloc, MallocFail1)
 {
     // Try to allocate a buffer of size 0
-    pBuffer = (uint8_t *)OCMalloc(0);
+    pBuffer = (uint8_t *)OICMalloc(0);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCMalloc, MallocFail2)
+TEST(OICMalloc, MallocFail2)
 {
     // Try to allocate a ridiculous amount of RAM
-    pBuffer = (uint8_t *)OCMalloc((size_t)0x7FFFFFFFFFFFFFFF);
+    pBuffer = (uint8_t *)OICMalloc((size_t)0x7FFFFFFFFFFFFFFF);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocPass1)
+TEST(OICCalloc, CallocPass1)
 {
     // Try to allocate a small buffer
-    pBuffer = (uint8_t *)OCCalloc(1, 1);
+    pBuffer = (uint8_t *)OICCalloc(1, 1);
     EXPECT_TRUE(pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocPass2)
+TEST(OICCalloc, CallocPass2)
 {
     // Try to allocate a small buffer
-    pBuffer = (uint8_t *)OCCalloc(1, 128);
+    pBuffer = (uint8_t *)OICCalloc(1, 128);
     EXPECT_TRUE(pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocPass3)
+TEST(OICCalloc, CallocPass3)
 {
     // Try to allocate a buffer for an array
-    pBuffer = (uint8_t *)OCCalloc(5, 128);
+    pBuffer = (uint8_t *)OICCalloc(5, 128);
     EXPECT_TRUE(pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocFail1)
+TEST(OICCalloc, CallocFail1)
 {
     // Try to allocate a buffer of size 0
-    pBuffer = (uint8_t *)OCCalloc(1, 0);
+    pBuffer = (uint8_t *)OICCalloc(1, 0);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocFail2)
+TEST(OICCalloc, CallocFail2)
 {
     // Try to allocate a buffer with num of 0
-    pBuffer = (uint8_t *)OCCalloc(0, 5);
+    pBuffer = (uint8_t *)OICCalloc(0, 5);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocFail3)
+TEST(OICCalloc, CallocFail3)
 {
     // Try to allocate a buffer with size and num 0
-    pBuffer = (uint8_t *)OCCalloc(0, 0);
+    pBuffer = (uint8_t *)OICCalloc(0, 0);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
 
-TEST(OCCalloc, CallocFail4)
+TEST(OICCalloc, CallocFail4)
 {
     // Try to allocate a ridiculous amount of RAM
-    pBuffer = (uint8_t *)OCCalloc(1, (size_t)0x7FFFFFFFFFFFFFFF);
+    pBuffer = (uint8_t *)OICCalloc(1, (size_t)0x7FFFFFFFFFFFFFFF);
     EXPECT_TRUE(NULL == pBuffer);
-    OCFree(pBuffer);
+    OICFree(pBuffer);
 }
diff --git a/resource/c_common/oic_string/include/oic_string.h b/resource/c_common/oic_string/include/oic_string.h
new file mode 100644 (file)
index 0000000..4aea907
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#ifndef OIC_STRING_H_
+#define OIC_STRING_H_
+
+#include <stddef.h>
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/**
+ * Duplicates the source string and returns it.
+ *
+ * @note Caller needs to release this memory by calling OICFree().
+ *
+ * @param str Original valid string which needs to be duplicated.
+ *
+ * @return a pointer to the duplicated string
+ */
+char *OICStrdup(const char *str);
+
+/**
+ * Copies a C string into destination buffer.  Ensures that the destination
+ * is null terminated.
+ *
+ * @param dest Destination C buffer.
+ * @param destSize The allocated size of the destination parameter.
+ * @param source Source C string.
+ *
+ * @return
+ *      returns a pointer to the passed in 'dest' parameter
+ */
+char* OICStrcpy(char* dest, size_t destSize, const char* source);
+
+/**
+ * Appends a C string into a previously allocated and initialized C string in a buffer. dest
+ * parameter is guaranteed to be null-terminated.
+ *
+ * @param dest Destination C buffer containing initial string.
+ * @param destSize The allocated size of the destination parameter.
+ * @param source Source C string.
+ *
+ * @return
+ *      returns a pointer to the passed in 'dest' parameter
+ */
+char* OICStrcat(char* dest, size_t destSize, const char* source);
+
+/**
+ * Copies a partial C string into destination buffer.
+ * Ensures that the destination is null terminated.
+ *
+ * @param dest Destination C buffer.
+ * @param destSize The allocated size of the destination parameter.
+ * @param source Source C string.
+ * @param sourceLen maximum number of characters to copy.
+ *
+ * @return
+ *      returns a pointer to the passed in 'dest' parameter
+ */
+char* OICStrcpyPartial(char* dest, size_t destSize, const char* source, size_t sourceLen);
+
+/**
+ * Appends a C string into a previously allocated and initialized C string in a buffer. dest
+ * parameter is guaranteed to be null-terminated.
+ *
+ * @param dest Destination C buffer containing initial string.
+ * @param destSize The allocated size of the destination parameter.
+ * @param source Source C string.
+ * @param sourceLen maximum number of characters to append, not including null termination
+ *
+ * @return
+ *      returns a pointer to the passed in 'dest' parameter
+ */
+char* OICStrcatPartial(char* dest, size_t destSize, const char* source, size_t sourceLen);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // OIC_STRING_H_
diff --git a/resource/c_common/oic_string/src/oic_string.c b/resource/c_common/oic_string/src/oic_string.c
new file mode 100644 (file)
index 0000000..644b4d2
--- /dev/null
@@ -0,0 +1,98 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "oic_string.h"
+
+#include <string.h>
+#include <assert.h>
+#include "oic_malloc.h"
+
+#define TAG "OIC_STRING"
+char *OICStrdup(const char *str)
+{
+    if(!str)
+    {
+        return NULL;
+    }
+
+    // Allocate memory for original string length and 1 extra byte for '\0'
+    size_t length = strlen(str);
+    char *dup = (char *)OICMalloc(length + 1);
+    if (NULL != dup)
+    {
+        memcpy(dup, str, length + 1);
+    }
+
+    return dup;
+}
+
+char* OICStrcpy(char* dest, size_t destSize, const char* source)
+{
+    return OICStrcpyPartial(dest, destSize, source, destSize == 0 ? 0 : destSize - 1);
+}
+
+char* OICStrcat(char* dest, size_t destSize, const char* source)
+{
+    return OICStrcatPartial(dest, destSize, source, destSize == 0 ? 0 : destSize - 1);
+}
+
+#ifndef min
+static size_t min(size_t a, size_t b)
+{
+    return a < b ? a : b;
+}
+#endif
+
+char* OICStrcpyPartial(char* dest, size_t destSize, const char* source, size_t sourceLen)
+{
+    if(!dest || !source)
+    {
+        return NULL;
+    }
+
+    if(destSize == 0 || sourceLen == 0)
+    {
+        return dest;
+    }
+
+    dest[0] = '\0';
+    return strncat(dest, source, min(destSize - 1, sourceLen));
+}
+
+char* OICStrcatPartial(char* dest, size_t destSize, const char* source, size_t sourceLen)
+{
+    if (!dest || !source)
+    {
+        return NULL;
+    }
+
+    if(destSize == 0 || sourceLen == 0)
+    {
+        return dest;
+    }
+
+    size_t destLen = strlen(dest);
+
+    if(destLen >= destSize)
+    {
+        return dest;
+    }
+
+    return strncat(dest, source, min(destSize - destLen - 1, sourceLen));
+}
diff --git a/resource/c_common/oic_string/test/SConscript b/resource/c_common/oic_string/test/SConscript
new file mode 100644 (file)
index 0000000..9d30251
--- /dev/null
@@ -0,0 +1,55 @@
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+import os
+
+stringtest_env = env.Clone()
+src_dir = stringtest_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+stringtest_env.PrependUnique(CPPPATH = [
+        '../include',
+        '#extlibs/gtest/gtest-1.7.0/include' ])
+
+stringtest_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common')])
+stringtest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
+stringtest_env.PrependUnique(LIBS = ['c_common', 'gtest', 'gtest_main', 'pthread'])
+
+if env.get('LOGGING'):
+       stringtest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+#
+######################################################################
+# Source files and Targets
+######################################################################
+stringtests = stringtest_env.Program('stringtests', ['linux/oic_string_tests.cpp'])
+
+Alias("test", [stringtests])
+
+env.AppendTarget('test')
+if env.get('TEST') == '1':
+       target_os = env.get('TARGET_OS')
+       if target_os == 'linux':
+                from tools.scons.RunTest import *
+                run_test(stringtest_env,
+                         'resource_ccommon_string_test.memcheck',
+                         'resource/c_common/oic_string/test/stringtests')
diff --git a/resource/c_common/oic_string/test/linux/oic_string_tests.cpp b/resource/c_common/oic_string/test/linux/oic_string_tests.cpp
new file mode 100644 (file)
index 0000000..eccf05e
--- /dev/null
@@ -0,0 +1,541 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+//*********************************************************************
+
+// Defining _POSIX_C_SOURCE macro with 200809L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1-2008 base
+// specification (excluding the XSI extension).
+// For POSIX.1-2008 base specification,
+// Refer http://pubs.opengroup.org/stage7tc1/
+//
+// For this specific file, see use of usleep
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif // _POSIX_C_SOURCE
+
+#include "gtest/gtest.h"
+
+#include <oic_string.h>
+#include <oic_malloc.h>
+
+const char SENTINEL_VALUE = 127;
+TEST(StringTests, StrdupNormalDup)
+{
+    char param[] = "This is a normal parameter";
+
+    char* result = OICStrdup(param);
+
+    ASSERT_TRUE(result != NULL);
+
+    // ensure not the same pointer
+    EXPECT_NE(param, result);
+
+    EXPECT_STREQ(param, result);
+
+    OICFree(result);
+}
+
+// Tests a normal copy where the buffer is exactly long enough
+TEST(StringTests, StrcpyExactSize)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpy(target, sizeof(target), source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ(source, result);
+}
+
+// Tests a normal copy where the buffer is exactly long enough
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcpyExactSizeSentinel)
+{
+    char target[10 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpy(target, sizeof(target) - 5, source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(target));
+    EXPECT_STREQ(source, result);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a copy where the source is smaller than the target
+TEST(StringTests, StrcpyShorterSource)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "12345";
+
+    char* result = OICStrcpy(target, sizeof(target), source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(source) - 1, strlen(result));
+    EXPECT_STREQ(source, result);
+
+    for(size_t i = sizeof(source); i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a copy where the destination is larger than the target
+TEST(StringTests, StrcpyShorterDestination)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789012345";
+
+    char *result = OICStrcpy(target, sizeof(target), source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(result));
+    EXPECT_STREQ("123456789", result);
+}
+
+// tests a copy where the destination is larger than the target
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcpyShorterDestinationSentinel)
+{
+    char target[10 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789012345";
+
+    char *result = OICStrcpy(target, sizeof(target) - 5, source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(result));
+    EXPECT_STREQ("123456789", result);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a copy where the source is of length 0
+TEST(StringTests, StrcpyZeroSource)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "";
+
+    char *result = OICStrcpy(target, sizeof(target), source);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(source) - 1, strlen(result));
+    EXPECT_STREQ("", result);
+
+    for(size_t i = sizeof(source); i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a copy where the destination is of length 0
+TEST(StringTests, StrcpyZeroDestination)
+{
+    char target[0];
+    char source[] = "123456789";
+
+    char *result = OICStrcpy(target, sizeof(target), source);
+
+    EXPECT_EQ(target, result);
+}
+
+// tests a copy where the destination is of length 0
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcpyZeroDestinationSentinel)
+{
+    char target[0 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char *result = OICStrcpy(target, sizeof(target) - 5, source);
+
+    EXPECT_EQ(target, result);
+
+    for(size_t i = 0; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a normal cat where the target has exactly enough room
+TEST(StringTests, StrcatExactSize)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "12345";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ("Orig12345", target);
+}
+
+// Tests a normal cat where the target has exactly enough room
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcatExactSizeSentinel)
+{
+    char target[10 + 5] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "12345";
+
+    char *result = OICStrcat(target, sizeof(target) - 5, source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(target));
+    EXPECT_STREQ("Orig12345", target);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a normal cat where the target has exactly enough room,
+// except it is of strlen 0
+TEST(StringTests, StrcatExactSizeEmptySourceString)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    target[0] = '\0';
+    char source[] = "123456789";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ(source, target);
+}
+// tests a normal cat where the target has exactly enough room,
+// except it is of strlen 0
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcatExactSizeEmptySourceStringSentinel)
+{
+    char target[10 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    target[0] = '\0';
+    char source[] = "123456789";
+
+    char *result = OICStrcat(target, sizeof(target) + 5, source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(target));
+    EXPECT_STREQ(source, target);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// tests a normal cat where the target has extra room
+TEST(StringTests, StrcatExtraRoom)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "12";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(static_cast<size_t>(6), strlen(target));
+    EXPECT_STREQ("Orig12", target);
+
+    for(size_t i = sizeof("Orig12"); i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a normal cat where the target has insufficient room
+TEST(StringTests, StrcatInsufficientRoom)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    target[0] = '\0';
+    char source[] = "1234567890123456";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ("123456789", target);
+}
+
+// Tests a normal cat where the target has insufficient room
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcatInsufficientRoomSentinel)
+{
+    char target[10 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    target[0]= '\0';
+    char source[] = "1234567890123456";
+
+    char *result = OICStrcat(target, sizeof(target) - 5, source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(target));
+    EXPECT_STREQ("123456789", target);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a normal cat where the target has zero room
+TEST(StringTests, StrcatZeroRoom)
+{
+    char target[10] = "Original1";
+    char source[] = "12345";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ("Original1", target);
+}
+
+// Tests a normal cat where the target has zero room
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcatZeroRoomSentinel)
+{
+    char target[10 + 5] = "Original1";
+    memset(target + sizeof("Original1"), SENTINEL_VALUE, sizeof(target) - sizeof("Original1"));
+    char source[] = "12345";
+
+    char *result = OICStrcat(target, sizeof(target) - 5, source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1 - 5, strlen(target));
+    EXPECT_STREQ("Original1", target);
+
+    for(size_t i = sizeof(target) - 5; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a cat where the source is zero length
+TEST(StringTests, StrcatZeroSource)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof("Orig") - 1, strlen(target));
+    EXPECT_STREQ("Orig", target);
+
+    for(size_t i = sizeof("Orig"); i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a cat where the Destination is zero length
+TEST(StringTests, StrcatZeroDestination)
+{
+    char target[0];
+    char source[] = "12345";
+
+    char *result = OICStrcat(target, sizeof(target), source);
+    EXPECT_EQ(target, result);
+}
+
+// Tests a cat where the Destination is zero length
+// Tests with what is in reality an oversized buffer to ensure that
+// the buffer isn't over-written
+TEST(StringTests, StrcatZeroDestinationSentinel)
+{
+    char target[0 + 5];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char *result = OICStrcat(target, sizeof(target) - 5, source);
+
+    EXPECT_EQ(target, result);
+
+    for(size_t i = 0; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a partial copy where the source length parameter is shorter
+// than the string length
+TEST(StringTests, StrcpyPartialShorterSourceLen)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpyPartial(target, sizeof(target), source, strlen(source) - 5);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(strlen(source) - 5, strlen(target));
+    EXPECT_STREQ("1234", result);
+
+    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a partial copy where the source length parameter is equal
+// to the string length
+TEST(StringTests, StrcpyPartialEqualSourceLen)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpyPartial(target, sizeof(target), source, strlen(source));
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ(source, result);
+}
+
+// Tests a partial copy where the source length parameter is longer
+// than the string length
+TEST(StringTests, StrcpyPartialLongerSourceLen)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpyPartial(target, sizeof(target), source, 99);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof(target) - 1, strlen(target));
+    EXPECT_STREQ(source, result);
+}
+
+// Tests a partial copy where the source length is zero
+TEST(StringTests, StrcpyPartialZeroSourceLen)
+{
+    char target[10];
+    memset(target, SENTINEL_VALUE, sizeof(target));
+    char source[] = "123456789";
+
+    char* result = OICStrcpyPartial(target, sizeof(target), source, 0);
+
+    EXPECT_EQ(target, result);
+
+    for(size_t i = 0; i < sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, target[i]);
+    }
+}
+
+// Tests a partial cat where the source length parameter is shorter
+// than the string length
+TEST(StringTests, StrcatPartialShorterSourceLen)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "123456";
+
+    char* result = OICStrcatPartial(target, sizeof(target), source, strlen(source) - 3);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ((sizeof("Orig") - 1) + (strlen(source) - 3), strlen(target));
+    EXPECT_STREQ("Orig123", result);
+
+    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a partial cat where the source length parameter is equal
+// to the string length
+TEST(StringTests, StrcatPartialEqualSourceLen)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "123";
+
+    char* result = OICStrcatPartial(target, sizeof(target), source, strlen(source));
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ((sizeof("Orig") - 1) + strlen(source), strlen(target));
+    EXPECT_STREQ("Orig123", result);
+
+    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a partial cat where the source length parameter is longer
+// than the string length
+TEST(StringTests, StrcatPartialLongerSourceLen)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "123";
+
+    char* result = OICStrcatPartial(target, sizeof(target), source, 99);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ((sizeof("Orig") - 1) + strlen(source), strlen(target));
+    EXPECT_STREQ("Orig123", result);
+
+    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
+
+// Tests a partial cat where the source length is zero
+TEST(StringTests, StrcatPartialZeroSourceLen)
+{
+    char target[10] = "Orig";
+    memset(target + sizeof("Orig"), SENTINEL_VALUE, sizeof(target) - sizeof("Orig"));
+    char source[] = "123";
+
+    char* result = OICStrcatPartial(target, sizeof(target), source, 0);
+
+    EXPECT_EQ(target, result);
+    EXPECT_EQ(sizeof("Orig") - 1, strlen(target));
+    EXPECT_STREQ("Orig", result);
+
+    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
+    {
+        EXPECT_EQ(SENTINEL_VALUE, result[i]);
+    }
+}
index 63e6462..cee8dc9 100644 (file)
@@ -29,6 +29,7 @@ SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env')
 liboctbstack_env = lib_env.Clone()
 
 target_os = env.get('TARGET_OS')
+with_ra = env.get('WITH_RA')
 # As in the source code, it includes arduino Time library (C++)
 # It requires compile the .c with g++
 if target_os == 'arduino':
@@ -43,17 +44,19 @@ liboctbstack_env.PrependUnique(CPPPATH = [
                '../../extlibs/timer/',
                'logger/include',
                'ocrandom/include',
-               'ocmalloc/include',
                'stack/include',
                'stack/include/internal',
                '../oc_logger/include',
                'connectivity/lib/libcoap-4.1.1',
                'connectivity/inc',
                'connectivity/api',
+               'connectivity/external/inc',
                'security/include',
                'security/include/internal',
                ])
 
+liboctbstack_env.AppendUnique(LIBS = ['ocsrm'])
+
 if target_os not in ['arduino', 'windows', 'winrt']:
        liboctbstack_env.AppendUnique(CPPDEFINES  = ['WITH_POSIX'])
        liboctbstack_env.AppendUnique(CFLAGS = ['-std=c99'])
@@ -63,8 +66,10 @@ if target_os not in ['windows', 'winrt']:
 
 liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 
-if target_os in ['android', 'linux', 'tizen']:
+if target_os in ['android', 'linux','tizen']:
        liboctbstack_env.AppendUnique(LIBS = ['connectivity_abstraction'])
+       if with_ra:
+               liboctbstack_env.AppendUnique(LIBS = ['ra_xmpp'])
 liboctbstack_env.AppendUnique(LIBS = ['coap', 'm'])
 
 if target_os == 'tizen':
@@ -90,6 +95,8 @@ if env.get('SECURED') == '1':
 if env.get('LOGGING'):
        liboctbstack_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+liboctbstack_env.Append(LIBS = ['c_common'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
@@ -98,22 +105,28 @@ liboctbstack_src = [
        '../../extlibs/cjson/cJSON.c',
        '../../extlibs/timer/timer.c',
        OCTBSTACK_SRC + 'ocstack.c',
+       OCTBSTACK_SRC + 'ocpayload.c',
+       OCTBSTACK_SRC + 'ocpayloadparse.c',
+       OCTBSTACK_SRC + 'ocpayloadconvert.c',
        OCTBSTACK_SRC + 'occlientcb.c',
        OCTBSTACK_SRC + 'ocresource.c',
        OCTBSTACK_SRC + 'ocobserve.c',
        OCTBSTACK_SRC + 'ocserverrequest.c',
        OCTBSTACK_SRC + 'occollection.c',
        OCTBSTACK_SRC + 'oicgroup.c',
-       'security/src/ocsecurity.c',
        'logger/src/logger.c',
-       'ocrandom/src/ocrandom.c',
-       'ocmalloc/src/ocmalloc.c'
+       'ocrandom/src/ocrandom.c'
        ]
+
+liboctbstack_src.extend(env['cbor_files'])
+
 if target_os in ['arduino','darwin','ios'] :
        static_liboctbstack = liboctbstack_env.StaticLibrary('octbstack', liboctbstack_src)
        liboctbstack_env.InstallTarget(static_liboctbstack, 'liboctbstack')
+       liboctbstack_env.UserInstallTargetLib(static_liboctbstack, 'liboctbstack')
 else:
        static_liboctbstack = liboctbstack_env.StaticLibrary('octbstack', liboctbstack_src)
        shared_liboctbstack = liboctbstack_env.SharedLibrary('octbstack', liboctbstack_src)
        liboctbstack_env.InstallTarget([static_liboctbstack, shared_liboctbstack], 'liboctbstack')
+       liboctbstack_env.UserInstallTargetLib([static_liboctbstack, shared_liboctbstack], 'liboctbstack')
 
index acfbac7..4c0f448 100644 (file)
@@ -7,6 +7,7 @@ Import('env')
 target_os = env.get('TARGET_OS')
 transport = env.get('TARGET_TRANSPORT')
 build_sample = env.get('BUILD_SAMPLE')
+with_ra = env.get('WITH_RA')
 
 print "Given Transport is %s" % transport
 print "Given OS is %s" % target_os
@@ -21,11 +22,13 @@ if target_os in targets_disallow_multitransport:
         Exit(1)
 
 if 'ALL' in transport:
+       if with_ra == True:
+                       env.AppendUnique(CPPDEFINES = ['RA_ADAPTER'])
        if target_os == 'linux':
                env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER'])
        elif target_os == 'tizen':
                env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
-       elif target_os == 'darwin':
+       elif target_os in['darwin','ios']:
                env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER'])
        else:
                env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
@@ -60,6 +63,9 @@ else:
 env.SConscript('./src/SConscript')
 
 if build_sample == 'ON':
-       if target_os in ['linux', 'arduino', 'android']:
-               env.SConscript('./samples/' + target_os + '/SConscript')
-       
+       if target_os in ['linux', 'arduino', 'android', 'darwin']:
+               target_path = target_os
+               if target_os == 'darwin':
+                       target_path = 'linux'
+               env.SConscript('./samples/' + target_path + '/SConscript')
+
diff --git a/resource/csdk/connectivity/SConstruct b/resource/csdk/connectivity/SConstruct
deleted file mode 100644 (file)
index 58d0fd9..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-##
-# The main build script
-#
-##
-
-# Load common build config
-# Load common build config
-SConscript('./build/SConscript')
-
-Import('env')
-
-sample_env = env.Clone()
-
-target_os = env.get('TARGET_OS')
-transport = env.get('TARGET_TRANSPORT')
-secured = env.get('SECURED')
-release_mode = env.get('RELEASE')
-buildsample = env.get('BUILD_SAMPLE')
-
-print "Given Transport is %s" % transport
-print "Given OS is %s" % target_os
-print "Secured %s" % env.get('SECURED')
-print "Build sample is set to %s" % buildsample
-
-build_dir = env.get('BUILD_DIR')
-
-if target_os == 'tizen':
-       command = "sh build/tizen/gbsbuild.sh %s %s %s" % (transport, buildsample, release_mode)
-       print "Created Command is %s" % command
-       gbs_script = env.Command('gbs_build', None, command)
-       AlwaysBuild ('gbs_script')
-elif target_os == 'arduino':
-       SConscript('build/arduino/arduino.scons')
-
-        # Build 'libcoap' library
-        SConscript(build_dir + 'lib/libcoap-4.1.1/SConscript')
-
-        # Build 'src' sub-project
-        SConscript(build_dir + 'SConscript')
-
-        # Build 'samples' sub-project
-        SConscript(build_dir + 'samples/arduino/SConscript')
-elif target_os == 'linux':
-
-       # Build 'libcoap' library
-       SConscript(build_dir  + 'lib/libcoap-4.1.1/SConscript')
-
-       # Build 'src' sub-project
-       SConscript(build_dir + 'SConscript')
-
-       # Build 'samples' sub-project
-       env.SConscript(build_dir + 'samples/linux/SConscript')
-elif target_os == 'android':
-
-       # Build 'libcoap' library
-       SConscript(build_dir  + 'lib/libcoap-4.1.1/SConscript')
-
-       # Build 'src' sub-project
-       SConscript(build_dir + 'SConscript')
-
-       # Build 'samples' sub-project
-       env.SConscript(build_dir + 'samples/android/SConscript')
index 1060410..00dac16 100644 (file)
@@ -42,6 +42,11 @@ extern "C"
 #define CA_IPADDR_SIZE 16
 
 /**
+ * @brief Remote Access jabber ID length.
+ */
+#define CA_RAJABBERID_SIZE 256
+
+/**
  * @brief Mac address length for BT port
  */
 #define CA_MACADDR_SIZE 18
@@ -75,6 +80,11 @@ extern "C"
 #endif
 
 /**
+ *@brief Maximum length of the remoteEndpoint identity
+ */
+#define CA_MAX_ENDPOINT_IDENTITY_LEN   (32)
+
+/**
  * @brief option types - the highest option number 63
  */
 #define CA_OPTION_IF_MATCH 1
@@ -93,7 +103,7 @@ extern "C"
 /**
  * @brief Payload information from resource model
  */
-typedef char *CAPayload_t;
+typedef uint8_t *CAPayload_t;
 
 /**
  * @brief URI for the OIC base.CA considers relative URI as the URI.
@@ -105,17 +115,53 @@ typedef char *CAURI_t;
  */
 typedef char *CAToken_t;
 
-/**
- * @enum CATransportType_t
- * @brief Different connectivities that are handled in Connectivity Abstraction
- */
+// The following flags are the same as the equivalent OIC values in
+// octypes.h, allowing direct copying with slight fixup.
+// The CA layer should used the OC types when build allows that.
+#ifdef RA_ADAPTER
+#define MAX_ADDR_STR_SIZE_CA (256)
+#else
+#define MAX_ADDR_STR_SIZE_CA (40)
+#endif
+
+typedef enum
+{
+    CA_DEFAULT_ADAPTER = 0,
+
+    // value zero indicates discovery
+    CA_ADAPTER_IP            = (1 << 0),   // IPv4 and IPv6, including 6LoWPAN
+    CA_ADAPTER_GATT_BTLE     = (1 << 1),   // GATT over Bluetooth LE
+    CA_ADAPTER_RFCOMM_BTEDR  = (1 << 2),   // RFCOMM over Bluetooth EDR
+
+    #ifdef RA_ADAPTER
+    CA_ADAPTER_REMOTE_ACCESS = (1 << 3)   // Remote Access over XMPP.
+    #endif
+} CATransportAdapter_t;
+
 typedef enum
 {
-    CA_IPV4 = (1 << 0),     /**< IPV4 Transport Type */
-    CA_IPV6 = (1 << 1),     /**< IPV6 Transport Type */
-    CA_EDR = (1 << 2),      /**< EDR Transport Type */
-    CA_LE = (1 << 3)        /**< LE Transport Type */
-} CATransportType_t;
+    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
+} CATransportFlags_t;
+
+#define CA_IPFAMILY_MASK (CA_IPV6|CA_IPV4)
+#define CA_SCOPE_MASK 0xf     // mask scope bits above
 
 /**
  * @enum CANetworkStatus_t
@@ -127,36 +173,14 @@ typedef enum
     CA_INTERFACE_UP    /**< Connection is Available */
 } CANetworkStatus_t;
 
-/**
- * @brief  Address of the local or remote endpoint
+/*
+ * @brief remoteEndpoint identity
  */
-typedef union
+typedef struct
 {
-    /**
-     * @brief BT Mac Information
-     */
-    struct
-    {
-        char btMacAddress[CA_MACADDR_SIZE];   /**< BT mac address **/
-    } BT;
-
-    /**
-     * @brief LE MAC Information
-     */
-    struct
-    {
-        char leMacAddress[CA_MACADDR_SIZE];   /**< BLE mac address **/
-    } LE;
-
-    /**
-     * @brief IP Information
-     */
-    struct
-    {
-        char ipAddress[CA_IPADDR_SIZE]; /**< Ip address of the interface**/
-        uint16_t port;                  /**< port information**/
-    } IP;
-} CAAddress_t;
+    uint16_t id_length;
+    unsigned char id[CA_MAX_ENDPOINT_IDENTITY_LEN];
+} CARemoteId_t;
 
 /**
  * @enum CAMessageType_t
@@ -184,36 +208,18 @@ typedef enum
 } CAMethod_t;
 
 /**
- * @brief Remote endpoint information for connectivities
- */
-typedef struct
-{
-
-    CAURI_t resourceUri;                    /**< Resource URI information **/
-    CAAddress_t addressInfo;                /**< Remote Endpoint address **/
-    CATransportType_t transportType;  /**< Transport Type of the endpoint**/
-    bool isSecured;                     /**< Secure connection**/
-} CARemoteEndpoint_t;
-
-
-/**
- * @brief Group endpoint information for connectivities
+ * @brief Endpoint information for connectivities
+ * Must be identical to OCDevAddr.
  */
 typedef struct
 {
-    CAURI_t resourceUri;                    /**< Resource URI information **/
-    CATransportType_t transportType;  /**< Transport type of the endpoint**/
-} CAGroupEndpoint_t;
-
-/**
- @brief Local Connectivity information
- */
-typedef struct
-{
-    CAAddress_t addressInfo;    /**< Address of the interface  **/
-    CATransportType_t type;  /**< Transport type of local device **/
-    bool isSecured;         /**< Secure connection**/
-} CALocalConnectivity_t;
+    CATransportAdapter_t    adapter;    // adapter type
+    CATransportFlags_t      flags;      // transport modifiers
+    char                    addr[MAX_ADDR_STR_SIZE_CA]; // address for all
+    uint32_t                interface;  // usually zero for default interface
+    uint16_t                port;       // for IP
+    CARemoteId_t identity;              // endpoint identity
+} CAEndpoint_t;
 
 /**
  * @enum CAResult_t
@@ -235,6 +241,7 @@ typedef enum
     CA_REQUEST_TIMEOUT,             /**< Request is Timeout */
     CA_DESTINATION_DISCONNECTED,    /**< Destination is disconnected */
     CA_NOT_SUPPORTED,               /**< Not supported */
+    CA_STATUS_NOT_INITIALIZED,      /**< CA layer is not initialized */
     CA_STATUS_FAILED =255           /**< Failure */
     /* Result code - END HERE */
 } CAResult_t;
@@ -250,8 +257,13 @@ typedef enum
     CA_SUCCESS = 200,                /**< Success */
     CA_CREATED = 201,                /**< Created */
     CA_DELETED = 202,                /**< Deleted */
+    CA_VALID = 203,                  /**< Valid */
+    CA_CHANGED = 204,                /**< Changed */
+    CA_CONTENT = 205,                /**< Content */
     CA_BAD_REQ = 400,                /**< Bad Request */
+    CA_UNAUTHORIZED_REQ = 401,       /**< Unauthorized Request */
     CA_BAD_OPT = 402,                /**< Bad Option */
+    CA_FORBIDDEN_REQ = 403,          /**< Forbidden Request */
     CA_NOT_FOUND = 404,              /**< Not found */
     CA_INTERNAL_SERVER_ERROR = 500,  /**< Internal Server Error */
     CA_RETRANSMIT_TIMEOUT = 504      /**< Retransmit timeout */
@@ -289,7 +301,7 @@ typedef struct
     uint16_t optionID;                                      /**< The header option ID which will be
                                                             added to communication packets */
     uint16_t optionLength;                                  /**< Option Length **/
-    uint8_t optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH];   /**< Optional data values**/
+    char optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH];      /**< Optional data values**/
 } CAHeaderOption_t;
 
 /**
@@ -309,6 +321,8 @@ typedef struct
     CAHeaderOption_t *options;  /** Header Options for the request */
     uint8_t numOptions;         /**< Number of Header options */
     CAPayload_t payload;        /**< payload of the request  */
+    size_t payloadSize;         /**< size in bytes of the payload */
+    CAURI_t resourceUri;        /**< Resource URI information **/
 } CAInfo_t;
 
 /**
@@ -320,6 +334,7 @@ typedef struct
 {
     CAMethod_t method;  /**< Name of the Method Allowed */
     CAInfo_t info;      /**< Information of the request. */
+    bool isMulticast;   /**< is multicast request */
 } CARequestInfo_t;
 
 /**
@@ -333,9 +348,85 @@ typedef struct
     CAInfo_t info;              /**< Information of the response */
 } CAResponseInfo_t;
 
+/**
+ * @brief Error information from CA
+ *        contains error code and message information
+ *
+ * This structure holds error information
+ */
+typedef struct
+{
+    CAResult_t result;  /**< CA API request result  */
+    CAInfo_t info;      /**< message information such as token and payload data
+                             helpful to identify the error */
+} CAErrorInfo_t;
+
+/**
+ * @brief CA Remote Access information for XMPP Client
+ *
+ */
+typedef struct
+{
+    char *hostname;     /**< XMPP server hostname */
+    uint16_t port;      /**< XMPP server serivce port */
+    char *xmpp_domain;  /**< XMPP login domain */
+    char *username;     /**< login username */
+    char *password;     /**< login password */
+    char *resource;     /**< specific resource for login */
+    char *user_jid;     /**< specific JID for login */
+} CARAInfo_t;
+
+
+/**
+ * @brief Hold global variables for CA layer (also used by RI layer)
+ */
+typedef struct
+{
+    int fd;
+    uint16_t port;
+} CASocket_t;
+
+typedef struct
+{
+    CATransportFlags_t clientFlags;
+    CATransportFlags_t serverFlags;
+    bool client;
+    bool server;
+
+    struct sockets
+    {
+        void *threadpool;   // threadpool between Initialize and Start
+        CASocket_t u6;      // unicast   IPv6
+        CASocket_t u6s;     // unicast   IPv6 secure
+        CASocket_t u4;      // unicast   IPv4
+        CASocket_t u4s;     // unicast   IPv4 secure
+        CASocket_t m6;      // multicast IPv6
+        CASocket_t m6s;     // multicast IPv6 secure
+        CASocket_t m4;      // multicast IPv4
+        CASocket_t m4s;     // multicast IPv4 secure
+        int netlinkFd;      // netlink
+        int shutdownFds[2]; // shutdown pipe
+        int selectTimeout;  // in seconds
+        int maxfd;          // highest fd (for select)
+        int numInterfaces;  // number of active interfaces
+        bool started;       // the IP adapter has started
+        bool terminate;     // the IP adapter needs to stop
+        bool ipv6enabled;   // IPv6 enabled by OCInit flags
+        bool ipv4enabled;   // IPv4 enabled by OCInit flags
+    } ip;
+
+    struct calayer
+    {
+        CATransportFlags_t previousRequestFlags; // address family filtering
+        uint16_t previousRequestMessageId;       // address family filtering
+    } ca;
+} CAGlobals_t;
+
+extern CAGlobals_t caglobals;
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
 
-#endif /* CA_COMMON_H_ */
+#endif //#ifndef CA_COMMON_H_
 
index 7607bfc..27b4ff2 100644 (file)
@@ -48,7 +48,7 @@ extern "C"
  * @param   requestInfo [OUT] Info for resource model to understand about the request.
  * @return  NONE
  */
-typedef void (*CARequestCallback)(const CARemoteEndpoint_t *object,
+typedef void (*CARequestCallback)(const CAEndpoint_t *object,
                                   const CARequestInfo_t *requestInfo);
 
 /**
@@ -57,8 +57,16 @@ typedef void (*CARequestCallback)(const CARemoteEndpoint_t *object,
  * @param   responseInfo    [OUT] Identifier which needs to be mapped with response.
  * @return  NONE
  */
-typedef void (*CAResponseCallback)(const CARemoteEndpoint_t *object,
+typedef void (*CAResponseCallback)(const CAEndpoint_t *object,
                                    const CAResponseInfo_t *responseInfo);
+/**
+ * @brief   Callback function type for error
+ * @param   object          [OUT] remote device information
+ * @param   errorInfo       [OUT] CA Error information
+ * @return  NONE
+ */
+typedef void (*CAErrorCallback)(const CAEndpoint_t *object,
+                                const CAErrorInfo_t *errorInfo);
 
 #ifdef __WITH_DTLS__
 
@@ -122,9 +130,11 @@ CAResult_t CAStartDiscoveryServer();
  * @param   RespHandler  [IN] Response Handler Callback
  * @see     CARequestCallback
  * @see     CAResponseCallback
+ * @see     CAErrorCallback
  * @return  NONE
  */
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                       CAErrorCallback ErrorHandler);
 
 #ifdef __WITH_DTLS__
 /**
@@ -132,34 +142,32 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
  * @param   GetDTLSCredentials   [IN] GetDTLS Credetials callback
  * @return  #CA_STATUS_OK
  */
-CAResult_t CARegisterDTLSCredentialsHandler(
-                                                   CAGetDTLSCredentialsHandler GetDTLSCredentials);
+CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSCredentials);
 #endif //__WITH_DTLS__
 
 /**
- * @brief   Create a Remote endpoint if the URI is available already.
- *          This is a Helper function which can be used before calling
- *          CASendRequest / CASendNotification.
- * @param   uri                 [IN]  Absolute URI of the resource to be used to generate the
- *                                    Remote endpoint
- *                                    \n For ex : coap://10.11.12.13:4545/resource_uri ( for IP)
- *                                    \n coap://10:11:12:13:45:45/resource_uri ( for BT)
- * @param   transportType    [IN]  Transport type of the endpoint
- * @param   object              [OUT] Endpoint object which contains the above parsed data
+ * @brief   Create an endpoint description
+ * @param   flags               [IN]  how the adapter should be used
+ * @param   adapter             [IN]  which adapter to use
+ * @param   addr                [IN]  string representation of address
+ * @param   port                [IN]  port (for IP_ADAPTER)
+ * @param   endpoint            [OUT] Endpoint which contains the above
  * @return  #CA_STATUS_OK or #CA_STATUS_FAILED
- * @remark  The created Remote endpoint can be freed using CADestroyRemoteEndpoint() API.
- * @see     CADestroyRemoteEndpoint
+ * @remark  The created Remote endpoint can be freed using CADestroyEndpoint().
+ * @see     CADestroyEndpoint
  */
-CAResult_t CACreateRemoteEndpoint(const CAURI_t uri,
-                                  const CATransportType_t transportType,
-                                  CARemoteEndpoint_t **object);
+CAResult_t CACreateEndpoint(CATransportFlags_t flags,
+                            CATransportAdapter_t adapter,
+                            const char *addr,
+                            uint16_t port,
+                            CAEndpoint_t **object);
 
 /**
  * @brief   Destroy the remote endpoint created
- * @param   object  [IN] Remote Endpoint object created with CACreateRemoteEndpoint
+ * @param   object  [IN] Remote Endpoint object created with CACreateEndpoint
  * @return  NONE
  */
-void CADestroyRemoteEndpoint(CARemoteEndpoint_t *object);
+void CADestroyEndpoint(CAEndpoint_t *object);
 
 /**
  * @brief   Generating the token for matching the request and response.
@@ -180,83 +188,46 @@ CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength);
 void CADestroyToken(CAToken_t token);
 
 /**
- * @brief   Find the resource in the network. This API internally sends multicast messages on all
- *          selected connectivity adapters. Responses are delivered via response callbacks.
- *
- * @param   resourceUri [IN] Uri to send multicast search request. Must contain only relative
- *                           path of Uri to be search.
- * @param   token       [IN] Token for the request
- * @param   tokenLength [IN]  length of the token
- * @return  #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_STATUS_NOT_INITIALIZED
- */
-CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength);
-
-/**
  * @brief   Send control Request on a resource
- * @param   object      [IN] Remote Endpoint where the payload need to be sent.
- *                           This Remote endpoint is delivered with Request or response callback.
+ * @param   object      [IN] Endpoint where the payload need to be sent.
+ *                           This endpoint is delivered with Request or response callback.
  * @param   requestInfo [IN] Information for the request.
  * @return  #CA_STATUS_OK #CA_STATUS_FAILED #CA_MEMORY_ALLOC_FAILED
  */
-CAResult_t CASendRequest(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
-
-/**
- * @brief   Send control Request on a resource to multicast group
- * @param   object      [IN] Group Endpoint where the payload need to be sent.
- *                           This Remote endpoint is delivered with Request or response callback.
- * @param   requestInfo [IN] Information for the request.
- * @return  #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED
- */
-CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
-                              const CARequestInfo_t *requestInfo);
+CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
 
 /**
  * @brief   Send the response
- * @param   object          [IN] Remote Endpoint where the payload need to be sent.
- *                               This Remote endpoint is delivered with Request or response callback
+ * @param   object          [IN] Endpoint where the payload need to be sent.
+ *                               This endpoint is delivered with Request or response callback
  * @param   responseInfo    [IN] Information for the response
  * @return  #CA_STATUS_OK or  #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED
  */
-CAResult_t CASendResponse(const CARemoteEndpoint_t *object,
-                const CAResponseInfo_t *responseInfo);
+CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
 
 /**
  * @brief   Send notification to the remote object
- * @param   object          [IN] Remote Endpoint where the payload need to be sent.
- *                               This Remote endpoint is delivered with Request or response callback.
+ * @param   object          [IN] Endpoint where the payload need to be sent.
+ *                               This endpoint is delivered with Request or response callback.
  * @param   responseInfo    [IN] Information for the response.
  * @return  #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED
  */
-CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
+CAResult_t CASendNotification(const CAEndpoint_t *object,
                       const  CAResponseInfo_t *responseInfo);
 
 /**
- * @brief   To advertise the resource
- * @param   resourceUri [IN] URI to be advertised
- * @param   token       [IN] Token for the request
- * @param   tokenLength [IN] length of the token
- * @param   options     [IN] Header options information
- * @param   numOptions  [IN] Number of options
- * @return  #CA_STATUS_OK or #CA_STATUS_FAILED or
- *          #CA_MEMORY_ALLOC_FAILED or #CA_STATUS_NOT_INITIALIZED
- */
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token,
-                               uint8_t tokenLength, const CAHeaderOption_t *options,
-                               const uint8_t numOptions);
-
-/**
  * @brief   Select network to use
  * @param   interestedNetwork   [IN] Connectivity Type enum
  * @return  #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED or #CA_NOT_SUPPORTED
  */
-CAResult_t CASelectNetwork(const uint32_t interestedNetwork);
+CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork);
 
 /**
  * @brief   Select network to unuse
  * @param   nonInterestedNetwork    [IN] Connectivity Type enum
  * @return  #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED
  */
-CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork);
+CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork);
 
 /**
  * @brief   Get network information
@@ -266,7 +237,7 @@ CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork);
  * @return  #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_STATUS_INVALID_PARAM or
 *                #CA_MEMORY_ALLOC_FAILED
  */
-CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief    To Handle the Request or Response
@@ -274,6 +245,95 @@ CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
  */
 CAResult_t CAHandleRequestResponse();
 
+#ifdef RA_ADAPTER
+/**
+ * @brief   Set Remote Access information for XMPP Client.
+ * @param   caraInfo          [IN] remote access info.
+ *
+ * @return  #CA_STATUS_OK
+ */
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
+#endif
+
+
+#ifdef __WITH_DTLS__
+
+/**
+ * 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
+ *
+ * @retval  CA_STATUS_OK    Successful
+ * @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+ * @retval  CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CASelectCipherSuite(const uint16_t cipher);
+
+/**
+ * Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA cipher suite in dtls
+ *
+ * @param[IN] enable  TRUE/FALSE enables/disables anonymous cipher suite
+ *
+ * @retval  CA_STATUS_OK    Successful
+ * @retval  CA_STATUS_FAILED Operation failed
+ *
+ * @note anonymous cipher suite should only be enabled for 'JustWorks' provisioning.
+ */
+CAResult_t CAEnableAnonECDHCipherSuite(const bool enable);
+
+
+/**
+ * Generate ownerPSK using PRF
+ * OwnerPSK = TLS-PRF('master key' , 'oic.sec.doxm.jw',
+ *                                    'ID of new device(Resource Server)',
+ *                                    'ID of owner smart-phone(Provisioning Server)')
+ *
+ * @param[IN] endpoint  information of network address
+ * @param[IN] label  Ownership transfer method e.g)"oic.sec.doxm.jw"
+ * @param[IN] labelLen  Byte length of label
+ * @param[IN] rsrcServerDeviceID  ID of new device(Resource Server)
+ * @param[IN] rsrcServerDeviceIDLen  Byte length of rsrcServerDeviceID
+ * @param[IN] provServerDeviceID  label of previous owner
+ * @param[IN] provServerDeviceIDLen  byte length of provServerDeviceID
+ * @param[IN,OUT] ownerPSK  Output buffer for owner PSK
+ * @param[IN] ownerPSKSize  Byte length of the ownerPSK to be generated
+ *
+ * @retval  CA_STATUS_OK    Successful
+ * @retval  CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t *endpoint,
+                              const uint8_t* label, const size_t labelLen,
+                              const uint8_t* rsrcServerDeviceID,
+                              const size_t rsrcServerDeviceIDLen,
+                              const uint8_t* provServerDeviceID,
+                              const size_t provServerDeviceIDLen,
+                              uint8_t* ownerPSK, const size_t ownerPSKSize);
+
+/**
+ * Initiate DTLS handshake with selected cipher suite
+ *
+ * @param[IN] endpoint  information of network address
+ *
+ * @retval  CA_STATUS_OK    Successful
+ * @retval  CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint);
+
+/**
+ * Close the DTLS session
+ *
+ * @param[IN] endpoint  information of network address
+ *
+ * @retval  CA_STATUS_OK    Successful
+ * @retval  CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint);
+
+#endif /* __WITH_DTLS__ */
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 2725deb..dcacc9a 100644 (file)
@@ -62,6 +62,8 @@ Note :- Upon successful execution of above command(s) CA library will be generat
 Tizen Build:
 
 1) If you are building first time, then delete GBS-ROOT folder from home directory.
+   Note: Default build server URL for Tizen is set in gbs configuration file @ iotivity/tools/tizen/.gbs.conf.
+         If need be, same can be modified as per appropriate target.
 
 2) Go to "iotivity/" folder.
 
index b901f1a..8117205 100644 (file)
@@ -68,6 +68,14 @@ help_vars.Add(EnumVariable('BUILD_SAMPLE', 'Build with sample', 'ON', allowed_va
 
 help_vars.AddVariables(('DEVICE_NAME', 'Network display name for device', 'OIC-DEVICE', None, None),)
 
+AddOption('--prefix',
+                  dest='prefix',
+                  type='string',
+                  nargs=1,
+                  action='store',
+                  metavar='DIR',
+                  help='installation prefix')
+
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
 ######################################################################
@@ -85,7 +93,7 @@ if target_os in ['android', 'arduino']: # Android/Arduino always uses GNU compil
                        tools = ['gnulink', 'gcc', 'g++', 'ar', 'as']
                        )
 else:
-       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os)
+       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os, PREFIX = GetOption('prefix'))
 
 Help(help_vars.GenerateHelpText(env))
 
@@ -161,6 +169,22 @@ def __install(ienv, targets, name):
        Alias(name, i_n)
        env.AppendUnique(TS = [name])
 
+def __installlib(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/lib', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
+def __installbin(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/bin', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
 def __append_target(ienv, target):
        env.AppendUnique(TS = [target])
 
@@ -182,6 +206,8 @@ env.AddMethod(__print_targets, 'PrintTargets')
 env.AddMethod(__src_to_obj, 'SrcToObj')
 env.AddMethod(__append_target, 'AppendTarget')
 env.AddMethod(__install, 'InstallTarget')
+env.AddMethod(__installlib, 'UserInstallTargetLib')
+env.AddMethod(__installbin, 'UserInstallTargetBin')
 env.SetDir(env.GetLaunchDir())
 env['ROOT_DIR']=env.GetLaunchDir()+'/..'
 
index 32880e7..1a50785 100644 (file)
@@ -164,7 +164,7 @@ else:
        env.AppendUnique(CCFLAGS = ['-g'])
 
 if env.get('LOGGING'):
-        env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+        env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__'])
 env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
index 54233f6..8754e31 100644 (file)
@@ -12,18 +12,20 @@ $(info PLATFORM=$(APP_PLATFORM))
 #define build type
 BUILD = debug
 
-PROJECT_ROOT_PATH                       ?= ../..
-EXT_LIB_PATH                            = ../../../../../../extlibs
-PROJECT_API_PATH                        = $(PROJECT_ROOT_PATH)/api
-PROJECT_INC_PATH                        = $(PROJECT_ROOT_PATH)/inc
-PROJECT_SRC_PATH                        = $(PROJECT_ROOT_PATH)/src
-PROJECT_COMMON_PATH                     = $(PROJECT_ROOT_PATH)/common
-PROJECT_COMMON_INC_PATH                 = $(PROJECT_COMMON_PATH)/inc
-PROJECT_COMMON_SRC_PATH                 = $(PROJECT_COMMON_PATH)/src
-PROJECT_LIB_PATH                        = $(PROJECT_ROOT_PATH)/lib
-PROJECT_EXTERNAL_PATH                   = $(PROJECT_ROOT_PATH)/external/inc
-DTLS_LIB                                = $(EXT_LIB_PATH)/tinydtls
-#GLIB_PATH                               = ../../../../../../extlibs/glib/glib-2.40.2
+PROJECT_ROOT_PATH           ?= ../..
+ROOT_DIR_PATH               = ../../../../../..
+EXT_LIB_PATH                = $(ROOT_DIR_PATH)/extlibs
+PROJECT_API_PATH            = $(PROJECT_ROOT_PATH)/api
+PROJECT_INC_PATH            = $(PROJECT_ROOT_PATH)/inc
+PROJECT_SRC_PATH            = $(PROJECT_ROOT_PATH)/src
+PROJECT_COMMON_PATH         = $(PROJECT_ROOT_PATH)/common
+PROJECT_COMMON_INC_PATH     = $(PROJECT_COMMON_PATH)/inc
+PROJECT_COMMON_SRC_PATH     = $(PROJECT_COMMON_PATH)/src
+PROJECT_LIB_PATH            = $(PROJECT_ROOT_PATH)/lib
+PROJECT_EXTERNAL_PATH       = $(PROJECT_ROOT_PATH)/external/inc
+DTLS_LIB                    = $(EXT_LIB_PATH)/tinydtls
+OIC_C_COMMON_PATH           = $(ROOT_DIR_PATH)/resource/c_common
+#GLIB_PATH                  = ../../../../../../extlibs/glib/glib-2.40.2
 
 #Modify below values to enable/disable the Adapter
 #Suffix "NO_" to disable given adapter
@@ -74,6 +76,24 @@ include $(CLEAR_VARS)
 include $(DTLS_LIB)/Android.mk
 
 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build OIC C Common libraries required for CA
+
+include $(CLEAR_VARS)
+LOCAL_MODULE = OICCommon
+
+#Build Common Libraries
+LOCAL_PATH = $(OIC_C_COMMON_PATH)
+LOCAL_CFLAGS = -D__ANDROID__ $(DEBUG_FLAG)
+LOCAL_CFLAGS += -std=c99
+
+LOCAL_C_INCLUDES = $(OIC_C_COMMON_PATH)/oic_malloc/include \
+                   $(OIC_C_COMMON_PATH)/oic_string/include
+LOCAL_SRC_FILES  = oic_malloc/src/oic_malloc.c \
+                   oic_string/src/oic_string.c
+
+include $(BUILD_STATIC_LIBRARY)
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #Build CACommon
 
 include $(CLEAR_VARS)
@@ -84,17 +104,20 @@ LOCAL_MODULE = CACommon
 LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
 #LOCAL_SHARED_LIBRARIES = Glib GLibThread
 LOCAL_STATIC_LIBRARIES = rt pthread
+LOCAL_STATIC_LIBRARIES += OICCommon
 
 LOCAL_CFLAGS = -D__ANDROID__ $(DEBUG_FLAG)
 LOCAL_CFLAGS += -std=c99
 
 LOCAL_C_INCLUDES = $(PROJECT_COMMON_INC_PATH)
 LOCAL_C_INCLUDES += $(PROJECT_API_PATH)
+LOCAL_C_INCLUDES += $(OIC_C_COMMON_PATH)/oic_malloc/include
+LOCAL_C_INCLUDES += $(OIC_C_COMMON_PATH)/oic_string/include
 
-LOCAL_SRC_FILES =       oic_logger.c \
-                        oic_console_logger.c logger.c oic_malloc.c \
-                        uarraylist.c uqueue.c oic_string.c \
-                        cathreadpool_pthreads.c camutex_pthreads.c
+LOCAL_SRC_FILES =       oic_logger.c oic_console_logger.c logger.c \
+                        uarraylist.c uqueue.c \
+                        cathreadpool_pthreads.c camutex_pthreads.c \
+                        caremotehandler.c
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -138,17 +161,20 @@ LOCAL_C_INCLUDES += $(PROJECT_COMMON_INC_PATH)
 LOCAL_C_INCLUDES += $(PROJECT_INC_PATH)
 LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/libcoap-4.1.1
 LOCAL_C_INCLUDES += $(PROJECT_EXTERNAL_PATH)
+LOCAL_C_INCLUDES += $(OIC_C_COMMON_PATH)/oic_malloc/include
+LOCAL_C_INCLUDES += $(OIC_C_COMMON_PATH)/oic_string/include
+
 LOCAL_C_INCLUDES += $(DTLS_LIB)
 
 LOCAL_CFLAGS += $(BUILD_FLAG)
 LOCAL_CFLAGS += -std=c99 -DWITH_POSIX
 
 LOCAL_SRC_FILES = \
-                caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c \
+                caconnectivitymanager.c cainterfacecontroller.c \
                 camessagehandler.c canetworkconfigurator.c caprotocolmessage.c \
                 caretransmission.c caqueueingthread.c \
                 $(ADAPTER_UTILS)/caadapternetdtls.c $(ADAPTER_UTILS)/caadapterutils.c \
-                $(ADAPTER_UTILS)/camsgparser.c \
+                $(ADAPTER_UTILS)/cafragmentation.c \
                 bt_le_adapter/caleadapter.c $(LE_ADAPTER_PATH)/caleclient.c \
                 $(LE_ADAPTER_PATH)/caleserver.c $(LE_ADAPTER_PATH)/caleutils.c \
                 $(LE_ADAPTER_PATH)/calenwmonitor.c \
@@ -156,7 +182,7 @@ LOCAL_SRC_FILES = \
                 $(EDR_ADAPTER_PATH)/caedrclient.c $(EDR_ADAPTER_PATH)/caedrserver.c \
                 $(EDR_ADAPTER_PATH)/caedrnwmonitor.c \
                 $(IP_ADAPTER_PATH)/caipadapter.c $(IP_ADAPTER_PATH)/caipserver.c \
-                $(IP_ADAPTER_PATH)/caipclient.c $(IP_ADAPTER_PATH)/android/caipnwmonitor.c \
+                $(IP_ADAPTER_PATH)/android/caipnwmonitor.c \
 
 include $(BUILD_STATIC_LIBRARY)
 
index 9d55105..7227798 100755 (executable)
@@ -95,7 +95,7 @@ CORE_CPPOBJ = CDC.cpp.o HardwareSerial.cpp.o HardwareSerial0.cpp.o HardwareSeria
               main.cpp.o new.cpp.o Print.cpp.o Stream.cpp.o Tone.cpp.o USBCore.cpp.o WMath.cpp.o WString.cpp.o
 SPI_OBJ = SPI.cpp.o
 LOGGER_OBJ = logger.c.o oic_logger.c.o oic_console_logger.c.o oic_malloc.c.o oic_string.c.o uarraylist.c.o
-UTIL_OBJ = caadapterutils.c.o camsgparser.c.o
+UTIL_OBJ = caadapterutils.c.o cafragmentation.c.o
 CACOMMON_OBJ = caconnectivitymanager_singlethread.c.o cainterfacecontroller_singlethread.c.o camessagehandler_singlethread.c.o canetworkconfigurator_singlethread.c.o caprotocolmessage_singlethread.c.o \
                           caremotehandler.c.o caretransmission_singlethread.c.o
 
diff --git a/resource/csdk/connectivity/build/common.mk b/resource/csdk/connectivity/build/common.mk
deleted file mode 100644 (file)
index 858dda1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#/******************************************************************
-# *
-# * Copyright 2014 Samsung Electronics All Rights Reserved.
-# *
-# *
-# *
-# * Licensed under the Apache License, Version 2.0 (the "License");
-# * you may not use this file except in compliance with the License.
-# * You may obtain a copy of the License at
-# *
-# *      http://www.apache.org/licenses/LICENSE-2.0
-# *
-# * Unless required by applicable law or agreed to in writing, software
-# * distributed under the License is distributed on an "AS IS" BASIS,
-# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# * See the License for the specific language governing permissions and
-# * limitations under the License.
-# *
-#******************************************************************/
-
-##
-##     Definitions
-##
-SHELL                                          = /bin/bash
-PROJECT_NAME                           = connectivity_abstraction
-PROJECT_ROOT_PATH                      = ..
-PROJECT_API_PATH                               = $(PROJECT_ROOT_PATH)/api
-PROJECT_INC_PATH                               = $(PROJECT_ROOT_PATH)/inc
-PROJECT_SRC_PATH                       = $(PROJECT_ROOT_PATH)/src
-PROJECT_COMMON_INC_PATH        = $(PROJECT_ROOT_PATH)/common/inc
-PROJECT_COMMON_SRC_PATH        = $(PROJECT_ROOT_PATH)/common/src
-PROJECT_COMMON_PATH            = $(PROJECT_ROOT_PATH)/common
-PROJECT_OUT_PATH                       = $(PROJECT_ROOT_PATH)/build/out
-PROJECT_LIB_PATH                               = $(PROJECT_ROOT_PATH)/lib
-
-##
-##     macro
-##
-define MAKE_PROJECT_OUT_PATH
-       @if     [ ! -d $(PROJECT_OUT_PATH) ]; then      \
-       mkdir $(PROJECT_OUT_PATH);      \
-       fi
-endef
-
-
-##
-##     Commands
-##
-CC                     = gcc
-CXX                    = g++
-RM                     = rm -rf
-CP                     = cp
-MV                     = mv
-AR                     = ar
-LD                     = ld
-LN                     = ln
-CD                     = cd
-RANLIB         = ranlib
-
-
index 528b060..0a61fc0 100755 (executable)
@@ -25,7 +25,6 @@ export RELEASE=$4
 echo $5
 export LOGGING=$5
 
-
 echo $TARGET_TRANSPORT
 echo $BUILD_SAMPLE
 
@@ -36,6 +35,7 @@ sourcedir=`pwd`
 
 echo `pwd`
 
+rm -rf ./tmp
 mkdir ./tmp
 mkdir ./tmp/con/
 cp -R $cur_dir/* $sourcedir/tmp/con
@@ -48,10 +48,21 @@ cp -R $cur_dir/lib/libcoap-4.1.1/SConscript $sourcedir/tmp/con/lib/libcoap-4.1.1
 cp -R $cur_dir/samples/tizen/ $sourcedir/tmp/con/sample/
 mkdir -p $sourcedir/tmp/con/sample/lib/tizen/ble/libs
 cp -R $cur_dir/lib/tizen/ble/libs/* $sourcedir/tmp/con/sample/lib/tizen/ble/libs/
+mkdir -p $sourcedir/tmp/con/sample/external/inc
+cp -R $cur_dir/external/inc/* $sourcedir/tmp/con/sample/external/inc/
+mkdir -p $sourcedir/tmp/con/extlibs/
+cp -R ./extlibs/tinydtls/ $sourcedir/tmp/con/extlibs/
+mkdir -p $sourcedir/tmp/con/c_common
+cp -R ./resource/c_common/* $sourcedir/tmp/con/c_common/
+
+# copy dependency RPMs and conf files for tizen build
+cp ./tools/tizen/*.rpm $sourcedir/tmp
+cp ./tools/tizen/*.rpm $sourcedir/tmp/con/sample
+cp ./tools/tizen/.gbs.conf ./tmp
+cp ./tools/tizen/.gbs.conf ./tmp/con/sample
 
 cd $sourcedir
 cd $cur_dir/build/tizen
-
 cp -R ./* $sourcedir/tmp/
 rm -f $sourcedir/tmp/SConscript
 cp SConstruct $sourcedir/tmp/
@@ -77,15 +88,15 @@ if [ ! -d .git ]; then
 fi
 
 echo "Calling core gbs build command"
-gbscommand="gbs build -A armv7l --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --repository ./"
+gbscommand="gbs build -A armv7l --include-all  --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5'"
 echo $gbscommand
 if eval $gbscommand; then
    echo "Core build is successful"
 else
-   echo "Core build failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
+   echo "Core build failed. Try 'find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
    cd $sourcedir
    rm -rf $sourcedir/tmp
-   exit
+   exit 1
 fi
 
 if echo $BUILD_SAMPLE|grep -qi '^ON$'; then
@@ -100,18 +111,19 @@ if echo $BUILD_SAMPLE|grep -qi '^ON$'; then
       git commit -m "Initial commit"
    fi
    echo "Calling sample gbs build command"
-   gbscommand="gbs build -A armv7l --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'LOGGING $5' --repository ./"
+   gbscommand="gbs build -A armv7l --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --repository ./"
    echo $gbscommand
    if eval $gbscommand; then
       echo "Sample build is successful"
    else
-      echo "Sample build is failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
+      echo "Sample build is failed. Try 'find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
+      exit 1
    fi
 else
        echo "Sample build is not enabled"
 fi
 
-
 cd $sourcedir
 rm -rf $sourcedir/tmp
 
+exit 0
index aba2653..8533188 100644 (file)
@@ -42,6 +42,9 @@ mkdir -p %{DEST_LIB_DIR}/pkgconfig
 
 cp -f %{ROOTDIR}/con/src/libconnectivity_abstraction.so %{buildroot}/%{_libdir}
 cp -f %{ROOTDIR}/con/lib/libcoap-4.1.1/libcoap.a %{buildroot}/%{_libdir}
+if echo %{SECURED}|grep -qi '1'; then
+       cp -f %{ROOTDIR}/con/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir}
+fi
 cp -rf %{ROOTDIR}/con/api/cacommon.h* %{DEST_INC_DIR}/
 cp -rf %{ROOTDIR}/con/inc/caadapterinterface.h* %{DEST_INC_DIR}/
 cp -rf %{ROOTDIR}/con/common/inc/cathreadpool.h* %{DEST_INC_DIR}/
index 318d954..9a9644d 100644 (file)
@@ -44,3 +44,4 @@ else:
 
 env.SConscript(['../con/lib/libcoap-4.1.1/SConscript'])
 env.SConscript(['../con/SConscript'])
+env.SConscript(['../con/c_common/SConscript'])
index 7c6c558..2336f2e 100644 (file)
@@ -27,34 +27,34 @@ for item in temp:
 # Source files and Target(s)
 ######################################################################
 ca_common_src = [
-               ca_common_src_path + 'oic_malloc.c',
-               ca_common_src_path + 'oic_string.c',
                ca_common_src_path + 'uarraylist.c',
                ca_common_src_path + 'uqueue.c',
+               ca_common_src_path + 'caremotehandler.c'
        ]
 
 if ca_os == 'arduino':
        env.Command(env.get('BUILD_DIR') + 'logger.c.o', None, '$CXX -o ' + env.get('BUILD_DIR') + 'logger.c.o' + ' $LINKFLAGS  $CCFLAGS  $CXXFLAGS ' + '-I' + Dir('.').srcnode().path + '/inc' + header + ' ' + Dir('.').srcnode().path + '/src/logger.c')
-       platform_src = [
+       logger_src = [
                env.get('BUILD_DIR') + 'logger.c.o',
        ]
-elif env['POSIX_SUPPORTED']:
-       platform_src = [
-                                       ca_common_src_path + 'logger.c',
-                                       ca_common_src_path + 'oic_logger.c',
-                                       ca_common_src_path + 'oic_console_logger.c',
-                                       ca_common_src_path + 'cathreadpool_pthreads.c',
-                                       ca_common_src_path + 'camutex_pthreads.c'
-       ]
 else:
-       platform_src = [
+       logger_src = [
                ca_common_src_path + 'logger.c',
                ca_common_src_path + 'oic_logger.c',
                ca_common_src_path + 'oic_console_logger.c'
                ]
 
+if env['POSIX_SUPPORTED']:
+       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'
+               ]
 
 
 env.AppendUnique(CA_SRC = ca_common_src)
+env.AppendUnique(CA_SRC = logger_src)
 env.AppendUnique(CA_SRC = platform_src)
-
@@ -39,34 +39,24 @@ extern "C"
  * @param   endpoint       [IN]    endpoint information where the data has to be sent
  * @return  remote endpoint created
  */
-CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *endpoint);
+CAEndpoint_t *CACloneEndpoint(const CAEndpoint_t *endpoint);
 
 /**
- * @brief   Creates a new remote endpoint from the input uri
- * @param   uri                 [IN]    absolute uri information to create remote endpoint
- * @param   transportType       [IN]    transport type of the endpoint
- * @return  remote endpoint created
- */
-CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri,
-                                                      const CATransportType_t transportType);
-
-/**
- * @brief   Creates a new remote endpoint from the input and other information
- * @param   resourceUri         [IN]    absolute uri information to create remote endpoint
- * @param   addr                [IN]    address of the endpoint
- * @param   type                [IN]    transport  type of the endpoint
- * @return  remote endpoint created
+ * @brief Allocate CAEndpoint_t instance.
+ * @param   flags        [IN]  Transport flag
+ * @param   adapter      [IN]  Adapter type
+ * @param   address      [IN]  Address
+ * @param   port         [IN]  Port
+ * @return  #CA_STATUS_OK or Appropriate error code
  */
-CARemoteEndpoint_t *CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
-                                                   const CAAddress_t addr,
-                                                   const CATransportType_t type);
-
+CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags, CATransportAdapter_t adapter,
+                                     const char *address, uint16_t port);
 /**
  * @brief   Destroy remote endpoint
  * @param   endpoint       [IN]    endpoint information where the data has to be sent
  * @return  none
  */
-void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t *rep);
+void CAFreeEndpoint(CAEndpoint_t *rep);
 
 /**
  * @brief   Creates a new request information
index bf6f130..ee208ad 100644 (file)
@@ -190,22 +190,13 @@ void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum,
 #endif //__TIZEN__
 #else //TB_LOG
 
-#ifdef __ANDROID__
-#define OIC_LOG_CONFIG(ctx)
-#define OIC_LOG_SHUTDOWN()
-#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)
-#define OIC_LOG_INIT()
-#define OIC_LOG(level,tag,mes) __android_log_print(ANDROID_LOG_INFO, tag, mes)
-#define OIC_LOG_V(level,tag,fmt,args...) __android_log_print(ANDROID_LOG_INFO, tag, fmt,##args)
-
-#else
 #define OIC_LOG_CONFIG(ctx)
 #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_INIT()
-#endif //__ANDROID__
+
 #endif // TB_LOG
 
 
index 17edead..7fa6200 100644 (file)
@@ -105,6 +105,13 @@ uint32_t u_arraylist_length(const u_arraylist_t *list);
  */
 bool u_arraylist_contains(const u_arraylist_t *list,const void *data);
 
+/**
+ * @brief Destroys array list and elements (assuming elements are shallow)
+ * @param list
+ *    [IN] pointer of array list
+ */
+void u_arraylist_destroy(u_arraylist_t *list);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/resource/csdk/connectivity/common/src/camutex_noop.c b/resource/csdk/connectivity/common/src/camutex_noop.c
new file mode 100644 (file)
index 0000000..2250cb3
--- /dev/null
@@ -0,0 +1,112 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+//*********************************************************************
+
+/**
+ * @file
+ * This file provides APIs related to mutex with no operation
+ * for Singlethread implementation.
+ */
+
+#include "camutex.h"
+
+/**
+ * TAG
+ * Logging tag for module name
+ */
+#define TAG "UMUTEX"
+
+typedef struct _tagMutexInfo_t
+{
+} ca_mutex_internal;
+
+typedef struct _tagEventInfo_t
+{
+} ca_cond_internal;
+
+/**
+ * @var g_mutexInfo
+ * @brief This is used to return a non NULL value for ca_mutex_new().
+ */
+static ca_mutex_internal g_mutexInfo = { 0 };
+
+/**
+ * @var g_condInfo
+ * @brief This is used to return a non NULL value for ca_cond_new().
+ */
+static ca_cond_internal g_condInfo = { 0 };
+
+ca_mutex ca_mutex_new(void)
+{
+    return &g_mutexInfo;
+}
+
+bool ca_mutex_free(ca_mutex mutex)
+{
+    return true;
+}
+
+void ca_mutex_lock(ca_mutex mutex)
+{
+    return;
+}
+
+bool ca_mutex_trylock(ca_mutex mutex)
+{
+    return true;
+}
+
+void ca_mutex_unlock(ca_mutex mutex)
+{
+    return;
+}
+
+ca_cond ca_cond_new(void)
+{
+    return &g_condInfo;
+}
+
+void ca_cond_free(ca_cond cond)
+{
+    return;
+}
+
+void ca_cond_signal(ca_cond cond)
+{
+    return;
+}
+
+void ca_cond_broadcast(ca_cond cond)
+{
+    return;
+}
+
+void ca_cond_wait(ca_cond cond, ca_mutex mutex)
+{
+    return;
+}
+
+CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds)
+{
+    return CA_WAIT_SUCCESS;
+}
+
diff --git a/resource/csdk/connectivity/common/src/caremotehandler.c b/resource/csdk/connectivity/common/src/caremotehandler.c
new file mode 100644 (file)
index 0000000..49eb444
--- /dev/null
@@ -0,0 +1,358 @@
+/******************************************************************
+ *
+ * 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 <string.h>
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "caremotehandler.h"
+#include "logger.h"
+
+#define TAG "CA"
+
+CAEndpoint_t *CACloneEndpoint(const CAEndpoint_t *rep)
+{
+    if (NULL == rep)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return NULL;
+    }
+
+    // allocate the remote end point structure.
+    CAEndpoint_t *clone = (CAEndpoint_t *)OICMalloc(sizeof (CAEndpoint_t));
+    if (NULL == clone)
+    {
+        OIC_LOG(ERROR, TAG, "CACloneRemoteEndpoint Out of memory");
+        return NULL;
+    }
+    *clone = *rep;
+
+    return clone;
+}
+
+CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
+{
+    if (NULL == rep)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return NULL;
+    }
+
+    // allocate the request info structure.
+    CARequestInfo_t *clone = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
+    if (!clone)
+    {
+        OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
+        return NULL;
+    }
+
+    *clone = *rep;
+
+    if (rep->info.token)
+    {
+        char *temp = NULL;
+
+        // allocate token field
+        uint8_t len = rep->info.tokenLength;
+
+        if (len)
+        {
+            temp = (char *) OICCalloc(len, sizeof(char));
+            if (!temp)
+            {
+                OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
+
+                CADestroyRequestInfoInternal(clone);
+
+                return NULL;
+            }
+            memcpy(temp, rep->info.token, len);
+        }
+
+        // save the token
+        clone->info.token = temp;
+        clone->info.tokenLength = len;
+    }
+
+    if (NULL != rep->info.options && 0 < rep->info.numOptions)
+    {
+        // save the options
+        clone->info.options =
+            (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
+        if (NULL == clone->info.options)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
+            OICFree(clone->info.token);
+            OICFree(clone);
+            return NULL;
+        }
+        memcpy(clone->info.options, rep->info.options,
+               sizeof(CAHeaderOption_t) * rep->info.numOptions);
+    }
+    else
+    {
+        clone->info.options = NULL;
+        clone->info.numOptions = 0;
+    }
+
+    if (NULL != rep->info.payload)
+    {
+        // allocate payload field
+        uint8_t *temp = OICMalloc(rep->info.payloadSize);
+        if (NULL == temp)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
+
+            CADestroyRequestInfoInternal(clone);
+
+            return NULL;
+        }
+        memcpy(temp, rep->info.payload, rep->info.payloadSize);
+
+        // save the payload
+        clone->info.payload = temp;
+    }
+
+    if (NULL != rep->info.resourceUri)
+    {
+        // allocate payload field
+        char *temp = OICStrdup(rep->info.resourceUri);
+        if (NULL == temp)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
+
+            CADestroyRequestInfoInternal(clone);
+
+            return NULL;
+        }
+
+        // save the resourceUri
+        clone->info.resourceUri = temp;
+    }
+
+    return clone;
+}
+
+CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
+{
+    if (NULL == rep)
+    {
+        OIC_LOG(ERROR, TAG, "Response pointer is NULL");
+        return NULL;
+    }
+
+    // check the result value of response info.
+    // Keep this check in sync with CAResponseResult_t
+    switch (rep->result)
+    {
+        case CA_EMPTY:
+        case CA_SUCCESS:
+        case CA_CREATED:
+        case CA_DELETED:
+        case CA_VALID:
+        case CA_CHANGED:
+        case CA_CONTENT:
+        case CA_BAD_REQ:
+        case CA_UNAUTHORIZED_REQ:
+        case CA_BAD_OPT:
+        case CA_FORBIDDEN_REQ:
+        case CA_NOT_FOUND:
+        case CA_INTERNAL_SERVER_ERROR:
+        case CA_RETRANSMIT_TIMEOUT:
+            break;
+
+        default:
+            OIC_LOG_V(ERROR, TAG, "Response code  %u is invalid", rep->result);
+            return NULL;
+    }
+
+    // allocate the response info structure.
+    CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
+    if (NULL == clone)
+    {
+        OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
+        return NULL;
+    }
+    *clone = *rep;
+
+    if (rep->info.token)
+    {
+        char *temp = NULL;
+
+        // allocate token field
+        uint8_t len = rep->info.tokenLength;
+
+        if (len)
+        {
+            temp = (char *) OICCalloc(len, sizeof(char));
+            if (!temp)
+            {
+                OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
+
+                CADestroyResponseInfoInternal(clone);
+
+                return NULL;
+            }
+            memcpy(temp, rep->info.token, len);
+        }
+        // save the token
+        clone->info.token = temp;
+        clone->info.tokenLength = len;
+    }
+
+    if (NULL != rep->info.options && rep->info.numOptions)
+    {
+        // save the options
+        clone->info.options =
+                (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
+
+        if (NULL == clone->info.options)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
+
+            OICFree(clone->info.token);
+            OICFree(clone);
+            return NULL;
+        }
+        memcpy(clone->info.options, rep->info.options,
+                sizeof(CAHeaderOption_t) * rep->info.numOptions);
+    }
+    else
+    {
+        clone->info.options = NULL;
+        clone->info.numOptions = 0;
+    }
+
+    if (NULL != rep->info.payload)
+    {
+        // allocate payload field
+        uint8_t *temp = (uint8_t *) OICMalloc(rep->info.payloadSize);
+        if (NULL == temp)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
+
+            CADestroyResponseInfoInternal(clone);
+
+            return NULL;
+        }
+        memcpy(temp, rep->info.payload, rep->info.payloadSize);
+
+        // save the payload
+        clone->info.payload = temp;
+    }
+
+    if (NULL != rep->info.resourceUri)
+    {
+        // allocate payload field
+        char *temp = OICStrdup(rep->info.resourceUri);
+        if (NULL == temp)
+        {
+            OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
+
+            CADestroyResponseInfoInternal(clone);
+
+            return NULL;
+        }
+
+        // save the resourceUri
+        clone->info.resourceUri = temp;
+    }
+
+    return clone;
+}
+
+CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags,
+                                     CATransportAdapter_t adapter,
+                                     const char *address,
+                                     uint16_t port)
+{
+    CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t));
+    if (NULL == info)
+    {
+        OIC_LOG(ERROR, TAG, "Memory allocation failed !");
+        return NULL;
+    }
+
+    if (address)
+    {
+        OICStrcpy(info->addr, sizeof(info->addr), address);
+        info->addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
+    }
+    info->flags = flags;
+    info->adapter = adapter;
+    info->port = port;
+
+    return info;
+}
+
+void CAFreeEndpoint(CAEndpoint_t *rep)
+{
+    OICFree(rep);
+}
+
+void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
+{
+    if (NULL == rep)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return;
+    }
+
+    // free token field
+    OICFree(rep->info.token);
+
+    // free options field
+    OICFree((CAHeaderOption_t *) rep->info.options);
+
+    // free payload field
+    OICFree((char *) rep->info.payload);
+
+    // free uri
+    OICFree(rep->info.resourceUri);
+
+    OICFree(rep);
+}
+
+void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
+{
+    if (NULL == rep)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return;
+    }
+
+    // free token field
+    OICFree(rep->info.token);
+
+    // free options field
+    if (rep->info.options != NULL && rep->info.numOptions)
+    {
+        OICFree((CAHeaderOption_t *) rep->info.options);
+    }
+
+    // free payload field
+    OICFree((char *) rep->info.payload);
+
+    // free uri
+    OICFree(rep->info.resourceUri);
+
+    OICFree(rep);
+}
+
index 9772f99..a5d48d9 100644 (file)
@@ -196,8 +196,7 @@ void OICLogv(LogLevel level, const char *tag, const char *format, ...)
     {
         return;
     }
-    char buffer[MAX_LOG_V_BUFFER_SIZE];
-    memset(buffer, 0, sizeof buffer);
+    char buffer[MAX_LOG_V_BUFFER_SIZE] = {};
     va_list args;
     va_start(args, format);
     vsnprintf(buffer, sizeof buffer - 1, format, args);
@@ -220,6 +219,8 @@ void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16
         return;
     }
 
+    // I've got no idea why static initialization doesn't work here.  It seems that the compiler
+    // seems to think that this is a variable-sized object
     char lineBuffer[LINE_BUFFER_SIZE];
     memset(lineBuffer, 0, sizeof lineBuffer);
     int lineIndex = 0;
@@ -272,7 +273,7 @@ void OICLogInit()
          return;
      }
 
-     char buffer[LINE_BUFFER_SIZE] = {0};
+     char buffer[LINE_BUFFER_SIZE] = {};
      strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
      Serial.print(buffer);
 
index 46106c6..9347c27 100644 (file)
@@ -19,6 +19,7 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "oic_logger.h"
+#include "oic_string.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -123,16 +124,12 @@ size_t oic_log_write_level(oic_log_ctx_t *ctx, const oic_log_level ll, const cha
 int oic_log_set_module(oic_log_ctx_t *ctx, const char *module_name)
 {
     char *mn;
-    size_t l;
 
     if (0 == ctx)
         return 0;
 
     /* Swap pointers so that module data's not erased in the event of failure: */
-    l = strlen(module_name);
-
-    mn = (char *) malloc(1 + l);
-
+    mn = OICStrdup(module_name);
     if (0 == mn)
     {
         if (0 != ctx->module_name)
@@ -140,8 +137,6 @@ int oic_log_set_module(oic_log_ctx_t *ctx, const char *module_name)
         return 0;
     }
 
-    memcpy(mn, module_name, 1 + l);
-
     if (0 != ctx->module_name)
         free(ctx->module_name);
 
index 7c569d4..be897be 100644 (file)
@@ -178,4 +178,17 @@ bool u_arraylist_contains(const u_arraylist_t *list,const void *data)
     return false;
 }
 
-
+// Assumes elements are shallow (have no pointers to allocated memory)
+void u_arraylist_destroy(u_arraylist_t *list)
+{
+    if (!list)
+    {
+        return;
+    }
+    uint32_t len = u_arraylist_length(list);
+    for (uint32_t i = 0; i < len; i++)
+    {
+        OICFree(u_arraylist_get(list, i));
+    }
+    (void)u_arraylist_free(&list);
+}
index f9e0ada..395e07f 100644 (file)
@@ -127,7 +127,6 @@ u_queue_message_t *u_queue_get_element(u_queue_t *queue)
 
     if (NULL == element)
     {
-        OIC_LOG(DEBUG, TAG, "QueueGetElement : empty, no messages");
         return NULL;
     }
 
index d0da447..6b16ce1 100644 (file)
@@ -79,17 +79,19 @@ typedef CAResult_t (*CAAdapterStartDiscoveryServer)();
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
  */
-typedef int32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t *endpoint,
-        const void *data, uint32_t dataLen);
+typedef int32_t (*CAAdapterSendUnicastData)(const CAEndpoint_t *endpoint,
+                                            const void *data, uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the adapter connectivity.
  * Note: length must be > 0.
+ * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
  * @param   data        [IN]    Data which required to be sent.
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
  */
-typedef int32_t (*CAAdapterSendMulticastData)(const void *data, uint32_t dataLen);
+typedef int32_t (*CAAdapterSendMulticastData)(const CAEndpoint_t *endpoint,
+        const void *data, uint32_t dataLen);
 
 /**
  * @brief Get Network Information
@@ -97,7 +99,7 @@ typedef int32_t (*CAAdapterSendMulticastData)(const void *data, uint32_t dataLen
  * @param   size        [OUT]   Number of local connectivity structures.
  * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-typedef CAResult_t (*CAAdapterGetNetworkInfo)(CALocalConnectivity_t **info, uint32_t *size);
+typedef CAResult_t (*CAAdapterGetNetworkInfo)(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief Read Synchronous API callback.
@@ -136,7 +138,7 @@ typedef struct
     CAAdapterStartDiscoveryServer startDiscoveryServer;
 
     /** Unicast data function address**/
-    CAAdapterSendUnitcastData sendData;
+    CAAdapterSendUnicastData sendData;
 
     /** Multicast data function address**/
     CAAdapterSendMulticastData sendDataToAll;
@@ -157,23 +159,30 @@ typedef struct
 
 /**
  * @brief This will be used during the registration of adapters call backs to the common logic
- * @see CAConnectivityHandler_t , CATransportType_t
+ * @see CAConnectivityHandler_t , CATransportAdapter_t
  */
 typedef void (*CARegisterConnectivityCallback)(CAConnectivityHandler_t handler,
-        CATransportType_t cType);
+        CATransportAdapter_t cType);
 
 /**
  * @brief This will be used during the recive of network requests and response.
- * @see SendUnitcastData(), SendMulticastData()
+ * @see SendUnicastData(), SendMulticastData()
  */
-typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t *endPoint, void *data,
+typedef void (*CANetworkPacketReceivedCallback)(const CAEndpoint_t *endPoint, void *data,
         uint32_t dataLen);
 
 /**
  * @brief This will be used to notify network changes to the connectivity common logic layer
- * @see SendUnitcastData(), SendMulticastData()
+ * @see SendUnicastData(), SendMulticastData()
+ */
+typedef void (*CANetworkChangeCallback)(const CAEndpoint_t *info, CANetworkStatus_t status);
+
+/**
+ * @brief This will be used to notify error result to the connectivity common logic layer
  */
-typedef void (*CANetworkChangeCallback)(CALocalConnectivity_t *info, CANetworkStatus_t status);
+typedef void (*CAErrorHandleCallback)(const CAEndpoint_t *endpoint,
+                                      const void *data, uint32_t dataLen,
+                                      CAResult_t result);
 
 #ifdef __cplusplus
 } /* extern "C" */
index debf3d3..c1d5349 100644 (file)
@@ -26,6 +26,7 @@
 #include "caadapterutils.h"
 #include "ocsecurityconfig.h"
 #include "cainterface.h"
+#include "cacommon.h"
 
 /**
  *   Currently DTLS supported adapters(2) WIFI and ETHENET for linux platform.
  */
 extern void OCGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
 
-typedef void (*CAPacketReceivedCallback)(const char *ipAddress, const uint16_t port,
-         const void *data, const uint32_t dataLength, const bool isSecured);
+typedef void (*CAPacketReceivedCallback)(const CAEndpoint_t *endpoint,
+                                         const void *data, uint32_t dataLength);
 
-typedef uint32_t (*CAPacketSendCallback)(const char *ipAddress, const uint16_t port,
-        const void *data, const uint32_t dataLength);
+typedef void (*CAPacketSendCallback)(CAEndpoint_t *endpoint,
+                                         const void *data, uint32_t dataLength);
 
 /**
  * @struct stCAAdapterCallbacks_t
@@ -60,6 +61,8 @@ typedef struct CAAdapterCallbacks
  */
 typedef struct stCADtlsContext
 {
+    u_arraylist_t *peerInfoList;        /**< peerInfo list which holds the mapping between
+                                             peer id to it's n/w address */
     u_arraylist_t *cacheList;            /**< PDU's are cached until DTLS session is formed. */
     struct dtls_context_t *dtlsContext;  /**< Pointer to tinyDTLS context. */
     struct stPacketInfo *packetInfo;     /**< used by callback during
@@ -116,20 +119,9 @@ typedef struct CACacheMessage
 {
     void *data;
     uint32_t dataLen;
-    stCADtlsAddrInfo_t *destSession;
+    stCADtlsAddrInfo_t destSession;
 } stCACacheMessage_t;
 
-/**
- * @enum eDtlsAdapterType_t
- * @brief This enum is used as array index for storing adapter level callbacks.
- *        So Keeping 0 instead of "1 << 0". It is not going to be used as addition
- *        and removal of adapter.
- *
- */
-typedef enum
-{
-    DTLS_IP = 0,
-} eDtlsAdapterType_t;
 
 /**
  * @fn  CADTLSSetAdapterCallbacks
@@ -143,7 +135,8 @@ typedef enum
  *
  */
 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
-                               CAPacketSendCallback sendCallback, eDtlsAdapterType_t type);
+                               CAPacketSendCallback sendCallback,
+                               CATransportAdapter_t type);
 
 /**
  * @brief   Register callback to get DTLS PSK credentials.
@@ -153,6 +146,70 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
 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
+ *                             0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
+ *                             0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+ *
+ * @retval  CA_STATUS_OK for success, otherwise some error value
+ */
+CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher);
+
+/**
+ * Enable anonymous ECDH cipher suite for dtls handshake
+ *
+ * @param[in] enable  TRUE/FALSE enables/disables anonymous cipher suite
+ *
+ * @retval  CA_STATUS_OK for success, otherwise some error value
+ */
+CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable);
+
+/**
+ * Initiate DTLS handshake with selected cipher suite
+ *
+ * @param[in] endpoint  information of network address
+ *
+ * @retval  CA_STATUS_OK for success, otherwise some error value
+ */
+CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint);
+
+/**
+ * Close the DTLS session
+ *
+ * @param[in] endpoint  information of network address
+ *
+ * @retval  CA_STATUS_OK for success, otherwise some error value
+ */
+CAResult_t CADtlsClose(const CAEndpoint_t *endpoint);
+
+/**
+ * Generate ownerPSK using PRF
+ * OwnerPSK = TLS-PRF('master key' , 'oic.sec.doxm.jw',
+ *                                    'ID of new device(Resource Server)',
+ *                                    'ID of owner smart-phone(Provisioning Server)')
+ *
+ * @param[in] endpoint  information of network address
+ * @param[in] label  Ownership transfer method e.g)"oic.sec.doxm.jw"
+ * @param[in] labelLen  Byte length of label
+ * @param[in] rsrcServerDeviceID  ID of new device(Resource Server)
+ * @param[in] rsrcServerDeviceIDLen  Byte length of rsrcServerDeviceID
+ * @param[in] provServerDeviceID  label of previous owner
+ * @param[in] provServerDeviceIDLen  byte length of provServerDeviceID
+ * @param[in,out] ownerPSK  Output buffer for owner PSK
+ * @param[in] ownerPSKSize  Byte length of the ownerPSK to be generated
+ *
+ * @retval  CA_STATUS_OK for success, otherwise some error value
+ */
+CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
+                    const uint8_t* label, const size_t labelLen,
+                    const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
+                    const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
+                    uint8_t* ownerPSK, const size_t ownerPSKSize);
+;
+
+/**
  * @fn  CAAdapterNetDtlsInit
  * @brief  initialize tinyDTLS library and other necessary intialization.
  *
@@ -181,15 +238,11 @@ void CAAdapterNetDtlsDeInit();
  *              a new DTLS handshake is started, pdu info is
  *              cached to be send when session setup is finished.
  *
- * @param[in]  remoteAddress  address to which data will be sent.
+ * @param[in]  endpoint  address to which data will be sent.
  * @param[in]  port  port to which data will be sent.
  * @param[in]  data  length of data.
  * @param[in]  dataLen  length of given data
- * @param[out]  decdata  output variable to store the starting address
- *                        of decrypted plaintext.
- * @param[out]  cacheFlag  utput variable to indicate if pdu
- *                        is cached and inform the caller to
- *                       NOT free the memory holding pdu.
+ *
  * @return  0 on success otherwise a positive error value.
  * @retval  CA_STATUS_OK  Successful
  * @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
@@ -197,12 +250,9 @@ void CAAdapterNetDtlsDeInit();
  *
  */
 
-CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
-                                   const uint16_t port,
+CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
                                    void *data,
-                                   uint32_t dataLen,
-                                   uint8_t *cacheFlag,
-                                   eDtlsAdapterType_t type);
+                                   uint32_t dataLen);
 
 /**
  * @fn  CAAdapterNetDtlsDecrypt
@@ -219,11 +269,9 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
  * @retval  CA_STATUS_FAILED Operation failed
  *
  */
-CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
-                                   const uint16_t port,
+CAResult_t CAAdapterNetDtlsDecrypt(const CAEndpoint_t *endpoint,
                                    uint8_t *data,
-                                   uint32_t dataLen,
-                                   eDtlsAdapterType_t type);
+                                   uint32_t dataLen);
 
 #endif /* CA_ADAPTER_NET_DTLS_H_ */
 
index f78cebb..197cc97 100644 (file)
 #include <jni.h>
 #endif
 
+#ifndef WITH_ARDUINO
+#include <sys/socket.h>
+#endif
+
 #include "cacommon.h"
 #include "logger.h"
 #include "pdu.h"
@@ -83,8 +87,9 @@ extern "C"
  */
 #define IPV4_ADDR_ONE_OCTECT_LEN 4
 
+#ifdef SINGLE_THREAD
 /**
- * @brief Network Interface Information.
+ * @brief Network Interface Information. Only needed for Arduino.
  */
 typedef struct
 {
@@ -92,6 +97,7 @@ typedef struct
     char subnetMask[CA_IPADDR_SIZE];            /**< Maintains interface subnetmask **/
     char interfaceName[CA_INTERFACE_NAME_SIZE]; /**< Interface  name**/
 } CANetInfo_t;
+#endif
 
 /**
  * @brief unicast and multicast server information.
@@ -99,9 +105,7 @@ typedef struct
 typedef struct
 {
     int socketFd;                               /**< Socket decriptor **/
-    char ipAddress[CA_IPADDR_SIZE];             /**< Address of the ip **/
-    uint16_t port;                              /**< Server port number **/
-    bool isSecured;                             /**< Indicates secured server **/
+    CAEndpoint_t endpoint;                      /**< endpoint description **/
     bool isServerStarted;                       /**< Indicates server started **/
     bool isMulticastServer;                     /**< Indicates multicast server **/
     char ifAddr[CA_IPADDR_SIZE];                /**< Address of the multicast interface  **/
@@ -115,44 +119,6 @@ typedef struct
 void CALogPDUData(coap_pdu_t *pdu);
 
 /**
- * @fn CAAdapterCreateLocalEndpoint
- * @brief Create CALocalConnectivity_t instance.
- */
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address);
-
-/**
- * @fn CAAdapterCopyLocalEndpoint
- * @brief Create CALocalConnectivity_t duplicate instance.
- */
-CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity);
-
-/**
- * @fn CAAdapterFreeLocalEndpoint
- * @brief Deallocate CALocalConnectivity_t instance.
- */
-void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndPoint);
-
-/**
- * @fn CAAdapterCreateRemoteEndpoint
- * @brief Allocate CARemoteEndpoint_t instance.
- */
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address,
-                                                  const char *resourceUri);
-
-/**
- * @fn CAAdapterCopyRemoteEndpoint
- * @brief Create CARemoteEndpoint_t duplicate instance.
- */
-CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(
-    const CARemoteEndpoint_t *remoteEndpoint);
-
-/**
- * @fn CAAdapterFreeRemoteEndpoint
- * @brief Deallocate CARemoteEndpoint_t instance.
- */
-void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndPoint);
-
-/**
  * @fn CAParseIPv4AddressInternal
  * @brief   To parse the IP address and port from "ipaddress:port"
  * @param   ipAddrStr   [IN]   IP address to be parsed
@@ -215,15 +181,13 @@ uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddr
  * @brief  Used to get the socket fd for given server information.
  *
  * @param   serverInfoList  [IN] Server information list.
- * @param   ipAddress       [IN] Ip address of the server.
- * @param   isSecured       [IN] To check whether it is secured server or not.
  * @param   isMulticast     [IN] To check whether it is multicast server or not.
- * @param   type            [IN] CA_IPV4, CA_IPV6 etc.
+ * @param   endpoint        [IN] network address
 
  * @return  positive value on success and -1 on error.
  */
-int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress,
-                                  bool isSecured, bool isMulticast, CATransportType_t type);
+int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList,
+                         bool isMulticast, const CAEndpoint_t *endpoint);
 
 /**
  * @brief  Used to add the server information into serverinfo list
@@ -268,6 +232,22 @@ void CAClearNetInterfaceInfoList(u_arraylist_t *infoList);
  */
 void CAClearServerInfoList(u_arraylist_t *serverInfoList);
 
+/**
+ * @brief   Convert address from binary to string
+ * @param   ipaddr  [IN] IP address info
+ * @param   host    [OUT] address string (must be CA_IPADDR_SIZE)
+ * @param   port    [OUT] host order port number
+ */
+void CAConvertAddrToName(const struct sockaddr_storage *sockaddr, char *host, uint16_t *port);
+
+/**
+ * @brief   Convert address from string to binary
+ * @param   host    [IN] address string
+ * @param   port    [IN] host order port number
+ * @param   ipaddr  [OUT] IP address info
+ */
+void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr);
+
 #ifdef __ANDROID__
 /**
  * @fn CANativeJNISetContext
index 678f864..7e0b533 100644 (file)
@@ -43,16 +43,19 @@ extern "C"
  * @brief   Initialize EDR Interface.
  * @param   registerCallback  [IN] Callback to register EDR interface to Connectivity
  *                                 Abstraction Layer
- * @param   reqRespCallback   [IN] Callback to notify request and response messages from server(s)
- *                                 started at Connectivity Abstraction Layer.
+ * @param   reqRespCallback   [IN] Callback to notify request and response messages from
+ *                                 server(s) started at Connectivity Abstraction Layer.
  * @param   netCallback       [IN] Callback to notify the network additions to Connectivity
  *                                 Abstraction Layer.
+ * @param   errorCallback     [IN] errorCallback to notify error to connectivity common logic
+ *                                 layer from adapter
  * @param   handle            [IN] Threadpool Handle
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
                            CANetworkPacketReceivedCallback reqRespCallback,
-                           CANetworkChangeCallback netCallback, ca_thread_pool_t handle);
+                           CANetworkChangeCallback netCallback,
+                           CAErrorHandleCallback errorCallback, ca_thread_pool_t handle);
 
 /**
  * @brief   Starts EDR connectivity adapters. As its peer to peer it doesnot require to start
@@ -79,24 +82,25 @@ CAResult_t CAStartEDRDiscoveryServer();
 
 /**
  * @brief  Sends data to the peer bluetooth OIC device using the adapter connectivity.
- * @param  remoteEndpoint  [IN] Remote Endpoint information (like ipaddress, port, reference uri and
+ * @param  endpoint        [IN] Remote Endpoint information (like ipaddress, port, and
  *                              connectivity type) to which the unicast data has to be sent.
  * @param  data            [IN] Data to be sent.
  * @param  dataLength      [IN] Size of data to be sent.
  * @return The number of bytes sent on the network. Returns -1 on error.
  *
  */
-int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+int32_t CASendEDRUnicastData(const CAEndpoint_t *endpoint, const void *data,
                              uint32_t dataLength);
 
 /**
  * @brief  Sends multicast data to all discovered bluetooth OIC devices using the adapter
- *         connectivity.
- * @param  data         [IN]  Data which needs to be sent to all discovered bluetooth OIC device.
- * @param  dataLength   [IN]  Length of data in bytes.
+ * @param  endpoint     [IN] Remote Endpoint information (like ipaddress, port, and connectivity.
+ * @param  data         [IN] Data which needs to be sent to all discovered bluetooth OIC device.
+ * @param  dataLength   [IN] Length of data in bytes.
  * @return Number of bytes sent on the network. Returns -1 on error.
  */
-int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength);
+int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data,
+                               uint32_t dataLength);
 
 /**
  * @brief  Get EDR Connectivity network information.
@@ -106,7 +110,7 @@ int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength);
  *
  * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief  Read Synchronous API callback.
index a5996d0..eea4e42 100644 (file)
@@ -91,13 +91,13 @@ CAResult_t CAStartEDRDiscoveryServer();
 
 /**
  * @brief  Sends data to the peer bluetooth OIC device using the adapter connectivity.
- * @param  remoteEndpoint  [IN] Remote Endpoint information (like ipaddress, port, reference uri and
+ * @param  endpoint        [IN] Remote Endpoint information (like ipaddress, port, reference uri and
  *                              connectivity type) to which the unicast data has to be sent.
  * @param  data            [IN] Data to be sent.
  * @param  dataLength      [IN] Size of data to be sent.
  * @return Number of bytes sent on the network. Returns -1 on error.
  */
-int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+int32_t CASendEDRUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
                               uint32_t dataLength);
 
 /**
@@ -122,7 +122,7 @@ int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength);
  * @retval #CA_STATUS_FAILED Operation failed
  * @remarks info is allocated in this API and should be freed by the caller.
  */
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief  Read Synchronous API callback.
index 57ac40e..cbf26e9 100644 (file)
@@ -68,7 +68,7 @@ typedef enum
  */
 typedef struct
 {
-    CARemoteEndpoint_t *remoteEndpoint; /**< Remote Endpoint */
+    CAEndpoint_t *remoteEndpoint;       /**< Remote Endpoint */
     void *data;                         /**< Data to be sent */
     uint32_t dataLen;                   /**< Length of the data to be sent */
 } CAEDRData;
@@ -79,7 +79,7 @@ typedef struct
  */
 typedef struct
 {
-    CALocalConnectivity_t *info; /**< Local Connectivity Information */
+    CAEndpoint_t *info;          /**< Local Connectivity Information */
     CANetworkStatus_t status;    /**< Network Status */
 } CAEDRNetworkEvent;
 
@@ -103,6 +103,19 @@ typedef void (*CAEDRDataReceivedCallback)(const char *remoteAddress, const void
 typedef void (*CAEDRNetworkStatusCallback)(CANetworkStatus_t status);
 
 /**
+ * @brief Callback to notify the error in the EDR adapter
+ * @param  remoteAddress   [IN] Remote EDR Address
+ * @param  serviceUUID     [IN] Service UUID of the device
+ * @param  data            [IN] data containing token, uri and coap data
+ * @param  dataLength      [IN] length of data
+ * @param  result          [IN] error code as defined in CAResult_t
+ * @return NONE
+ * @pre Callback must be registered using CAEDRSetPacketReceivedCallback()
+ */
+typedef void (*CAEDRErrorHandleCallback)(const char *remoteAddress, const char *serviceUUID,
+                                         const void *data, uint32_t dataLength, CAResult_t result);
+
+/**
  * @brief  Initialize the network monitor module
  * @param  threadPool   [IN] Threadpool Handle
  * @return #CA_STATUS_OK or Appropriate error code
@@ -188,6 +201,15 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall
 void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkStateChangeCallback);
 
 /**
+ * @brief  set error callback to notify error in EDR adapter
+ *
+ * @param  errorHandleCallback [IN] Callback function to notify the error in the EDR adapter
+ * @return NONE
+ */
+void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback);
+
+
+/**
  * @brief  Get the local bluetooth adapter information.
  *
  * @param  info [OUT] Local bluetooth adapter information
@@ -200,7 +222,7 @@ void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkStateChange
  * @see #CALocalConnectivity_t
  *
  */
-CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info);
+CAResult_t CAEDRGetInterfaceInformation(CAEndpoint_t **info);
 
 /**
  * @brief  Start RFCOMM server for given service UUID
@@ -25,8 +25,8 @@
  * fragmentation and reassemebly.
  */
 
-#ifndef CA_MSG_PARSER_H_
-#define CA_MSG_PARSER_H_
+#ifndef CA_FRAGMENTATION_H_
+#define CA_FRAGMENTATION_H_
 
 #include "cacommon.h"
 #include "logger.h"
@@ -129,7 +129,7 @@ extern "C"
 
 /*****************************************************************
  * @file The CA Header format
- * @brief CA Header will be difined by 2 bytes of Header.
+ * @brief CA Header will be defined by 2 bytes of Header.
  * First two bits : Header version(Currently Its not being used)
  * Third bit and fourth bit: Reserved bits for future use.
  * 5th to 16th bit : 12 bits to provide the length of the data.
@@ -137,29 +137,39 @@ extern "C"
 
 /**
 * @fn CAGenerateHeader
-* @brief This function is used to generate the CA specific header to maintain the fragmentation
-*           logic. The header sturcture explained above will be formed and returned to the caller.
+* @brief This function is used to generate the CA specific header to
+*        maintain the fragmentation logic. The header structure
+*        explained above will be formed and returned to the caller.
 *
-* @param[in]  data    Pointer to the charcter data which needs to be printed.
-* @param[in]  length The total legth of the data which will be represented from 5th -16th bits
-*                              in the header.
+* @param[in,out] header Pointer to the octet array that will contain
+*                       the generated header.
+* @param[in]     length The total length of the data.  The length will
+*                       be embedded in bits 5-16 of the header,
+*                       meaning the maximum overall length of the
+*                       data to be fragmented can be no more than 4096
+*                       (2^12).
 *
-* @return  CA_STATUS_OK on success. One of theCA_STATUS_FAILED or other error values on error.
-* @retval  CA_STATUS_OK  Successful
-* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
-* @retval  CA_STATUS_FAILED Operation failed
+* @return @c CA_STATUS_OK on success. One of the @c CA_STATUS_FAILED or
+*         other error values on error.
+* @retval @c CA_STATUS_OK             Successful
+* @retval @c CA_STATUS_INVALID_PARAM  Invalid input arguments
+* @retval @c CA_STATUS_FAILED         Operation failed
 */
 CAResult_t CAGenerateHeader(char *header, uint32_t length);
 
 /**
 * @fn CAParseHeader
-* @brief This function is used to parse the header in the receiver end. This function will
-*            provide the information of the total length of the data which has been fragmented.
+* @brief This function is used to parse the header in the receiver
+*        end. This function will provide the information of the total
+*        length of the data which has been fragmented.
 *
-* @param[in]  header  Pointer to the charcter data which contains the header information.
-*                                Note that pointer should point to two bytes of data header
-*                                 which needs to be parsed.
+* @param[in] header Pointer to the octet array data which contains the
+*                   header information.  Note that pointer should
+*                   point to two bytes of data header which needs to
+*                   be parsed.
 *
+* @return Overall length of the data to be reassembled, or 0 on
+*         failure.
 */
 uint32_t CAParseHeader(const char *header);
 
@@ -167,5 +177,5 @@ uint32_t CAParseHeader(const char *header);
 } /* extern "C" */
 #endif
 
-#endif  /* CA_MSG_PARSER_H_ */
+#endif  /* CA_FRAGMENTATION_H_ */
 
index 8aa5940..034e374 100644 (file)
 #define CA_INTERFACE_CONTROLLER_H_
 
 #include "caadapterinterface.h"
+
+#ifndef SINGLE_THREAD
 #include "cathreadpool.h" /* for thread pool */
+#endif
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
+#ifdef SINGLE_THREAD
+/**
+ * @brief   Initializes different adapters based on the compilation flags.
+ * @return   none
+ */
+void CAInitializeAdapters();
+#else
 /**
  * @brief   Initializes different adapters based on the compilation flags.
  * @param   handle         [IN]    thread pool handle created by message handler for different adapters.
  * @return  none
  */
 void CAInitializeAdapters(ca_thread_pool_t handle);
+#endif
 
 /**
  * @brief   Set the received packets callback for message handler
@@ -50,6 +61,13 @@ void CAInitializeAdapters(ca_thread_pool_t handle);
 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
 
 /**
+ * @brief   Set the error handler callback for message handler
+ * @param   errorCallback       [IN]    error handler callback from adapters
+ * @return  none
+ */
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback);
+
+/**
  * @brief   Set the network status changed callback for message handler
  * @param   callback       [IN]    message handler network status callback to receive network changes.
  * @return  none
@@ -61,14 +79,24 @@ void CASetNetworkChangeCallback(CANetworkChangeCallback callback);
  * @param   transportType   [IN]    interested network for starting
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAStartAdapter(CATransportType_t transportType);
+CAResult_t CAStartAdapter(CATransportAdapter_t transportType);
 
 /**
  * @brief   Stopping different connectivity adapters based on the network un-selection.
  * @param   transportType   [IN]    network type that want to stop
  * @return  none
  */
-void CAStopAdapter(CATransportType_t transportType);
+void CAStopAdapter(CATransportAdapter_t transportType);
+
+#ifdef RA_ADAPTER
+/**
+ * @brief   Set Remote Access information for XMPP Client.
+ * @param   caraInfo            [IN] remote access info.
+ *
+ * @return  CA_STATUS_OK
+ */
+CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo);
+#endif
 
 /**
  * @brief   Get network information such as ipaddress and mac information
@@ -76,7 +104,7 @@ void CAStopAdapter(CATransportType_t transportType);
  * @param   size           [OUT]    number of connectivity information structures
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief   Sends unicast data to the remote endpoint
@@ -85,16 +113,17 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
  * @param   length         [IN]    length of the data that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length);
+CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length);
 
 /**
  * @brief   Sends multicast data to all endpoints in the network.
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
  * @param   data           [IN]    data that needs to be sent
  * @param   length         [IN]    length of the data that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
 
-CAResult_t CASendMulticastData(const void *data, uint32_t length);
+CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length);
 
 /**
  * @brief   Start listening servers to receive search requests from clients
@@ -114,6 +143,14 @@ CAResult_t CAStartDiscoveryServerAdapters();
  */
 void CATerminateAdapters();
 
+#ifdef SINGLE_THREAD
+/**
+ * @brief   Checks for available data and reads it
+ * @return   CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAReadData();
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 70f0759..db003a2 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "caadapterinterface.h"
 
-
 #ifdef __cplusplus
 extern "C"
 {
@@ -60,18 +59,25 @@ void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
 void CASetNetworkChangeCallback(CANetworkChangeCallback callback);
 
 /**
+ * @brief   Set the error handler callback for message handler
+ * @param   errorCallback       [IN]    error handler callback from adapters
+ * @return  none
+ */
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback);
+
+/**
  * @brief   Starting different connectivity adapters based on the network selection.
- * @param   transportType    [IN]    network type that want to stop
+ * @param   transportAdapter [IN]    network type that want to stop
  * @return  none
  */
-CAResult_t CAStartAdapter(CATransportType_t transportType);
+CAResult_t CAStartAdapter(CATransportAdapter_t transportType);
 
 /**
  * @brief   Stopping different connectivity adapters based on the network un-selection.
- * @param   transportType    [IN]    un selected network for stopping the packets transfer
+ * @param   transportAdapter [IN]    un selected network for stopping the packets transfer
  * @return   none
  */
-void CAStopAdapter(CATransportType_t transportType);
+void CAStopAdapter(CATransportAdapter_t transportType);
 
 /**
  * @brief   Get network information such as ipaddress and mac information.  Gets the network
@@ -80,7 +86,7 @@ void CAStopAdapter(CATransportType_t transportType);
  * @param   size            [OUT]    number of connectivity information structures
  * @return   CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief   Sends unicast data to the remote endpoint
@@ -89,15 +95,16 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
  * @param   length          [IN]    length of the data that needs to be sent
  * @return   CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length);
+CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length);
 
 /**
  * @brief   Sends multicast data to all endpoints in the network.
+ * @param   endpoint        [IN]    endpoint information where the data has to be sent
  * @param   data            [IN]    data that needs to be sent
  * @param   length          [IN]    length of the data that needs to be sent
  * @return   CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CASendMulticastData(const void *data, uint32_t length);
+CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length);
 
 /**
  * @brief   Start listening servers to receive search requests from clients
index fc1e697..b6aa76f 100644 (file)
@@ -42,13 +42,15 @@ extern "C"
  *                                   started at Connectivity Abstraction Layer.
  * @param netCallback           [IN] Callback to notify the network additions to Connectivity
  *                                   Abstraction Layer.
+ * @param errorCallback         [IN] Callback to notify the network errors to Connectivity
+ *                                   Abstraction Layer
  * @param handle                [IN] Threadpool Handle
  * @return  #CA_STATUS_OK or Appropriate error code
  */
-    CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
-                              CANetworkPacketReceivedCallback networkPacketCallback,
-                              CANetworkChangeCallback netCallback, ca_thread_pool_t handle);
-
+CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
+                          CANetworkPacketReceivedCallback networkPacketCallback,
+                          CANetworkChangeCallback netCallback,
+                          CAErrorHandleCallback errorCallback, ca_thread_pool_t handle);
 
 /**
  * @brief Start IP Interface adapter.
@@ -68,7 +70,7 @@ CAResult_t CAStartIPListeningServer();
 /**
  * @brief Start discovery servers for receiving multicast advertisements
  * Transport Specific Behavior:
- * IP Starts Start multicast server on a particular interface and prefixed port
+ * IP Starts multicast server on a particular interface and prefixed port
  * number as per OIC Specification
  * @return  #CA_STATUS_OK or Appropriate error code
  */
@@ -76,24 +78,25 @@ CAResult_t CAStartIPDiscoveryServer();
 
 /**
  * @brief Sends data to the endpoint using the adapter connectivity.
- * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
- * reference uri and transport type) to which the unicast data has to be sent.
+ * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port, reference uri
+ *                              and transport type) to which the unicast data has to be sent.
  * @param   data        [IN]    Data which is required to be sent.
  * @param   dataLen     [IN]    Size of data to be sent.
- * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
- * @remarks dataLen must be > 0.
+ * @return  The number of bytes sent on the network. Return value equal to -1 indicates error.
+ * @remark  dataLen must be > 0.
  */
-int32_t CASendIPUnicastData(const CARemoteEndpoint_t *endpoint, const void *data,
-                                   uint32_t dataLen);
+int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint, const void *data,
+                            uint32_t dataLen);
 
 /**
- * @brief Sends Multicast data to the endpoint using the IP connectivity.
- * @param   data        [IN]    Data which required to be sent.
+ * @brief Send Multicast data to the endpoint using the IP connectivity.
+ * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port)
+ * @param   data        [IN]    Data which is required to be sent.
  * @param   dataLen     [IN]    Size of data to be sent.
- * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
- * @remarks dataLen must be > 0.
+ * @return  The number of bytes sent on the network. Return value equal to -1 indicates error.
+ * @remark  dataLen must be > 0.
  */
-int32_t CASendIPMulticastData(const void *data, uint32_t dataLen);
+int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen);
 
 /**
  * @brief Get IP Connectivity network information
@@ -102,7 +105,7 @@ int32_t CASendIPMulticastData(const void *data, uint32_t dataLen);
  * @return  #CA_STATUS_OK or Appropriate error code
  * @remarks info is allocated in this API and should be freed by the caller.
  */
-CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief Read Synchronous API callback.
diff --git a/resource/csdk/connectivity/inc/caipadapter_singlethread.h b/resource/csdk/connectivity/inc/caipadapter_singlethread.h
deleted file mode 100644 (file)
index 7625a04..0000000
+++ /dev/null
@@ -1,128 +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 caipadapter_singlethread.h
- * @brief This file contains the APIs for IP Adapter.
- */
-#ifndef CA_IP_ADAPTER_SINGLETHREAD_H_
-#define CA_IP_ADAPTER_SINGLETHREAD_H_
-
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief API to initialize IP Interface.
- * @param registerCallback      [IN] Callback to register IP interfaces to Connectivity
- *                                   Abstraction Layer
- * @param networkPacketCallback [IN] Callback to notify request and response messages from server(s)
- *                                   started at Connectivity Abstraction Layer.
- * @param netCallback           [IN] Callback to notify the network additions to Connectivity
- *                                   Abstraction Layer.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback networkPacketCallback,
-                                CANetworkChangeCallback netCallback);
-
-/**
- * @brief Start IP Interface adapter.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartIP();
-
-/**
- * @brief Start listening server for receiving multicast search requests
- * Transport Specific Behavior:
- * IP Starts Multicast Server on  all available IPs and prefixed port number and
- * as per OIC Specification.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartIPListeningServer();
-
-/**
- * @brief Start discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- * IP Starts multicast server on all available IPs and prefixed port
- * number as per OIC Specification
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartIPDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
- * reference uri and connectivity type) to which the unicast data has to be sent.
- * @param   data        [IN]    Data which required to be sent.
- * @param   dataLen     [IN]    Size of data to be sent.
- * @return  The number of bytes sent on the network. Return value equal to -1 indicates error.
- * @remark  dataLen must be > 0.
- */
-int32_t CASendIPUnicastData(const CARemoteEndpoint_t *endpoint, const void *data,
-                                  uint32_t dataLen);
-
-/**
- * @brief Send Multicast data to the endpoint using the IP connectivity.
- * @param   data        [IN]    Data which is required to be sent.
- * @param   dataLen     [IN]    Size of data to be sent.
- * @return  The number of bytes sent on the network. Return value equal to -1 indicates error.
- * @remark  dataLen must be > 0.
- */
-int32_t CASendIPMulticastData(const void *data, uint32_t dataLen);
-
-/**
- * @brief Get IP Connectivity network information
- * @param   info        [OUT]   Local connectivity information structures
- * @param   size        [OUT]   Number of local connectivity structures.
- * @return  #CA_STATUS_OK or Appropriate error code
- * @remarks info is allocated in this API and should be freed by the caller.
- */
-CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAReadIPData();
-
-/**
- * @brief Stops Unicast, Multicast servers and close the sockets.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStopIP();
-
-/**
- * @brief Terminate the Ethernet connectivity adapter.
- * Configuration information will be deleted from further use
- * @return NONE
- */
-void CATerminateIP();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif  /* CA_IP_ADAPTER_SINGLETHREAD_H_ */
-
index 092a51e..a7afbd9 100644 (file)
@@ -43,26 +43,37 @@ extern "C"
  */
 typedef enum
 {
-    CA_UNICAST_SERVER = 0,    /**< Unicast Server */
-    CA_MULTICAST_SERVER,      /**< Multicast Server */
-    CA_SECURED_UNICAST_SERVER /**< Secured Unicast Server */
+    CA_UNICAST_SERVER = 0,      /**< Unicast Server */
+    CA_MULTICAST_SERVER,        /**< Multicast Server */
+    CA_SECURED_UNICAST_SERVER   /**< Secured Unicast Server */
 } CAAdapterServerType_t;
 
 /**
  * @brief Callback to be notified on reception of any data from remote OIC devices.
  *
- * @param  ipAddress    [IN] IP address of remote OIC device.
- * @param  port         [IN] Port number on which data is received.
+ * @param  endpoint     [IN] network endpoint description
  * @param  data         [IN] Data received from remote OIC device.
  * @param  dataLength   [IN] Length of data in bytes.
- * @param  isSecured    [IN] Indicates the data is secure or not.
  *
  * @return NONE
  * @pre  Callback must be registered using CAIPSetPacketReceiveCallback()
  */
-typedef void (*CAIPPacketReceivedCallback)(const char *ipAddress, uint16_t port,
-                                           const void *data, uint32_t dataLength,
-                                           bool isSecured);
+typedef void (*CAIPPacketReceivedCallback)(const CAEndpoint_t *endpoint,
+                                           const void *data,
+                                           uint32_t dataLength);
+
+/**
+  * @brief Callback to notify error in the IP adapter
+  *
+  * @param  endpoint     [IN] [IN] network endpoint description
+  * @param  data         [IN] Data sent/received
+  * @param  dataLength   [IN] Length of data in bytes.
+  * @param  result       [IN] result of request from R.I
+  * @return NONE
+  * @pre  Callback must be registered using CAIPSetPacketReceiveCallback()
+ */
+typedef void (*CAIPErrorHandleCallback)(const CAEndpoint_t *endpoint, const void *data,
+                                        uint32_t dataLength, CAResult_t result);
 
 /**
  * @brief  Callback to be notified when exception occures on multicast/unicast server.
@@ -73,7 +84,7 @@ typedef void (*CAIPPacketReceivedCallback)(const char *ipAddress, uint16_t port,
 typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type);
 
 /**
- * @brief  Initialize IP server
+ * @brief  Start IP server
  *
  * @param   threadPool  [IN] Thread pool for managing Unicast/Multicast server threads.
  *
@@ -82,121 +93,17 @@ typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type);
  * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
  * @retval  #CA_STATUS_FAILED Initialization failed
  */
-CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool);
+#ifdef SINGLE_THREAD
+CAResult_t CAIPStartServer();
+#else
+CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool);
+#endif
 
 /**
- * @brief  Terminate IP server
+ * @brief  Stop IP server
  * @return NONE
  */
-void CAIPTerminateServer();
-
-/**
- * @brief  Start multicast server for specified multicast address and port
- *
- * @param   localAddress        [IN]      Local adapter address to which server to be binded.
- * @param   multicastAddress    [IN]      Multicast group address.
- * @param   multicastPort       [IN,OUT]  Port number on which server will be running. If binding
- *                                        the port failed, server starts in the next available port.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
-                                    uint16_t multicastPort);
-
-/**
- * @brief  Start unicast server for specified local address and port
- *
- * @param  localAddress [IN]      Local adapter address to which server to be binded.
- * @param  port         [IN,OUT]  Port number on which server will be running. If binding
- *                                the port failed, server starts in the next available port.
- * @param  forceStart   [IN]      Indicate whether to start server forcesfully on specified port
- *                                or not.
- * @param  secured      [IN]      True if the secure server to be started, otherwise false.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool forceStart,
-                                  bool secured);
-
-/**
- * @brief  Stop servers that are running in particular interface address.
- *
- * @param   interfaceAddress  [IN] interface address in which servers are running.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopServer(const char *interfaceAddress);
-
-/**
- * @brief  Used to stop all unicast and multicast servers.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopAllServers();
-
-/**
- * @brief  Used to get the socket fd based on index value of server info list.
- *
- * @param   index      [IN] Index where we need socket fd value.
- * @param   isSecured  [IN] For secured unicast server or normal server.
- *
- * @return  positive value on success and -1 on error.
- */
-int CAGetSocketFdFromUnicastIPServerbyIndex(int16_t index, bool isSecured);
-
-/**
- * @brief  Used to get the number of unicast server currently running.
- *
- * @param   isSecured  [IN] To identify whether its secured unicast server or normal server.
- *
- * @return  positive value on success and -1 on error.
- */
-int16_t CAGetNumberOfUnicastIPServers(bool isSecured);
-
-/**
- * @brief  Used to get the stored socket fd for corresponding ipAddress.
- *
- * @param   ipAddress    [IN] IpAddress of server.
- * @param   isSecured    [IN] Used to check the server is secured or not.
- * @param   isMulticast  [IN] To identify whether its for multicast or unicast.
- *
- * @return  socket fd on success and -1 on error.
- */
-int CAGetSocketFdFromUnicastIPServer(const char *ipAddress, bool isSecured, bool isMulticast);
-
-/**
- * @brief  Used to get the port number to the corresponding ip for giving interface info.
- *
- * @param   ipAddress  [IN] IpAddress of server.
- * @param   isSecured  [IN] Used to check the server is secured or not.
- *
- * @return  port number on success and -1 on error.
- */
-uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured);
-
-/**
- * @brief  Used to get the port number for corresponding ipAddress.
- *
- * @param   serverInfoList  [OUT] ServerInfoList holds unicast and multicast server informations.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList);
+void CAIPStopServer();
 
 /**
  * @brief  Set this callback for receiving data packets from peer devices.
@@ -217,109 +124,74 @@ void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback);
 void CAIPSetExceptionCallback(CAIPExceptionCallback callback);
 
 /**
- * @brief  API to send unicast UDP data
+ * @brief  Set socket description for sending unicast UDP data. Once the Unicast server is started,
+ *         the same socket descriptor is used for sending the Unicast UDP data.
  *
- * @param  remoteAddress    [IN] IP address to which data needs to be sent.
- * @param  port             [IN] Port to which data needs to be send.
- * @param  data             [IN] Data to be send.
- * @param  dataLength       [IN] Length of data in bytes
- * @param  isMulticast      [IN] Whether data needs to be sent to multicast ip
- * @param  isSecured        [IN] Whether data to be sent on secured channel.
- *
- * @return  The number of bytes sent on the network. Returns 0 on error.
- * @remarks isSecure will be ignored when isMulticast is true.
- */
-uint32_t CAIPSendData(const char *remoteAddress, uint16_t port, const void *data,
-                      uint32_t dataLength, bool isMulticast, bool isSecure);
-
-/**
- * @brief  Callback to be notified when IP adapter connection state changes.
- *
- * @param  ipAddress    [IN] IP address of remote OIC device.
- * @param  status       [IN] Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ * @param  socketFD [IN]  Socket descriptor used for sending UDP data.
  * @return  NONE
- * @pre  Callback must be registered using CAIPSetConnectionStateChangeCallback()
  */
-typedef void (*CAIPConnectionStateChangeCallback)(const char *ipAddress,
-                                                  CANetworkStatus_t status);
+void CAIPSetUnicastSocket(int socketFD);
 
 /**
- * @brief Initialize IP network monitor
- *
- * @param  threadPool [IN] Thread pool for managing network monitor thread.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool);
-
-/**
- * @brief Terminate IP network monitor by removing interface list.
- * @return  NONE
+ * @brief  Set the port number for sending unicast UDP data
+ * @param  port [IN] Port number used for sending UDP data.
+ * @return NONE
  */
-void CAIPTerminateNetworkMonitor();
+void CAIPSetUnicastPort(uint16_t port);
 
 /**
- * @brief  Start network monitoring process. It will start the monitor thread.
+ * @brief  API to send unicast UDP data
  *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
+ * @param  endpoint         [IN] complete network address to send to
+ * @param  data             [IN] Data to be send.
+ * @param  dataLength       [IN] Length of data in bytes
+ * @param  isMulticast      [IN] Whether data needs to be sent to multicast ip
  */
-CAResult_t CAIPStartNetworkMonitor();
+void CAIPSendData(CAEndpoint_t *endpoint,
+                  const void *data,
+                  uint32_t dataLength,
+                  bool isMulticast);
 
 /**
- * @brief  Stop network monitoring process. It will stop the monitor thread.
+ * @brief  Get IP adapter connection state.
  *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
+ * @return  True if IP adapter is connected, otherwise false
  */
-CAResult_t CAIPStopNetworkMonitor();
+bool CAIPIsConnected();
 
 /**
- * @brief  Get local adapter network information.
- *
- * @param  netInterfaceList [OUT] network interface information list
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- * @remarks  interfaceName and ipAddress must be freed using free().
+ * @brief  Pull the Received Data
+ * @return NONE
  */
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList);
+void CAIPPullData();
 
-/**
- * @brief  Get local adapter network subnet mask.
- *
- * @param  ipAddress  [IN]  IpAddress which is used for getting subnet mask.
- * @param  subnetMask [OUT] Local adapter interface subnet mask
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- * @remarks subnetMask must be freed using free().
- */
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask);
+#define CA_COAP        5683
+#define CA_SECURE_COAP 5684
+#define INTERFACE_NAME_MAX 16
+
+typedef struct
+{
+    char name[INTERFACE_NAME_MAX];
+    uint32_t index;
+    uint32_t flags;
+    uint16_t family;
+    uint32_t ipv4addr;        // used for IPv4 only
+} CAInterface_t;
 
 /**
- * @brief  Get IP adapter connection state.
+ * @brief  Get a list of CAInterface_t items
  *
- * @return  True if IP adapter is connected, otherwise false
+ * @return  List of CAInterface_t items
  */
- bool CAIPIsConnected();
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
 
 /**
- * @brief  Set callback for receiving local IP adapter connection status.
+ * @brief  Set callback for error handling
  *
- * @param  callback [IN] Callback to be notified when IP adapter connection state changes.
+ * @param  ipErrorCallback [IN] callback to notify error to the ipadapter
  * @return NONE
  */
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback);
+void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback);
 
 #ifdef __cplusplus
 }
diff --git a/resource/csdk/connectivity/inc/caipinterface_singlethread.h b/resource/csdk/connectivity/inc/caipinterface_singlethread.h
deleted file mode 100644 (file)
index 69133c3..0000000
+++ /dev/null
@@ -1,307 +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 caipinterface_singlethread.h
- * @brief This file provides APIs IP client/server/network monitor modules
- */
-
-#ifndef CA_IP_INTERFACE_SINGLETHREAD_H_
-#define CA_IP_INTERFACE_SINGLETHREAD_H_
-
-#include <stdbool.h>
-
-#include "cacommon.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @enum CAAdapterServerType_t
- * @brief Enum for defining different server types.
- */
-typedef enum
-{
-    CA_UNICAST_SERVER = 0,      /**< Unicast Server */
-    CA_MULTICAST_SERVER,        /**< Multicast Server */
-    CA_SECURED_UNICAST_SERVER   /**< Secured Unicast Server */
-} CAAdapterServerType_t;
-
-/**
- * @brief Callback to be notified on reception of any data from remote OIC devices.
- * @param  ipAddress    [IN] IP address of remote OIC device.
- * @param  port         [IN] Port number on which data is received.
- * @param  data         [IN] Data received from remote OIC device.
- * @param  dataLength   [IN] Length of data in bytes.
- * @return NONE
- * @pre  Callback must be registered using CAIPSetPacketReceiveCallback()
- */
-typedef void (*CAIPPacketReceivedCallback)(const char *ipAddress, uint16_t port,
-                                                 const void *data, uint32_t dataLength);
-
-/**
- * @brief  Callback to be notified when exception occures on multicast/unicast server.
- * @param  type  [IN] Type of server(#CAAdapterServerType_t)
- * @return NONE
- * @pre  Callback must be registered using CAIPSetExceptionCallback()
- */
-typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type);
-
-/**
- * @brief  Initialize IP server
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAIPInitializeServer(void);
-
-/**
- * @brief  Terminate IP server
- * @return NONE
- */
-void CAIPTerminateServer(void);
-
-/**
- * @brief  Start multicast server for specified multicast address and port
- *
- * @param   localAddress        [IN]      Local adapter address to which server to be binded.
- * @param   multicastAddress    [IN]      Multicast group address.
- * @param   multicastPort       [IN,OUT]  Port number on which server will be running. If binding
-                                          the port failed, server starts in the next available port.
- * @param   serverFD            [OUT]     Multicast server socket FD.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
-                                          uint16_t multicastPort, int *serverFD);
-
-/**
- * @brief  Start unicast server for specified local address and port
- *
- * @param  localAddress [IN]      Local adapter address to which server to be binded.
- * @param  port         [IN,OUT]  Port number on which server will be running. If binding
-                                  the port failed, server starts in the next available port.
- * @param  forceStart   [IN]      Indicate whether to start server forcesfully on specified port
- *                                or not.
- * @param  serverFD     [OUT]     Unicast server socket FD.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
-                                        bool forceStart, int *serverFD);
-
-/**
- * @brief  Stop multicast server.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopMulticastServer(void);
-
-/**
- * @brief  Stop unicast server.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopUnicastServer();
-
-#ifdef __WITH_DTLS__
-/**
- * @brief  Stop secured unicast server.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopSecureUnicastServer();
-#endif
-
-/**
- * @brief  Get the Unicast Server Information if it is started
- * @param  ipAddress    [OUT] IP address on which server is binded and running.
- * @param  port         [OUT]Port number on which server is running
- * @param  serverFD     [OUT]Server socket fd.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- * @remarks  ipAddress must be freed using free().
- */
-CAResult_t CAIPGetUnicastServerInfo(char **ipAddress, uint16_t *port, int *serverFD);
-
-/**
- * @brief  Set this callback for receiving data packets from peer devices.
- * @param  callback   [IN] Callback to be notified on reception of unicast/multicast data packets.
- *
- * @return  NONE
- */
-void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback);
-
-/**
- * @brief  Pull the Received Data
- * @return NONE
- */
-void CAIPPullData();
-
-/**
- * @brief  Set this callback for receiving exception notifications.
- *
- * @param  callback [IN] Callback to be notified on occurance of exception on running servers.
- *
- * @return  NONE
- */
-void CAIPSetExceptionCallback(CAIPExceptionCallback callback);
-
-/**
- * @brief  Set socket description for sending unicast UDP data. Once the Unicast server is started,
- *         the same socket descriptor is used for sending the Unicast UDP data.
- *
- * @param  socketFD [IN]  Socket descriptor used for sending UDP data.
- * @return  NONE
- */
-void CAIPSetUnicastSocket(int socketFD);
-
-/**
- * @brief  Set the port number for sending unicast UDP data
- * @param  port [IN] Port number used for sending UDP data.
- * @return NONE
- */
-void CAIPSetUnicastPort(uint16_t port);
-
-#ifdef __WITH_DTLS__
-/**
- * @brief  Set socket description for sending secured (encrypted) unicast UDP data
- *
- * @param socketFD [IN] Socket descriptor used for sending secured (encrypted) UDP data.
- * @return  NONE
- */
-void CAIPSetSecureUnicastSocket(int socketFD);
-#endif
-
-/**
- * @brief  API to send unicast UDP data
- *
- * @param  remoteAddress    [IN] IP address to which data needs to be sent.
- * @param  port             [IN] Port to which data needs to be send.
- * @param  buf              [IN] Data to be send.
- * @param  bufLen           [IN] Length of data in bytes
- * @param  isMulticast      [IN] Whether data needs to be sent to multicast ip
- *
- * @return  The number of bytes sent on the network. Returns 0 on error.
- */
-uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
-                            const char *buf, uint32_t bufLen, bool isMulticast);
-
-/**
- * @brief  Callback to be notified when IP adapter connection state changes.
- *
- * @param  ipAddress    [IN] IP address of remote OIC device.
- * @param  status       [IN] Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
- * @return  NONE
- * @pre  Callback must be registered using CAIPSetConnectionStateChangeCallback()
- */
-typedef void (*CAIPConnectionStateChangeCallback)(const char *ipAddress,
-                                                        CANetworkStatus_t status);
-
-/**
- * @brief Initialize IP network monitor
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Initialization failed
- */
-CAResult_t CAIPInitializeNetworkMonitor(void);
-
-/**
- * @brief Terminate IP network monitor
- * @return  NONE
- */
-void CAIPTerminateNetworkMonitor(void);
-
-/**
- * @brief  Start network monitoring process.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStartNetworkMonitor(void);
-
-/**
- * @brief  Stop network monitoring process.
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAIPStopNetworkMonitor(void);
-
-/**
- * @brief  Get local adapter network information.
- *
- * @param  interfaceName [OUT] Local adapter interface name
- * @param  ipAddress     [OUT] IP address
- *
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
- * @retval  #CA_STATUS_FAILED Operation failed
- * @remarks  interfaceName and ipAddress must be freed using free().
- */
-CAResult_t CAIPGetInterfaceInfo(char **ipAddress, char **interfaceName);
-
-/**
- * @brief  Get Ethernet adapter connection state.
- *
- * @return  True if Ethernet adapter is connected, otherwise false
- */
-bool CAIPIsConnected(void);
-
-/**
- * @brief  Set callback for receiving local ethernet adapter connection status.
- *
- * @param  callback [IN] Callback to be notified when local Ethernet adapter connection state
- *                       changes.
- * @return NONE
- */
-void CAIPSetConnectionStateChangeCallback
-                (CAIPConnectionStateChangeCallback callback);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CA_IP_INTERFACE_SINGLETHREAD_H_ */
-
index ad6e4bb..284db86 100644 (file)
@@ -46,7 +46,7 @@ extern "C"
  */
 typedef struct
 {
-    CARemoteEndpoint_t
+    CAEndpoint_t
     *remoteEndpoint;   /**< Remote endpoint contains the inforamtion of remote device */
     void *data;        /**< Data to be transmitted over LE tranport */
     uint32_t dataLen;  /**< Length of the data being transmitted */
@@ -60,13 +60,15 @@ typedef struct
  *                               started at Connectivity Abstraction Layer.
  * @param  netCallback      [IN] Callback to notify the network additions to Connectivity
  *                               Abstraction Layer.
+ * @param  errorCallback    [IN] errorCallback to notify error to connectivity common logic
+ *                               layer from adapter
  * @param  handle           [IN] Threadpool Handle
  * @return #CA_STATUS_OK or Appropriate error code
  */
 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CANetworkPacketReceivedCallback reqRespCallback,
                           CANetworkChangeCallback netCallback,
-                          ca_thread_pool_t handle);
+                          CAErrorHandleCallback errorCallback, ca_thread_pool_t handle);
 
 /**
  * @brief Starting LE connectivity adapters.
@@ -100,17 +102,18 @@ CAResult_t CAStartLEDiscoveryServer();
  * @return  The number of bytes sent on the network. Returns -1 on error.
  * @remarks  dataLen must be > 0.
  */
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data,
+int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, const void *data,
                              uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the LE connectivity.
- * @param   data        [IN]    Data which required to be sent.
- * @param   dataLen     [IN]    Size of data to be sent.
+ * @param   endpoint    [IN]  Remote Endpoint information to which the unicast data has to be sent.
+ * @param   data        [IN]  Data which required to be sent.
+ * @param   dataLen     [IN]  Size of data to be sent.
  * @return  The number of bytes sent on the network. Returns -1 on error.
  * @remarks  dataLen must be > 0.
  */
-int32_t CASendLEMulticastData(const void *data, uint32_t dataLen);
+int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen);
 
 /**
  * @brief Starts notification server on EDR adapters.
@@ -127,7 +130,7 @@ CAResult_t CAStartLENotifyServer();
  * @return  The number of bytes sent on the network. Returns 0 on error.
  * @remarks dataLen must be > 0.
  */
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data,
+uint32_t CASendLENotification(const CAEndpoint_t *endpoint, const void *data,
                               uint32_t dataLen);
 
 /**
@@ -136,7 +139,7 @@ uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *da
  * @param  size        [OUT]   Number of local connectivity structures.
  * @return #CA_STATUS_OK or Appropriate error code
  */
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief Read Synchronous API callback.
@@ -171,8 +174,9 @@ void CATerminateLE();
  * @retval #CA_STATUS_FAILED Operation failed
  *
  */
-CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength);
+CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                         const void *data, uint32_t dataLength,
+                                         uint32_t *sentLength);
 
 /**
  * @brief  This function will receive the data from the GattClient and add the data into the
@@ -187,8 +191,9 @@ CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *servic
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength);
+CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                         const void *data, uint32_t dataLength,
+                                         uint32_t *sentLength);
 
 /**
  * @brief  This function is used to set the NetworkPacket received callback to CA layer from
@@ -196,7 +201,7 @@ CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *servic
  * @param  callback [IN] callback handle sent from the upper layer.
  * @return NONE
  */
-void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
+void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
 
 /**
  * @brief  This function will push the data from CA layer to the Sender processor queue.
@@ -210,8 +215,8 @@ void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data, uint32_t dataLen);
+CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
+                                     const void *data, uint32_t dataLen);
 
 /**
  * @brief  This function will push the data from CA layer to the Sender processor queue.
@@ -225,8 +230,8 @@ CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data,  uint32_t dataLen);
+CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
+                                     const void *data,  uint32_t dataLen);
 
 /**
  * @brief  This function will be associated with the sender queue for GattServer.This function will
@@ -238,7 +243,7 @@ CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
  *
  * @return  NONE
  */
-void CABLEServerSendDataThread(void *threadData);
+void CALEServerSendDataThread(void *threadData);
 
 /**
  * @brief  This function will be associated with the sender queue for GattClient.This function will
@@ -250,7 +255,7 @@ void CABLEServerSendDataThread(void *threadData);
  *
  * @return NONE
  */
-void CABLEClientSendDataThread(void *threadData);
+void CALEClientSendDataThread(void *threadData);
 
 /**
  * @brief  This function will be associated with the receiver queue of GattServer. This function
@@ -263,7 +268,7 @@ void CABLEClientSendDataThread(void *threadData);
  *
  * @return  NONE
  */
-void CABLEServerDataReceiverHandler(void *threadData);
+void CALEServerDataReceiverHandler(void *threadData);
 
 /**
  * @brief  This function will be associated with the receiver queue of GattClient. This function
@@ -275,28 +280,28 @@ void CABLEServerDataReceiverHandler(void *threadData);
  *                         and Data.
  * @return NONE
  */
-void CABLEClientDataReceiverHandler(void *threadData);
+void CALEClientDataReceiverHandler(void *threadData);
 
 /**
  * @brief  This function is used to Initalize both GattServer and GattClient queues. All four
  *         queues will be initialized with this function invocations.
  * @return  NONE
  */
-void CAInitBleQueues();
+void CAInitLEQueues();
 
 /**
  * @brief  This function will stop all queues created for GattServer and GattClient. All
  *         four queues will be be stopped with this function invocations.
  * @return  NONE
  */
-void CAStopBleQueues();
+void CAStopLEQueues();
 
 /**
  * @brief  This function will terminate all queues created for GattServer and GattClient. All
  *         four queues will be be terminated with this function invocations.
  * @return  NONE
  */
-void CATerminateBleQueues();
+void CATerminateLEQueues();
 
 /**
  * @brief  This function will initalize the Receiver and Sender queues for GattServer. This
@@ -307,7 +312,7 @@ void CATerminateBleQueues();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAInitBleServerQueues();
+CAResult_t CAInitLEServerQueues();
 
 /**
  * @brief  This function will initalize the Receiver and Sender queues for GattClient. This
@@ -320,7 +325,7 @@ CAResult_t CAInitBleServerQueues();
  * @retval #CA_STATUS_FAILED Operation failed
  *
  */
-CAResult_t CAInitBleClientQueues();
+CAResult_t CAInitLEClientQueues();
 
 /**
  * @brief  This function will initalize the Receiver queue for GattServer. This will initialize
@@ -332,7 +337,7 @@ CAResult_t CAInitBleClientQueues();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAInitBleServerSenderQueue();
+CAResult_t CAInitLEServerSenderQueue();
 
 /**
  * @brief  This function will initalize the Receiver queue for GattClient. This will initialize
@@ -344,7 +349,7 @@ CAResult_t CAInitBleServerSenderQueue();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAInitBleClientSenderQueue();
+CAResult_t CAInitLEClientSenderQueue();
 
 /**
  * @brief  This function will initalize the Receiver queue for GattServer. This will initialize
@@ -357,7 +362,7 @@ CAResult_t CAInitBleClientSenderQueue();
  * @retval #CA_STATUS_FAILED Operation failed
  *
  */
-CAResult_t CAInitBleServerReceiverQueue();
+CAResult_t CAInitLEServerReceiverQueue();
 
 /**
  * @brief  This function will initalize the Receiver queue for GattClient. This will initialize
@@ -369,7 +374,7 @@ CAResult_t CAInitBleServerReceiverQueue();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAInitBleClientReceiverQueue();
+CAResult_t CAInitLEClientReceiverQueue();
 
 /**
  * @brief  This function will create the Data required to send it in the queue.
@@ -383,7 +388,7 @@ CAResult_t CAInitBleClientReceiverQueue();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, const void *data,
                            uint32_t dataLength);
 
 /**
@@ -391,7 +396,7 @@ CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void
  * @param bleData [IN] Structure contains the information of a particular data segment.
  * @return NONE
  */
-void CAFreeBLEData(CALEData_t *bleData);
+void CAFreeLEData(CALEData_t *bleData);
 
 /**
  * @brief This will be used to notify device status changes to the LE adapter layer
diff --git a/resource/csdk/connectivity/inc/caleadapter_singlethread.h b/resource/csdk/connectivity/inc/caleadapter_singlethread.h
deleted file mode 100644 (file)
index c790889..0000000
+++ /dev/null
@@ -1,427 +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 contains the APIs for LE adapters to be implemented.
- */
-
-#ifndef CA_LEADAPTER_SINGLETHREAD_H_
-#define CA_LEADAPTER_SINGLETHREAD_H_
-
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-/**
- * BLE Interface APIs.
- */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @struct CALEData_t
- * @brief Stores the information of the Data to be sent from the queues.
- *        This structure will be pushed to the sender/receiver queue for processing.
- */
-typedef struct
-{
-    CARemoteEndpoint_t
-    *remoteEndpoint;    /**< Remote endpoint contains the inforamtion of remote device */
-    void *data;         /**< Data to be transmitted over LE tranport */
-    uint32_t dataLen;   /**< Length of the data being transmitted */
-} CALEData_t;
-
-/**
- * @brief Initialize LE connectivity interface.
- * @param registerCallback [IN] Callback to register LE interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback  [IN] Callback to notify request and response messages from server(s)
- *                              started at Connectivity Abstraction Layer.
- * @param netCallback      [IN] Callback to notify the network additions to Connectivity
- *                              Abstraction Layer.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback);
-
-/**
- * @brief Starting LE connectivity adapters.
- *        As its peer to peer it doesnot require to start any servers
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartLE();
-
-/**
- * @brief Starting listening server for receiving multicast search requests
- * Transport Specific Behavior:
- *   LE  Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartLEListeningServer();
-
-/**
- * @brief for starting discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- *   LE  Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartLEDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * @param  endpoint  [IN]  Remote Endpoint information (like ipaddress , port, reference uri
- *                         and connectivity type) to which the unicast data has to be sent.
- * @param  data      [IN]  Data which required to be sent.
- * @param  dataLen   [IN]  Size of data to be sent.
- * @return  The number of bytes sent on the network. Returns -1 on error.
- * @remarks dataLen must be > 0.
- */
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data,
-                             uint32_t dataLen);
-
-/**
- * @brief Sends Multicast data to the endpoint using the LE connectivity.
- * @param   data        [IN]    Data which required to be sent.
- * @param   dataLen     [IN]    Size of data to be sent.
- * @return  The number of bytes sent on the network. Returns -1 on error.
- * @remarks  dataLen must be > 0.
- */
-int32_t CASendLEMulticastData(const void *data, uint32_t dataLen);
-
-/**
- * @brief Starts notification server on EDR adapters.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStartLENotifyServer();
-
-/**
- * @brief Send notification information.
- * @param   endpoint  [IN]    Remote Endpoint information (like ipaddress , port, reference uri
- *                            and connectivity type) to which the unicast data has to be sent.
- * @param   data      [IN]    Data which required to be sent.
- * @param   dataLen   [IN]    Size of data to be sent.
- * @return  The number of bytes sent on the network. Returns 0 on error.
- * @remarks dataLen must be > 0.
- */
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data,
-                              uint32_t dataLen);
-
-/**
- * @brief   Get LE Connectivity network information
- * @param   info        [OUT]   Local connectivity information structures
- * @param   size        [OUT]   Number of local connectivity structures.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAReadLEData();
-
-/**
- * @brief Stopping the adapters and close socket connections
- *   LE Stops all GATT servers and close sockets.
- * @return  #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CAStopLE();
-
-/**
- * @brief Terminate the LE connectivity adapter.
- * Configuration information will be deleted from further use
- */
-void CATerminateLE();
-
-/**
- * @brief  This function will receive the data from the GattServer and add the data to
- *         the Server receiver queue.
- * @param  remoteAddress [IN] Remote address of the device from where data is received.
- * @param  serviceUUID   [IN] Uuid of the OIC service running on the remote device
- * @param  data          [IN] Actual data recevied from the remote device.
- * @param  dataLength    [IN] Length of the data received from the remote device.
- * @param  sentLength    [IN] Length of the data sent from the remote device.
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength);
-
-/**
- * @brief  This function will receive the data from the GattClient and add the data into the
- *         Client receiver queue.
- * @param  remoteAddress [IN] Remote address of the device from where data is received.
- * @param  serviceUUID   [IN] Uuid of the OIC service running on the remote device
- * @param  data          [IN] Actual data recevied from the remote device.
- * @param  dataLength    [IN] Length of the data received from the remote device.
- * @param  sentLength    [IN] Length of the data sent from the remote device.
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength);
-
-/**
- * @brief  This function is used to set the NetworkPacket received callback to CA layer from
- *         adapter layer.
- * @param  callback [IN] callback handle sent from the upper layer.
- * @return NONE
- */
-void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
-
-/**
- * @brief  This function will push the data from CA layer to the Sender processor queue.
- *
- * @param  remoteEndpoint [IN] Remote endpoint information of the server.
- * @param  data           [IN] Data to be transmitted from LE.
- * @param  dataLen        [IN] length of the Data being transmitted.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data, uint32_t dataLen);
-
-/**
- * @brief  This function will push the data from CA layer to the Sender processor queue.
- *
- * @param  remoteEndpoint [IN] Remote endpoint information of the server.
- * @param  data           [IN] Data to be transmitted from LE.
- * @param  dataLen        [IN] length of the Data being transmitted.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data, uint32_t dataLen);
-
-/**
- * @brief  This function will be associated with the sender queue for GattClient.This function will
- *         fragment the data to the MTU of the transport and send the data in fragments to the
- *         adapters. The function will be blocked untill all data is sent out from the adapter.
- *
- * @param  threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
- *                         and Data.
- *
- * @return NONE
- */
-void CABLEClientSendDataThread(void *threadData);
-
-/**
- * @brief  This function will be associated with the receiver queue of GattClient. This function
- *         will defragment the data received and will send the data UP to the CA layer only after
- *         it collects all the data from the adapter layer. Adapter Header will provide the length
- *         of the data sent from the server.
- *
- * @param  threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
- *                         and Data.
- * @return NONE
- */
-void CABLEClientDataReceiverHandler(void *threadData);
-
-/**
- * @brief  This function will terminate all queues created for GattServer and GattClient. All
- *         four queues will be be terminated with this function invocations.
- * @return  NONE
- */
-void CATerminateBleQueues();
-
-/**
- * @brief  This function will initalize the Receiver queue for GattClient. This will initialize
- *         the queue to process the function CABLEClientDataReceiverHandler() when ever the task
- *         is added to this queue.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAInitBleClientReceiverQueue();
-
-/**
- * @brief  This function will initalize the Receiver queue for GattServer. This will initialize
- *         the queue to process the function CABLEServerDataReceiverHandler() when ever the task
- *         is added to this queue.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CAInitBleServerReceiverQueue();
-
-/**
- * @brief  This function is used to Initalize both GattServer and GattClient queues. All four
- *         queues will be initialized with this function invocations.
- * @return  NONE
- */
-void CAInitBleQueues();
-
-/**
- * @brief  This function will initalize the Receiver and Sender queues for GattServer. This
- *         function will inturn call the functions CAInitBleServerReceiverQueue() and
- *         CAInitBleServerSenderQueue() to initialize the queues.
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAInitBleServerQueues();
-
-/**
- * @brief  This function will initalize the Receiver and Sender queues for GattClient. This
- *         function will inturn call the functions CAInitBleClientReceiverQueue() and
- *         CAInitBleClientSenderQueue() to initialize the queues.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- *
- */
-CAResult_t CAInitBleClientQueues();
-
-/**
- * @brief  This function will initalize the Receiver queue for GattServer. This will initialize
- *         the queue to process the function CABLEServerSendDataThread() when ever the task is
- *         added to this queue.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAInitBleServerSenderQueue();
-
-/**
- * @brief  This function will initalize the Receiver queue for GattClient. This will initialize
- *         the queue to process the function CABLEClientSendDataThread() when ever the task is
- *         added to this queue.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAInitBleClientSenderQueue();
-
-/**
- * @brief  This function will be associated with the receiver queue of GattServer. This function
- *         will defragment the data received and will send the data UP to the CA layer only after
- *         it collects all the data from the adapter layer. Adapter Header will provide the
- *         length of the data sent from the server.
- *
- * @param  context [IN] Data pushed to the queue which contains the info about RemoteEndpoint
- *                      and Data.
- *
- * @return  NONE
- */
-void CABLEServerDataReceiverHandler(void *context);
-
-/**
- * @brief  This function will be associated with the sender queue for GattServer.This function will
- *         fragment the data to the MTU of the transport and send the data in fragments to the
- *         adapters. The function will be blocked untill all data is sent out from the adapter.
- *
- * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint
- *                        and Data.
- *
- * @return  NONE
- */
-void CABLEServerSendDataThread(void *threadData);
-
-/**
- * @brief  This function will create the Data required to send it in the queue.
- *
- * @param  remoteEndpoint [IN] Remote endpoint information of the server.
- * @param  data           [IN] Data to be transmitted from LE.
- * @param  dataLength     [IN] length of the Data being transmitted.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                            uint32_t dataLength);
-
-/**
- * @brief Used to free the BLE information stored in the sender/receiver queues.
- * @param bleData [IN] Structure contains the information of a particular data segment.
- * @return NONE
- */
-void CAFreeBLEData(CALEData_t *bleData);
-
-/**
- * @brief This will be used to notify the device status changes to the LE adapter layer
- * @param  adapter_state [IN] State of the adapter
- * @return NONE
- */
-typedef void (*CALEDeviceStateChangedCallback)(CAAdapterState_t adapter_state);
-
-/**
- * @brief This will be used to notify that network packet recieved from GATTClient to adapter layer.
- * @param  remoteAddress  [IN] Remote endpoint Address
- * @param  serviceUUID    [IN] Service UUID
- * @param  data           [IN] Data received
- * @param  dataLength     [IN] Length of the data received
- * @param  sentLength     [IN] Length of the data sent
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-typedef CAResult_t (*CABLEClientDataReceivedCallback)(const char *remoteAddress,
-                    const char *serviceUUID, const void *data, uint32_t dataLength,
-                    uint32_t *sentLength);
-
-/**
- * @brief This will be used to notify that network packet recieved from GATTServer to adapter layer.
- * @param  remoteAddress  [IN] Remote endpoint Address
- * @param  serviceUUID    [IN] Service UUID
- * @param  data           [IN] Data received
- * @param  dataLength     [IN] Length of the data received
- * @param  sentLength     [IN] Length of the data sent
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-typedef CAResult_t (*CABLEServerDataReceivedCallback)(const char *remoteAddress,
-        const char *serviceUUID, const void *data, uint32_t dataLength, uint32_t *sentLength);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* CA_LEADAPTER_SINGLETHREAD_H_ */
-
index ff1ab29..5f83e51 100644 (file)
@@ -135,7 +135,7 @@ CAResult_t CAGetLEAddress(char **local_address);
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAStartBleGattServer();
+CAResult_t CAStartLEGattServer();
 
 /**
  * @brief  Used to stop BLE Gatt Service.
@@ -145,13 +145,13 @@ CAResult_t CAStartBleGattServer();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAStopBleGattServer();
+CAResult_t CAStopLEGattServer();
 
 /**
  * @brief  Used to stop Gatt Server thread and remove service registration, stop advertising.
  * @return NONE
  */
-void CATerminateBleGattServer();
+void CATerminateLEGattServer();
 
 /**
  * @brief  Used to store upper layer callback locally which will be used to send the data to
@@ -159,7 +159,7 @@ void CATerminateBleGattServer();
  * @param  callback [IN] Callback function to pass the data to CA layer.
  * @return NONE
  */
-void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
+void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
 
 /**
  * @brief  Used to update characteristics(Read/Write) value that we want to send to particular
@@ -189,7 +189,7 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *
  * @retval #CA_STATUS_FAILED Operation failed
  */
 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
-                                                   const uint32_t charValueLen);
+                                                   uint32_t charValueLen);
 
 /**
  * @brief  Used to start CAStartBleGattClientThread for initializing Gatt Client
@@ -199,7 +199,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-CAResult_t CAStartBLEGattClient();
+CAResult_t CAStartLEGattClient();
 
 /**
  * @brief  Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient
@@ -209,13 +209,19 @@ CAResult_t CAStartBLEGattClient();
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-void CAStopBLEGattClient();
+void CAStopLEGattClient();
 
 /**
  * @brief  Used to unset all the callbacks and stop service discovery
  * @return NONE
  */
-void CATerminateBLEGattClient();
+void CATerminateLEGattClient();
+
+/**
+ * @brief API to read the data from characteristics and invoke notifyCallback.
+ * @return - NONE
+ */
+void CACheckLEData();
 
 /**
  * @brief  Sets the value of characteristic and update the value to GATTServer(unicast).
@@ -255,7 +261,7 @@ CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, uint32_t
  *
  * @return  void
  */
-void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
+void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
 
 /**
  * @brief  Used to Set the gThreadPool handle which is required for spawning new thread.
@@ -267,7 +273,7 @@ void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
  * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
  * @retval #CA_STATUS_FAILED Operation failed
  */
-void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle);
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle);
 
 /**
 * @brief  Used to Set the gThreadPool handle which is required for spawning new thread.
@@ -275,7 +281,7 @@ void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle);
 *                    task.
 * @return NONE
 */
-void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle);
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle);
 
 /**
  * @brief  Used to unset the callback of adapter connection state change.
@@ -286,6 +292,33 @@ void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle);
  * @retval #CA_STATUS_FAILED Operation failed
  */
 CAResult_t CAUnSetLEAdapterStateChangedCb();
+
+/**
+ * @brief This will be used to notify errors in BLE adapter
+ * @param  remoteAddress    [IN] Remote endpoint Address
+ * @param  serviceUUID      [IN] Service UUID
+ * @param  data             [IN] Data received
+ * @param  dataLength       [IN] Length of the data received
+ * @param  result           [IN] error code as per CAResult_t
+ * @return NONE
+ */
+typedef void (*CABLEErrorHandleCallback)(const char *remoteAddress, const void *data,
+                                         uint32_t dataLength, CAResult_t result);
+/**
+ * @brief  sets the error handle callback
+ * @param  callback [IN] Callback function to update error to the adapter
+ * @return NONE
+ */
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback);
+
+
+/**
+ * @brief  sets the error handle callback
+ * @param  callback [IN] Callback function to update error to the adapter
+ * @return NONE
+ */
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/resource/csdk/connectivity/inc/caleinterface_singlethread.h b/resource/csdk/connectivity/inc/caleinterface_singlethread.h
deleted file mode 100644 (file)
index 6cc639b..0000000
+++ /dev/null
@@ -1,216 +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 for BLE modules.
- */
-
-#ifndef CA_LE_INTERFACE_SINGLETHREAD_H_
-#define CA_LE_INTERFACE_SINGLETHREAD_H_
-
-#include <stdbool.h>
-
-#include "cacommon.h"
-#include "caleadapter_singlethread.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @enum CALETransferType_t
- * @brief Provide information about different mode of data transfer
- *        This enum is used to differentiate between unicast and multicast data transfer.
- */
-typedef enum
-{
-    LE_MULTICAST,    /**< When this enum is selected, data will be updated to all OIC servers. */
-    LE_UNICAST       /**< When this enum is selected, data will be updated to desired OIC Server. */
-} CALETransferType_t;
-
-
-/**
- * @brief  Used to get the current state of the LE adapter.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_ADAPTER_NOT_ENABLED  adapter not enabled
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAGetLEAdapterState();
-
-/**
- * @brief  Used to initialize the network monitor layer of the LE adapter.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEInitializeNetworkMonitor();
-
-/**
- * @brief  Used to terminate the network monitor layer of the LE adapter.
- * @return NONE
- */
-void CALETerminateNetworkMonitor();
-
-/**
- * @brief  This function is used to set the callback for the Device state changes in the adapter.
- *
- * @param  callback  [IN]  Callback to notify the Device state change to the CA Layer
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback);
-
-/**
- * @brief  Provides the BD address of the local adapter.
- * @param  local_address [OUT] pointer to the location where bd address needs to be stored.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAGetLEAddress(char **local_address);
-
-/**
- * @brief  Used to start Gatt Server thread for service creation and advertise ble service.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAStartBleGattServer();
-
-/**
- * @brief  Used to stop BLE Gatt Service.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAStopBleGattServer();
-
-/**
- * @brief  Used to store upper layer callback locally which will be used to send the data to
- *         application
- * @param  callback [IN] Callback function to pass the data to CA layer.
- * @return NONE
- */
-void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
-
-/**
- * @brief  Used to update characteristics(Read/Write) value that we want to send to particular
- *         client. Both unicast and multicast will use the same api. In mulicast, we will be
- *         sending in loop to all clients.
- *
- * @param  charValue     [IN] Data that we want to send to client(unicast)/clients(multicast)
- * @param  charValueLen  [IN] Length of the data.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
-                                                   uint8_t charValueLen);
-
-/**
- * @brief  Used to start CAStartBleGattClientThread for initializing Gatt Client
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAStartBLEGattClient();
-
-/**
- * @brief  Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient
- *         function.
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-void CAStopBLEGattClient();
-
-/**
- * @brief  Used to unset all the callbacks and stop service discovery
- * @return NONE
- */
-void CATerminateBLEGattClient();
-
-/**
- * @brief  Sets the value of characteristic and update the value to GATTServer(unicast).
- *
- * @param  remoteAddress [IN] The address of the remote device
- * @param  data          [IN] The value of characteristic (byte array)
- * @param  dataLen       [IN] The length of value
- * @param  type          [IN] Type of the transfer(#CALETransferType_t)
- * @param  position      [IN] The unique index of each ble server. Used for multicast feature.
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
-                                                const uint32_t dataLen, CALETransferType_t type,
-                                                const int32_t position);
-
-/**
- * @brief  Sets the value of characteristic and update the value to all registered
- *         GATTServer -> Multicast
- * @param  data     [IN] The value of characteristic (byte array)
- * @param  dataLen  [IN] The length of value
- *
- * @return #CA_STATUS_OK or Appropriate error code
- * @retval #CA_STATUS_OK  Successful
- * @retval #CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval #CA_STATUS_FAILED Operation failed
- */
-CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, uint32_t dataLen);
-
-/**
- * @brief  Used to store upper layer callback locally which will be used to send the data to
- *         application
- * @param  callback  [IN] Callback function to pass the data to CA layer.
- *
- * @return  void
- */
-void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CA_LE_INTERFACE_SINGLETHREAD_H_ */
-
index e5ee5cb..9e58735 100644 (file)
@@ -63,7 +63,7 @@ extern "C"
  * @param   request        [IN]    request that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
+CAResult_t CADetachRequestMessage(const CAEndpoint_t *endpoint,
                                   const CARequestInfo_t *request);
 
 /**
@@ -72,7 +72,7 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
  * @param   request        [IN]    request that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
+CAResult_t CADetachRequestToAllMessage(const CAEndpoint_t *object,
                                        const CARequestInfo_t *request);
 
 /**
@@ -81,7 +81,7 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
  * @param   response       [IN]    response that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint,
+CAResult_t CADetachResponseMessage(const CAEndpoint_t *endpoint,
                                    const CAResponseInfo_t *response);
 
 /**
@@ -101,9 +101,11 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
  * @brief   Setting the request and response callbacks for network packets
  * @param   ReqHandler     [IN]    callback for receiving the requests
  * @param   RespHandler    [IN]    callback for receiving the response
+ * @param   ErrorHandler   [IN]    callback for receiving error response
  * @return  NONE
  */
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback ErrorHandler);
 
 /**
  * @brief   Initialize the message handler by starting thread pool and initializing the
index 469c6ea..10f2416 100644 (file)
@@ -63,7 +63,7 @@ extern "C"
  * @param   request        [IN]    request that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
+CAResult_t CADetachRequestMessage(const CAEndpoint_t *endpoint,
                                   const CARequestInfo_t *request);
 
 /**
@@ -72,7 +72,7 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
  * @param   request        [IN]    request that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
+CAResult_t CADetachRequestToAllMessage(const CAEndpoint_t *object,
                                        const CARequestInfo_t *request);
 
 /**
@@ -81,7 +81,7 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
  * @param   response       [IN]    response that needs to be sent
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint,
+CAResult_t CADetachResponseMessage(const CAEndpoint_t *endpoint,
                                    const CAResponseInfo_t *response);
 
 /**
@@ -101,9 +101,11 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
  * @brief   Setting the request and response callbacks for network packets
  * @param   ReqHandler     [IN]    callback for receiving the requests
  * @param   RespHandler    [IN]    callback for receiving the response
+ * @param   ErrorHandler   [IN]    callback for receiving error response
  * @return  NONE
  */
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback ErrorHandler);
 
 /**
  * @brief   Initialize the message handler by starting thread pool and initializing the
index 2031ab6..0ace516 100644 (file)
@@ -37,17 +37,17 @@ extern "C"
 
 /**
  * @brief   Add network type to the selected networks for network packets reception
- * @param   transportType       [IN]    Transport type that needs to be added
+ * @param   transportAdapter     [IN]  Adapter that needs to be added
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAAddNetworkType(CATransportType_t transportType);
+CAResult_t CAAddNetworkType(CATransportAdapter_t transportAdapter);
 
 /**
  * @brief   Remove network type from the selected configuration
- * @param   transportType       [IN]    Transport type that needs to be removed
+ * @param   transportAdapter     [IN]  Adapter that needs to be removed
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CARemoveNetworkType(CATransportType_t transportType);
+CAResult_t CARemoveNetworkType(CATransportAdapter_t transportAdapter);
 
 /**
  * @brief   Get selected network information
@@ -61,7 +61,7 @@ u_arraylist_t *CAGetSelectedNetworkList();
  * @param   size    [OUT]   No Of Array objects
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t *size);
+CAResult_t CAGetNetworkInformationInternal(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * @brief   Terminate network type from selected configuration
index d96c7a3..591aac1 100644 (file)
@@ -40,14 +40,22 @@ typedef uint32_t code_t;
 #define CA_RESPONSE_CLASS(C) (((C) >> 5)*100)
 #define CA_RESPONSE_CODE(C) (CA_RESPONSE_CLASS(C) + (C - COAP_RESPONSE_CODE(CA_RESPONSE_CLASS(C))))
 
+
+// Include files from the arduino platform do not provide these conversions:
+#ifdef ARDUINO
+#define htons(x) ( ((x)<< 8 & 0xFF00) | ((x)>> 8 & 0x00FF) )
+#define ntohs(x) htons(x)
+#else
+#define HAVE_TIME_H 1
+#endif
+
 /**
  * @brief   generates pdu structure from the given information.
- * @param   uri              [IN]    uri information of the pdu
  * @param   code             [IN]    code of the pdu packet
  * @param   info             [IN]    pdu information
  * @return  generated pdu
  */
-coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info);
+coap_pdu_t *CAGeneratePDU(uint32_t code, const CAInfo_t *info);
 
 /**
  * function for generating
@@ -57,23 +65,25 @@ coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info);
  * @brief   extracts request information from received pdu.
  * @param   pdu              [IN]     received pdu
  * @param   outReqInfo       [OUT]    request info structure made from received pdu
- * @param   outUri           [OUT]    uri received in the received pdu
- * @param   buflen           [IN]     Buffer Length for outUri parameter
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri,
-                                   uint32_t buflen);
+CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo);
 
 /**
  * @brief   extracts response information from received pdu.
  * @param   pdu              [IN]     received pdu
  * @param   outResInfo       [OUT]    response info structure made from received pdu
- * @param   outUri           [OUT]    uri received in the received pdu
- * @param   buflen           [IN]     Buffer Length for outUri parameter
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
-                                    char *outUri, uint32_t buflen);
+CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo);
+
+/**
+ * @brief   extracts error information from received pdu.
+ * @param   pdu              [IN]     received pdu
+ * @param   errorInfo        [OUT]    error info structure made from received pdu
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo);
 
 /**
  * @brief   creates pdu from the request information
@@ -83,8 +93,8 @@ CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *out
  * @param   payload          [IN]    payload for the request or response consumed
  * @return  generated pdu
  */
-coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t info,
-                              const char *payload, size_t payloadSize);
+coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t *info,
+                              const uint8_t *payload, size_t payloadSize);
 
 /**
  * @brief   parse the URI and creates the options
@@ -115,7 +125,7 @@ CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target
  * @param   optlist          [OUT]   options information
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist);
+CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **optlist);
 
 /**
  * @brief   creates option node from key length and data
@@ -124,7 +134,7 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **o
  * @param   data             [IN]    data that needs to be sent
  * @return  created list
  */
-coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const uint8_t *data);
+coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const char *data);
 
 /**
  * @brief   order the inserted options
@@ -157,12 +167,9 @@ uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uin
  * @param   pdu              [IN]     received pdu
  * @param   outCode          [OUT]    code of the received pdu
  * @param   outInfo          [OUT]    request info structure made from received pdu
- * @param   outUri           [OUT]    uri received in the received pdu
- * @param   buflen           [IN]     Buffer Length for outUri parameter
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
-                            char *outUri, uint32_t buflen);
+CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo);
 
 /**
  * @brief   create pdu from received data
diff --git a/resource/csdk/connectivity/inc/caraadapter.h b/resource/csdk/connectivity/inc/caraadapter.h
new file mode 100644 (file)
index 0000000..3f08647
--- /dev/null
@@ -0,0 +1,131 @@
+/******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+******************************************************************/
+
+/**
+ * @file caraadapter.h
+ * @brief This file contains the APIs for IP Adapter.
+ */
+#ifndef CA_RA_ADAPTER_H_
+#define CA_RA_ADAPTER_H_
+
+#include "cacommon.h"
+#include "caadapterinterface.h"
+#include "cathreadpool.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+ * @brief API to initialize RA Interface.
+ * @param registerCallback      [IN] Callback to register RA interfaces to Connectivity
+ *                                   Abstraction Layer
+ * @param networkPacketCallback [IN] Callback to notify request and response messages from server(s)
+ *                                   started at Connectivity Abstraction Layer.
+ * @param netCallback           [IN] Callback to notify the network additions to Connectivity
+ *                                   Abstraction Layer.
+ * @param handle                [IN] Threadpool Handle
+ * @return  #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
+                          CANetworkPacketReceivedCallback networkPacketCallback,
+                          CANetworkChangeCallback netCallback,
+                          ca_thread_pool_t handle);
+
+
+/**
+ * @brief Start RA Interface adapter.
+ * @return  #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAStartRA();
+
+/**
+ * @brief Sends data to the endpoint using the adapter connectivity.
+ * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
+ * reference uri and transport type) to which the unicast data has to be sent.
+ * @param   data        [IN]    Data which is required to be sent.
+ * @param   dataLen     [IN]    Size of data to be sent.
+ * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
+ * @remarks dataLen must be > 0.
+ */
+int32_t CASendRAUnicastData(const CAEndpoint_t *endpoint, const void *data,
+                            uint32_t dataLen);
+
+/**
+ * @brief Get RA Connectivity network information
+ * @param   info        [OUT]   Local connectivity information structures
+ * @param   size        [OUT]   Number of local connectivity structures.
+ * @return  #CA_STATUS_OK or Appropriate error code
+ * @remarks info is allocated in this API and should be freed by the caller.
+ */
+CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
+
+/**
+ * @brief Stops RA server and de-register XMPP callback listeners
+ * @return  #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAStopRA();
+
+/**
+ * @brief Terminate the RA connectivity adapter.
+ * Configuration information will be deleted from further use
+ * @return  NONE
+ */
+void CATerminateRA();
+
+/**
+ * @brief   Set Remote Access information for XMPP Client.
+ * @param   caraInfo            [IN] remote access info.
+ *
+ * @return  CA_STATUS_OK
+ */
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
+
+/**
+ * These functions are not applicable to Remote Access adapter
+ */
+int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
+                 const void *data, uint32_t dataLen);
+/**
+ * @brief Start listening server for receiving search requests.
+ * @return  #CA_NOT_SUPPORTED
+ */
+CAResult_t CAStartRAListeningServer();
+
+/**
+ * @brief Start discovery servers for receiving advertisements.
+ * @return  #CA_NOT_SUPPORTED
+ */
+CAResult_t CAStartRADiscoveryServer();
+
+/**
+ * @brief Read Synchronous API callback.
+ * @return  #CA_NOT_SUPPORTED
+ */
+CAResult_t CAReadRAData();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  //CA_RA_ADAPTER_H_
+
index 052fa41..d43db32 100644 (file)
 #include "uarraylist.h"
 #include "cacommon.h"
 
-/** CA_IPV4, CA_EDR, CA_LE **/
-#define DEFAULT_RETRANSMISSION_TYPE     (CA_IPV4 | CA_EDR | CA_LE)
+/** IP, EDR, LE **/
+#define DEFAULT_RETRANSMISSION_TYPE (CA_ADAPTER_IP | \
+                                     CA_ADAPTER_RFCOMM_BTEDR | \
+                                     CA_ADAPTER_GATT_BTLE)
 
 /** default ACK time is 2 sec.(CoAP) **/
 #define DEFAULT_ACK_TIMEOUT_SEC     2
 
 /** default max retransmission trying count is 4.(CoAP) **/
-#define DEFAULT_MAX_RETRANSMIT      4
+#define DEFAULT_RETRANSMISSION_COUNT      4
 
 /** check period is 1 sec. **/
 #define RETRANSMISSION_CHECK_PERIOD_SEC     1
 
 /** retransmission data send method type**/
-typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, const void *pdu,
+typedef CAResult_t (*CADataSendMethod_t)(const CAEndpoint_t *endpoint,
+                                         const void *pdu,
                                          uint32_t size);
 
 /** retransmission timeout callback type**/
-typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu,
+typedef void (*CATimeoutCallback_t)(const CAEndpoint_t *endpoint,
+                                    const void *pdu,
                                     uint32_t size);
 
 typedef struct
 {
     /** retransmission support transport type **/
-    CATransportType_t supportType;
+    CATransportAdapter_t supportType;
 
     /** retransmission trying count **/
     uint8_t tryingCount;
@@ -106,7 +110,8 @@ extern "C"
  *                                           if NULL is coming, it will set default values.
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
-CAResult_t CARetransmissionInitialize(CARetransmission_t *context, ca_thread_pool_t handle,
+CAResult_t CARetransmissionInitialize(CARetransmission_t *context,
+                                      ca_thread_pool_t handle,
                                       CADataSendMethod_t retransmissionSendMethod,
                                       CATimeoutCallback_t timeoutCallback,
                                       CARetransmissionConfig_t* config);
@@ -128,8 +133,8 @@ CAResult_t CARetransmissionStart(CARetransmission_t *context);
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
 CAResult_t CARetransmissionSentData(CARetransmission_t* context,
-                                    const CARemoteEndpoint_t* endpoint, const void* pdu,
-                                    uint32_t size);
+                                    const CAEndpoint_t* endpoint,
+                                    const void* pdu, uint32_t size);
 
 /**
  * @brief   Pass the received pdu data. if received pdu is ACK data for the retransmission CON data,
@@ -142,7 +147,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t* context,
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
  */
 CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
-                                        const CARemoteEndpoint_t *endpoint, const void *pdu,
+                                        const CAEndpoint_t *endpoint, const void *pdu,
                                         uint32_t size, void **retransmissionPdu);
 
 /**
@@ -159,6 +164,12 @@ CAResult_t CARetransmissionStop(CARetransmission_t *context);
  */
 CAResult_t CARetransmissionDestroy(CARetransmission_t *context);
 
+/**
+ * @brief   Invoke Retransmission according to TimedAction Response
+ * @param   threadValue [IN]    context for retransmission
+ */
+void CARetransmissionBaseRoutine(void *threadValue);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/resource/csdk/connectivity/inc/caretransmission_singlethread.h b/resource/csdk/connectivity/inc/caretransmission_singlethread.h
deleted file mode 100644 (file)
index 5e581be..0000000
+++ /dev/null
@@ -1,155 +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 caretransmission_singlethread.h
- * @brief This file contains common function for retransmission messages.
- */
-
-#ifndef CA_RETRANSMISSION_SINGLETHREAD_H_
-#define CA_RETRANSMISSION_SINGLETHREAD_H_
-
-#include <stdint.h>
-
-#include "uarraylist.h"
-#include "cacommon.h"
-
-/** CA_IPV4, CA_LE **/
-#define DEFAULT_RETRANSMISSION_TYPE     (CA_IPV4 | CA_LE)
-
-/** default retransmission trying count is 4. **/
-#define DEFAULT_RETRANSMISSION_COUNT    4
-
-/** check period is 1 sec. **/
-#define RETRANSMISSION_CHECK_PERIOD_SEC     1
-
-/** retransmission data send method type**/
-typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, const void *pdu,
-                                         uint32_t size);
-
-/** retransmission timeout callback type**/
-typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu,
-                                    uint32_t size);
-
-typedef struct
-{
-    /** retransmission support transport type **/
-    CATransportType_t supportType;
-
-    /** retransmission trying count **/
-    uint8_t tryingCount;
-
-} CARetransmissionConfig_t;
-
-typedef struct
-{
-    /** send method for retransmission data **/
-    CADataSendMethod_t dataSendMethod;
-
-    /** callback function for retransmit timeout **/
-    CATimeoutCallback_t timeoutCallback;
-
-    /** retransmission configure data **/
-    CARetransmissionConfig_t config;
-
-    /** Variable to inform the thread to stop **/
-    bool isStop;
-
-    /** array list on which the thread is operating. **/
-    u_arraylist_t *dataList;
-
-} CARetransmission_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief   Initializes the retransmission context
- * @param   context                   [IN]    context for retransmission
- * @param   retransmissionSendMethod  [IN]    function to be called for retransmission
- * @param   timeoutCallback           [IN]    callback for retransmit timeout
- * @param   config                    [IN]    configuration for retransmission.
- * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
- */
-CAResult_t CARetransmissionInitialize(CARetransmission_t *context,
-                                      CADataSendMethod_t retransmissionSendMethod,
-                                      CATimeoutCallback_t timeoutCallback,
-                                      CARetransmissionConfig_t *config);
-
-/**
- * @brief   Pass the sent pdu data. if retransmission process need, internal thread will wake up
- *          and process the retransmission data.
- * @param   context     [IN]    context for retransmission
- * @param   endpoint    [IN]    endpoint information
- * @param   pdu         [IN]    sent pdu binary data
- * @param   size        [IN]    sent pdu binary data size
- * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
- */
-CAResult_t CARetransmissionSentData(CARetransmission_t *context,
-                                    const CARemoteEndpoint_t *endpoint,
-                                    const void *pdu, uint32_t size);
-
-/**
- * @brief   Paas the received pdu data. if received pdu is ACK data for the retransmission CON data,
- *          the specified CON data will remove on retransmission list.
- * @param   context             [IN]    context for retransmission
- * @param   endpoint            [IN]    endpoint information
- * @param   pdu                 [IN]    received pdu binary data
- * @param   size                [IN]    received pdu binary data size
- * @param   retransmissionPdu   [OUT]   pdu data of the request for reset and ack
- * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
- */
-CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
-                                        const CARemoteEndpoint_t *endpoint, const void *pdu,
-                                        uint32_t size, void **retransmissionPdu);
-
-/**
- * @brief   Stopping the retransmission context
- * @param   context     [IN]    context for retransmission
- * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
- */
-CAResult_t CARetransmissionStop(CARetransmission_t *context);
-
-/**
- * @brief   Terminating the retransmission context
- * @param   context     [IN]    context for retransmission
- * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
- */
-CAResult_t CARetransmissionDestroy(CARetransmission_t *context);
-
-/**
- * @brief   Retransmitting the request/response for CONFIRMABLE type
- */
-void CACheckRetransmissionList();
-
-/**
- * @brief   Invoke Retransmission according to TimedAction Response
- * @param   threadValue [IN]    context for retransmission
- */
-void CARetransmissionBaseRoutine(void *threadValue);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif  /* CA_RETRANSMISSION_SINGLETHREAD_H_ */
-
diff --git a/resource/csdk/connectivity/inc/ifaddrs.h b/resource/csdk/connectivity/inc/ifaddrs.h
new file mode 100644 (file)
index 0000000..ec2f458
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1995, 1999
+ *  Berkeley Software Design, Inc.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
+ *
+ *  BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
+ */
+
+#ifndef _IFADDRS_H_
+#define _IFADDRS_H_
+
+struct ifaddrs {
+    struct ifaddrs  *ifa_next;
+    char        *ifa_name;
+    unsigned int     ifa_flags;
+    struct sockaddr *ifa_addr;
+    struct sockaddr *ifa_netmask;
+    union {
+        struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */
+        struct sockaddr *ifu_dstaddr;   /* Point-to-point destination address */
+    } ifa_ifu;
+    void        *ifa_data;
+};
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+/*
+ * This may have been defined in <net/if.h>.  Note that if <net/if.h> is
+ * to be included it must be included before this header file.
+ */
+#ifndef ifa_broadaddr
+#define ifa_broadaddr   ifa_dstaddr /* broadcast address interface */
+#endif
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int getifaddrs(struct ifaddrs **ifap);
+extern void freeifaddrs(struct ifaddrs *ifa);
+__END_DECLS
+
+#endif
index 167613c..c5f9425 100644 (file)
@@ -69,3 +69,4 @@ libcoap_src = [
 libcoap = libcoap_env.StaticLibrary('libcoap', libcoap_src, OBJPREFIX='libcoap_')
 
 libcoap_env.InstallTarget([libcoap], 'libcoap')
+libcoap_env.UserInstallTargetLib([libcoap], 'libcoap')
index 6d2beb6..71d396a 100644 (file)
 #  define WORDS_BIGENDIAN 1
 # endif
 #else
-# ifndef WORDS_BIGENDIAN
-/* #  undef WORDS_BIGENDIAN */
+# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#  define WORDS_BIGENDIAN 1
 # endif
 #endif
 
index 11e01ca..6bda314 100644 (file)
@@ -239,7 +239,7 @@ int parse_param(unsigned char *search, size_t search_len, unsigned char *data, s
             data_len -= search_len;
 
             /* key is only valid if we are at end of string or delimiter follows */
-            if (!data_len || *data == '=' || *data == '&')
+            if (!data_len || *data == '=' || *data == ';')
             {
                 while (data_len && *data != '=')
                 {
@@ -252,7 +252,7 @@ int parse_param(unsigned char *search, size_t search_len, unsigned char *data, s
                     /* value begins after '=' */
 
                     result->s = ++data;
-                    while (--data_len && *data != '&')
+                    while (--data_len && *data != ';')
                     {
                         ++data;
                         result->length++;
@@ -264,7 +264,7 @@ int parse_param(unsigned char *search, size_t search_len, unsigned char *data, s
         }
 
         /* otherwise proceed to next */
-        while (--data_len && *data++ != '&')
+        while (--data_len && *data++ != ';')
             ;
     }
 
index 5762007..d246654 100644 (file)
@@ -276,7 +276,7 @@ int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data)
     return 1;
 }
 
-int coap_get_data(coap_pdu_t *pdu, size_t *len, unsigned char **data)
+int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data)
 {
     assert(pdu);
     assert(len);
index c469b24..f45831a 100644 (file)
@@ -346,6 +346,6 @@ int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data);
  * or 1 if *len and *data have correct values. Note that these values are
  * destroyed with the pdu.
  */
-int coap_get_data(coap_pdu_t *pdu, size_t *len, unsigned char **data);
+int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data);
 
 #endif /* _PDU_H_ */
index 31ac600..1e8d000 100644 (file)
@@ -21,7 +21,6 @@
 #include "pdu.h"
 #include "option.h"
 #include "uri.h"
-
 /**
  * A length-safe version of strchr(). This function returns a pointer
  * to the first occurrence of @p c  in @p s, or @c NULL if not found.
@@ -398,7 +397,8 @@ int coap_split_path(const unsigned char *s, size_t length, unsigned char *buf, s
     { *buflen, buf }, 0 };
     coap_parse_iterator_t pi;
 
-    coap_parse_iterator_init((unsigned char *) s, length, '/', (unsigned char *) "?#", 2, &pi);
+    coap_parse_iterator_init((unsigned char *) s, length, (unsigned char *)"/",
+                             (unsigned char *) "?#", 2, &pi);
     coap_split_path_impl(&pi, write_option, &tmp);
 
     *buflen = *buflen - tmp.buf.length;
@@ -412,7 +412,8 @@ int coap_split_query(const unsigned char *s, size_t length, unsigned char *buf,
     { *buflen, buf }, 0 };
     coap_parse_iterator_t pi;
 
-    coap_parse_iterator_init((unsigned char *) s, length, '&', (unsigned char *) "#", 1, &pi);
+    coap_parse_iterator_init((unsigned char *) s, length, (unsigned char *)OC_QUERY_SEPARATOR,
+                             (unsigned char *) "#", 1, &pi);
 
     coap_split_path_impl(&pi, write_option, &tmp);
 
@@ -506,7 +507,8 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key)
 
     memset(key, 0, sizeof(coap_key_t));
 
-    coap_parse_iterator_init((unsigned char *) path, len, '/', (unsigned char *) "?#", 2, &pi);
+    coap_parse_iterator_init((unsigned char *) path, len, (unsigned char *)"/",
+                              (unsigned char *) "?#", 2, &pi);
     coap_split_path_impl(&pi, hash_segment, key);
 
     return 1;
@@ -515,7 +517,7 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key)
 /* iterator functions */
 
 coap_parse_iterator_t *
-coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char separator, unsigned char *delim,
+coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char *separator, unsigned char *delim,
         size_t dlen, coap_parse_iterator_t *pi)
 {
     assert(pi);
@@ -534,7 +536,7 @@ coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char separator, un
 unsigned char *
 coap_parse_next(coap_parse_iterator_t *pi)
 {
-    unsigned char *p;
+    unsigned char *p, *s;
 
     if (!pi)
         return NULL;
@@ -543,6 +545,7 @@ coap_parse_next(coap_parse_iterator_t *pi)
     pi->n -= pi->segment_length;
     pi->pos += pi->segment_length;
     pi->segment_length = 0;
+    s = pi->separator;
 
     /* last segment? */
     if (!pi->n || strnchr(pi->delim, pi->dlen, *pi->pos))
@@ -552,26 +555,27 @@ coap_parse_next(coap_parse_iterator_t *pi)
     }
 
     /* skip following separator (the first segment might not have one) */
-    if (*pi->pos == pi->separator)
-    {
-        ++pi->pos;
-        --pi->n;
-    }
 
-    p = pi->pos;
+      if (strchr(s,*(pi->pos)))
+      {
+          ++pi->pos;
+          --pi->n;
+      }
 
-    while (pi->segment_length < pi->n && *p != pi->separator && !strnchr(pi->delim, pi->dlen, *p))
-    {
-        ++p;
-        ++pi->segment_length;
-    }
+      p = pi->pos;
+
+      while ((pi->segment_length < pi->n) && (!strchr(s,*p))
+              && (!strnchr(pi->delim, pi->dlen, *p)))
+      {
+          ++p;
+          ++pi->segment_length;
+      }
 
     if (!pi->n)
     {
         pi->pos = NULL;
         pi->segment_length = 0;
     }
-
     return pi->pos;
 }
 
index 820a045..24e23a4 100644 (file)
 
 #include "hashkey.h"
 #include "str.h"
+#include <stdbool.h>
+
+///Separtor for multiple query string
+#define OC_QUERY_SEPARATOR                "&;"
 
 /** Representation of parsed URI. Components may be filled from a
  * string with coap_split_uri() and can be used as input for
@@ -69,7 +73,7 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key);
  * @code
  * unsigned char *token;
  * coap_parse_iterator_t pi;
- * coap_parse_iterator_init(uri.path.s, uri.path.length, '/', "?#", 2, &pi);
+ * coap_parse_iterator_init(uri.path.s, uri.path.length, "/", "?#", 2, &pi);
  *
  * while ((token = coap_parse_next(&pi))) {
  *   ... do something with token ...
@@ -79,7 +83,7 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key);
 typedef struct
 {
     size_t n; /**< number of remaining characters in buffer */
-    unsigned char separator; /**< segment separators */
+    unsigned char *separator; /**< segment separators */
     unsigned char *delim; /**< delimiters where to split the string */
     size_t dlen; /**< length of separator */
     unsigned char *pos; /**< current position in buffer */
@@ -99,7 +103,7 @@ typedef struct
  * @return The initialized iterator object @p pi.
  */
 coap_parse_iterator_t *
-coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char separator, unsigned char *delim,
+coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char *separator, unsigned char *delim,
         size_t dlen, coap_parse_iterator_t *pi);
 
 /**
@@ -167,5 +171,4 @@ int coap_split_path(const unsigned char *s, size_t length, unsigned char *buf, s
 int coap_split_query(const unsigned char *s, size_t length, unsigned char *buf, size_t *buflen);
 
 /** @} */
-
 #endif /* _COAP_URI_H_ */
index e3a4f18..373a3e7 100644 (file)
@@ -47,5 +47,6 @@ if secured == '1':
 \r
 libRMInterface = app_env.SharedLibrary('RMInterface', sample_src, OBJPREFIX='libRMInterface_')\r
 app_env.InstallTarget(libRMInterface, 'RMInterface')\r
+app_env.UserInstallTargetLib(libRMInterface, 'RMInterface')\r
 \r
 \r
index 91fcef9..4ffc3e2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.iotivity.sample_service"
+    package="org.iotivity.ca.sample_service"
     android:versionCode="1"
     android:versionName="1.0" >
 
@@ -13,7 +13,7 @@
         android:label="@string/app_name"
         android:theme="@style/AppTheme" >
         <activity
-            android:name="org.iotivity.service.MainActivity"
+            android:name="org.iotivity.ca.service.MainActivity"
             android:label="@string/app_name"
             android:windowSoftInputMode="stateHidden" >
             <intent-filter>
index 55ac16d..6d51eff 100644 (file)
@@ -4,17 +4,12 @@ PROJECT_ROOT_PATH     = ../../..
 
 include $(CLEAR_VARS)
 LOCAL_PATH := $(APP_PATH)
-LOCAL_MODULE := CAInterface
-LOCAL_STATIC_LIBRARIES = CA
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_PATH := $(APP_PATH)
 LOCAL_MODULE := RMInterface
 LOCAL_SRC_FILES := ResourceModel.c
+LOCAL_CFLAGS = -D__WITH_DTLS__
+LOCAL_C_INCLUDES = $(PROJECT_ROOT_PATH)/api $(PROJECT_ROOT_PATH)/external/inc
 LOCAL_STATIC_LIBRARIES := CA
 LOCAL_LDLIBS := -llog
-LOCAL_C_INCLUDES := ../../../api
 include $(BUILD_SHARED_LIBRARY)
 
 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index acca05d..21ba6b9 100644 (file)
@@ -8,7 +8,7 @@
 #include "cainterface.h"
 #include "cacommon.h"
 
-#include "org_iotivity_service_RMInterface.h"
+#include "org_iotivity_ca_service_RMInterface.h"
 
 #define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
 #define OPTION_INFO_LENGTH 1024
 #define NETWORK_INFO_LENGTH 1024
 
-uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
+typedef struct
+{
+    char ipAddress[CA_IPADDR_SIZE];
+    uint16_t port;
+} addressSet_t;
 
-void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
-void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
+void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length);
 uint32_t get_secure_information(CAPayload_t payLoad);
 CAResult_t get_network_type(uint32_t selectedNetwork);
 void callback(char *subject, char *receivedData);
-CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo);
+CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address);
+void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
 
-CATransportType_t g_selectedNwType = CA_IPV4;
+uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
+CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
 static CAToken_t g_lastRequestToken = NULL;
-static uint8_t g_lastRequestTokenLength;
+static uint8_t g_lastRequestTokenLength = 0;
 
-static const char SECURE_COAPS_PREFIX[] = "coaps://";
+static const char COAP_PREFIX[] =  "coap://";
+static const char COAPS_PREFIX[] = "coaps://";
+static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
+static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
 
 static const char SECURE_INFO_DATA[]
                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
-                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
+                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
+                                     "%d}}]}";
 static const char NORMAL_INFO_DATA[]
                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
 
-
 static jobject g_responseListenerObject = NULL;
 static JavaVM *g_jvm;
 
-static CARemoteEndpoint_t *g_clientEndpoint = NULL;
-static CAToken_t g_clientToken;
-static uint8_t g_clientTokenLength = NULL;
+static CAEndpoint_t *g_clientEndpoint = NULL;
+static char *g_resourceUri = NULL;
+static CAToken_t g_clientToken = NULL;
+static uint8_t g_clientTokenLength = 0;
 
-static uint16_t g_clientMsgId;
+static uint16_t g_clientMsgId = 0;
 static char *g_remoteAddress = NULL;
 
 // init
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
-                                                                jobject listener)
+Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
+                                                                   jobject listener)
 {
     LOGI("setNativeResponseListener");
     g_responseListenerObject = (*env)->NewGlobalRef(env, obj);
@@ -180,7 +191,7 @@ void JNI_OnUnload(JavaVM *jvm, void *reserved)
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
+Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
 {
     LOGI("RMInitialize");
 
@@ -211,7 +222,7 @@ Java_org_iotivity_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, job
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
 {
     LOGI("RMTerminate");
     CADestroyToken(g_lastRequestToken);
@@ -219,7 +230,7 @@ Java_org_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
 {
     LOGI("RMStartListeningServer");
 
@@ -230,7 +241,7 @@ Java_org_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobjec
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
 {
     LOGI("RMStartDiscoveryServer");
 
@@ -241,56 +252,17 @@ Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobjec
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
 {
     LOGI("RMRegisterHandler");
 
-    CARegisterHandler(request_handler, response_handler);
-}
-
-JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj, jstring uri)
-{
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        LOGE("token generate error!!");
-        return;
-    }
-
-    printf("Generated token %s\n", token);
-
-    const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
-    LOGI("RMFindResource - %s", strUri);
-
-    res = CAFindResource((const CAURI_t) strUri, token, tokenLength);
-
-    //ReleseStringUTFCharss for strUri
-    (*env)->ReleaseStringUTFChars(env, uri, strUri);
-
-    if (CA_STATUS_OK != res)
-    {
-        LOGE("Could not find resource");
-        //destroy token
-        CADestroyToken(token);
-    }
-    else
-    {
-        LOGI("find resource to %s URI", strUri);
-        CADestroyToken(g_lastRequestToken);
-        g_lastRequestToken = token;
-        g_lastRequestTokenLength = tokenLength;
-    }
+    CARegisterHandler(request_handler, response_handler, error_handler);
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
-                                                    jstring payload, jint selectedNetwork,
-                                                    jint isSecured, jint msgType)
+Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
+                                                       jstring payload, jint selectedNetwork,
+                                                       jint isSecured, jint msgType)
 {
     LOGI("selectedNetwork - %d", selectedNetwork);
     CAResult_t res = get_network_type(selectedNetwork);
@@ -302,16 +274,18 @@ Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, js
     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
     LOGI("RMSendRequest - %s", strUri);
 
-    //create remote endpoint
-    CARemoteEndpoint_t* endpoint = NULL;
-    res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint);
-
-    //ReleaseStringUTFChars for strUri
-    (*env)->ReleaseStringUTFChars(env, uri, strUri);
+    CATransportFlags_t flags;
+    addressSet_t address = {};
+    parsing_coap_uri(strUri, &address, &flags);
 
+    //create remote endpoint
+    CAEndpoint_t* endpoint = NULL;
+    res = CACreateEndpoint(flags, g_selectedNwType, (const char*)address.ipAddress,
+                           address.port, &endpoint);
     if (CA_STATUS_OK != res)
     {
         LOGE("Could not create remote end point");
+        (*env)->ReleaseStringUTFChars(env, uri, strUri);
         return;
     }
 
@@ -326,13 +300,15 @@ Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, js
     {
         LOGE("token generate error!!");
         // destroy remote endpoint
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
+        (*env)->ReleaseStringUTFChars(env, uri, strUri);
         return;
     }
 
     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
 
     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
+    (*env)->ReleaseStringUTFChars(env, uri, strUri);
 
     CAInfo_t requestData = { 0 };
     requestData.token = token;
@@ -348,10 +324,11 @@ Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, js
             // destroy token
             CADestroyToken(token);
             // destroy remote endpoint
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             return;
         }
         snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
+        requestData.payloadSize = length;
     }
     else
     {
@@ -363,16 +340,30 @@ Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, js
             // destroy token
             CADestroyToken(token);
             // destroy remote endpoint
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             return;
         }
         snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
+        requestData.payloadSize = length;
     }
 
     requestData.type = messageType;
+    requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
+    if (NULL == requestData.resourceUri)
+    {
+        LOGE("Memory allocation failed!");
+        // destroy token
+        CADestroyToken(token);
+        // destroy remote endpoint
+        CADestroyEndpoint(endpoint);
+        free(requestData.payload);
+        return;
+    }
+    memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
 
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
+    requestInfo.isMulticast = false;
     requestInfo.info = requestData;
 
     // send request
@@ -385,14 +376,15 @@ Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, js
     CADestroyToken(token);
 
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
 
     free(requestData.payload);
+    free(requestData.resourceUri);
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
-                                                        jint selectedNetwork)
+Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
+                                                           jint selectedNetwork)
 {
     LOGI("selectedNetwork - %d", selectedNetwork);
     CAResult_t res = get_network_type(selectedNetwork);
@@ -401,15 +393,9 @@ Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj
         return;
     }
 
-    const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
-    LOGI("RMSendReqestToAll - %s", strUri);
-
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint);
-
-    //ReleaseStringUTFChars for strUri
-    (*env)->ReleaseStringUTFChars(env, uri, strUri);
+    CAEndpoint_t *endpoint = NULL;
+    res = CACreateEndpoint(CA_DEFAULT_FLAGS, g_selectedNwType, NULL, 0, &endpoint);
 
     if (CA_STATUS_OK != res)
     {
@@ -417,16 +403,6 @@ Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj
         return;
     }
 
-    CAGroupEndpoint_t *group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t));
-    if (NULL == group)
-    {
-        LOGE("Memory allocation failed!");
-        CADestroyRemoteEndpoint(endpoint);
-        return;
-    }
-    group->transportType = endpoint->transportType;
-    group->resourceUri = endpoint->resourceUri;
-
     // create token
     CAToken_t token = NULL;
     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
@@ -436,8 +412,7 @@ Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj
     {
         LOGE("token generate error!!");
         // destroy remote endpoint
-        CADestroyRemoteEndpoint(endpoint);
-        free(group);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -446,15 +421,45 @@ Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj
     CAInfo_t requestData = { 0 };
     requestData.token = token;
     requestData.tokenLength = tokenLength;
-    requestData.payload = "Temp Json Payload";
+    requestData.payload = (CAPayload_t) "TempJsonPayload";
+    requestData.payloadSize = strlen((const char *) requestData.payload);
     requestData.type = CA_MSG_NONCONFIRM;
 
+    const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
+    LOGI("resourceUri - %s", strUri);
+    requestData.resourceUri = (CAURI_t)strUri;
+
+    uint8_t optionNum = 2;
+    CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
+                                                             sizeof(CAHeaderOption_t) * optionNum);
+    if (NULL == headerOpt)
+    {
+        LOGE("Memory allocation failed");
+        // destroy remote endpoint
+        CADestroyEndpoint(endpoint);
+        return;
+    }
+
+    char* FirstOptionData = "Hello";
+    headerOpt[0].optionID = 3000;
+    memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
+    headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
+
+    char* SecondOptionData2 = "World";
+    headerOpt[1].optionID = 3001;
+    memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
+    headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
+
+    requestData.numOptions = optionNum;
+    requestData.options = headerOpt;
+
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
+    requestInfo.isMulticast = true;
     requestInfo.info = requestData;
 
     // send request to all
-    res = CASendRequestToAll(group, &requestInfo);
+    res = CASendRequest(endpoint, &requestInfo);
     if (CA_STATUS_OK != res)
     {
         LOGE("Could not send request to all");
@@ -468,17 +473,20 @@ Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj
         g_lastRequestTokenLength = tokenLength;
     }
 
-    // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
-    free(group);
+    //ReleaseStringUTFChars for strUri
+    (*env)->ReleaseStringUTFChars(env, uri, strUri);
+
+    free(headerOpt);
 
+    // destroy remote endpoint
+    CADestroyEndpoint(endpoint);
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
-                                                     jint selectedNetwork,
-                                                     jint isSecured, jint msgType,
-                                                     jint responseValue)
+Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
+                                                        jint selectedNetwork,
+                                                        jint isSecured, jint msgType,
+                                                        jint responseValue)
 {
     LOGI("RMSendResponse");
 
@@ -502,6 +510,7 @@ Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
     CAInfo_t responseData = { 0 };
     responseData.type = messageType;
     responseData.messageId = g_clientMsgId;
+    responseData.resourceUri = (CAURI_t)g_resourceUri;
 
     CAResponseInfo_t responseInfo = { 0 };
 
@@ -513,16 +522,18 @@ Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
 
         if (1 == isSecured)
         {
-            uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1;
+            uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
             responseData.payload = (CAPayload_t) malloc(length);
-            sprintf(responseData.payload, SECURE_INFO_DATA, g_clientEndpoint->resourceUri,
+            sprintf(responseData.payload, SECURE_INFO_DATA, g_resourceUri,
                     g_localSecurePort);
+            responseData.payloadSize = length;
         }
         else
         {
-            uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1;
+            uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
             responseData.payload = (CAPayload_t) malloc(length);
-            sprintf(responseData.payload, NORMAL_INFO_DATA, g_clientEndpoint->resourceUri);
+            sprintf(responseData.payload, NORMAL_INFO_DATA, g_resourceUri);
+            responseData.payloadSize = length;
         }
     }
     //msgType is RESET
@@ -546,74 +557,15 @@ Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
     g_clientTokenLength = 0;
 
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(g_clientEndpoint);
+    CADestroyEndpoint(g_clientEndpoint);
     g_clientEndpoint = NULL;
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMAdvertiseResource(JNIEnv *env, jobject obj, jstring uri)
-{
-    LOGI("RMAdvertiseResource");
-
-    uint32_t optionNum = 2;
-
-    CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
-                                                             sizeof(CAHeaderOption_t) * optionNum);
-    if (NULL == headerOpt)
-    {
-        LOGE("Memory allocation failed!");
-        return;
-    }
-
-    char* tmpOptionData1 = "Hello";
-    headerOpt[0].optionID = 3000;
-    memcpy(headerOpt[0].optionData, tmpOptionData1, strlen(tmpOptionData1));
-    headerOpt[0].optionLength = (uint16_t) strlen(tmpOptionData1);
-
-    char* tmpOptionData2 = "World";
-    headerOpt[1].optionID = 3001;
-    memcpy(headerOpt[1].optionData, tmpOptionData2, strlen(tmpOptionData2));
-    headerOpt[1].optionLength = (uint16_t) strlen(tmpOptionData2);
-
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        LOGE("token generate error!");
-        free(headerOpt);
-        return;
-    }
-
-    const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
-
-    res = CAAdvertiseResource((const CAURI_t) strUri, token, tokenLength,
-                              headerOpt, (uint8_t) optionNum);
-    if (CA_STATUS_OK != res)
-    {
-        LOGE("Could not start advertise resource");
-        CADestroyToken(token);
-    }
-    else
-    {
-        CADestroyToken(g_lastRequestToken);
-        g_lastRequestToken = token;
-        g_lastRequestTokenLength = tokenLength;
-    }
-
-    free(headerOpt);
-
-    //ReleaseStringUTFChars for strUri
-    (*env)->ReleaseStringUTFChars(env, uri, strUri);
-}
-
-JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
-                                                         jstring payload, jint selectedNetwork,
-                                                         jint isSecured, jint msgType,
-                                                         jint responseValue)
+Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
+                                                            jstring payload, jint selectedNetwork,
+                                                            jint isSecured, jint msgType,
+                                                            jint responseValue)
 {
     LOGI("selectedNetwork - %d", selectedNetwork);
 
@@ -627,10 +579,15 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
     LOGI("RMSendNotification - %s", strUri);
 
+    CATransportFlags_t flags;
+    addressSet_t address = {};
+    parsing_coap_uri(strUri, &address, &flags);
+
     //create remote endpoint
-    CARemoteEndpoint_t* endpoint = NULL;
-    if (CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t) strUri,
-                                               g_selectedNwType, &endpoint))
+    CAEndpoint_t* endpoint = NULL;
+    if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
+                                         (const char*)address.ipAddress,
+                                         address.port, &endpoint))
     {
         //ReleaseStringUTFChars for strUri
         (*env)->ReleaseStringUTFChars(env, uri, strUri);
@@ -639,7 +596,7 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
     }
 
     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
-    get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
+    get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
 
     //ReleaseStringUTFChars for strUri
     (*env)->ReleaseStringUTFChars(env, uri, strUri);
@@ -654,13 +611,24 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
     if ((CA_STATUS_OK != res) || (!token))
     {
         LOGE("token generate error!");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
     CAInfo_t responseData = { 0 };
     responseData.token = token;
     responseData.tokenLength = tokenLength;
+    responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
+    if (NULL == responseData.resourceUri)
+    {
+        LOGE("Memory allocation failed!");
+        // destroy token
+        CADestroyToken(token);
+        // destroy remote endpoint
+        CADestroyEndpoint(endpoint);
+        return;
+    }
+    memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI));
 
     if (1 == isSecured)
     {
@@ -672,7 +640,9 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
             // destroy token
             CADestroyToken(token);
             // destroy remote endpoint
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
+
+            free(responseData.resourceUri);
             return;
         }
         snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
@@ -687,7 +657,9 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
             // destroy token
             CADestroyToken(token);
             // destroy remote endpoint
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
+
+            free(responseData.resourceUri);
             return;
         }
         snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
@@ -711,13 +683,15 @@ Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject ob
     CADestroyToken(token);
 
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
 
     free(responseData.payload);
+    free(responseData.resourceUri);
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj, jint networkType)
+Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
+                                                         jint networkType)
 {
     LOGI("RMSelectNetwork Type : %d", networkType);
 
@@ -728,7 +702,8 @@ Java_org_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj, jint networkType)
+Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
+                                                           jint networkType)
 {
     LOGI("RMUnSelectNetwork Type : %d", networkType);
 
@@ -739,18 +714,18 @@ Java_org_iotivity_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
 {
     LOGI("RMGetNetworkInfomation");
 
-    CALocalConnectivity_t *tempInfo = NULL;
+    CAEndpoint_t *tempInfo = NULL;
     uint32_t tempSize = 0;
 
     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
     if (CA_STATUS_OK != res)
     {
         LOGE("Could not start get network information");
-        OICFree(tempInfo);
+        free(tempInfo);
         return;
     }
 
@@ -761,43 +736,43 @@ Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobjec
     uint32_t index;
     for (index = 0; index < tempSize; index++)
     {
-        res = get_remote_address(tempInfo[index].type, tempInfo[index].addressInfo);
+        res = get_remote_address(tempInfo[index].adapter, tempInfo[index].addr);
         if (CA_STATUS_OK != res)
         {
-            OICFree(tempInfo);
+            free(tempInfo);
             return;
         }
         if (NULL != g_responseListenerObject)
         {
             char networkInfo[NETWORK_INFO_LENGTH];
-            LOGI("Type: %d", tempInfo[index].type);
-            sprintf(networkInfo, "%d",tempInfo[index].type);
+            LOGI("Type: %d", tempInfo[index].adapter);
+            sprintf(networkInfo, "%d",tempInfo[index].adapter);
             callback("Type :", networkInfo);
-            if (CA_IPV4 == tempInfo[index].type)
+            if (CA_ADAPTER_IP == tempInfo[index].adapter)
             {
-                LOGI("Port: %d", tempInfo[index].addressInfo.IP.port);
-                sprintf(networkInfo, "%d",tempInfo[index].addressInfo.IP.port);
+                LOGI("Port: %d", tempInfo[index].port);
+                sprintf(networkInfo, "%d",tempInfo[index].port);
                 callback("Port: ", networkInfo);
             }
-            LOGI("Secured: %d", tempInfo[index].isSecured);
+            LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
             LOGI("Address: %s", g_remoteAddress);
             callback("Address: ", g_remoteAddress);
             free(g_remoteAddress);
         }
-        if (true == tempInfo[index].isSecured)
+        if (tempInfo[index].flags & CA_SECURE)
         {
-            g_localSecurePort = tempInfo[index].addressInfo.IP.port;
+            g_localSecurePort = tempInfo[index].port;
         }
     }
 
     // free
-    OICFree(tempInfo);
+    free(tempInfo);
 
     LOGI("##############################################################");
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
+Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
 {
     LOGI("RMHandleRequestResponse");
 
@@ -807,7 +782,7 @@ Java_org_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobje
     }
 }
 
-void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
+void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
 {
 
     if (!object)
@@ -830,18 +805,15 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
         return;
     }
 
-    CAResult_t res = get_remote_address(object->transportType, object->addressInfo);
+    CAResult_t res = get_remote_address(object->adapter, object->addr);
     if (CA_STATUS_OK != res)
     {
         return;
     }
 
     LOGI("##########received request from remote device #############");
-    if (object->resourceUri)
-    {
-        LOGI("Uri: %s", object->resourceUri);
-    }
     LOGI("Remote Address: %s", g_remoteAddress);
+    LOGI("Uri: %s", requestInfo->info.resourceUri);
     LOGI("Data: %s", requestInfo->info.payload);
     LOGI("Token: %s", requestInfo->info.token);
     LOGI("Code: %d", requestInfo->method);
@@ -853,10 +825,10 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
         char *cloneUri = NULL;
         uint32_t len = 0;
 
-        if (NULL != object->resourceUri)
+        if (NULL != requestInfo->info.resourceUri)
         {
-            len = strlen(object->resourceUri);
-            cloneUri = (char *) malloc(sizeof(char) * (len + 1));
+            len = strlen(requestInfo->info.resourceUri);
+            cloneUri = (char *)malloc(sizeof(char) * (len + 1));
 
             if (NULL == cloneUri)
             {
@@ -865,7 +837,7 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
                 return;
             }
 
-            memcpy(cloneUri, object->resourceUri, len + 1);
+            memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
             callback("Uri: ", cloneUri);
         }
 
@@ -887,27 +859,27 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
         free(g_remoteAddress);
 
         //clone g_clientEndpoint
-        g_clientEndpoint = (CARemoteEndpoint_t *) malloc(sizeof(CARemoteEndpoint_t));
+        g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
         if (NULL == g_clientEndpoint)
         {
             LOGE("g_clientEndpoint Out of memory");
             free(cloneUri);
             return;
         }
-        memcpy(g_clientEndpoint, object, sizeof(CARemoteEndpoint_t));
+        memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
 
         if (NULL != cloneUri)
         {
             len = strlen(cloneUri);
-            g_clientEndpoint->resourceUri = (char *) malloc(sizeof(char) * (len + 1));
-            if (NULL == g_clientEndpoint)
+            g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
+            if (NULL == g_resourceUri)
             {
                 LOGE("g_clientEndpoint->resourceUri Out of memory");
                 free(g_clientEndpoint);
                 free(cloneUri);
                 return;
             }
-            memcpy(g_clientEndpoint->resourceUri, cloneUri, len + 1);
+            memcpy(g_resourceUri, cloneUri, len + 1);
             free(cloneUri);
         }
         //clone g_clientToken
@@ -917,7 +889,6 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
         if (NULL == g_clientToken)
         {
             LOGE("g_clientToken Out of memory");
-            free(g_clientEndpoint->resourceUri);
             free(g_clientEndpoint);
             return;
         }
@@ -940,7 +911,6 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
             if (NULL == clonePayload)
             {
                 LOGE("clonePayload Out of memory");
-                free(g_clientEndpoint->resourceUri);
                 free(g_clientEndpoint);
                 return;
             }
@@ -975,12 +945,11 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
 
                 callback("Option info: ", optionInfo);
 
-                uint32_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
+                size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
                 if (NULL == cloneOptionData)
                 {
                     LOGE("cloneOptionData Out of memory");
-                    free(g_clientEndpoint->resourceUri);
                     free(g_clientEndpoint);
                     return;
                 }
@@ -996,56 +965,36 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re
     LOGI("############################################################");
 
     //Check if this has secure communication information
-    if (requestInfo->info.payload && CA_IPV4 == object->transportType)
+    if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
     {
         uint32_t securePort = get_secure_information(requestInfo->info.payload);
         if (0 < securePort) //Set the remote endpoint secure details and send response
         {
             LOGI("This is secure resource...");
-            char *uri = NULL;
-            uint32_t length = 0;
-
-            length = sizeof(SECURE_COAPS_PREFIX) - 1; //length of "coaps://"
-            // length of "ipaddress:port"
-            length += strlen(object->addressInfo.IP.ipAddress) + PORT_LENGTH;
-            length += strlen(object->resourceUri) + 1;
-
-            uri = calloc(1, sizeof(char) * length);
-            if (!uri)
-            {
-                LOGE("Failed to create new uri");
-                free(uri);
-                return;
-            }
-            sprintf(uri, "%s%s:%d/%s", SECURE_COAPS_PREFIX, object->addressInfo.IP.ipAddress,
-                    securePort, object->resourceUri);
 
-            CARemoteEndpoint_t *endpoint = NULL;
-            if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->transportType, &endpoint))
+            CAEndpoint_t *endpoint = NULL;
+            if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
+                        object->adapter, object->addr, securePort, &endpoint))
             {
                 LOGE("Failed to create duplicate of remote endpoint!");
-                free(uri);
                 return;
             }
-            endpoint->isSecured = true;
             object = endpoint;
-
-            free(uri);
         }
     }
 }
 
-void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
+void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
 {
 
-    CAResult_t res = get_remote_address(object->transportType, object->addressInfo);
+    CAResult_t res = get_remote_address(object->adapter, object->addr);
     if (CA_STATUS_OK != res)
     {
         return;
     }
 
     LOGI("##########Received response from remote device #############");
-    LOGI("Uri: %s", object->resourceUri);
+    LOGI("Uri: %s", responseInfo->info.resourceUri);
     LOGI("Remote Address: %s", g_remoteAddress);
     LOGI("response result: %d", responseInfo->result);
     LOGI("Data: %s", responseInfo->info.payload);
@@ -1056,9 +1005,9 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
     {
         uint32_t len = 0;
 
-        if (NULL != object->resourceUri)
+        if (NULL != responseInfo->info.resourceUri)
         {
-            len = strlen(object->resourceUri);
+            len = strlen(responseInfo->info.resourceUri);
             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
 
             if (NULL == cloneUri)
@@ -1068,7 +1017,7 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
                 return;
             }
 
-            memcpy(cloneUri, object->resourceUri, len + 1);
+            memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
 
             callback("Uri: ", cloneUri);
             free(cloneUri);
@@ -1128,7 +1077,7 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
 
                 callback("Option info: ", optionInfo);
 
-                uint32_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
+                size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
                 if (NULL == cloneOptionData)
                 {
@@ -1145,7 +1094,7 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
     LOGI("############################################################");
 
     //Check if this has secure communication information
-    if (responseInfo->info.payload && CA_IPV4 == object->transportType)
+    if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
     {
         uint32_t securePort = get_secure_information(responseInfo->info.payload);
         if (0 < securePort) //Set the remote endpoint secure details and send response
@@ -1155,11 +1104,52 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
     }
 }
 
+void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        LOGI("Error Handler, ErrorInfo :");
+        LOGI("Error Handler result    : %d", errorInfo->result);
+        LOGI("Error Handler token     : %s", info->token);
+        LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
+        LOGI("Error Handler resourceUri : %s", info->resourceUri);
+        LOGI("Error Handler type      : %d", info->type);
+        LOGI("Error Handler payload   : %s", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
+        }
+    }
+    LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
+
+    return;
+}
+
 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length)
 {
     const char *startPos = URI;
-    const char *temp = NULL;
-    if (NULL != (temp = strstr(URI, "://")))
+    const char *temp = strstr(URI, "://");
+    if (NULL != temp)
     {
         startPos = strchr(temp + 3, '/');
         if (!startPos)
@@ -1237,19 +1227,19 @@ CAResult_t get_network_type(uint32_t selectedNetwork)
     {
         return CA_NOT_SUPPORTED;
     }
-    if (number & CA_IPV4)
+    if (number & CA_ADAPTER_IP)
     {
-        g_selectedNwType = CA_IPV4;
+        g_selectedNwType = CA_ADAPTER_IP;
         return CA_STATUS_OK;
     }
-    if (number & CA_EDR)
+    if (number & CA_ADAPTER_RFCOMM_BTEDR)
     {
-        g_selectedNwType = CA_EDR;
+        g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
         return CA_STATUS_OK;
     }
-    if (number & CA_LE)
+    if (number & CA_ADAPTER_GATT_BTLE)
     {
-        g_selectedNwType = CA_LE;
+        g_selectedNwType = CA_ADAPTER_GATT_BTLE;
         return CA_STATUS_OK;
     }
 
@@ -1272,51 +1262,149 @@ void callback(char *subject, char *receivedData)
 
 }
 
-CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo)
+CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address)
 {
+    uint32_t len = strlen(address);
 
-    uint32_t len = 0;
-    if (CA_IPV4 == transportType)
+    g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
+    if (NULL == g_remoteAddress)
     {
-        len = strlen(addressInfo.IP.ipAddress);
-        g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
+        LOGE("g_remoteAddress Out of memory");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    memcpy(g_remoteAddress, address, len + 1);
+
+    return CA_STATUS_OK;
+}
+
+
+void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
+{
+    if (NULL == uri || NULL == address)
+    {
+        LOGE("parameter is null");
+        return;
+    }
+
+    // parse uri
+    // #1. check prefix
+    uint8_t startIndex = 0;
+    if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
+    {
+        LOGI("uri has '%s' prefix", COAPS_PREFIX);
+        startIndex = COAPS_PREFIX_LEN;
+        *flags = CA_SECURE;
+    }
+    else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
+    {
+        LOGI("uri has '%s' prefix", COAP_PREFIX);
+        startIndex = COAP_PREFIX_LEN;
+        *flags = CA_DEFAULT_FLAGS;
+    }
+
+    // #2. copy uri for parse
+    int32_t len = strlen(uri) - startIndex;
+
+    if (len <= 0)
+    {
+        LOGE("uri length is 0!");
+        return;
+    }
+
+    char *cloneUri = (char *) calloc(len + 1, sizeof(char));
+    if (NULL == cloneUri)
+    {
+        LOGE("Out of memory");
+        return;
+    }
+
+    memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
+    cloneUri[len] = '\0';
 
-        if (NULL == g_remoteAddress)
+    char *pAddress = cloneUri;
+    char *pResourceUri = NULL;
+
+    int32_t i = 0;
+    for (i = 0; i < len; i++)
+    {
+        if (cloneUri[i] == '/')
         {
-            LOGE("g_remoteAddress Out of memory");
-            return CA_MEMORY_ALLOC_FAILED;
+            // separate
+            cloneUri[i] = 0;
+            pResourceUri = &cloneUri[i + 1];
+            break;
         }
+    }
+    LOGI("pAddress : %s", pAddress);
 
-        memcpy(g_remoteAddress, addressInfo.IP.ipAddress, len + 1);
+    int res = get_address_set(pAddress, address);
+    if (res == -1)
+    {
+        LOGE("address parse error");
+
+        free(cloneUri);
+        return;
     }
+    return;
+}
 
-    else if (CA_EDR == transportType)
+int get_address_set(const char *pAddress, addressSet_t* outAddress)
+{
+    if (NULL == pAddress || NULL == outAddress)
     {
-        len = strlen(addressInfo.BT.btMacAddress);
-        g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
+        LOGE("parameter is null");
+        return -1;
+    }
 
-        if (NULL == g_remoteAddress)
+    int32_t len = strlen(pAddress);
+    int32_t isIp = 0;
+    int32_t ipLen = 0;
+
+    int32_t i = 0;
+    for (i = 0; i < len; i++)
+    {
+        if (pAddress[i] == '.')
         {
-            LOGE("g_remoteAddress Out of memory");
-            return CA_MEMORY_ALLOC_FAILED;
+            isIp = 1;
         }
 
-        memcpy(g_remoteAddress, addressInfo.BT.btMacAddress, len + 1);
+        // found port number start index
+        if (isIp && pAddress[i] == ':')
+        {
+            ipLen = i;
+            break;
+        }
     }
 
-    else if (CA_LE == transportType)
+    if (isIp)
     {
-        len = strlen(addressInfo.LE.leMacAddress);
-        g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
-
-        if (NULL == g_remoteAddress)
+        if(ipLen && ipLen < sizeof(outAddress->ipAddress))
+        {
+            strncpy(outAddress->ipAddress, pAddress, ipLen);
+            outAddress->ipAddress[ipLen] = '\0';
+        }
+        else if (!ipLen && len < sizeof(outAddress->ipAddress))
+        {
+            strncpy(outAddress->ipAddress, pAddress, len);
+            outAddress->ipAddress[len] = '\0';
+        }
+        else
         {
-            LOGE("g_remoteAddress Out of memory");
-            return CA_MEMORY_ALLOC_FAILED;
+            LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
+            return -1;
         }
 
-        memcpy(g_remoteAddress, addressInfo.LE.leMacAddress, len + 1);
+        if (ipLen > 0)
+        {
+            outAddress->port = atoi(pAddress + ipLen + 1);
+        }
+    }
+    else
+    {
+        strncpy(outAddress->ipAddress, pAddress, len);
+        outAddress->ipAddress[len] = '\0';
     }
 
-    return CA_STATUS_OK;
+    return isIp;
 }
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_ca_service_RMInterface.h b/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_ca_service_RMInterface.h
new file mode 100644 (file)
index 0000000..6f60059
--- /dev/null
@@ -0,0 +1,118 @@
+#include <jni.h>
+/* Header for class org_iotivity_ca_service_RMInterface */
+
+#ifndef _Included_org_iotivity_ca_service_RMInterface
+#define _Included_org_iotivity_ca_service_RMInterface
+#ifdef __cplusplus
+extern "C" {
+#endif
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener
+  (JNIEnv *, jobject, jobject);
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMInitialize
+ * Signature: (Landroid/content/Context;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMInitialize
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMTerminate
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMTerminate
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMStartListeningServer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMStartDiscoveryServer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMRegisterHandler
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMSendRequest
+ * Signature: (Ljava/lang/String;Ljava/lang/String;III)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendRequest
+  (JNIEnv *, jobject, jstring, jstring, jint, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMSendReqestToAll
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll
+  (JNIEnv *, jobject, jstring, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMSendResponse
+ * Signature: (IIII)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendResponse
+  (JNIEnv *, jobject, jint, jint, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMSendNotification
+ * Signature: (Ljava/lang/String;Ljava/lang/String;IIII)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendNotification
+  (JNIEnv *, jobject, jstring, jstring, jint, jint, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMSelectNetwork
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMUnSelectNetwork
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMGetNetworkInfomation
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     org_iotivity_ca_service_RMInterface
+ * Method:    RMHandleRequestResponse
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h b/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h
deleted file mode 100644 (file)
index 8c6b61f..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <jni.h>
-/* Header for class org_iotivity_service_RMInterface */
-
-#ifndef _Included_org_iotivity_service_RMInterface
-#define _Included_org_iotivity_service_RMInterface
-#ifdef __cplusplus
-extern "C" {
-#endif
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_setNativeResponseListener
-  (JNIEnv *, jobject, jobject);
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMInitialize
- * Signature: (Landroid/content/Context;)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMInitialize
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMTerminate
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMTerminate
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMStartListeningServer
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMStartListeningServer
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMStartDiscoveryServer
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMRegisterHandler
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMRegisterHandler
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMFindResource
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMFindResource
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMSendRequest
- * Signature: (Ljava/lang/String;Ljava/lang/String;III)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendRequest
-  (JNIEnv *, jobject, jstring, jstring, jint, jint, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMSendReqestToAll
- * Signature: (Ljava/lang/String;I)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendReqestToAll
-  (JNIEnv *, jobject, jstring, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMSendResponse
- * Signature: (IIII)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendResponse
-  (JNIEnv *, jobject, jint, jint, jint, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMAdvertiseResource
- * Signature: (Ljava/lang/String)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMAdvertiseResource
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMSendNotification
- * Signature: (Ljava/lang/String;Ljava/lang/String;IIII)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendNotification
-  (JNIEnv *, jobject, jstring, jstring, jint, jint, jint, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMSelectNetwork
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSelectNetwork
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMUnSelectNetwork
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMUnSelectNetwork
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMGetNetworkInfomation
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_iotivity_service_RMInterface
- * Method:    RMHandleRequestResponse
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMHandleRequestResponse
-  (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
index 25ce793..05c2bf9 100644 (file)
@@ -6,7 +6,7 @@
     android:paddingLeft="@dimen/activity_horizontal_margin"
     android:paddingRight="@dimen/activity_horizontal_margin"
     android:paddingTop="@dimen/activity_vertical_margin"
-    tools:context="org.iotivity.service.MainActivity" >
+    tools:context="org.iotivity.ca.service.MainActivity" >
 
     <RelativeLayout
         android:id="@+id/sample_service_layout"
         </RelativeLayout>
 
         <RelativeLayout
-            android:id="@+id/layout_find_title"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_mode" >
-                        
-            <TextView
-                android:id="@+id/tv_find"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="[Find Resource]"
-                />
-
-         </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/layout_find"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_find_title" >
-
-            <Button
-                android:id="@+id/btn_find_resource"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:text="@string/find" />
-
-            <EditText
-                android:id="@+id/et_uri"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_centerVertical="true"
-                android:layout_toLeftOf="@id/btn_find_resource"
-                android:text="@string/uri" />
-        </RelativeLayout>
-
-        <RelativeLayout
             android:id="@+id/layout_Response_Noti_title"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
         </RelativeLayout>
 
         <RelativeLayout
-            android:id="@+id/layout_request_setting_for_server"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_Response_Noti_title" >
-
-            <Button
-                android:id="@+id/btn_Request_setting_for_server"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:text="@string/request_setting" />
-        </RelativeLayout>
-
-        <RelativeLayout
             android:id="@+id/layout_notify"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/layout_request_setting_for_server" >
+            android:layout_below="@id/layout_Response_Noti_title" >
 
             <EditText
                 android:id="@+id/et_notification"
         </RelativeLayout>
 
         <RelativeLayout
-            android:id="@+id/layout_payload_server_ed"
+            android:id="@+id/layout_request_setting_for_server"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_below="@id/layout_notify" >
 
-            <EditText
-                android:id="@+id/et_payload_data_for_server"
-                android:layout_width="fill_parent"
+            <Button
+                android:id="@+id/btn_Request_setting_for_server"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_centerVertical="true"
-                android:text="@string/payload_data_server" />
-
-        </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/layout_server_bt"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_payload_server_ed" >
+                android:layout_alignParentLeft="true"
+                android:text="@string/request_setting" />
 
             <Button
                 android:id="@+id/btn_notify"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
+                android:layout_toRightOf="@id/btn_Request_setting_for_server"
                 android:text="@string/notify" />
 
             <Button
                 android:id="@+id/btn_sendresponse"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_toLeftOf="@id/btn_notify"
-                android:text="@string/sendresponse" />
-        </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/layout_advertise_title"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_server_bt" >
-
-            <TextView
-                android:id="@+id/tv_advertise"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="[Advertise Resource]"
-                />
-
-         </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/layout_advertise_resource"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_advertise_title" >
-
-            <Button
-                android:id="@+id/btn_advertise"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:text="@string/advertise" />
-
-            <EditText
-                android:id="@+id/et_uri_advertise"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_toLeftOf="@id/btn_advertise"
-                android:text="@string/uri" />
+                android:layout_toRightOf="@id/btn_notify"
+                android:text="@string/sendresponse" />
         </RelativeLayout>
 
         <RelativeLayout
             android:id="@+id/layout_request_title"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/layout_find" >
+            android:layout_below="@id/layout_mode" >
 
             <TextView
                 android:id="@+id/tv_request"
                 android:layout_height="wrap_content"
                 android:text="[Send Request]" />
 
-         </RelativeLayout>
+        </RelativeLayout>
 
         <RelativeLayout
             android:id="@+id/layout_request"
         </RelativeLayout>
 
         <RelativeLayout
-            android:id="@+id/layout_payload_client_ed"
+            android:id="@+id/layout_request_setting_for_client"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_below="@id/layout_request" >
 
-            <EditText
-                android:id="@+id/et_payload_data"
-                android:layout_width="fill_parent"
+            <Button
+                android:id="@+id/btn_Request_setting_for_client"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_centerVertical="true"
-                android:text="@string/payload_data_client" />
-        </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/layout_request_setting_for_client"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/layout_payload_client_ed" >
+                android:layout_alignParentLeft="true"
+                android:text="@string/request_setting" />
 
             <Button
                 android:id="@+id/btn_Request"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
+                android:layout_toRightOf="@id/btn_Request_setting_for_client"
                 android:text="@string/request" />
 
-            <Button
-                android:id="@+id/btn_Request_setting_for_client"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_toLeftOf="@id/btn_Request"
-                android:text="@string/request_setting" />
         </RelativeLayout>
 
         <RelativeLayout
             android:layout_below="@id/layout_request_to_all" >
 
             <Button
-                android:id="@+id/btn_request_to_all"
+                android:id="@+id/btn_request_to_all_setting_for_client"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:text="@string/request_to_all" />
+                android:layout_alignParentLeft="true"
+                android:text="@string/request_setting" />
 
             <Button
-                android:id="@+id/btn_request_to_all_setting_for_client"
-                android:layout_width="fill_parent"
+                android:id="@+id/btn_request_to_all"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_toLeftOf="@id/btn_request_to_all"
-                android:text="@string/request_setting" />
+                android:layout_toRightOf="@id/btn_request_to_all_setting_for_client"
+                android:text="@string/request_to_all" />
         </RelativeLayout>
 
         <RelativeLayout
             android:layout_below="@id/layout_handle_title" >
 
             <Button
-                android:id="@+id/btn_get_network_info"
+                android:id="@+id/btn_receive"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:text="@string/get_network_info" />
+                android:layout_alignParentLeft="true"
+                android:text="@string/receive" />
+
             <Button
-                android:id="@+id/btn_receive"
-                android:layout_width="fill_parent"
+                android:id="@+id/btn_get_network_info"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_toLeftOf="@id/btn_get_network_info"
-                android:text="@string/receive" />
+                android:layout_toRightOf="@id/btn_receive"
+                android:text="@string/get_network_info" />
+
         </RelativeLayout>
     </RelativeLayout>
 
             android:layout_height="wrap_content" />
     </ScrollView>
 
-</RelativeLayout>
+</RelativeLayout>
\ No newline at end of file
index ae3d56a..e0d03f4 100644 (file)
@@ -1,6 +1,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    tools:context="org.iotivity.sample_service.MainActivity" >
+    tools:context="org.iotivity.ca.sample_service.MainActivity" >
 
     <item
         android:id="@+id/action_settings"
index f75b6be..d365f1e 100644 (file)
@@ -1,22 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+
     <string name="app_name">CA Android Sample</string>
-    <string name="find">Find</string>
-    <string name="sendresponse">Send Response</string>
-    <string name="notify">Send Notification</string>
-    <string name="advertise">Advertise</string>
-    <string name="request_setting">Request Setting</string>
+    <string name="sendresponse">Response</string>
+    <string name="notify">Notification</string>
+    <string name="request_setting">Setting</string>
     <string name="request">Request</string>
     <string name="request_to_all">Request to All</string>
     <string name="response">Response</string>
     <string name="uri">/a/light</string>
+    <string name="coap_prefix">coap://</string>
+    <string name="port_num">:6298</string>
     <string name="notification"></string>
     <string name="req_data"></string>
     <string name="resp_data">resourceUri/response</string>
     <string name="get_network_info">Network Info</string>
     <string name="receive">Receive</string>
     <string name="received">Received Message</string>
+    <string name="remote_address">"Remote Address: "</string>
     <string name="action_settings">Settings</string>
-    <string name="payload_data_client">PayloadData</string>
-    <string name="payload_data_server">PayloadData</string>
 </resources>
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaEdrInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaEdrInterface.java
new file mode 100644 (file)
index 0000000..1e4d47c
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************
+ *
+ * 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.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public class CaEdrInterface {
+
+    private CaEdrInterface(Context context) {
+
+        registerIntentFilter(context);
+    }
+
+    private static IntentFilter registerIntentFilter(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        context.registerReceiver(mReceiver, filter);
+        return filter;
+    }
+
+    // Network Monitor
+    private native static void caEdrStateChangedCallback(int state);
+
+    private native static void caEdrBondStateChangedCallback(String addr);
+
+    private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+
+            String action = intent.getAction();
+
+            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+
+                int state =
+                        intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+
+                // STATE_ON:12, STATE_OFF:10
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                {
+                    caEdrStateChangedCallback(state);
+                }
+            }
+
+            if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+
+                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                                   BluetoothDevice.ERROR);
+
+                if (bondState == BluetoothDevice.BOND_NONE) {
+                    if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+                                            BluetoothDevice.ERROR)
+                                                == BluetoothDevice.BOND_BONDED)) {
+                        BluetoothDevice device
+                            = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+                        caEdrBondStateChangedCallback(device.getAddress());
+                    }
+                }
+            }
+        }
+    };
+}
index 43d0ace..901520b 100644 (file)
@@ -1,24 +1,22 @@
-/*\r
- * //******************************************************************\r
- * //\r
- * // Copyright 2015 Intel Corporation.\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
+ *\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
@@ -50,21 +48,21 @@ public class CaIpInterface {
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
             if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,\r
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {\r
-                stateDisabled();\r
+                WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {\r
+                caIpStateDisabled();\r
             } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {\r
                 ConnectivityManager manager = (ConnectivityManager)\r
                         mContext.getSystemService(Context.CONNECTIVITY_SERVICE);\r
                 NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);\r
 \r
                 if(nwInfo.isConnected()) {\r
-                    stateEnabled();\r
+                    caIpStateEnabled();\r
                 }\r
             }\r
         }\r
     };\r
 \r
-    private native static void stateEnabled();\r
+    private native static void caIpStateEnabled();\r
 \r
-    private native static void stateDisabled();\r
+    private native static void caIpStateDisabled();\r
 }
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeClientInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeClientInterface.java
new file mode 100644 (file)
index 0000000..891cb40
--- /dev/null
@@ -0,0 +1,295 @@
+/******************************************************************
+ *
+ * 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 java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+public class CaLeClientInterface {
+
+    private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
+    private static String TAG          = "Sample_Service : CaLeClientInterface";
+
+    private CaLeClientInterface(Context context) {
+
+        caLeRegisterLeScanCallback(mLeScanCallback);
+        caLeRegisterGattCallback(mGattCallback);
+
+        registerIntentFilter(context);
+    }
+
+    public static void getLeScanCallback() {
+        caLeRegisterLeScanCallback(mLeScanCallback);
+    }
+
+    public static void getLeGattCallback() {
+        caLeRegisterGattCallback(mGattCallback);
+    }
+
+    private static IntentFilter registerIntentFilter(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        context.registerReceiver(mReceiver, filter);
+        return filter;
+    }
+
+    private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
+
+    private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
+
+    // BluetoothAdapter.LeScanCallback
+    private native static void caLeScanCallback(BluetoothDevice device,
+                                                int rssi, byte[] scanRecord);
+
+    // BluetoothGattCallback
+    private native static void caLeGattConnectionStateChangeCallback(
+            BluetoothGatt gatt, int status, int newState);
+
+    private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
+
+    private native static void caLeGattCharacteristicReadCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+            byte[] data, int status);
+
+    private native static void caLeGattCharacteristicWriteCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+            byte[] data, int status);
+
+    private native static void caLeGattCharacteristicChangedCallback(
+            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data);
+
+    private native static void caLeGattDescriptorReadCallback(BluetoothGatt gatt,
+                                                             BluetoothGattDescriptor descriptor,
+                                                             int status);
+
+    private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt,
+                                                              BluetoothGattDescriptor descriptor,
+                                                              int status);
+
+    private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
+                                                                     int status);
+
+    private native static void caLeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi,
+                                                             int status);
+
+    // Network Monitor
+    private native static void caLeStateChangedCallback(int state);
+
+    // bond state
+    private native static void caLeBondStateChangedCallback(String address);
+
+    // Callback
+    private static BluetoothAdapter.LeScanCallback mLeScanCallback =
+                   new BluetoothAdapter.LeScanCallback() {
+
+        @Override
+        public void onLeScan(BluetoothDevice device, int rssi, byte[] 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");
+                        caLeScanCallback(device, rssi, scanRecord);
+                    }
+                }
+            } catch(UnsatisfiedLinkError e) {
+
+            }
+        }
+    };
+
+    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)
+                break;
+
+            int type = scanRecord[offset++];
+
+            switch (type) {
+            case 0x02:
+            case 0x03:
+                while (len > 1) {
+                    int uuid16 = scanRecord[offset++];
+                    uuid16 += (scanRecord[offset++] << 8);
+                    len -= 2;
+                    uuids.add(UUID.fromString(String.format(
+                            "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
+                }
+                break;
+            case 0x06:
+            case 0x07:
+                while (len >= 16) {
+                    try {
+                        ByteBuffer buffer = ByteBuffer.wrap(scanRecord, offset++, 16).
+                                                            order(ByteOrder.LITTLE_ENDIAN);
+                        long mostSigBits = buffer.getLong();
+                        long leastSigBits = buffer.getLong();
+                        uuids.add(new UUID(leastSigBits, mostSigBits));
+                    } catch (IndexOutOfBoundsException e) {
+                        Log.e(TAG, e.toString());
+                        continue;
+                    } finally {
+                        offset += 15;
+                        len -= 16;
+                    }
+                }
+                break;
+            default:
+                offset += (len - 1);
+                break;
+            }
+        }
+        return uuids;
+    }
+
+    private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+            super.onConnectionStateChange(gatt, status, newState);
+
+            caLeGattConnectionStateChangeCallback(gatt, status, newState);
+        }
+
+        @Override
+        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+            super.onServicesDiscovered(gatt, status);
+
+            caLeGattServicesDiscoveredCallback(gatt, status);
+        }
+
+        @Override
+        public void onCharacteristicRead(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicRead(gatt, characteristic, status);
+
+            caLeGattCharacteristicReadCallback(gatt, characteristic,
+                                               characteristic.getValue(), status);
+        }
+
+        @Override
+        public void onCharacteristicWrite(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicWrite(gatt, characteristic, status);
+
+            caLeGattCharacteristicWriteCallback(gatt, characteristic,
+                                                characteristic.getValue(), status);
+        }
+
+        @Override
+        public void onCharacteristicChanged(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicChanged(gatt, characteristic);
+
+            caLeGattCharacteristicChangedCallback(gatt, characteristic,
+                                                  characteristic.getValue());
+        }
+
+        @Override
+        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorRead(gatt, descriptor, status);
+
+            caLeGattDescriptorReadCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorWrite(gatt, descriptor, status);
+
+            caLeGattDescriptorWriteCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+            super.onReliableWriteCompleted(gatt, status);
+
+            caLeGattReliableWriteCompletedCallback(gatt, status);
+        }
+
+        @Override
+        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+            super.onReadRemoteRssi(gatt, rssi, status);
+
+            caLeGattReadRemoteRssiCallback(gatt, rssi, status);
+        }
+    };
+
+    private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+
+            String action = intent.getAction();
+
+            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                               BluetoothAdapter.ERROR);
+
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                {
+                    caLeStateChangedCallback(state);
+                }
+            }
+
+            if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+
+                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                                   BluetoothDevice.ERROR);
+
+                if (bondState == BluetoothDevice.BOND_NONE) {
+                    if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+                            BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED)) {
+                            BluetoothDevice device = intent
+                                .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+                        caLeBondStateChangedCallback(device.getAddress());
+                    }
+                }
+            }
+        }
+    };
+}
+
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeServerInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/ca/CaLeServerInterface.java
new file mode 100644 (file)
index 0000000..75f447b
--- /dev/null
@@ -0,0 +1,180 @@
+/******************************************************************
+ *
+ * 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.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattServerCallback;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseSettings;
+
+public class CaLeServerInterface {
+
+    private CaLeServerInterface() {
+
+        caLeRegisterGattServerCallback(mGattServerCallback);
+        caLeRegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+    }
+
+    public static void getLeGattServerCallback() {
+        caLeRegisterGattServerCallback(mGattServerCallback);
+    }
+
+    public static void getBluetoothLeAdvertiseCallback() {
+        caLeRegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+    }
+
+    private native static void caLeRegisterGattServerCallback(BluetoothGattServerCallback callback);
+
+    private native static void caLeRegisterBluetoothLeAdvertiseCallback(AdvertiseCallback callback);
+
+    // BluetoothGattServerCallback
+    private native static void caLeGattServerConnectionStateChangeCallback(
+            BluetoothDevice device, int status, int newState);
+
+    private native static void caLeGattServerServiceAddedCallback(int status,
+                                                                  BluetoothGattService service);
+
+    private native static void caLeGattServerCharacteristicReadRequestCallback(
+            BluetoothDevice device,
+            int requestId, int offset, BluetoothGattCharacteristic characteristic, byte[] data);
+
+    private native static void caLeGattServerCharacteristicWriteRequestCallback(
+            BluetoothDevice device, int requestId,
+            BluetoothGattCharacteristic characteristic, byte[] data, boolean preparedWrite,
+            boolean responseNeeded, int offset, byte[] value);
+
+    private native static void caLeGattServerDescriptorReadRequestCallback(
+            BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor);
+
+    public native static void caLeGattServerDescriptorWriteRequestCallback(
+            BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor,
+            boolean preparedWrite, boolean responseNeeded, int offset, byte[] value);
+
+    private native static void caLeGattServerExecuteWriteCallback(BluetoothDevice device,
+                                                                 int requestId, boolean execute);
+
+    private native static void caLeGattServerNotificationSentCallback(BluetoothDevice device,
+                                                                     int status);
+
+    // AdvertiseCallback
+    private native static void caLeAdvertiseStartSuccessCallback(
+            AdvertiseSettings settingsInEffect);
+
+    private native static void caLeAdvertiseStartFailureCallback(int errorCode);
+
+    private static final BluetoothGattServerCallback mGattServerCallback =
+                         new BluetoothGattServerCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothDevice device, int status,
+                int newState) {
+            super.onConnectionStateChange(device, status, newState);
+
+            caLeGattServerConnectionStateChangeCallback(device, status, newState);
+        }
+
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            super.onServiceAdded(status, service);
+
+            caLeGattServerServiceAddedCallback(status, service);
+        }
+
+        @Override
+        public void onCharacteristicReadRequest(
+                BluetoothDevice device, int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
+
+            caLeGattServerCharacteristicReadRequestCallback(device, requestId, offset,
+                                                            characteristic,
+                                                            characteristic.getValue());
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(
+                BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic,
+                boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
+            super.onCharacteristicWriteRequest(device, requestId, characteristic,
+                    preparedWrite, responseNeeded, offset, value);
+
+            caLeGattServerCharacteristicWriteRequestCallback(device, requestId, characteristic,
+                                                             value, preparedWrite, responseNeeded,
+                                                             offset, value);
+        }
+
+        @Override
+        public void onDescriptorReadRequest(
+                BluetoothDevice device,
+                int requestId, int offset, BluetoothGattDescriptor descriptor) {
+            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
+
+            caLeGattServerDescriptorReadRequestCallback(device, requestId, offset, descriptor);
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(
+                BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor,
+                boolean preparedWrite, boolean responseNeeded, int offset,
+                byte[] value) {
+            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite,
+                                           responseNeeded, offset, value);
+
+            caLeGattServerDescriptorWriteRequestCallback(device, requestId, descriptor,
+                                                         preparedWrite, responseNeeded, offset,
+                                                         value);
+        }
+
+        @Override
+        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
+            super.onExecuteWrite(device, requestId, execute);
+
+            caLeGattServerExecuteWriteCallback(device, requestId, execute);
+        }
+
+        @Override
+        public void onNotificationSent(BluetoothDevice device, int status) {
+            super.onNotificationSent(device, status);
+
+            caLeGattServerNotificationSentCallback(device, status);
+        }
+    };
+
+    private static final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
+
+        @Override
+        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+            super.onStartSuccess(settingsInEffect);
+
+            caLeAdvertiseStartSuccessCallback(settingsInEffect);
+        }
+
+        @Override
+        public void onStartFailure(int errorCode) {
+            super.onStartFailure(errorCode);
+
+            caLeAdvertiseStartFailureCallback(errorCode);
+        }
+    };
+}
@@ -1,12 +1,12 @@
 
-package org.iotivity.service;
+package org.iotivity.ca.service;
 
 import android.os.Handler;
 import android.widget.TextView;
 
 public final class DLog {
 
-    private final static String MAIN_TAG = "Sample_Service";
+    private final static String MAIN_TAG = "Sample_Service : DLog";
 
     private static TextView mLogView = null;
 
@@ -1,10 +1,11 @@
-package org.iotivity.service;
+package org.iotivity.ca.service;
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.os.Bundle;
 import android.os.Handler;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -14,16 +15,16 @@ import android.widget.EditText;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import org.iotivity.sample_service.R;
+import org.iotivity.ca.sample_service.R;
 
 public class MainActivity extends Activity {
 
     static RMInterface RM = new RMInterface();
 
-    private final static String TAG = "MainActivity";
+    private final static String TAG = "Sample_Service : MainActivity";
 
-    private final CharSequence[] mNetworkCheckBoxItems = { Network.IPV4.name(),
-            Network.IPV6.name(), Network.EDR.name(), Network.LE.name()};
+    private final CharSequence[] mNetworkCheckBoxItems = { Network.IP.name(),
+            Network.LE.name(), Network.EDR.name()};
 
     private final CharSequence[] mDTLSCheckBoxItems = { DTLS.UNSECURED.name(),
             DTLS.SECURED.name() };
@@ -33,9 +34,10 @@ public class MainActivity extends Activity {
 
     private final CharSequence[] mResponseResultCheckBoxItems = {
             ResponseResult.CA_SUCCESS.name(), ResponseResult.CA_CREATED.name(),
-            ResponseResult.CA_DELETED.name(), ResponseResult.CA_EMPTY.name(),
-            ResponseResult.CA_BAD_REQ.name(), ResponseResult.CA_BAD_OPT.name(),
-            ResponseResult.CA_NOT_FOUND.name(),
+            ResponseResult.CA_DELETED.name(), ResponseResult.CA_VALID.name(),
+            ResponseResult.CA_CHANGED.name(), ResponseResult.CA_CONTENT.name(),
+            ResponseResult.CA_EMPTY.name(), ResponseResult.CA_BAD_REQ.name(),
+            ResponseResult.CA_BAD_OPT.name(), ResponseResult.CA_NOT_FOUND.name(),
             ResponseResult.CA_INTERNAL_SERVER_ERROR.name(),
             ResponseResult.CA_RETRANSMIT_TIMEOUT.name() };
 
@@ -44,7 +46,7 @@ public class MainActivity extends Activity {
     };
 
     private enum Network {
-        IPV4, IPV6, EDR, LE
+        IP, LE, EDR
     };
 
     private enum DTLS {
@@ -56,22 +58,20 @@ public class MainActivity extends Activity {
     };
 
     private enum ResponseResult {
-        CA_SUCCESS, CA_CREATED, CA_DELETED, CA_EMPTY, CA_BAD_REQ, CA_BAD_OPT,
-        CA_NOT_FOUND, CA_INTERNAL_SERVER_ERROR, CA_RETRANSMIT_TIMEOUT
+        CA_SUCCESS, CA_CREATED, CA_DELETED, CA_VALID, CA_CHANGED, CA_CONTENT, CA_EMPTY,
+        CA_BAD_REQ, CA_BAD_OPT, CA_NOT_FOUND, CA_INTERNAL_SERVER_ERROR, CA_RETRANSMIT_TIMEOUT
     }
 
     private boolean mCheckedItems[] = {
             false, false, false, false
     };
 
-    private int mSelectedItems[] = { 0, 0, 0, 0 };
+    private int mSelectedItems[] = { 0, 0, 0 };
 
-    private int mUnSelectedItems[] = { 0, 0, 0, 0 };
+    private int mUnSelectedItems[] = { 0, 0, 0 };
 
     private Mode mCurrentMode = Mode.UNKNOWN;
 
-    private RelativeLayout mFindResourceLayout = null;
-
     private RelativeLayout mSendNotificationLayout = null;
 
     private RelativeLayout mSendRequestLayout = null;
@@ -86,48 +86,26 @@ public class MainActivity extends Activity {
 
     private RelativeLayout mReceiveLayout = null;
 
-    private RelativeLayout mFindTitleLayout = null;
-
     private RelativeLayout mRequestTitleLayout = null;
 
     private RelativeLayout mRequestToAllTitleLayout = null;
 
     private RelativeLayout mResponseNotificationTitleLayout = null;
 
-    private RelativeLayout mAdvertiseTitleLayout = null;
-
     private RelativeLayout mHandleTitleLayout = null;
 
-    private RelativeLayout mPayLoadClientEditLayout = null;
-
-    private RelativeLayout mPayLoadServerEditLayout = null;
-
-    private RelativeLayout mAdvertiseResourceLayout = null;
-
-    private RelativeLayout mServerButtonLayout = null;
-
     private TextView mMode_tv = null;
 
     private TextView mNetwork_tv = null;
 
-    private EditText mUri_ed = null;
-
     private EditText mNotification_ed = null;
 
     private EditText mReqData_ed = null;
 
     private EditText mReqToAllData_ed = null;
 
-    private EditText mPayload_ed = null;
-
-    private EditText mAdvertise_ed = null;
-
-    private Button mFind_btn = null;
-
     private Button mNotify_btn = null;
 
-    private Button mAdvertiseResource_btn = null;
-
     private Button mReqeust_btn = null;
 
     private Button mReqeust_setting_btn = null;
@@ -149,12 +127,11 @@ public class MainActivity extends Activity {
     /**
      * Defined ConnectivityType in cacommon.c
      *
-     * CA_IPV4 = (1 << 0) CA_IPV6 = (1 << 1) CA_EDR = (1 << 2) CA_LE = (1 << 3)
+     * CA_IP = (1 << 0) CA_LE = (1 << 2) CA_EDR = (1 << 3)
      */
-    private int CA_IPV4 = (1 << 0);
-    private int CA_IPV6 = (1 << 1);
+    private int CA_IP = (1 << 0);
+    private int CA_LE = (1 << 1);
     private int CA_EDR = (1 << 2);
-    private int CA_LE = (1 << 3);
     private int isSecured = 0;
     private int msgType = 1;
     private int responseValue = 0;
@@ -190,39 +167,26 @@ public class MainActivity extends Activity {
                 findViewById(R.id.layout_request_setting_for_client);
         mSendRequestToAllSettingLayout = (RelativeLayout)
                 findViewById(R.id.layout_request_to_all_setting_for_client);
-        mFindResourceLayout = (RelativeLayout) findViewById(R.id.layout_find);
-        mFindTitleLayout = (RelativeLayout) findViewById(R.id.layout_find_title);
         mRequestTitleLayout = (RelativeLayout) findViewById(R.id.layout_request_title);
         mRequestToAllTitleLayout = (RelativeLayout) findViewById(R.id.layout_request_to_all_title);
         mHandleTitleLayout = (RelativeLayout) findViewById(R.id.layout_handle_title);
-        mPayLoadClientEditLayout = (RelativeLayout) findViewById(R.id.layout_payload_client_ed);
 
         // server
         mSendNotificationLayout = (RelativeLayout) findViewById(R.id.layout_notify);
-        mPayLoadServerEditLayout = (RelativeLayout)
-                findViewById(R.id.layout_payload_server_ed);
         mSendResponseNotiSettingLayout = (RelativeLayout)
                 findViewById(R.id.layout_request_setting_for_server);
-        mServerButtonLayout = (RelativeLayout) findViewById(R.id.layout_server_bt);
         mResponseNotificationTitleLayout = (RelativeLayout)
                 findViewById(R.id.layout_Response_Noti_title);
-        mAdvertiseTitleLayout = (RelativeLayout) findViewById(R.id.layout_advertise_title);
-        mAdvertiseResourceLayout = (RelativeLayout) findViewById(R.id.layout_advertise_resource);
 
         mMode_tv = (TextView) findViewById(R.id.tv_mode);
         mNetwork_tv = (TextView) findViewById(R.id.tv_network);
 
-        mUri_ed = (EditText) findViewById(R.id.et_uri);
         mNotification_ed = (EditText) findViewById(R.id.et_notification);
         mReqData_ed = (EditText) findViewById(R.id.et_req_data);
         mReqToAllData_ed = (EditText) findViewById(R.id.et_req_to_all_data);
-        mPayload_ed = (EditText) findViewById(R.id.et_payload_data_for_server);
-        mAdvertise_ed = (EditText) findViewById(R.id.et_uri_advertise);
 
-        mFind_btn = (Button) findViewById(R.id.btn_find_resource);
         mResponse_btn = (Button) findViewById(R.id.btn_sendresponse);
         mNotify_btn = (Button) findViewById(R.id.btn_notify);
-        mAdvertiseResource_btn = (Button) findViewById(R.id.btn_advertise);
         mReqeust_btn = (Button) findViewById(R.id.btn_Request);
         mReqeust_setting_btn = (Button) findViewById(R.id.btn_Request_setting_for_client);
         mReqeustToAll_btn = (Button) findViewById(R.id.btn_request_to_all);
@@ -232,10 +196,8 @@ public class MainActivity extends Activity {
         mGetNetworkInfo_btn = (Button) findViewById(R.id.btn_get_network_info);
         mRecv_btn = (Button) findViewById(R.id.btn_receive);
 
-        mFind_btn.setOnClickListener(mFindResourceHandler);
         mResponse_btn.setOnClickListener(mSendResponseHandler);
         mNotify_btn.setOnClickListener(mNotifyHandler);
-        mAdvertiseResource_btn.setOnClickListener(mAdvertiseResourceHandler);
         mReqeust_btn.setOnClickListener(mSendRequestHandler);
         mReqeust_setting_btn.setOnClickListener(mSendRequestSettingHandler);
         mReqeustToAll_btn.setOnClickListener(mSendRequestToAllHandler);
@@ -256,65 +218,50 @@ public class MainActivity extends Activity {
 
     private void showSelectModeView() {
 
-        mFindResourceLayout.setVisibility(View.INVISIBLE);
         mSendNotificationLayout.setVisibility(View.INVISIBLE);
         mSendRequestLayout.setVisibility(View.INVISIBLE);
         mSendRequestToAllLayout.setVisibility(View.INVISIBLE);
         mSendRequestSettingLayout.setVisibility(View.INVISIBLE);
         mSendRequestToAllSettingLayout.setVisibility(View.INVISIBLE);
         mReceiveLayout.setVisibility(View.INVISIBLE);
-        mFindTitleLayout.setVisibility(View.INVISIBLE);
         mRequestTitleLayout.setVisibility(View.INVISIBLE);
         mRequestToAllTitleLayout.setVisibility(View.INVISIBLE);
         mHandleTitleLayout.setVisibility(View.INVISIBLE);
-        mPayLoadClientEditLayout.setVisibility(View.INVISIBLE);
-        mPayLoadServerEditLayout.setVisibility(View.INVISIBLE);
-        mServerButtonLayout.setVisibility(View.INVISIBLE);
         mResponseNotificationTitleLayout.setVisibility(View.INVISIBLE);
-        mAdvertiseTitleLayout.setVisibility(View.INVISIBLE);
-        mAdvertiseResourceLayout.setVisibility(View.INVISIBLE);
         mSendResponseNotiSettingLayout.setVisibility(View.INVISIBLE);
 
         mMode_tv.setText("Select Mode (Server or Client)");
+        Log.i(TAG, "Select Mode (Server or Client)");
     }
 
     private void showNetworkView() {
 
         mNetwork_tv.setText("Select Network Type");
+        Log.i(TAG, "Select Network Type");
     }
 
     private void showModeView() {
 
         if (mCurrentMode == Mode.SERVER) {
 
-            mFindResourceLayout.setVisibility(View.INVISIBLE);
             mSendNotificationLayout.setVisibility(View.VISIBLE);
             mSendRequestLayout.setVisibility(View.INVISIBLE);
-            mSendRequestToAllLayout.setVisibility(View.INVISIBLE);
+            mSendRequestToAllLayout.setVisibility(View.VISIBLE);
             mSendRequestSettingLayout.setVisibility(View.INVISIBLE);
-            mSendRequestToAllSettingLayout.setVisibility(View.INVISIBLE);
+            mSendRequestToAllSettingLayout.setVisibility(View.VISIBLE);
             mReceiveLayout.setVisibility(View.VISIBLE);
 
-            mFindTitleLayout.setVisibility(View.INVISIBLE);
             mRequestTitleLayout.setVisibility(View.INVISIBLE);
-            mRequestToAllTitleLayout.setVisibility(View.INVISIBLE);
+            mRequestToAllTitleLayout.setVisibility(View.VISIBLE);
             mHandleTitleLayout.setVisibility(View.VISIBLE);
-            mPayLoadClientEditLayout.setVisibility(View.INVISIBLE);
-
-            mPayLoadServerEditLayout.setVisibility(View.VISIBLE);
-            mServerButtonLayout.setVisibility(View.VISIBLE);
 
             mResponseNotificationTitleLayout.setVisibility(View.VISIBLE);
-            mAdvertiseTitleLayout.setVisibility(View.VISIBLE);
-            mAdvertiseResourceLayout.setVisibility(View.VISIBLE);
-
             mSendResponseNotiSettingLayout.setVisibility(View.VISIBLE);
 
             mNetwork_tv.setText("");
 
         } else if (mCurrentMode == Mode.CLIENT) {
 
-            mFindResourceLayout.setVisibility(View.VISIBLE);
             mSendNotificationLayout.setVisibility(View.INVISIBLE);
             mSendRequestLayout.setVisibility(View.VISIBLE);
             mSendRequestToAllLayout.setVisibility(View.VISIBLE);
@@ -322,19 +269,11 @@ public class MainActivity extends Activity {
             mSendRequestToAllSettingLayout.setVisibility(View.VISIBLE);
             mReceiveLayout.setVisibility(View.VISIBLE);
 
-            mFindTitleLayout.setVisibility(View.VISIBLE);
             mRequestTitleLayout.setVisibility(View.VISIBLE);
             mRequestToAllTitleLayout.setVisibility(View.VISIBLE);
             mHandleTitleLayout.setVisibility(View.VISIBLE);
-            mPayLoadClientEditLayout.setVisibility(View.VISIBLE);
-
-            mPayLoadServerEditLayout.setVisibility(View.INVISIBLE);
-            mServerButtonLayout.setVisibility(View.INVISIBLE);
 
             mResponseNotificationTitleLayout.setVisibility(View.INVISIBLE);
-            mAdvertiseTitleLayout.setVisibility(View.INVISIBLE);
-            mAdvertiseResourceLayout.setVisibility(View.INVISIBLE);
-
             mSendResponseNotiSettingLayout.setVisibility(View.INVISIBLE);
 
             mNetwork_tv.setText("");
@@ -372,11 +311,13 @@ public class MainActivity extends Activity {
             if (interestedNetwork == 0) {
                 mCurrentMode = Mode.SERVER;
                 mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                Log.i(TAG, "MODE: " + mCurrentMode.toString());
                 showNetworkView();
 
             } else {
                 mCurrentMode = Mode.SERVER;
                 mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                Log.i(TAG, "MODE: " + mCurrentMode.toString());
                 showModeView();
             }
 
@@ -389,11 +330,13 @@ public class MainActivity extends Activity {
             if (interestedNetwork == 0) {
                 mCurrentMode = Mode.CLIENT;
                 mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                Log.i(TAG, "MODE: " + mCurrentMode.toString());
                 showNetworkView();
 
             } else {
                 mCurrentMode = Mode.CLIENT;
                 mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                Log.i(TAG, "MODE: " + mCurrentMode.toString());
                 showModeView();
             }
 
@@ -409,17 +352,6 @@ public class MainActivity extends Activity {
         return super.onOptionsItemSelected(item);
     }
 
-    private OnClickListener mFindResourceHandler = new OnClickListener() {
-
-        @Override
-        public void onClick(View v) {
-
-            DLog.v(TAG, "FindResource click");
-            RM.RMFindResource(mUri_ed.getText().toString());
-
-        }
-    };
-
     private OnClickListener mSendResponseHandler = new OnClickListener() {
 
         @Override
@@ -443,8 +375,7 @@ public class MainActivity extends Activity {
             DLog.v(TAG, "SendNotification click");
             if ( selectedNetwork != -1) {
                 RM.RMSendNotification(mNotification_ed.getText().toString(),
-                    mPayload_ed.getText().toString(), selectedNetwork,
-                    isSecured, msgType, responseValue);
+                    null, selectedNetwork, isSecured, msgType, responseValue);
             }
             else {
                 DLog.v(TAG, "Please Select Network Type");
@@ -452,16 +383,6 @@ public class MainActivity extends Activity {
         }
     };
 
-    private OnClickListener mAdvertiseResourceHandler = new OnClickListener() {
-
-        @Override
-        public void onClick(View v) {
-
-            DLog.v(TAG, "AdvertiseResource click");
-            RM.RMAdvertiseResource(mAdvertise_ed.getText().toString());
-        }
-    };
-
     private OnClickListener mSendRequestHandler = new OnClickListener() {
 
         @Override
@@ -469,8 +390,8 @@ public class MainActivity extends Activity {
 
             DLog.v(TAG, "SendRequest click");
             if ( selectedNetwork != -1) {
-                RM.RMSendRequest(mReqData_ed.getText().toString(), mPayload_ed
-                    .getText().toString(), selectedNetwork, isSecured, msgType);
+                RM.RMSendRequest(mReqData_ed.getText().toString(), null,
+                    selectedNetwork, isSecured, msgType);
             }
             else {
                 DLog.v(TAG, "Please Select Network Type");
@@ -568,10 +489,7 @@ public class MainActivity extends Activity {
 
                         for (int i = 0; i < mSelectedItems.length; i++) {
                             if (mSelectedItems[i] == 1) {
-                                if(i != 1)
-                                    interestedNetwork |= (1 << i);
-                                else
-                                    checkNotSupportedTransport("Not Supported Transport");
+                                interestedNetwork |= (1 << i);
                             }
                         }
                         if(0 != interestedNetwork)
@@ -581,11 +499,7 @@ public class MainActivity extends Activity {
 
                         for (int i = 0; i < mUnSelectedItems.length; i++) {
                             if (mUnSelectedItems[i] == 1) {
-                                if (i != 1)
-                                    uninterestedNetwork |= (1 << i);
-                                else
-                                    checkNotSupportedTransport("Not Supported Transport");
-                                mUnSelectedItems[i] = 0;
+                                uninterestedNetwork |= (1 << i);
                             }
                         }
                         if(0 != uninterestedNetwork)
@@ -595,20 +509,6 @@ public class MainActivity extends Activity {
                 }).show();
     }
 
-    private void checkNotSupportedTransport(String title) {
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
-        builder.setTitle(title).
-        setMessage("Selected Transport Not Supported")
-        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
-
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-
-            }
-        }).show();
-    }
-
     private void checkMsgSecured(String title) {
 
         AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
@@ -632,23 +532,9 @@ public class MainActivity extends Activity {
                             isSecured = 1;
                             DLog.v(TAG, "Send secured message");
 
-                            mPayLoadClientEditLayout
-                                    .setVisibility(View.INVISIBLE);
-
-                            mPayLoadServerEditLayout
-                                    .setVisibility(View.INVISIBLE);
-
                         } else if (selectedMsgSecured == DTLS.UNSECURED.ordinal()) {
                             isSecured = 0;
                             DLog.v(TAG, "Send unsecured message");
-
-                            if (mCurrentMode == Mode.SERVER) {
-                                mPayLoadServerEditLayout
-                                        .setVisibility(View.VISIBLE);
-                            } else if (mCurrentMode == Mode.CLIENT) {
-                                mPayLoadClientEditLayout
-                                        .setVisibility(View.VISIBLE);
-                            }
                         }
                         checkMsgType("Select Msg Type");
                     }
@@ -726,6 +612,18 @@ public class MainActivity extends Activity {
                                 .ordinal()) {
                             responseValue = 202;
                             DLog.v(TAG, "Response Value is CA_DELETED");
+                        } else if (selectedResponseValue == ResponseResult.CA_VALID
+                                .ordinal()) {
+                            responseValue = 203;
+                            DLog.v(TAG, "Response Value is CA_VALID");
+                        } else if (selectedResponseValue == ResponseResult.CA_CHANGED
+                                .ordinal()) {
+                            responseValue = 204;
+                            DLog.v(TAG, "Response Value is CA_CHANGED");
+                        } else if (selectedResponseValue == ResponseResult.CA_CONTENT
+                                .ordinal()) {
+                            responseValue = 205;
+                            DLog.v(TAG, "Response Value is CA_CONTENT");
                         } else if (selectedResponseValue == ResponseResult.CA_EMPTY
                                 .ordinal()) {
                             responseValue = 0;
@@ -775,17 +673,16 @@ public class MainActivity extends Activity {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
 
-                        if (selectedNetworkType == Network.IPV4.ordinal()) {
-                            selectedNetwork = CA_IPV4;
-                            DLog.v(TAG, "Selected Network is CA_IPV4");
-                        } else if (selectedNetworkType == Network.EDR.ordinal()) {
-                            selectedNetwork = CA_EDR;
-                            DLog.v(TAG, "Selected Network is EDR");
+                        if (selectedNetworkType == Network.IP.ordinal()) {
+                            selectedNetwork = CA_IP;
+                            DLog.v(TAG, "Selected Network is CA_IP");
                         } else if (selectedNetworkType == Network.LE.ordinal()) {
                             selectedNetwork = CA_LE;
                             DLog.v(TAG, "Selected Network is LE");
-                        }
-                        else {
+                        } else if (selectedNetworkType == Network.EDR.ordinal()) {
+                            selectedNetwork = CA_EDR;
+                            DLog.v(TAG, "Selected Network is EDR");
+                        } else {
                             DLog.v(TAG, "Selected Network is NULL");
                             selectedNetwork = -1;
                         }
@@ -802,5 +699,15 @@ public class MainActivity extends Activity {
         String callbackData = subject + receivedData;
         DLog.v(TAG, callbackData);
 
+        if (subject.equals(getString(R.string.remote_address))) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(getString(R.string.coap_prefix)).append(receivedData);
+            if (receivedData.contains(".")) { // IP
+                sb.append(getString(R.string.port_num));
+            }
+            sb.append(getString(R.string.uri));
+            mReqData_ed.setText(sb.toString());
+            mNotification_ed.setText(sb.toString());
+        }
     }
 }
@@ -1,4 +1,4 @@
-package org.iotivity.service;
+package org.iotivity.ca.service;
 
 import android.content.Context;
 
@@ -9,7 +9,7 @@ public class RMInterface {
         System.loadLibrary("RMInterface");
     }
 
-    private org.iotivity.service.MainActivity mResponseListener = null;
+    private org.iotivity.ca.service.MainActivity mResponseListener = null;
 
     public native void setNativeResponseListener(Object listener);
 
@@ -46,7 +46,7 @@ public class RMInterface {
 
     public native void RMHandleRequestResponse();
 
-    public void setResponseListener(org.iotivity.service.MainActivity listener) {
+    public void setResponseListener(org.iotivity.ca.service.MainActivity listener) {
         mResponseListener = listener;
         setNativeResponseListener(this);
     }
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/CALeInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/CALeInterface.java
deleted file mode 100644 (file)
index ccc24cb..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-package org.iotivity.jar;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattServerCallback;
-import android.bluetooth.BluetoothGattService;
-import android.bluetooth.le.AdvertiseCallback;
-import android.bluetooth.le.AdvertiseSettings;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-public class CALeInterface {
-
-    public CALeInterface(Context context) {
-
-        CARegisterLeScanCallback(mLeScanCallback);
-        CARegisterLeGattCallback(mGattCallback);
-        CARegisterLeGattServerCallback(mGattServerCallback);
-        CARegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
-
-        registerIntentFilter(context);
-    }
-
-    public static void getLeScanCallback() {
-        CARegisterLeScanCallback(mLeScanCallback);
-    }
-
-    public static void getLeGattCallback() {
-        CARegisterLeGattCallback(mGattCallback);
-    }
-
-    public static void getLeGattServerCallback() {
-        CARegisterLeGattServerCallback(mGattServerCallback);
-    }
-
-    public static void getBluetoothLeAdvertiseCallback() {
-        CARegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
-    }
-
-    public static IntentFilter registerIntentFilter(Context context) {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        context.registerReceiver(mReceiver, filter);
-        return filter;
-    }
-
-    public native static void CARegisterLeScanCallback(
-            BluetoothAdapter.LeScanCallback callback);
-
-    public native static void CARegisterLeGattCallback(
-            BluetoothGattCallback callback);
-
-    public native static void CARegisterLeGattServerCallback(
-            BluetoothGattServerCallback callback);
-
-    public native static void CARegisterBluetoothLeAdvertiseCallback(
-            AdvertiseCallback callback);
-
-    // BluetoothAdapter.LeScanCallback
-    public native static void CALeScanCallback(BluetoothDevice device,
-            int rssi, byte[] scanRecord);
-
-    // BluetoothGattCallback
-    public native static void CALeGattConnectionStateChangeCallback(
-            BluetoothGatt gatt, int status, int newState);
-
-    public native static void CALeGattServicesDiscoveredCallback(
-            BluetoothGatt gatt, int status);
-
-    public native static void CALeGattCharacteristicReadCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            byte[] data, int status);
-
-    public native static void CALeGattCharacteristicWriteCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            byte[] data, int status);
-
-    public native static void CALeGattCharacteristicChangedCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            byte[] data);
-
-    public native static void CALeGattDescriptorReadCallback(
-            BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status);
-
-    public native static void CALeGattDescriptorWriteCallback(
-            BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status);
-
-    public native static void CALeGattReliableWriteCompletedCallback(
-            BluetoothGatt gatt, int status);
-
-    public native static void CALeGattReadRemoteRssiCallback(
-            BluetoothGatt gatt, int rssi, int status);
-
-    // BluetoothGattServerCallback
-    public native static void CALeGattServerConnectionStateChangeCallback(
-            BluetoothDevice device, int status, int newState);
-
-    public native static void CALeGattServerServiceAddedCallback(int status,
-            BluetoothGattService service);
-
-    public native static void CALeGattServerCharacteristicReadRequestCallback(
-            BluetoothDevice device, int requestId, int offset,
-            BluetoothGattCharacteristic characteristic, byte[] data);
-
-    public native static void CALeGattServerCharacteristicWriteRequestCallback(
-            BluetoothDevice device, int requestId,
-            BluetoothGattCharacteristic characteristic, byte[] data,
-            boolean preparedWrite, boolean responseNeeded, int offset,
-            byte[] value);
-
-    public native static void CALeGattServerDescriptorReadRequestCallback(
-            BluetoothDevice device, int requestId, int offset,
-            BluetoothGattDescriptor descriptor);
-
-    public native static void CALeGattServerDescriptorWriteRequestCallback(
-            BluetoothDevice device, int requestId,
-            BluetoothGattDescriptor descriptor, boolean preparedWrite,
-            boolean responseNeeded, int offset, byte[] value);
-
-    public native static void CALeGattServerExecuteWriteCallback(
-            BluetoothDevice device, int requestId, boolean execute);
-
-    public native static void CALeGattServerNotificationSentCallback(
-            BluetoothDevice device, int status);
-
-    // AdvertiseCallback
-    public native static void CALeAdvertiseStartSuccessCallback(
-            AdvertiseSettings settingsInEffect);
-
-    public native static void CALeAdvertiseStartFailureCallback(int errorCode);
-
-    // Network Monitor
-    public native static void CALeStateChangedCallback(int state);
-
-    // Callback
-    private static BluetoothAdapter.LeScanCallback mLeScanCallback
-        = new BluetoothAdapter.LeScanCallback() {
-
-        @Override
-        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
-
-            try {
-                CALeScanCallback(device, rssi, scanRecord);
-            } catch(UnsatisfiedLinkError e) {
-
-            }
-        }
-    };
-
-    private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
-
-        @Override
-        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
-            super.onConnectionStateChange(gatt, status, newState);
-
-            CALeGattConnectionStateChangeCallback(gatt, status, newState);
-        }
-
-        @Override
-        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
-            super.onServicesDiscovered(gatt, status);
-
-            CALeGattServicesDiscoveredCallback(gatt, status);
-        }
-
-        @Override
-        public void onCharacteristicRead(BluetoothGatt gatt,
-                BluetoothGattCharacteristic characteristic, int status) {
-            super.onCharacteristicRead(gatt, characteristic, status);
-
-            CALeGattCharacteristicReadCallback(gatt, characteristic,
-                    characteristic.getValue(), status);
-        }
-
-        @Override
-        public void onCharacteristicWrite(BluetoothGatt gatt,
-                BluetoothGattCharacteristic characteristic, int status) {
-            super.onCharacteristicWrite(gatt, characteristic, status);
-
-            CALeGattCharacteristicWriteCallback(gatt, characteristic,
-                    characteristic.getValue(), status);
-        }
-
-        @Override
-        public void onCharacteristicChanged(BluetoothGatt gatt,
-                BluetoothGattCharacteristic characteristic) {
-            super.onCharacteristicChanged(gatt, characteristic);
-
-            CALeGattCharacteristicChangedCallback(gatt, characteristic,
-                    characteristic.getValue());
-        }
-
-        @Override
-        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-                int status) {
-            super.onDescriptorRead(gatt, descriptor, status);
-
-            CALeGattDescriptorReadCallback(gatt, descriptor, status);
-        }
-
-        @Override
-        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-                int status) {
-            super.onDescriptorWrite(gatt, descriptor, status);
-
-            CALeGattDescriptorWriteCallback(gatt, descriptor, status);
-        }
-
-        @Override
-        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
-            super.onReliableWriteCompleted(gatt, status);
-
-            CALeGattReliableWriteCompletedCallback(gatt, status);
-        }
-
-        @Override
-        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
-            super.onReadRemoteRssi(gatt, rssi, status);
-
-            CALeGattReadRemoteRssiCallback(gatt, rssi, status);
-        }
-    };
-
-    private static final BluetoothGattServerCallback mGattServerCallback
-        = new BluetoothGattServerCallback() {
-
-        @Override
-        public void onConnectionStateChange(BluetoothDevice device, int status,
-                int newState) {
-            super.onConnectionStateChange(device, status, newState);
-
-            CALeGattServerConnectionStateChangeCallback(device, status, newState);
-        }
-
-        @Override
-        public void onServiceAdded(int status, BluetoothGattService service) {
-            super.onServiceAdded(status, service);
-
-            CALeGattServerServiceAddedCallback(status, service);
-        }
-
-        @Override
-        public void onCharacteristicReadRequest(BluetoothDevice device,
-                int requestId, int offset,
-                BluetoothGattCharacteristic characteristic) {
-            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
-
-            CALeGattServerCharacteristicReadRequestCallback(device, requestId, offset,
-                    characteristic, characteristic.getValue());
-        }
-
-        @Override
-        public void onCharacteristicWriteRequest(BluetoothDevice device,
-                int requestId, BluetoothGattCharacteristic characteristic,
-                boolean preparedWrite, boolean responseNeeded, int offset,
-                byte[] value) {
-            super.onCharacteristicWriteRequest(device, requestId, characteristic,
-                    preparedWrite, responseNeeded, offset, value);
-
-            CALeGattServerCharacteristicWriteRequestCallback(device, requestId, characteristic,
-                    value, preparedWrite, responseNeeded, offset, value);
-        }
-
-        @Override
-        public void onDescriptorReadRequest(BluetoothDevice device,
-                int requestId, int offset, BluetoothGattDescriptor descriptor) {
-            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
-
-            CALeGattServerDescriptorReadRequestCallback(device, requestId, offset, descriptor);
-        }
-
-        @Override
-        public void onDescriptorWriteRequest(BluetoothDevice device,
-                int requestId, BluetoothGattDescriptor descriptor,
-                boolean preparedWrite, boolean responseNeeded, int offset,
-                byte[] value) {
-            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite,
-                    responseNeeded, offset, value);
-
-            CALeGattServerDescriptorWriteRequestCallback(device, requestId, descriptor,
-                    preparedWrite, responseNeeded, offset, value);
-        }
-
-        @Override
-        public void onExecuteWrite(BluetoothDevice device, int requestId,
-                boolean execute) {
-            super.onExecuteWrite(device, requestId, execute);
-
-            CALeGattServerExecuteWriteCallback(device, requestId, execute);
-        }
-
-        @Override
-        public void onNotificationSent(BluetoothDevice device, int status) {
-            super.onNotificationSent(device, status);
-
-            CALeGattServerNotificationSentCallback(device, status);
-        }
-    };
-
-    private static final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
-
-        @Override
-        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
-            super.onStartSuccess(settingsInEffect);
-
-            CALeAdvertiseStartSuccessCallback(settingsInEffect);
-        }
-
-        @Override
-        public void onStartFailure(int errorCode) {
-            super.onStartFailure(errorCode);
-
-            CALeAdvertiseStartFailureCallback(errorCode);
-        }
-    };
-
-    private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-
-            String action = intent.getAction();
-
-            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                        BluetoothAdapter.ERROR);
-                // STATE_ON:12, STATE_OFF:10
-                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF) {
-                    CALeStateChangedCallback(state);
-                }
-            }
-        }
-    };
-}
-
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/caipinterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/org/iotivity/jar/caipinterface.java
deleted file mode 100644 (file)
index c6e5e78..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.iotivity.jar;
-
-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 String TAG = "caipinterface";
-    private static Context mContext = null;
-
-    public caipinterface(Context context) {
-        Log.d(TAG, "caipinterface");
-        mContext = context;
-        registerIpStateReceiver();
-    }
-
-    private void registerIpStateReceiver() {
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-
-        mContext.registerReceiver(mReceiver, intentFilter);
-    }
-
-    private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {
-                CAIPStateDisabled();
-            } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
-                ConnectivityManager manager = (ConnectivityManager)
-                        mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-                NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-
-                if(nwInfo.isConnected()) {
-                    CAIPStateEnabled();
-                }
-            }
-        }
-    };
-
-    public native static void CAIPStateEnabled();
-
-    public native static void CAIPStateDisabled();
-}
-
index 660cd72..0722421 100644 (file)
@@ -26,5 +26,5 @@ Alias('arduino_simplecs', i_arduino_simplecs)
 sample_env.Default('CASample.hex')
 
 if(sample_env['UPLOAD'] == True):
-       sample_env.Upload(env.get('BUILD_DIR') + '/samples/arduino/' + 'CASample.hex')
+       sample_env.Upload(env.get('BUILD_DIR') + 'resource/csdk/connectivity/samples/arduino/' + 'CASample.hex')
 
index f22eb1c..3d5c961 100644 (file)
@@ -39,6 +39,7 @@
 
 #define MAX_BUF_LEN 100 //1024
 #define MAX_OPT_LEN 16
+#define PORT_LENGTH 5
 
 static bool g_isLeSelected = false;
 
@@ -47,18 +48,18 @@ static void Process();
 static void Initialize();
 static void StartListeningServer();
 static void StartDiscoveryServer();
-static void FindResource();
 static void SendRequest();
 static void SendRequestAll();
-static void SendResponse(CARemoteEndpoint_t *endpoint, const CAInfo_t* info);
-static void AdvertiseResource();
+static void SendResponse(CAEndpoint_t *endpoint, const CAInfo_t* info);
 static void SendNotification();
 static void SelectNetwork();
 static void UnselectNetwork();
 static void HandleRequestResponse();
+static void GetNetworkInfo();
 
-static void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
-static void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+static void RequestHandler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
+static void ResponseHandler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+static void ErrorHandler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
 static void Terminate();
 
 void GetData(char *readInput, size_t bufferLength, size_t *dataLength)
@@ -90,36 +91,67 @@ void GetData(char *readInput, size_t bufferLength, size_t *dataLength)
 
     readInput[len] = '\0';
     Serial.flush();
-    Serial.print("PD:");
+    Serial.print("PD: ");
     Serial.println(readInput);
     (*dataLength) = len;
 }
 
-CATransportType_t GetConnectivityType()
+bool ParseData(char *buf, char *url, char *port, char *resourceUri)
+{
+    char *slash = strchr(buf, '/');
+    if (!slash)
+    {
+        return false;
+    }
+
+    strcpy(resourceUri, slash);
+
+    char *dot = strchr(buf, '.');
+    if (dot && dot < slash)
+    {
+        char *colon = strchr(buf, ':');
+
+        if (colon)
+        {
+            strncpy(port, colon, slash - colon);
+            memmove(port, port+1, strlen(port));
+        }
+        if (colon && colon < slash)
+        {
+            strncpy(url, buf, colon - buf);
+            return true;
+        }
+    }
+
+    strncpy(url, buf, slash - buf);
+    return true;
+}
+
+CATransportAdapter_t GetConnectivityType()
 {
     char type[2] = {0};
     Serial.println("Select network");
-    Serial.println("IPv4: 0");
-    Serial.println("EDR: 2");
-    Serial.println("LE: 3");
+    Serial.println("IP: 0");
+    Serial.println("GATT (BLE): 1");
+    Serial.println("RFCOMM (EDR): 2");
 
     size_t typeLen = 0;
     GetData(type, sizeof(type), &typeLen);
     if (0 >= typeLen)
     {
         Serial.println("i/p err,default ethernet");
-        return CA_IPV4;
+        return CA_ADAPTER_IP;
     }
     switch (type[0])
     {
         case '0':
-            return CA_IPV4;
+            return CA_ADAPTER_IP;
+        case '1':
+            return CA_ADAPTER_GATT_BTLE;
         case '2':
-            return CA_EDR;
-        case '3':
-            return CA_LE;
+            return CA_ADAPTER_RFCOMM_BTEDR;
     }
-    return CA_IPV4;
+    return CA_ADAPTER_IP;
 }
 
 void setup()
@@ -166,23 +198,19 @@ void loop()
                 StartDiscoveryServer();
                 break;
 
-            case 'F': // find resource
-                FindResource();
-                break;
-
             case 'R': // send request
                 SendRequest();
                 break;
+
             case 'E': //send request to all
                 SendRequestAll();
                 break;
-            case 'A': // advertise resource
-                AdvertiseResource();
-                break;
-
             case 'B': // send notification
                 SendNotification();
                 break;
+            case 'G': // Get network info
+                GetNetworkInfo();
+                break;
 
             case 'N': // select network
                 SelectNetwork();
@@ -222,7 +250,7 @@ void Initialize()
     }
     SelectNetwork();
     // set handler.
-    CARegisterHandler(RequestHandler, ResponseHandler);
+    CARegisterHandler(RequestHandler, ResponseHandler, ErrorHandler);
 }
 
 void StartListeningServer()
@@ -249,51 +277,13 @@ void StartDiscoveryServer()
     }
 }
 
-void FindResource()
-{
-    char buf[MAX_BUF_LEN] = {0};
-    Serial.println("============");
-    Serial.println("ex) /a/light");
-    Serial.println("uri: ");
-    size_t len = 0;
-    GetData(buf, sizeof(buf), &len);
-    if (0 >= len)
-    {
-        Serial.println("i/p err");
-        return;
-    }
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if (res != CA_STATUS_OK || (!token))
-    {
-        Serial.println("token error");
-        return;
-    }
-
-    Serial.print("token:");
-    Serial.println(token);
-
-    res = CAFindResource(buf, token, tokenLength);
-    if (res != CA_STATUS_OK)
-    {
-        Serial.print("find error: ");
-        Serial.println(res);
-    }
-    else
-    {
-        Serial.println("success: ");
-        Serial.println(buf);
-    }
-    CADestroyToken(token);
-}
-
 void SendRequest()
 {
     char buf[MAX_BUF_LEN] = {0};
-    CATransportType_t selectedNetwork;
+    char address[MAX_BUF_LEN] = {0};
+    char resourceUri[MAX_BUF_LEN] = {0};
+    char port[PORT_LENGTH] = {0};
+    CATransportAdapter_t selectedNetwork;
     selectedNetwork = GetConnectivityType();
 
     Serial.println("============");
@@ -309,13 +299,20 @@ void SendRequest()
         return;
     }
 
+    if (!ParseData(buf, address, port, resourceUri))
+    {
+        Serial.println("bad uri");
+        return;
+    }
+
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    CAResult_t res = CACreateRemoteEndpoint(buf,selectedNetwork,&endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateEndpoint(CA_DEFAULT_FLAGS, selectedNetwork, address, atoi(port),
+                                      &endpoint);
     if (res != CA_STATUS_OK)
     {
         Serial.println("Out of memory");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -352,12 +349,17 @@ void SendRequest()
     requestData.token = token;
     requestData.tokenLength = tokenLength;
     requestData.payload = (CAPayload_t)"Json Payload";
+    requestData.payloadSize = strlen((const char *) requestData.payload);
 
     requestData.type = msgType;
+    requestData.resourceUri = (char *)OICMalloc(strlen(resourceUri) + 1);
+    strcpy(requestData.resourceUri, resourceUri);
 
     CARequestInfo_t requestInfo = {CA_GET, {CA_MSG_RESET}};
     requestInfo.method = CA_GET;
+    requestInfo.isMulticast = false;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
 
     // send request
     CASendRequest(endpoint, &requestInfo);
@@ -369,24 +371,25 @@ void SendRequest()
     // destroy remote endpoint
     if (endpoint != NULL)
     {
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
     }
 
-    CADestroyToken(token);
     Serial.println("============");
 }
 
 void SendRequestAll()
 {
     char buf[MAX_BUF_LEN] = {0};
+    char address[MAX_BUF_LEN] = {0};
+    char resourceUri[MAX_BUF_LEN] = {0};
+    char port[PORT_LENGTH] = {0};
 
-    CATransportType_t selectedNetwork;
+    CATransportAdapter_t selectedNetwork;
     selectedNetwork = GetConnectivityType();
 
-    Serial.println("=========");
-    Serial.println("10.11.12.13:4545/resource_uri ( for IP )");
-    Serial.println("10:11:12:13:45:45/resource_uri ( for BT )");
-    Serial.println("uri : ");
+    Serial.println("\n=============================================\n");
+    Serial.println("ex) /a/light\n");
+    Serial.println("resource uri : ");
 
     size_t len = 0;
     GetData(buf, sizeof(buf), &len);
@@ -396,22 +399,24 @@ void SendRequestAll()
         return;
     }
 
+    if (!ParseData(buf, address, port, resourceUri))
+    {
+        Serial.println("bad uri");
+        return;
+    }
+
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    CAResult_t res = CACreateRemoteEndpoint(buf, selectedNetwork, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateEndpoint(CA_IPV4, selectedNetwork, address, atoi(port),
+                                        &endpoint);
 
     if (res != CA_STATUS_OK)
     {
         Serial.println("create remote endpoint error");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
-    CAGroupEndpoint_t *group = NULL;
-    group = (CAGroupEndpoint_t *)OICMalloc(sizeof(CAGroupEndpoint_t));
-    group->transportType = endpoint->transportType;
-    group->resourceUri = endpoint->resourceUri;
-
     // create token
     CAToken_t token = NULL;
     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
@@ -428,16 +433,19 @@ void SendRequestAll()
     CAInfo_t requestData = {CA_MSG_RESET};
     requestData.token = token;
     requestData.tokenLength = tokenLength;
-    requestData.payload = "Temp Json Payload";
+    requestData.payload = (CAPayload_t)"Temp Json Payload";
+    requestData.payloadSize = strlen((const char *) requestData.payload);
     requestData.type = CA_MSG_NONCONFIRM;
+    requestData.resourceUri = (char *)OICMalloc(strlen(resourceUri) + 1);
+    strcpy(requestData.resourceUri, resourceUri);
 
     CARequestInfo_t requestInfo = {CA_GET, {CA_MSG_RESET}};
     requestInfo.method = CA_GET;
+    requestInfo.isMulticast = true;
     requestInfo.info = requestData;
 
     // send request
-    // CASendRequest(endpoint, &requestInfo);
-    CASendRequestToAll(group, &requestInfo);
+    CASendRequest(endpoint, &requestInfo);
 
     if (NULL != token)
     {
@@ -447,115 +455,19 @@ void SendRequestAll()
     // destroy remote endpoint
     if (endpoint != NULL)
     {
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
     }
 
-    OICFree(group);
     Serial.println("==========");
 }
 
-void AdvertiseResource()
-{
-    char buf[MAX_BUF_LEN] = {0};
-
-    Serial.println("============");
-    Serial.println("uri: ");
-
-    size_t len = 0;
-    GetData(buf, sizeof(buf), &len);
-    if (0 >= len)
-    {
-        Serial.println("no i/p");
-        return;
-    }
-
-    int16_t optionNum = 0;
-    char optionData[MAX_OPT_LEN] = {0};
-    char optionNumBuf[2] = {0};
-
-    Serial.println("Option Num: ");
-    GetData(optionNumBuf, sizeof(optionNumBuf), &len);
-    if (0 >= len)
-    {
-        Serial.println("no i/p,0 option");
-    }
-    else
-    {
-        optionNum = atoi(optionNumBuf);
-        Serial.println(optionNum);
-    }
-
-    CAHeaderOption_t *headerOpt = NULL;
-    if (optionNum > 0)
-    {
-        headerOpt = (CAHeaderOption_t *) OICCalloc(optionNum, sizeof(CAHeaderOption_t));
-        if (NULL == headerOpt)
-        {
-            Serial.println("Out of memory");
-            return;
-        }
-    }
-
-    int i;
-    for (i = 0 ; i < optionNum ; i++)
-    {
-        int optionID = 0;
-        char getOptionID[4];
-        Serial.println("Opt ID:");
-        GetData(getOptionID, sizeof(getOptionID), &len);
-        if (0 >= len)
-        {
-            Serial.println("no i/p");
-            continue;
-        }
-        else
-        {
-            optionID = atoi(getOptionID);
-        }
-
-        memset(optionData, 0, sizeof(optionData));
-        Serial.println("Opt Data:");
-        GetData(optionData, sizeof(optionData), &len);
-        if (0 >= len)
-        {
-            Serial.println("no i/p");
-            continue;
-        }
-
-        headerOpt[i].optionID = optionID;
-        memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
-        Serial.println("ID:");
-        Serial.println(optionID);
-        Serial.println("Data:");
-        Serial.println(optionData);
-
-        headerOpt[i].optionLength = (uint16_t)strlen(optionData);
-    }
-
-    Serial.println("============");
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if (res != CA_STATUS_OK || (!token))
-    {
-        Serial.println("token error");
-        return;
-    }
-
-    Serial.println("token");
-    Serial.println(token);
-
-    CAAdvertiseResource(buf, token, tokenLength, headerOpt, (uint8_t)optionNum);
-    OICFree(headerOpt);
-    CADestroyToken(token);
-}
-
 void SendNotification()
 {
     char buf[MAX_BUF_LEN] = {0};
-    CATransportType_t selectedNetwork;
+    char address[MAX_BUF_LEN] = {0};
+    char resourceUri[MAX_BUF_LEN] = {0};
+    char port[PORT_LENGTH] = {0};
+    CATransportAdapter_t selectedNetwork;
     selectedNetwork = GetConnectivityType();
 
     Serial.println("============");
@@ -571,13 +483,20 @@ void SendNotification()
         return;
     }
 
+    if (!ParseData(buf, address, port, resourceUri))
+    {
+        Serial.println("bad uri");
+        return;
+    }
+
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    CAResult_t res = CACreateRemoteEndpoint(buf,selectedNetwork,&endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateEndpoint(CA_DEFAULT_FLAGS, selectedNetwork, address, atoi(port),
+                                      &endpoint);
     if (CA_STATUS_OK != res)
     {
         Serial.println("Out of memory");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -596,9 +515,12 @@ void SendNotification()
     respondData.token = token;
     respondData.tokenLength = tokenLength;
     respondData.payload = (CAPayload_t)"Notification Data";
+    respondData.payloadSize = strlen((const char *) respondData.payload);
+    respondData.resourceUri = (char *)OICMalloc(strlen(resourceUri) + 1);
+    strcpy(respondData.resourceUri, resourceUri);
 
     CAResponseInfo_t responseInfo = {CA_BAD_REQ, {CA_MSG_RESET}};
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = respondData;
 
     // send request
@@ -606,7 +528,7 @@ void SendNotification()
     // destroy remote endpoint
     if (NULL != endpoint)
     {
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
     }
 
     CADestroyToken(token);
@@ -619,9 +541,9 @@ void SelectNetwork()
 
     Serial.println("============");
     Serial.println("Select network");
-    Serial.println("IPv4: 0");
-    Serial.println("EDR: 2");
-    Serial.println("LE: 3\n");
+    Serial.println("IP: 0");
+    Serial.println("LE: 1");
+    Serial.println("EDR: 2\n");
 
     size_t len = 0;
     GetData(buf, sizeof(buf), &len);
@@ -668,15 +590,15 @@ void SelectNetwork()
 #endif
             }
             break;
+        case 1:
+            g_isLeSelected = true;
+            break;
         case 2:
             // Nothing TBD here
             break;
-        case 3:
-            g_isLeSelected = true;
-            break;
     }
 
-    CASelectNetwork(CATransportType_t(1<<number));
+    CASelectNetwork(CATransportAdapter_t(1<<number));
     Serial.println("============");
 }
 
@@ -687,8 +609,8 @@ void UnselectNetwork()
     Serial.println("============");
     Serial.println("Unselect network");
     Serial.println("IPv4: 0");
-    Serial.println("EDR: 2");
-    Serial.println("LE: 3\n");
+    Serial.println("LE: 1");
+    Serial.println("EDR: 2\n");
 
     size_t len = 0;
     GetData(buf, sizeof(buf), &len);
@@ -703,12 +625,43 @@ void UnselectNetwork()
     {
         g_isLeSelected = false;
     }
-    CAUnSelectNetwork(1 << number);
+    CAUnSelectNetwork((CATransportAdapter_t)(1 << number));
     Serial.println("Terminate");
     CATerminate();
     Serial.println("============");
 }
 
+void GetNetworkInfo()
+{
+    CAEndpoint_t *tempInfo = NULL;
+    uint32_t tempSize = 0;
+    CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
+    if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
+    {
+        Serial.println("Network not connected");
+        free(tempInfo);
+        return;
+    }
+    Serial.println("=========");
+    Serial.print("Network info total size is ");
+    Serial.println(tempSize);
+    int index;
+    for (index = 0; index < tempSize; index++)
+    {
+        Serial.print("Type: ");
+        Serial.println(tempInfo[index].adapter);
+        if (CA_ADAPTER_IP == tempInfo[index].adapter)
+        {
+            Serial.print("Address: ");
+            Serial.println(tempInfo[index].addr);
+            Serial.print("Port: ");
+            Serial.println(tempInfo[index].port);
+        }
+    }
+    free(tempInfo);
+    Serial.println("=======");
+}
+
 void PrintMenu()
 {
 
@@ -716,11 +669,10 @@ void PrintMenu()
     Serial.println("i: Initialize");
     Serial.println("s: start listening server");
     Serial.println("d: start discovery server");
-    Serial.println("f: find resource");
     Serial.println("r: send request");
     Serial.println("e: send request to all");
-    Serial.println("a: advertise resource");
     Serial.println("b: send notification");
+    Serial.println("g: get network info");
     Serial.println("n: select network");
     Serial.println("x: unselect network");
     Serial.println("h: handle request response");
@@ -734,11 +686,11 @@ void HandleRequestResponse()
     CAHandleRequestResponse();
 }
 
-void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
+void RequestHandler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
 {
     if (!object)
     {
-        Serial.println("Remote endpoint is NULL!");
+        Serial.println("endpoint is NULL!");
         return;
     }
 
@@ -748,15 +700,17 @@ void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *req
         return;
     }
 
-    Serial.println("uri: ");
-    Serial.println(object->resourceUri);
-    Serial.println("RAddr: ");
-    Serial.println(object->addressInfo.IP.ipAddress);
-    Serial.println("Port: ");
-    Serial.println(object->addressInfo.IP.port);
-    Serial.println("data: ");
-    Serial.println(requestInfo->info.payload);
-    Serial.println("Type: ");
+    Serial.print("RAddr: ");
+    Serial.println(object->addr);
+    Serial.print("Port: ");
+    Serial.println(object->port);
+    Serial.print("uri: ");
+    Serial.println(requestInfo->info.resourceUri);
+    Serial.print("data: ");
+    Serial.println((char*)requestInfo->info.payload);
+    Serial.print("data size: ");
+    Serial.println(requestInfo->info.payloadSize);
+    Serial.print("Type: ");
     Serial.println(requestInfo->info.type);
 
     if (requestInfo->info.options)
@@ -765,30 +719,34 @@ void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *req
         uint32_t i;
         for (i = 0; i < len; i++)
         {
-            Serial.println("Option:");
+            Serial.print("Option: ");
             Serial.println(i+1);
-            Serial.println("ID:");
+            Serial.print("ID: ");
             Serial.println(requestInfo->info.options[i].optionID);
-            Serial.println("Data:");
+            Serial.print("Data: ");
             Serial.println((char*)requestInfo->info.options[i].optionData);
         }
     }
     Serial.println("send response");
-    SendResponse((CARemoteEndpoint_t *)object, (requestInfo != NULL) ? &requestInfo->info : NULL);
+    SendResponse((CAEndpoint_t *)object, (requestInfo != NULL) ? &requestInfo->info : NULL);
 }
 
-void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
+void ResponseHandler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
-    if (object && object->resourceUri)
+    if (object)
     {
         Serial.print("uri: ");
-        Serial.println(object->resourceUri);
+        Serial.println(object->addr);
     }
 
     if (responseInfo)
     {
+        Serial.print("uri: ");
+        Serial.println(responseInfo->info.resourceUri);
         Serial.print("data: ");
-        Serial.println(responseInfo->info.payload);
+        Serial.println((char*)responseInfo->info.payload);
+        Serial.print("data size: ");
+        Serial.println(responseInfo->info.payloadSize);
         Serial.print("Type: ");
         Serial.println(responseInfo->info.type);
         Serial.print("res result=");
@@ -796,31 +754,104 @@ void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *r
     }
 }
 
-void SendResponse(CARemoteEndpoint_t *endpoint, const CAInfo_t* info)
+void ErrorHandler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    Serial.println("ErrorInfo");
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        Serial.print("result: ");
+        Serial.println(errorInfo->result);
+        Serial.print("token: ");
+        Serial.println(info->token);
+        Serial.print("messageId: ");
+        Serial.println(info->messageId);
+        Serial.print("type: ");
+        Serial.println(info->type);
+        Serial.print("resourceUri: ");
+        Serial.println(info->resourceUri);
+        Serial.print("payload: ");
+        Serial.println((char*)info->payload);
+    }
+
+    return;
+}
+
+void SendResponse(CAEndpoint_t *endpoint, const CAInfo_t* info)
 {
     char buf[MAX_BUF_LEN] = {0};
 
     Serial.println("============");
-    CAInfo_t responseData = {CA_MSG_RESET};
-    if(info && info->type == CA_MSG_CONFIRM)
-    {
-        responseData.type = CA_MSG_ACKNOWLEDGE;
-    }
-    else
+    Serial.println("Select Message Type");
+    Serial.println("CON: 0");
+    Serial.println("NON: 1");
+    Serial.println("ACK: 2");
+    Serial.println("RESET: 3");
+
+    size_t len = 0;
+    int messageType = 0;
+    while(1)
     {
-        responseData.type = CA_MSG_NONCONFIRM;
+        GetData(buf, sizeof(buf), &len);
+        if(len >= 1)
+        {
+            messageType = buf[0] - '0';
+            if (messageType >= 0 && messageType <= 3)
+            {
+                break;
+            }
+        }
+        Serial.println("Invalid type");
+    }
+
+    int respCode = 0;
+    if(messageType != 3)
+    {
+        Serial.println("============");
+        Serial.println("Enter Resp Code:");
+        Serial.println("For Ex: Empty  : 0");
+        Serial.println("Success: 200");
+        Serial.println("Created: 201");
+        Serial.println("Deleted: 202");
+        Serial.println("Valid  : 203");
+        Serial.println("Changed: 204");
+        Serial.println("Content: 205");
+        Serial.println("BadReq : 400");
+        Serial.println("BadOpt : 402");
+        Serial.println("NotFnd : 404");
+        Serial.println("Internal Srv Err:500");
+        Serial.println("Timeout: 504");
+        while(1)
+        {
+            GetData(buf, sizeof(buf), &len);
+            if(len >= 1)
+            {
+                respCode = atoi(buf);
+                if (respCode >= 0 && respCode <= 504)
+                {
+                    break;
+                }
+            }
+            Serial.println("Invalid response");
+        }
     }
 
+    CAInfo_t responseData = {CA_MSG_RESET};
+    responseData.type = static_cast<CAMessageType_t>(messageType);
     responseData.messageId = (info != NULL) ? info->messageId : 0;
-    responseData.token = (info != NULL) ? (CAToken_t)info->token : NULL;
-    responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
-    responseData.payload = (CAPayload_t)"response payload";
-
+    responseData.resourceUri = (info != NULL) ? info->resourceUri : 0;
+    if(messageType != 3)
+    {
+        responseData.token = (info != NULL) ? info->token : NULL;
+        responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
+        responseData.payload = reinterpret_cast<CAPayload_t>(const_cast<char*>("response payload"));
+        responseData.payloadSize = strlen((const char *) responseData.payload);
+    }
     CAResponseInfo_t responseInfo = {CA_BAD_REQ, {CA_MSG_RESET}};
-    responseInfo.result = (CAResponseResult_t)203;
+    responseInfo.result = static_cast<CAResponseResult_t>(respCode);
     responseInfo.info = responseData;
-
-    // send request (connectivityType from remoteEndpoint of request Info)
+    // send request (transportType from remoteEndpoint of request Info)
     CAResult_t res = CASendResponse(endpoint, &responseInfo);
     if(res != CA_STATUS_OK)
     {
index 99f365d..bc122b4 100644 (file)
@@ -1,31 +1,17 @@
-//----------------------------------------------------------------------
-// NOTICE - Transition to SCONS
-//----------------------------------------------------------------------
-
-The IoTivity build system is transitioning to SCONS. Although the 
-makefiles are still available (until v1.0) and some developers are 
-still using them, they are currently no longer supported. To learn more 
-about building using SCONS see Readme.scons.txt in the repository root 
-directory. The build steps used in continuous integration can be found
+The build steps used in continuous integration can be found
 in auto_build.sh which is also in the the repository root directory.
 
-//----------------------------------------------------------------------
+Go to the top directory of 'iotivity' project(Note: should always run 'scons'
+command in this directory)
 
-#1. build "connectivity" project
-       - execute make command in "connectivity/build/" folder.
+#1. build "connectivity" project (for release mode)
+       - execute 'scons resource/csdk/connectivity/' command
 
 #2. build "example" for linux
-       - execute make command in "connectivity/samples/linux/" folder.
+       - execute 'scons resource/csdk/connectivity/samples/linux/' command
 
 #3. execute sample program
        - you should link the "connectivity_abstraction" library.
-       ex. LD_LIBRARY_PATH=../../../build/out ./sample_main
-       
-#4     execute sample.sh in "connectivity/samples/linux/" folder
- ex.    $./sample.sh (This will make a clean build and execute application)
-
-#4     execute sample.sh in if you want to build with DTLS
- ex.    $./sample.sh  WITH_DTLS (This will make a clean build and execute application)
-
-
+       ex. cd out/linux/x86/release/resource/csdk/connectivity/samples/linux
+           ./casample
 
old mode 100644 (file)
new mode 100755 (executable)
index 9c0a0a3..9bcc7e2
@@ -9,9 +9,9 @@ sample_env = env.Clone()
 ca_os = sample_env.get('TARGET_OS')
 ca_transport = sample_env.get('TARGET_TRANSPORT')
 secured = sample_env.get('SECURED')
+with_ra = sample_env.get('WITH_RA')
 root_dir = './../../'
 
-
 #####################################################################
 # Source files and Target(s)
 ######################################################################
@@ -36,17 +36,25 @@ sample_src = ['./sample_main.c',]
 print " sample src %s" % sample_src
 #env.StaticLibrary('casample', sample_src)
 
-sample_env.PrependUnique(LIBPATH = [sample_env.get('BUILD_DIR'), '.',])
+sample_env.PrependUnique(LIBPATH = [sample_env.get('BUILD_DIR'), '.'])
 sample_env.PrependUnique(RPATH = [sample_env.get('BUILD_DIR'), '.',])
-sample_env.PrependUnique(LIBS = ['connectivity_abstraction', 'coap', 'pthread', 'rt'])
+sample_env.PrependUnique(LIBS = ['connectivity_abstraction'])
+if with_ra:
+       sample_env.AppendUnique(LIBS = ['ra_xmpp'])
+sample_env.AppendUnique(LIBS = ['coap', 'pthread'])
+
+if ca_os not in ['darwin']:
+       sample_env.PrependUnique(LIBS = ['rt'])
 
 if secured == '1':
+       current_dir=env.get('SRC_DIR')
        sample_env.AppendUnique(CPPPATH = [root_dir + 'external/inc/'])
        sample_env.AppendUnique(LIBS = ['tinydtls'])
        casample =sample_env.Program('casample', [sample_src])
 else:
        casample =sample_env.Program('casample', [sample_src])
 env.InstallTarget(casample, 'casample')
+env.UserInstallTargetBin(casample, 'casample')
 
 
 
diff --git a/resource/csdk/connectivity/samples/linux/sample.sh b/resource/csdk/connectivity/samples/linux/sample.sh
deleted file mode 100755 (executable)
index bebc545..0000000
+++ /dev/null
@@ -1,36 +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.
-# *
-#******************************************************************/
-
-cd ../../build/linux
-make clean
-if echo $1 | grep -q -i "WITH_DTLS"
-then
-make DTLS=1
-else
-make
-fi
-
-cd ../../samples/linux
-make clean
-make
-
-cd out
-LD_LIBRARY_PATH=../../../build/out ./sample_main
-
index d7c2354..edfe4ef 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "cacommon.h"
 #include "cainterface.h"
-#include "oic_malloc.h"
 #ifdef __WITH_DTLS__
 #include "ocsecurityconfig.h"
 #endif
 
 int g_received;
 uint16_t g_local_secure_port = SECURE_DEFAULT_PORT;
-CATransportType_t g_selected_nw_type = CA_IPV4;
+CATransportAdapter_t g_selected_nw_type = CA_ADAPTER_IP;
 const char *MESSAGE_TYPE[] = {"CON", "NON", "ACK", "RESET"};
 
+typedef struct
+{
+    char ipAddress[CA_IPADDR_SIZE];
+    uint16_t port;
+} addressSet_t;
+
 char get_menu();
 void process();
 CAResult_t get_network_type();
@@ -66,29 +71,36 @@ CAResult_t get_input_data(char *buf, int32_t length);
 
 void start_listening_server();
 void start_discovery_server();
-void find_resource();
 void send_request();
 void send_request_all();
-void advertise_resource();
 void send_notification();
 void select_network();
 void unselect_network();
 void handle_request_response();
-void find_fixed_resource();
 void get_network_info();
 void send_secure_request();
 
-void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
-void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
-void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info);
+void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
+void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info);
 void get_resource_uri(char *URI, char *resourceURI, int length);
 int get_secure_information(CAPayload_t payLoad);
+int get_address_set(const char *pAddress, addressSet_t* outAddress);
+void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
+CAHeaderOption_t* get_option_data(CAInfo_t* requestData);
 
 static CAToken_t g_last_request_token = NULL;
-static const char SECURE_COAPS_PREFIX[] = "coaps://";
+
+static const char COAP_PREFIX[] =  "coap://";
+static const char COAPS_PREFIX[] = "coaps://";
+static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
+static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
+
 static const char SECURE_INFO_DATA[] =
                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
-                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
+                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
+                                     "%d}}]}";
 static const char NORMAL_INFO_DATA[] =
                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
@@ -222,7 +234,7 @@ int main()
 #endif
 
     // set handler.
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
 
     process();
 
@@ -269,21 +281,11 @@ void process()
                 start_discovery_server();
                 break;
 
-            case 'f': // find resource
-            case 'F':
-                find_resource();
-                break;
-
             case 'r': // send request
             case 'R':
                 send_request();
                 break;
 
-            case 'a': // advertise resource
-            case 'A':
-                advertise_resource();
-                break;
-
             case 'b': // send notification
             case 'B':
                 send_notification();
@@ -304,21 +306,6 @@ void process()
                 handle_request_response();
                 break;
 
-            case 'y':
-            case 'Y':
-                while (1)
-                {
-                    g_received = 0;
-                    find_fixed_resource();
-                    while (g_received == 0)
-                    {
-                        sleep(1);
-                        handle_request_response();
-
-                    }
-                }
-                break;
-
             case 'w':
             case 'W':
                 g_received = 0;
@@ -383,80 +370,6 @@ void start_discovery_server()
     }
 }
 
-void find_fixed_resource()
-{
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        printf("Token generate error!!");
-        return;
-    }
-    printf("Generated token %s\n", token);
-
-    char buf[MAX_BUF_LEN] = { 0 };
-    strcpy(buf, "/a/light");
-
-    res = CAFindResource(buf, token, tokenLength);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Find resource error : %d\n", res);
-    }
-    else
-    {
-        printf("Find resource to %s URI\n", buf);
-    }
-
-    // delete token
-    CADestroyToken(token);
-
-    printf("=============================================\n");
-}
-
-void find_resource()
-{
-    printf("\n=============================================\n");
-    printf("ex) /a/light\n");
-    printf("reference uri : ");
-
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
-    {
-        return;
-    }
-
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        printf("Token generate error!!\n");
-        return;
-    }
-
-    printf("Generated token %s\n", token);
-
-    res = CAFindResource(buf, token, tokenLength);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Find resource error : %d\n", res);
-        CADestroyToken(token);
-    }
-    else
-    {
-        printf("Find resource to %s URI\n", buf);
-        CADestroyToken(g_last_request_token);
-        g_last_request_token = token;
-    }
-
-    printf("=============================================\n");
-}
-
 void send_request()
 {
     CAResult_t res = get_network_type();
@@ -497,8 +410,15 @@ void send_request()
     }
 
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(uri, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CATransportFlags_t flags;
+
+    printf("URI : %s\n", uri);
+    addressSet_t address = {};
+    parsing_coap_uri(uri, &address, &flags);
+
+    res = CACreateEndpoint(flags, g_selected_nw_type,
+                           (const char*)address.ipAddress, address.port, &endpoint);
     if (CA_STATUS_OK != res || !endpoint)
     {
         printf("Failed to create remote endpoint, error code : %d\n", res);
@@ -512,7 +432,7 @@ void send_request()
     char buf[MAX_BUF_LEN] = { 0 };
     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
     {
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -526,22 +446,22 @@ void send_request()
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error, error code : %d\n", res);
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
     printf("Generated token %s\n", token);
 
     // extract relative resourceuri from give uri
-    printf("URI : %s\n", uri);
-
     char resourceURI[RESOURCE_URI_LENGTH + 1] = {0};
     get_resource_uri(uri, resourceURI, RESOURCE_URI_LENGTH);
+    printf("resourceURI : %s\n", resourceURI);
 
     // create request data
     CAInfo_t requestData = { 0 };
     requestData.token = token;
     requestData.tokenLength = tokenLength;
+    requestData.resourceUri = (CAURI_t)resourceURI;
 
     if (strcmp(secureRequest, "1") == 0)
     {
@@ -550,11 +470,13 @@ void send_request()
         if (NULL == requestData.payload)
         {
             printf("Memory allocation fail\n");
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             CADestroyToken(token);
             return;
         }
-        snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_local_secure_port);
+        snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
+                 (const char *) resourceURI, g_local_secure_port);
+        requestData.payloadSize = length;
     }
     else
     {
@@ -563,17 +485,21 @@ void send_request()
         if (NULL == requestData.payload)
         {
             printf("Memory allocation fail\n");
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             CADestroyToken(token);
             return;
         }
-        snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
+        snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA,
+                 (const char *) resourceURI);
+        requestData.payloadSize = length;
     }
     requestData.type = msgType;
+    CAHeaderOption_t* headerOpt = get_option_data(&requestData);
 
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
 
     // send request
     res = CASendRequest(endpoint, &requestInfo);
@@ -582,13 +508,17 @@ void send_request()
         printf("Could not send request : %d\n", res);
     }
 
+    if (headerOpt)
+    {
+        free(headerOpt);
+    }
+
     //destroy token
     CADestroyToken(token);
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
     free(requestData.payload);
 
-
     printf("=============================================\n");
 }
 
@@ -604,11 +534,11 @@ void send_secure_request()
     {
         return;
     }
-    snprintf(uri, MAX_BUF_LEN, "%s%s:5684/a/light", SECURE_COAPS_PREFIX, ipv4addr);
+    snprintf(uri, MAX_BUF_LEN, "%s%s:5684/a/light", COAPS_PREFIX, ipv4addr);
 
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    CAResult_t res = CACreateRemoteEndpoint(uri, CA_IPV4, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateEndpoint(0, CA_ADAPTER_IP, ipv4addr, SECURE_DEFAULT_PORT, &endpoint);
     if (CA_STATUS_OK != res)
     {
         printf("Failed to create remote endpoint, error code: %d\n", res);
@@ -638,6 +568,7 @@ void send_secure_request()
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
 
     // send request
     CASendRequest(endpoint, &requestInfo);
@@ -645,7 +576,7 @@ void send_secure_request()
 exit:
     // cleanup
     CADestroyToken(token);
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
     printf("=============================================\n");
 }
 
@@ -662,30 +593,29 @@ void send_request_all()
     printf("ex) /a/light\n");
     printf("resource uri : ");
 
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+    char resourceURI[MAX_BUF_LEN] = { 0 };
+    if (CA_STATUS_OK != get_input_data(resourceURI, MAX_BUF_LEN))
     {
         return;
     }
 
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(buf, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    res = CACreateEndpoint(0, g_selected_nw_type, NULL, 0, &endpoint);
     if (CA_STATUS_OK != res)
     {
         printf("Create remote endpoint error, error code: %d\n", res);
         return;
     }
 
-    CAGroupEndpoint_t *group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t));
+    CAEndpoint_t *group = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
     if (NULL == group)
     {
         printf("Memory allocation failed!\n");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
-    group->transportType = endpoint->transportType;
-    group->resourceUri = endpoint->resourceUri;
+    group->adapter = endpoint->adapter;
 
     // create token
     CAToken_t token = NULL;
@@ -695,7 +625,7 @@ void send_request_all()
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error!!\n");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         free(group);
         return;
     }
@@ -705,15 +635,20 @@ void send_request_all()
     CAInfo_t requestData = { 0 };
     requestData.token = token;
     requestData.tokenLength = tokenLength;
-    requestData.payload = "Temp Json Payload";
+    requestData.payload = (CAPayload_t) "TempJsonPayload";
+    requestData.payloadSize = strlen((const char *) requestData.payload);
     requestData.type = CA_MSG_NONCONFIRM;
+    requestData.resourceUri = (CAURI_t)resourceURI;
+
+    CAHeaderOption_t* headerOpt = get_option_data(&requestData);
 
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = true;
 
     // send request
-    res = CASendRequestToAll(group, &requestInfo);
+    res = CASendRequest(group, &requestInfo);
     if (CA_STATUS_OK != res)
     {
         printf("Could not send request to all\n");
@@ -725,98 +660,16 @@ void send_request_all()
         g_last_request_token = token;
     }
 
-    // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
-    free(group);
-
-    printf("=============================================\n");
-}
-
-void advertise_resource()
-{
-    printf("\n=============================================\n");
-    printf("uri : ");
-
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+    if (headerOpt)
     {
-        return;
-    }
-
-    char optionNumBuf[MAX_BUF_LEN] = { 0 };
-    char optionData[MAX_OPT_LEN] = { 0 } ;
-
-    printf("Option Num : ");
-    if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
-    {
-        return;
-    }
-    int optionNum = atoi(optionNumBuf);
-
-    CAHeaderOption_t * headerOpt = (CAHeaderOption_t *)
-            calloc(1, optionNum * sizeof(CAHeaderOption_t));
-    if (NULL == headerOpt)
-    {
-        printf("Memory allocation failed!\n");
-        return;
-    }
-
-    int i;
-    for (i = 0; i < optionNum; i++)
-    {
-        char getOptionID[MAX_BUF_LEN] = { 0 } ;
-
-        printf("[%d] Option ID : ", i + 1);
-        if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
-        {
-            free(headerOpt);
-            return;
-        }
-        int optionID = atoi(getOptionID);
-
-        headerOpt[i].optionID = optionID;
-
-        printf("[%d] Option Data : ", i + 1);
-        if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
-        {
-            free(headerOpt);
-            return;
-        }
-
-        memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
-        printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData);
-
-        headerOpt[i].optionLength = (uint16_t) strlen(optionData);
-    }
-    printf("\n=============================================\n");
-
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        printf("Token generate error!!\n");
         free(headerOpt);
-        return;
     }
 
-    printf("Generated token %s\n", token);
-
-    res = CAAdvertiseResource(buf, token, tokenLength, headerOpt, (uint8_t) optionNum);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Could not start advertise resource\n");
-        CADestroyToken(token);
-    }
-    else
-    {
-        CADestroyToken(g_last_request_token);
-        g_last_request_token = token;
-    }
+    // destroy remote endpoint
+    CADestroyEndpoint(endpoint);
+    free(group);
 
-    free(headerOpt);
+    printf("=============================================\n");
 }
 
 void send_notification()
@@ -829,12 +682,12 @@ void send_notification()
 
     printf("\n=============================================\n");
     printf("Enter the URI like below....\n");
-    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
-    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
     printf("uri : ");
 
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+    char uri[MAX_BUF_LEN] = { 0 };
+    if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
     {
         return;
     }
@@ -855,9 +708,13 @@ void send_notification()
 
     int messageType = messageTypeBuf[0] - '0';
 
+    CATransportFlags_t flags;
+    addressSet_t address = {};
+    parsing_coap_uri(uri, &address, &flags);
+
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(buf, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
     if (CA_STATUS_OK != res)
     {
         printf("Create remote endpoint error, error code: %d\n", res);
@@ -872,7 +729,7 @@ void send_notification()
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error!!\n");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -880,11 +737,14 @@ void send_notification()
 
     CAInfo_t respondData = { 0 };
     respondData.token = token;
-    respondData.payload = "Temp Notification Data";
+    respondData.tokenLength = tokenLength;
+    respondData.payload = (CAPayload_t) "TempNotificationData";
+    respondData.payloadSize = strlen((const char *) respondData.payload);
     respondData.type = messageType;
+    respondData.resourceUri = (CAURI_t)uri;
 
     CAResponseInfo_t responseInfo = { 0 };
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = respondData;
 
     // send request
@@ -901,7 +761,7 @@ void send_notification()
     // destroy token
     CADestroyToken(token);
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
 
     printf("\n=============================================\n");
 }
@@ -910,9 +770,9 @@ void select_network()
 {
     printf("\n=============================================\n");
     printf("\tselect network\n");
-    printf("IPv4 : 0\n");
-    printf("EDR  : 2\n");
-    printf("LE   : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     char buf[MAX_BUF_LEN] = { 0 };
@@ -946,9 +806,9 @@ void unselect_network()
 {
     printf("\n=============================================\n");
     printf("\tunselect enabled network\n");
-    printf("IPv4 : 0\n");
-    printf("EDR : 2\n");
-    printf("LE : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     char buf[MAX_BUF_LEN] = { 0 };
@@ -984,16 +844,13 @@ char get_menu()
     printf("\t\tMenu\n");
     printf("\ts : start server\n");
     printf("\tc : start client\n");
-    printf("\tf : find resource\n");
     printf("\tr : send request\n");
     printf("\tt : send request to all\n");
-    printf("\ta : advertise resource\n");
     printf("\tb : send notification\n");
     printf("\tn : select network\n");
     printf("\tx : unselect network\n");
     printf("\tg : get network information\n");
     printf("\th : handle request response\n");
-    printf("\ty : run static client\n");
     printf("\tz : run static server\n");
     printf("\tw : send secure request\n");
     printf("\tq : quit\n");
@@ -1026,7 +883,7 @@ void handle_request_response()
 
 void get_network_info()
 {
-    CALocalConnectivity_t *tempInfo = NULL;
+    CAEndpoint_t *tempInfo = NULL;
     uint32_t tempSize = 0;
 
     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
@@ -1043,25 +900,25 @@ void get_network_info()
     int index;
     for (index = 0; index < tempSize; index++)
     {
-        printf("Type: %d\n", tempInfo[index].type);
-        if (CA_IPV4 == tempInfo[index].type)
+        printf("Type: %d\n", tempInfo[index].adapter);
+        if (CA_ADAPTER_IP == tempInfo[index].adapter)
         {
-            printf("Address: %s\n", tempInfo[index].addressInfo.IP.ipAddress);
-            printf("Port: %d\n", tempInfo[index].addressInfo.IP.port);
+            printf("Address: %s\n", tempInfo[index].addr);
+            printf("Port: %d\n", tempInfo[index].port);
         }
-        else if (CA_EDR == tempInfo[index].type)
+        else if (CA_ADAPTER_RFCOMM_BTEDR == tempInfo[index].adapter)
         {
-            printf("Address: %s\n", tempInfo[index].addressInfo.BT.btMacAddress);
+            printf("Address: %s\n", tempInfo[index].addr);
         }
-        else if (CA_LE == tempInfo[index].type)
+        else if (CA_ADAPTER_GATT_BTLE == tempInfo[index].adapter)
         {
-            printf("Address: %s\n", tempInfo[index].addressInfo.LE.leMacAddress);
+            printf("Address: %s\n", tempInfo[index].addr);
         }
-        printf("Secured: %s\n\n", tempInfo[index].isSecured ? "true" : "false");
+        printf("Secured: %s\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" : "false");
 
-        if (tempInfo[index].isSecured)
+        if (tempInfo[index].flags & CA_SECURE)
         {
-            g_local_secure_port = tempInfo[index].addressInfo.IP.port;
+            g_local_secure_port = tempInfo[index].port;
             printf("Secured: in global %d\n\n", g_local_secure_port);
         }
     }
@@ -1070,7 +927,7 @@ void get_network_info()
     printf("##############################################################");
 }
 
-void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
+void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
 {
     if (NULL == object || NULL == requestInfo)
     {
@@ -1087,19 +944,18 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
     }
 
     printf("##########received request from remote device #############\n");
-    printf("Uri: %s\n", object->resourceUri);
-    if (CA_IPV4 == object->transportType)
+    if (CA_ADAPTER_IP == object->adapter)
     {
-        printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
-               object->addressInfo.IP.port, object->isSecured);
+        printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
+               object->port, object->flags & CA_SECURE);
     }
-    else if (CA_EDR == object->transportType)
+    else if (CA_ADAPTER_RFCOMM_BTEDR == object->adapter)
     {
-        printf("Remote Address: %s \n", object->addressInfo.BT.btMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
-    else if (CA_LE == object->transportType)
+    else if (CA_ADAPTER_GATT_BTLE == object->adapter)
     {
-        printf("Remote Address: %s \n", object->addressInfo.LE.leMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
     printf("Data: %s\n", requestInfo->info.payload);
     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
@@ -1120,39 +976,22 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
 
     //Check if this has secure communication information
     if (requestInfo->info.payload &&
-            (CA_IPV4 == object->transportType))
+            (CA_ADAPTER_IP == object->adapter))
     {
         int securePort = get_secure_information(requestInfo->info.payload);
         if (0 < securePort) //Set the remote endpoint secure details and send response
         {
             printf("This is secure resource...\n");
 
-            //length of "coaps://"
-            size_t length = sizeof(SECURE_COAPS_PREFIX) - 1;
-
-            // length of "ipaddress:port"
-            length += strlen(object->addressInfo.IP.ipAddress) + PORT_LENGTH;
-            length += strlen(object->resourceUri) + 1;
-
-            char *uri = calloc(1, sizeof(char) * length);
-            if (!uri)
-            {
-                printf("Failed to create new uri\n");
-                return;
-            }
-            sprintf(uri, "%s%s:%d/%s", SECURE_COAPS_PREFIX, object->addressInfo.IP.ipAddress,
-                    object->addressInfo.IP.port, object->resourceUri);
-
-            CARemoteEndpoint_t *endpoint = NULL;
-            if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->transportType, &endpoint))
+            CAEndpoint_t *endpoint = NULL;
+            if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
+                                                 object->port, &endpoint))
             {
                 printf("Failed to create duplicate of remote endpoint!\n");
                 return;
             }
-            endpoint->isSecured = true;
+            endpoint->flags = CA_SECURE;
             object = endpoint;
-
-            free(uri);
         }
     }
 
@@ -1162,22 +1001,21 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
     g_received = 1;
 }
 
-void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
+void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
     printf("##########Received response from remote device #############\n");
-    printf("Uri: %s\n", object->resourceUri);
-    if (CA_IPV4 == object->transportType)
+    if (CA_ADAPTER_IP == object->adapter)
     {
-        printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
-               object->addressInfo.IP.port, object->isSecured);
+        printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
+               object->port, object->flags & CA_SECURE);
     }
-    else if (CA_EDR == object->transportType)
+    else if (CA_ADAPTER_RFCOMM_BTEDR == object->adapter)
     {
-        printf("Remote Address: %s \n", object->addressInfo.BT.btMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
-    else if (CA_LE == object->transportType)
+    else if (CA_ADAPTER_GATT_BTLE == object->adapter)
     {
-        printf("Remote Address: %s \n", object->addressInfo.LE.leMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
     printf("response result : %d\n", responseInfo->result);
     printf("Data: %s\n", responseInfo->info.payload);
@@ -1209,7 +1047,48 @@ void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *
     }
 }
 
-void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
+void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        printf("Error Handler, ErrorInfo :\n");
+        printf("Error Handler result    : %d\n", errorInfo->result);
+        printf("Error Handler token     : %s\n", info->token);
+        printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
+        printf("Error Handler type      : %d\n", info->type);
+        printf("Error Handler resourceUri : %s\n", info->resourceUri);
+        printf("Error Handler payload   : %s\n", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
+        }
+    }
+    printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
+
+    return;
+}
+
+void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
 {
     printf("entering send_response\n");
 
@@ -1244,6 +1123,9 @@ void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
         printf("SUCCESS                  : 200\n");
         printf("CREATED                  : 201\n");
         printf("DELETED                  : 202\n");
+        printf("VALID                    : 203\n");
+        printf("CHANGED                  : 204\n");
+        printf("CONTENT                  : 205\n");
         printf("BAD_REQ                  : 400\n");
         printf("BAD_OPT                  : 402\n");
         printf("NOT_FOUND                : 404\n");
@@ -1260,38 +1142,42 @@ void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
     CAInfo_t responseData = { 0 };
     responseData.type = messageType;
     responseData.messageId = (info != NULL) ? info->messageId : 0;
+    responseData.resourceUri = (info != NULL) ? info->resourceUri : 0;
 
     if(CA_MSG_RESET != messageType)
     {
         responseData.token = (info != NULL) ? info->token : NULL;
         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
 
-        if (endpoint->isSecured)
+        if (endpoint->flags & CA_SECURE)
         {
             printf("Sending response on secure communication\n");
 
-            uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(endpoint->resourceUri);
+            uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri);
             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
             if (NULL == responseData.payload)
             {
                 printf("Memory allocation fail\n");
                 return;
             }
-            snprintf(responseData.payload, length, SECURE_INFO_DATA, endpoint->resourceUri,
-                     g_local_secure_port);
+            snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
+                     (const char *) responseData.resourceUri, g_local_secure_port);
+            responseData.payloadSize = length;
         }
         else
         {
             printf("Sending response on non-secure communication\n");
 
-            uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(endpoint->resourceUri);
+            uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
             responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
             if (NULL == responseData.payload)
             {
                 printf("Memory allocation fail\n");
                 return;
             }
-            snprintf(responseData.payload, length, NORMAL_INFO_DATA, endpoint->resourceUri);
+            snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
+                     (const char *) responseData.resourceUri);
+            responseData.payloadSize = length;
         }
     }
 
@@ -1310,6 +1196,11 @@ void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
         printf("Send response success\n");
     }
 
+    if (responseData.payload)
+    {
+        free(responseData.payload);
+    }
+
     printf("=============================================\n");
 }
 
@@ -1324,13 +1215,13 @@ int get_secure_information(CAPayload_t payLoad)
     }
 
     char *subString = NULL;
-    if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
+    if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
     {
         printf("This is not secure resource\n");
         return -1;
     }
 
-    if (NULL == (subString = strstr(payLoad, "\"port\":")))
+    if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
     {
         printf("This secure resource does not have port information\n");
         return -1;
@@ -1350,7 +1241,7 @@ int get_secure_information(CAPayload_t payLoad)
         return -1;
     }
 
-    char portStr[4] = {0};
+    char portStr[6] = {0};
     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
 
     printf("secured port is: %s\n", portStr);
@@ -1392,9 +1283,9 @@ CAResult_t get_network_type()
 
     printf("\n=============================================\n");
     printf("\tselect network type\n");
-    printf("IPv4 : 0\n");
-    printf("BT : 2\n");
-    printf("LE : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
@@ -1406,29 +1297,23 @@ CAResult_t get_network_type()
 
     number = (number < 0 || number > 3) ? 0 : 1 << number;
 
-    if (!(number & 0xf))
-    {
-        return CA_NOT_SUPPORTED;
-    }
-    if (number & CA_IPV4)
+    if (number == 1)
     {
-        g_selected_nw_type = CA_IPV4;
+        g_selected_nw_type = CA_ADAPTER_IP;
         return CA_STATUS_OK;
     }
-    if (number & CA_EDR)
+    if (number == 2)
     {
-        g_selected_nw_type = CA_EDR;
+        g_selected_nw_type = CA_ADAPTER_GATT_BTLE;
         return CA_STATUS_OK;
     }
-    if (number & CA_LE)
+    if (number == 3)
     {
-        g_selected_nw_type = CA_LE;
+        g_selected_nw_type = CA_ADAPTER_RFCOMM_BTEDR;
         return CA_STATUS_OK;
     }
 
-    printf("\n=============================================\n");
-
-    return CA_STATUS_FAILED;
+    return CA_NOT_SUPPORTED;
 }
 
 CAResult_t get_input_data(char *buf, int32_t length)
@@ -1447,3 +1332,173 @@ CAResult_t get_input_data(char *buf, int32_t length)
 
     return CA_STATUS_OK;
 }
+
+CAHeaderOption_t* get_option_data(CAInfo_t* requestData)
+{
+    char optionNumBuf[MAX_BUF_LEN] = { 0 };
+    char optionData[MAX_OPT_LEN] = { 0 } ;
+
+    printf("Option Num : ");
+    if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
+    {
+        return NULL;
+    }
+    int optionNum = atoi(optionNumBuf);
+
+    CAHeaderOption_t * headerOpt = NULL;
+    if (0 >= optionNum)
+    {
+        printf("there is no headerOption!\n");
+        return NULL;
+    }
+    else
+    {
+        headerOpt = (CAHeaderOption_t *)calloc(1, optionNum * sizeof(CAHeaderOption_t));
+        if (NULL == headerOpt)
+        {
+            printf("Memory allocation failed!\n");
+            return NULL;
+        }
+
+        int i;
+        for (i = 0; i < optionNum; i++)
+        {
+            char getOptionID[MAX_BUF_LEN] = { 0 } ;
+
+            printf("[%d] Option ID : ", i + 1);
+            if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
+            {
+                free(headerOpt);
+                return NULL;
+            }
+            int optionID = atoi(getOptionID);
+            headerOpt[i].optionID = optionID;
+
+            printf("[%d] Option Data : ", i + 1);
+            if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
+            {
+                free(headerOpt);
+                return NULL;
+            }
+
+            memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
+
+            headerOpt[i].optionLength = (uint16_t) strlen(optionData);
+        }
+        requestData->numOptions = optionNum;
+        requestData->options = headerOpt;
+    }
+    return headerOpt;
+}
+
+void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
+{
+    if (NULL == uri)
+    {
+        printf("parameter is null\n");
+        return;
+    }
+
+    // parse uri
+    // #1. check prefix
+    uint8_t startIndex = 0;
+    if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
+    {
+        printf("uri has '%s' prefix\n", COAPS_PREFIX);
+        startIndex = COAPS_PREFIX_LEN;
+        *flags = CA_SECURE;
+    }
+    else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
+    {
+        printf("uri has '%s' prefix\n", COAP_PREFIX);
+        startIndex = COAP_PREFIX_LEN;
+        *flags = CA_DEFAULT_FLAGS;
+    }
+
+    // #2. copy uri for parse
+    int32_t len = strlen(uri) - startIndex;
+
+    if (len <= 0)
+    {
+        printf("uri length is 0!\n");
+        return;
+    }
+
+    char *cloneUri = (char *) calloc(len + 1, sizeof(char));
+    if (NULL == cloneUri)
+    {
+        printf("Out of memory\n");
+        return;
+    }
+
+    memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
+    cloneUri[len] = '\0';
+
+    char *pAddress = cloneUri;
+    printf("pAddress : %s\n", pAddress);
+
+    int res = get_address_set(pAddress, address);
+    if (res == -1)
+    {
+        printf("address parse error\n");
+
+        free(cloneUri);
+        return;
+    }
+    free(cloneUri);
+    return;
+}
+
+int get_address_set(const char *pAddress, addressSet_t* outAddress)
+{
+    if (NULL == pAddress)
+    {
+        printf("parameter is null !\n");
+        return -1;
+    }
+
+    int32_t len = strlen(pAddress);
+    int32_t isIp = 0;
+    int32_t ipLen = 0;
+
+    for (int i = 0; i < len; i++)
+    {
+        if (pAddress[i] == '.')
+        {
+            isIp = 1;
+        }
+
+        // found port number start index
+        if (isIp && pAddress[i] == ':')
+        {
+            ipLen = i;
+            break;
+        }
+    }
+
+    if (isIp)
+    {
+        if(ipLen && ipLen < sizeof(outAddress->ipAddress))
+        {
+            strncpy(outAddress->ipAddress, pAddress, ipLen);
+            outAddress->ipAddress[ipLen] = '\0';
+        }
+        else if (!ipLen && len < sizeof(outAddress->ipAddress))
+        {
+            strncpy(outAddress->ipAddress, pAddress, len);
+            outAddress->ipAddress[len] = '\0';
+        }
+        else
+        {
+            printf("IP Address too long: %d\n", ipLen==0 ? len : ipLen);
+            return -1;
+        }
+
+        if (ipLen > 0)
+        {
+            outAddress->port = atoi(pAddress + ipLen + 1);
+        }
+    }
+
+    return isIp;
+}
index be3619b..7013cf4 100644 (file)
@@ -56,6 +56,15 @@ help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL'
 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')))
 
+
+AddOption('--prefix',
+                  dest='prefix',
+                  type='string',
+                  nargs=1,
+                  action='store',
+                  metavar='DIR',
+                  help='installation prefix')
+
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
 ######################################################################
@@ -73,7 +82,7 @@ if target_os in ['android', 'arduino']: # Android/Arduino always uses GNU compil
                        tools = ['gnulink', 'gcc', 'g++', 'ar', 'as']
                        )
 else:
-       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os)
+       env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os, PREFIX = GetOption('prefix'))
 
 Help(help_vars.GenerateHelpText(env))
 
@@ -149,6 +158,22 @@ def __install(ienv, targets, name):
 def __append_target(ienv, target):
        env.AppendUnique(TS = [target])
 
+def __installlib(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/lib', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
+def __installbin(ienv, targets, name):
+       user_prefix = env.get('PREFIX')
+       if user_prefix:
+               i_n = ienv.Install(user_prefix + '/bin', targets)
+       else:
+               i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+       ienv.Alias("install", i_n)
+
 def __print_targets(env):
        Help('''
 ===============================================================================
@@ -167,6 +192,8 @@ env.AddMethod(__print_targets, 'PrintTargets')
 env.AddMethod(__src_to_obj, 'SrcToObj')
 env.AddMethod(__append_target, 'AppendTarget')
 env.AddMethod(__install, 'InstallTarget')
+env.AddMethod(__installlib, 'UserInstallTargetLib')
+env.AddMethod(__installbin, 'UserInstallTargetBin')
 env.SetDir(env.GetLaunchDir())
 env['ROOT_DIR']=env.GetLaunchDir()
 
index 3052feb..4afae38 100644 (file)
 
 #define RESOURCE_URI_LENGTH 14
 
+#define COAP_PREFIX          "coap://"
+#define COAP_PREFIX_LEN      7
+#define COAPS_PREFIX         "coaps://"
+#define COAPS_PREFIX_LEN     8
+
 /**
  * @def RS_IDENTITY
  * @brief
@@ -72,9 +77,15 @@ pthread_t thread;
 
 int g_received;
 uint16_t g_local_secure_port = SECURE_DEFAULT_PORT;
-CATransportType_t g_selected_nw_type = CA_IPV4;
+CATransportAdapter_t g_selected_nw_type = CA_ADAPTER_IP;
 const char *MESSAGE_TYPE[] = {"CON", "NON", "ACK", "RESET"};
 
+typedef struct
+{
+    char ipAddress[CA_IPADDR_SIZE];
+    uint16_t port;
+} addressSet_t;
+
 char get_menu();
 void process();
 CAResult_t get_network_type();
@@ -82,22 +93,23 @@ CAResult_t get_input_data(char *buf, int32_t length);
 
 void start_listening_server();
 void start_discovery_server();
-void find_resource();
 void send_request();
 void send_request_all();
-void advertise_resource();
 void send_notification();
 void select_network();
 void unselect_network();
 void handle_request_response();
-void find_fixed_resource();
 void get_network_info();
+void send_secure_request();
 
-void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
-void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
-void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info);
+void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
+void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info);
 void get_resource_uri(char *URI, char *resourceURI, int length);
 int get_secure_information(CAPayload_t payLoad);
+int get_address_set(const char *uri, addressSet_t* outAddress);
+void parse_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
 
 static CAToken_t g_last_request_token = NULL;
 static const char SECURE_COAPS_PREFIX[] = "coaps://";
@@ -264,7 +276,7 @@ int main()
 #endif
 
     // set handler.
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
 
     process();
 
@@ -309,21 +321,11 @@ void process()
                 start_discovery_server();
                 break;
 
-            case 'f': // find resource
-            case 'F':
-                find_resource();
-                break;
-
             case 'r': // send request
             case 'R':
                 send_request();
                 break;
 
-            case 'a': // advertise resource
-            case 'A':
-                advertise_resource();
-                break;
-
             case 'b': // send notification
             case 'B':
                 send_notification();
@@ -344,26 +346,11 @@ void process()
                 handle_request_response();
                 break;
 
-            case 'y':
-            case 'Y':
-                while (1)
-                {
-                    g_received = 0;
-                    find_fixed_resource();
-                    while (g_received == 0)
-                    {
-                        sleep(1);
-                        handle_request_response();
-
-                    }
-                }
-                break;
-
             case 'w':
             case 'W':
                 g_received = 0;
                 start_discovery_server();
-                //send_secure_request();
+                send_secure_request();
                 while (g_received == 0)
                 {
                     sleep(1);
@@ -424,81 +411,6 @@ void start_discovery_server()
     }
 }
 
-void find_fixed_resource()
-{
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        printf("Token generate error!!");
-        return;
-    }
-
-    printf("Generated token %s\n", token);
-
-    char buf[MAX_BUF_LEN] = { 0 };
-    strcpy(buf, "/a/light");
-
-    res = CAFindResource(buf, token, tokenLength);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Find resource error : %d\n", res);
-    }
-    else
-    {
-        printf("Find resource to %s URI\n", buf);
-    }
-
-    // delete token
-    CADestroyToken(token);
-
-    printf("=============================================\n");
-}
-
-void find_resource()
-{
-    printf("\n=============================================\n");
-    printf("ex) /a/light\n");
-    printf("reference uri : ");
-
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
-    {
-        return;
-    }
-
-    // create token
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
-    if ((CA_STATUS_OK != res) || (!token))
-    {
-        printf("Token generate error!!\n");
-        return;
-    }
-
-    printf("Generated token %s\n", token);
-
-    res = CAFindResource(buf, token, tokenLength);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Find resource error : %d\n", res);
-        CADestroyToken(token);
-    }
-    else
-    {
-        printf("Find resource to %s URI\n", buf);
-        CADestroyToken(g_last_request_token);
-        g_last_request_token = token;
-    }
-
-    printf("=============================================\n");
-}
-
 void send_request()
 {
     CAResult_t res = get_network_type();
@@ -539,8 +451,15 @@ void send_request()
     }
 
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(uri, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CATransportFlags_t flags;
+
+    printf("URI : %s\n", uri);
+    addressSet_t address = {};
+    parse_coap_uri(uri, &address, &flags);
+
+    res = CACreateEndpoint(flags, g_selected_nw_type,
+                           (const char*)address.ipAddress, address.port, &endpoint);
     if (CA_STATUS_OK != res || !endpoint)
     {
         printf("Failed to create remote endpoint, error code : %d\n", res);
@@ -554,7 +473,7 @@ void send_request()
     char buf[MAX_BUF_LEN] = { 0 };
     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
     {
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -568,54 +487,59 @@ void send_request()
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error, error code : %d\n", res);
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
     printf("Generated token %s\n", token);
 
     // extract relative resourceuri from give uri
-    printf("URI : %s\n", uri);
-
-    char resourceURI[15] = {0};
+    char resourceURI[RESOURCE_URI_LENGTH + 1] = {0};
     get_resource_uri(uri, resourceURI, RESOURCE_URI_LENGTH);
+    printf("resourceURI : %s\n", resourceURI);
 
     // create request data
     CAInfo_t requestData = { 0 };
     requestData.token = token;
     requestData.tokenLength = tokenLength;
+    requestData.resourceUri = (CAURI_t)resourceURI;
 
     if (strcmp(secureRequest, "1") == 0)
     {
-        uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
+        size_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
         requestData.payload = (CAPayload_t) calloc(length,  sizeof(char));
         if (NULL == requestData.payload)
         {
             printf("Memory allocation fail\n");
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             CADestroyToken(token);
             return;
         }
-        snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_local_secure_port);
+        snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
+                 (const char *) resourceURI, g_local_secure_port);
+        requestData.payloadSize = length;
     }
     else
     {
-        uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
+        size_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
         requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
         if (NULL == requestData.payload)
         {
             printf("Memory allocation fail\n");
-            CADestroyRemoteEndpoint(endpoint);
+            CADestroyEndpoint(endpoint);
             CADestroyToken(token);
             return;
         }
-        snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
+        snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA,
+                 (const char *) resourceURI);
+        requestData.payloadSize = length;
     }
     requestData.type = msgType;
 
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
 
     // send request
     res = CASendRequest(endpoint, &requestInfo);
@@ -627,49 +551,34 @@ void send_request()
     //destroy token
     CADestroyToken(token);
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
     free(requestData.payload);
 
 
     printf("=============================================\n");
 }
 
-void send_request_all()
+void send_secure_request()
 {
-    CAResult_t res = get_network_type();
-    if (CA_STATUS_OK != res)
-    {
-        return;
-    }
+    char ipv4addr[CA_IPADDR_SIZE];
 
     printf("\n=============================================\n");
-    printf("ex) /a/light\n");
-    printf("resource uri : ");
+    printf("Enter IPv4 address of the source hosting secure resource (Ex: 11.12.13.14)\n");
 
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+    if (CA_STATUS_OK != get_input_data(ipv4addr, CA_IPADDR_SIZE))
     {
         return;
     }
+    printf("%s%s:5684/a/light", SECURE_COAPS_PREFIX, ipv4addr);
 
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(buf, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateEndpoint(0, CA_ADAPTER_IP, ipv4addr, SECURE_DEFAULT_PORT, &endpoint);
     if (CA_STATUS_OK != res)
     {
-        printf("Create remote endpoint error, error code: %d\n", res);
-        return;
-    }
-
-    CAGroupEndpoint_t *group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t));
-    if (NULL == group)
-    {
-        printf("Memory allocation failed!\n");
-        CADestroyRemoteEndpoint(endpoint);
-        return;
+        printf("Failed to create remote endpoint, error code: %d\n", res);
+        goto exit;
     }
-    group->transportType = endpoint->transportType;
-    group->resourceUri = endpoint->resourceUri;
 
     // create token
     CAToken_t token = NULL;
@@ -678,121 +587,95 @@ void send_request_all()
     res = CAGenerateToken(&token, tokenLength);
     if ((CA_STATUS_OK != res) || (!token))
     {
-        printf("Token generate error!!\n");
-        CADestroyRemoteEndpoint(endpoint);
-        free(group);
-        return;
+        printf("Token generate error, error code : %d\n", res);
+        goto exit;
     }
 
-    printf("generated token %s\n", token);
+    printf("Generated token %s\n", token);
 
-    CAInfo_t requestData = {CA_MSG_RESET};
+    // create request data
+    CAMessageType_t msgType = CA_MSG_NONCONFIRM;
+    CAInfo_t requestData = { 0 };
     requestData.token = token;
     requestData.tokenLength = tokenLength;
-    requestData.payload = "Temp Json Payload";
-    requestData.type = CA_MSG_NONCONFIRM;
+    requestData.type = msgType;
 
-    CARequestInfo_t requestInfo = {CA_GET, {CA_MSG_RESET}};
+    CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = CA_GET;
     requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
 
-    // send request all
-    res = CASendRequestToAll(group, &requestInfo);
-    if (CA_STATUS_OK != res)
-    {
-        printf("Could not send request to all\n");
-        CADestroyToken(token);
-    }
-    else
-    {
-        CADestroyToken(g_last_request_token);
-        g_last_request_token = token;
-    }
-
-    // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
-    free(group);
+    // send request
+    CASendRequest(endpoint, &requestInfo);
 
+exit:
+    // cleanup
+    CADestroyToken(token);
+    CADestroyEndpoint(endpoint);
     printf("=============================================\n");
 }
 
-void advertise_resource()
-{
-    printf("\n=============================================\n");
-    printf("uri : ");
 
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+void send_request_all()
+{
+    CAResult_t res = get_network_type();
+    if (CA_STATUS_OK != res)
     {
         return;
     }
 
-    char optionNumBuf[MAX_BUF_LEN] = { 0 };
-    char optionData[MAX_OPT_LEN] = { 0 } ;
+    printf("\n=============================================\n");
+    printf("ex) /a/light\n");
+    printf("resource uri : ");
 
-    printf("Option Num : ");
-    if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
+    char resourceURI[MAX_BUF_LEN] = { 0 };
+    if (CA_STATUS_OK != get_input_data(resourceURI, MAX_BUF_LEN))
     {
         return;
     }
-    int optionNum = atoi(optionNumBuf);
 
-    CAHeaderOption_t * headerOpt = (CAHeaderOption_t *)
-            calloc(1, optionNum * sizeof(CAHeaderOption_t));
-    if (NULL == headerOpt)
+    // create remote endpoint
+    CAEndpoint_t *endpoint = NULL;
+    res = CACreateEndpoint(CA_IPV4, g_selected_nw_type, NULL, 0, &endpoint);
+    if (CA_STATUS_OK != res)
     {
-        printf("Memory allocation failed!\n");
+        printf("Create remote endpoint error, error code: %d\n", res);
         return;
     }
 
-    int i;
-    for (i = 0; i < optionNum; i++)
-    {
-        char getOptionID[MAX_BUF_LEN] = { 0 } ;
-
-        printf("[%d] Option ID : ", i + 1);
-        if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
-        {
-            free(headerOpt);
-            return;
-        }
-        int optionID = atoi(getOptionID);
-
-        headerOpt[i].optionID = optionID;
-
-        printf("[%d] Option Data : ", i + 1);
-        if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
-        {
-            free(headerOpt);
-            return;
-        }
-
-        memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
-        printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData);
-
-        headerOpt[i].optionLength = (uint16_t) strlen(optionData);
-    }
-    printf("\n=============================================\n");
-
     // create token
     CAToken_t token = NULL;
     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
 
-    CAResult_t res = CAGenerateToken(&token, tokenLength);
+    res = CAGenerateToken(&token, tokenLength);
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error!!\n");
-        free(headerOpt);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
-    printf("Generated token %s\n", token);
+    printf("generated token %s\n", token);
+
+    CAInfo_t requestData = { 0 };
+    requestData.token = token;
+    requestData.tokenLength = tokenLength;
+    requestData.payload = (CAPayload_t) "TempJsonPayload";
+    requestData.payloadSize = strlen((const char *) requestData.payload);
+    requestData.type = CA_MSG_NONCONFIRM;
+    requestData.resourceUri = (CAURI_t)resourceURI;
+
+    CARequestInfo_t requestInfo = { 0 };
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+    requestInfo.isMulticast = true;
 
-    res = CAAdvertiseResource(buf, token, tokenLength, headerOpt, (uint8_t) optionNum);
+    // send request
+    res = CASendRequest(endpoint, &requestInfo);
     if (CA_STATUS_OK != res)
     {
-        printf("Could not start advertise resource\n");
-        CADestroyToken(token);
+        printf("Could not send request to all\n");
+        CADestroyEndpoint(endpoint);
     }
     else
     {
@@ -800,7 +683,10 @@ void advertise_resource()
         g_last_request_token = token;
     }
 
-    free(headerOpt);
+    // destroy remote endpoint
+    CADestroyEndpoint(endpoint);
+
+    printf("=============================================\n");
 }
 
 void send_notification()
@@ -813,12 +699,12 @@ void send_notification()
 
     printf("\n=============================================\n");
     printf("Enter the URI like below....\n");
-    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
-    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
     printf("uri : ");
 
-    char buf[MAX_BUF_LEN] = { 0 };
-    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
+    char uri[MAX_BUF_LEN] = { 0 };
+    if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
     {
         return;
     }
@@ -827,6 +713,9 @@ void send_notification()
     printf("\tselect message type\n");
     printf("CON     : 0\n");
     printf("NON     : 1\n");
+    printf("ACK     : 2\n");
+    printf("RESET   : 3\n");
+
     printf("select : ");
 
     char messageTypeBuf[MAX_BUF_LEN] = { 0 };
@@ -850,9 +739,13 @@ void send_notification()
                 return;
     }
 
+    CATransportFlags_t flags;
+    addressSet_t address = {};
+    parse_coap_uri(uri, &address, &flags);
+
     // create remote endpoint
-    CARemoteEndpoint_t *endpoint = NULL;
-    res = CACreateRemoteEndpoint(buf, g_selected_nw_type, &endpoint);
+    CAEndpoint_t *endpoint = NULL;
+    res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
     if (CA_STATUS_OK != res)
     {
         printf("Create remote endpoint error, error code: %d\n", res);
@@ -867,7 +760,7 @@ void send_notification()
     if ((CA_STATUS_OK != res) || (!token))
     {
         printf("Token generate error!!\n");
-        CADestroyRemoteEndpoint(endpoint);
+        CADestroyEndpoint(endpoint);
         return;
     }
 
@@ -876,11 +769,13 @@ void send_notification()
     CAInfo_t respondData = { 0 };
     respondData.token = token;
     respondData.tokenLength = tokenLength;
-    respondData.payload = "Temp Notification Data";
+    respondData.payload = (CAPayload_t) "TempNotificationData";
+    respondData.payloadSize = strlen((const char *) respondData.payload);
     respondData.type = messageType;
+    respondData.resourceUri = (CAURI_t)uri;
 
     CAResponseInfo_t responseInfo = { 0 };
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = respondData;
 
     // send notification
@@ -897,7 +792,7 @@ void send_notification()
     // destroy token
     CADestroyToken(token);
     // destroy remote endpoint
-    CADestroyRemoteEndpoint(endpoint);
+    CADestroyEndpoint(endpoint);
 
     printf("\n=============================================\n");
 }
@@ -906,9 +801,9 @@ void select_network()
 {
     printf("\n=============================================\n");
     printf("\tselect network\n");
-    printf("IPv4 : 0\n");
-    printf("EDR : 2\n");
-    printf("LE : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     char buf[MAX_BUF_LEN] = { 0 };
@@ -935,7 +830,6 @@ void select_network()
     {
         printf("Select network success\n");
     }
-
     printf("=============================================\n");
 }
 
@@ -943,9 +837,9 @@ void unselect_network()
 {
     printf("\n=============================================\n");
     printf("\tunselect enabled network\n");
-    printf("IPv4 : 0\n");
-    printf("EDR : 2\n");
-    printf("LE : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     char buf[MAX_BUF_LEN] = { 0 };
@@ -981,16 +875,13 @@ char get_menu()
     printf("\t\tMenu\n");
     printf("\ts : start server\n");
     printf("\tc : start client\n");
-    printf("\tf : find resource\n");
     printf("\tr : send request\n");
     printf("\tt : send request to all\n");
-    printf("\ta : advertise resource\n");
     printf("\tb : send notification\n");
     printf("\tn : select network\n");
     printf("\tx : unselect network\n");
     printf("\tg : get network information\n");
     printf("\th : handle request response\n");
-    printf("\ty : run static client\n");
     printf("\tz : run static server\n");
     printf("\tw : send secure request\n");
     printf("\tq : quit\n");
@@ -1023,7 +914,7 @@ void handle_request_response()
 
 void get_network_info()
 {
-    CALocalConnectivity_t *tempInfo = NULL;
+    CAEndpoint_t *tempInfo = NULL;
     uint32_t tempSize = 0;
 
     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
@@ -1040,21 +931,22 @@ void get_network_info()
     int index;
     for (index = 0; index < tempSize; index++)
     {
-        printf("Type: %d\n", tempInfo[index].type);
-        if (CA_IPV4 == tempInfo[index].type)
+        printf("Type: %d\n", tempInfo[index].adapter);
+        if (CA_ADAPTER_IP == tempInfo[index].adapter)
         {
-            printf("Address: %s\n", tempInfo[index].addressInfo.IP.ipAddress);
-            printf("Port: %d\n", tempInfo[index].addressInfo.IP.port);
+            printf("Address: %s\n", tempInfo[index].addr);
+            printf("Port: %d\n", tempInfo[index].port);
         }
-        else if (CA_EDR == tempInfo[index].type)
+        else
         {
-            printf("Address: %s\n", tempInfo[index].addressInfo.BT.btMacAddress);
+            printf("Address: %s\n", tempInfo[index].addr);
         }
-        printf("Secured: %d\n\n", tempInfo[index].isSecured);
 
-        if (tempInfo[index].isSecured)
+        printf("Secured: %s\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" : "false");
+
+        if (tempInfo[index].flags & CA_SECURE)
         {
-            g_local_secure_port = tempInfo[index].addressInfo.IP.port;
+            g_local_secure_port = tempInfo[index].port;
             printf("Secured: in global %d\n\n", g_local_secure_port);
         }
     }
@@ -1063,7 +955,7 @@ void get_network_info()
     printf("##############################################################");
 }
 
-void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
+void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
 {
     if (NULL == object || NULL == requestInfo)
     {
@@ -1080,15 +972,14 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
     }
 
     printf("##########received request from remote device #############\n");
-    printf("Uri: %s\n", object->resourceUri);
-    if (CA_IPV4 == object->transportType)
+    if (CA_ADAPTER_IP == object->adapter)
     {
-        printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
-               object->addressInfo.IP.port, object->isSecured);
+        printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
+               object->port, object->flags & CA_SECURE);
     }
-    else if (CA_EDR == object->transportType)
+    else
     {
-        printf("Remote Address: %s \n", object->addressInfo.BT.btMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
     printf("Data: %s\n", requestInfo->info.payload);
     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
@@ -1109,39 +1000,22 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
 
     //Check if this has secure communication information
     if (requestInfo->info.payload &&
-            (CA_IPV4 == object->transportType))
+            (CA_ADAPTER_IP == object->adapter))
     {
         int securePort = get_secure_information(requestInfo->info.payload);
         if (0 < securePort) //Set the remote endpoint secure details and send response
         {
             printf("This is secure resource...\n");
 
-            //length of "coaps://"
-            int length = sizeof(SECURE_COAPS_PREFIX) - 1;
-
-            // length of "ipaddress:port"
-            length += strlen(object->addressInfo.IP.ipAddress) + PORT_LENGTH;
-            length += strlen(object->resourceUri) + 1;
-
-            char *uri = calloc(1, sizeof(char) * length);
-            if (!uri)
-            {
-                printf("Failed to create new uri\n");
-                return;
-            }
-            sprintf(uri, "%s%s:%d/%s", SECURE_COAPS_PREFIX, object->addressInfo.IP.ipAddress,
-                    object->addressInfo.IP.port, object->resourceUri);
-
-            CARemoteEndpoint_t *endpoint = NULL;
-            if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->transportType, &endpoint))
+            CAEndpoint_t *endpoint = NULL;
+            if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
+                                                 object->port, &endpoint))
             {
                 printf("Failed to create duplicate of remote endpoint!\n");
                 return;
             }
-            endpoint->isSecured = true;
+            endpoint->flags = CA_SECURE;
             object = endpoint;
-
-            free(uri);
         }
     }
 
@@ -1151,19 +1025,20 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re
     g_received = 1;
 }
 
-void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
+void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
     printf("##########Received response from remote device #############\n");
-    printf("Uri: %s\n", object->resourceUri);
-    if (CA_IPV4 == object->transportType)
+    if (CA_ADAPTER_IP == object->adapter)
     {
-        printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
-               object->addressInfo.IP.port, object->isSecured);
+        printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
+               object->port, object->flags & CA_SECURE);
     }
-    else if (CA_EDR == object->transportType)
+    else
     {
-        printf("Remote Address: %s \n", object->addressInfo.BT.btMacAddress);
+        printf("Remote Address: %s \n", object->addr);
     }
+
+    printf("resource uri : %s\n", responseInfo->info.resourceUri);
     printf("response result : %d\n", responseInfo->result);
     printf("Data: %s\n", responseInfo->info.payload);
     printf("Message type: %s\n", MESSAGE_TYPE[responseInfo->info.type]);
@@ -1194,7 +1069,48 @@ void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *
     }
 }
 
-void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
+void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        printf("Error Handler, ErrorInfo :\n");
+        printf("Error Handler result    : %d\n", errorInfo->result);
+        printf("Error Handler token     : %s\n", info->token);
+        printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
+        printf("Error Handler type      : %d\n", info->type);
+        printf("Error Handler resourceUri : %s\n", info->resourceUri);
+        printf("Error Handler payload   : %s\n", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
+        }
+    }
+    printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
+
+    return;
+}
+
+void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
 {
     printf("entering send_response\n");
 
@@ -1223,6 +1139,9 @@ void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
         printf("SUCCESS                  : 200\n");
         printf("CREATED                  : 201\n");
         printf("DELETED                  : 202\n");
+        printf("VALID                    : 203\n");
+        printf("CHANGED                  : 204\n");
+        printf("CONTENT                  : 205\n");
         printf("BAD_REQ                  : 400\n");
         printf("BAD_OPT                  : 402\n");
         printf("NOT_FOUND                : 404\n");
@@ -1238,39 +1157,44 @@ void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
     }
     CAInfo_t responseData = { 0 };
     responseData.type = messageType;
-
     responseData.messageId = (info != NULL) ? info->messageId : 0;
+    responseData.resourceUri = (info != NULL) ? info->resourceUri : 0;
+
     if(CA_MSG_RESET != messageType)
     {
         responseData.token = (info != NULL) ? info->token : NULL;
         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
 
-        if (endpoint->isSecured)
+        if (endpoint->flags & CA_SECURE)
         {
             printf("Sending response on secure communication\n");
 
-            uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(endpoint->resourceUri);
+            uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri)
+                              + sizeof(g_local_secure_port);
             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
             if (NULL == responseData.payload)
             {
                 printf("Memory allocation fail\n");
                 return;
             }
-            snprintf(responseData.payload, length, SECURE_INFO_DATA, endpoint->resourceUri,
-                     g_local_secure_port);
+            snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
+                     (const char *) responseData.resourceUri, g_local_secure_port);
+            responseData.payloadSize = length;
         }
         else
         {
             printf("Sending response on non-secure communication\n");
 
-            uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(endpoint->resourceUri);
+            uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
             responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
             if (NULL == responseData.payload)
             {
                 printf("Memory allocation fail\n");
                 return;
             }
-            snprintf(responseData.payload, length, NORMAL_INFO_DATA, endpoint->resourceUri);
+            snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
+                     (const char *) responseData.resourceUri);
+            responseData.payloadSize = length;
         }
     }
 
@@ -1303,13 +1227,13 @@ int get_secure_information(CAPayload_t payLoad)
     }
 
     char *subString = NULL;
-    if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
+    if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
     {
         printf("This is not secure resource\n");
         return -1;
     }
 
-    if (NULL == (subString = strstr(payLoad, "\"port\":")))
+    if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
     {
         printf("This secure resource does not have port information\n");
         return -1;
@@ -1329,13 +1253,7 @@ int get_secure_information(CAPayload_t payLoad)
         return -1;
     }
 
-    if(((endPos - 1) - startPos) > 4)
-    {
-        printf("port length is not proper.Exceeding length 4\n");
-        return -1;
-    }
-
-    char portStr[4] = {0};
+    char portStr[6] = {0};
     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
 
     printf("secured port is: %s\n", portStr);
@@ -1375,9 +1293,9 @@ CAResult_t get_network_type()
 {
     printf("\n=============================================\n");
     printf("\tselect network type\n");
-    printf("IPv4 : 0\n");
-    printf("BT : 2\n");
-    printf("LE : 3\n");
+    printf("IP     : 0\n");
+    printf("GATT   : 1\n");
+    printf("RFCOMM : 2\n");
     printf("select : ");
 
     char buf[MAX_BUF_LEN] = { 0 };
@@ -1387,31 +1305,15 @@ CAResult_t get_network_type()
     }
 
     int number = buf[0] - '0';
-    number = (number < 0 || number > 3) ? 0 : 1 << number;
-
-    if (!(number & 0xf))
+    if (0 > number || 2 < number)
     {
+        printf("\nInvalid Network type");
         return CA_NOT_SUPPORTED;
     }
-    if (number & CA_IPV4)
-    {
-        g_selected_nw_type = CA_IPV4;
-        return CA_STATUS_OK;
-    }
-    if (number & CA_EDR)
-    {
-        g_selected_nw_type = CA_EDR;
-        return CA_STATUS_OK;
-    }
-    if (number & CA_LE)
-    {
-        g_selected_nw_type = CA_LE;
-        return CA_STATUS_OK;
-    }
 
-    printf("\n=============================================\n");
+    g_selected_nw_type = 1 << number;
 
-    return CA_STATUS_FAILED;
+    return CA_STATUS_OK;
 }
 
 CAResult_t get_input_data(char *buf, int32_t length)
@@ -1430,3 +1332,90 @@ CAResult_t get_input_data(char *buf, int32_t length)
 
     return CA_STATUS_OK;
 }
+
+
+void parse_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
+{
+    if (NULL == uri)
+    {
+        printf("parameter is null\n");
+        return;
+    }
+
+    // parse uri
+    // #1. check prefix
+    uint8_t startIndex = 0;
+    if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
+    {
+        printf("uri has '%s' prefix\n", COAPS_PREFIX);
+        startIndex = COAPS_PREFIX_LEN;
+        *flags = CA_SECURE;
+    }
+    else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
+    {
+        printf("uri has '%s' prefix\n", COAP_PREFIX);
+        startIndex = COAP_PREFIX_LEN;
+        *flags = CA_IPV4;
+    }
+
+    // #2. copy uri for parse
+    int32_t len = strlen(uri) - startIndex;
+
+    if (len <= 0)
+    {
+        printf("uri length is 0!\n");
+        return;
+    }
+
+    int res = get_address_set(uri + startIndex, address);
+    if (res == -1)
+    {
+        printf("address parse error\n");
+        return;
+    }
+
+    return;
+}
+
+int get_address_set(const char *uri, addressSet_t* outAddress)
+{
+    if (NULL == uri || NULL == outAddress)
+    {
+        printf("parameter is null !\n");
+        return -1;
+    }
+
+    int32_t len = strlen(uri);
+    if (len <= 0)
+    {
+        printf("uri length is 0!\n");
+        return -1;
+    }
+
+    int32_t isIp = 0;
+    int32_t ipLen = 0;
+    for (int i = 0; i < len; i++)
+    {
+        if (uri[i] == '.')
+        {
+            isIp = 1;
+        }
+
+        // found port number start index
+        if (isIp && uri[i] == ':')
+        {
+            ipLen = i;
+            outAddress->port = atoi(uri + ipLen + 1);
+            break;
+        }
+
+        if (uri[i] == '/')
+        {
+            break;
+        }
+
+        outAddress->ipAddress[i] = uri[i];
+    }
+
+    return isIp;
+}
index cc32466..6954f53 100644 (file)
@@ -30,7 +30,7 @@ OIC interfacesample application
 %build
 
 scons TARGET_OS=tizen -c
-scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT}
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE}
 
 %install
 
index 301a366..8efa77c 100644 (file)
@@ -7,6 +7,7 @@ Import('env')
 
 target_os = env.get('TARGET_OS')
 transport = env.get('TARGET_TRANSPORT')
+secured = env.get('SECURED')
 
 OIC_LIB = 'oic'
 root_dir = env.get('ROOT_DIR')
@@ -21,6 +22,11 @@ env.Append(LIBS=[
   '-lm', '-lpthread', '-lrt', '-ldl', '-lstdc++', '-lgobject-2.0', '-lgio-2.0', '-lglib-2.0', '-lcapi-network-wifi', '-ldlog', '-lcapi-network-bluetooth', '-lconnectivity_abstraction', 'coap',
 ])
 
+if secured == '1':
+       env.PrependUnique(CPPPATH = [root_dir + '/external/inc/'])
+       env.AppendUnique(CPPDEFINES = ['__WITH_DTLS__'])
+       env.Append(LIBS=['-ltinydtls'])
+
 env.Prepend(RPATH=[root_dir +'/lib/tizen/ble/libs/',])
 if 'ALL' in transport:
                env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER','BT_ADAPTER_TEST','BLE_ADAPTER_TEST'])
old mode 100644 (file)
new mode 100755 (executable)
index 45db09b..7a91274
@@ -2,19 +2,16 @@
 # CA build script
 ##
 
+import os.path
+
 Import('env')
 
 ca_os = env.get('TARGET_OS')
 ca_transport = env.get('TARGET_TRANSPORT')
 secured = env.get('SECURED')
-root_dir = './../'
-ca_path = './'
-current_dir=env.get('SRC_DIR')
-
-# The tinydtls library location is ~/iotivity/extlibs. When scons run from connectivity folder,
-# the build folder is ~/iotivity/resource/csdk/connectivity/out/linux/x86_64/release/.
-# To include  ~/iotivity/extlibs/tinyDTLS, it should go seven level up from the build folder.
-extlib_dir ='../../../../../../../../'
+with_ra = env.get ('WITH_RA')
+root_dir = os.pardir
+ca_path = os.curdir
 
 #####################################################################
 # Source files and Target(s)
@@ -22,85 +19,98 @@ extlib_dir ='../../../../../../../../'
 
 print"Reading ca script %s"%ca_transport
 
-env.PrependUnique(CPPPATH = [root_dir + '/api/'])
-env.AppendUnique(CPPPATH = [root_dir + '/inc/'])
-env.AppendUnique(CPPPATH = [root_dir + '/lib/libcoap-4.1.1/'])
-env.AppendUnique(CPPPATH = [root_dir + '/common/inc/'])
+env.PrependUnique(CPPPATH = [ os.path.join(root_dir, 'api') ])
+env.AppendUnique(CPPPATH = [ os.path.join(root_dir, 'inc'),
+                             os.path.join(root_dir, 'lib/libcoap-4.1.1'),
+                             os.path.join(root_dir, 'common/inc') ])
 
 if ca_os not in ['arduino', 'windows', 'winrt']:
        env.AppendUnique(CPPDEFINES = ['WITH_POSIX'])
 
-if ca_os in ['darwin']:
+if ca_os in ['darwin','ios']:
        env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
 
-#Getting common source files
+# Getting common source files
 env.SConscript('./../common/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.
 if env.get('SECURED') == '1':
-       if current_dir.find('connectivity') == -1:
-               env.SConscript(current_dir +'/extlibs/tinydtls/SConscript')
-       else:
-               env.SConscript(extlib_dir + '/extlibs/tinydtls/SConscript')
-
-
-env.AppendUnique(CA_SRC=[ca_path+'adapter_util/caadapterutils.c'])
-env.AppendUnique(CA_SRC=[ca_path+'adapter_util/camsgparser.c'])
+        if ca_os == 'tizen':
+                env.SConscript(os.path.join(root_dir, 'extlibs/tinydtls/SConscript'))
+        else:
+                env.SConscript('#extlibs/tinydtls/SConscript')
+
+env.AppendUnique(CA_SRC = [os.path.join(ca_path,
+                                        'adapter_util/caadapterutils.c')])
+env.AppendUnique(CA_SRC = [os.path.join(ca_path,
+                                        'adapter_util/cafragmentation.c')])
+if ca_os in ['android', 'tizen']:
+       env.AppendUnique(CA_SRC=[os.path.join(ca_path, 'adapter_util/ifaddrs.c')])
 if env.get('SECURED') == '1':
-       env.AppendUnique(CA_SRC=[ca_path+'adapter_util/caadapternetdtls.c'])
-       env.AppendUnique(CPPPATH = [root_dir + '/external/inc/'])
+       env.AppendUnique(CA_SRC = [os.path.join(ca_path,
+                                                'adapter_util/caadapternetdtls.c')])
+       env.AppendUnique(CPPPATH = [os.path.join(root_dir,
+                                                 'external/inc')])
 
+ca_common_src = None
 if ca_os == 'arduino':
        env.AppendUnique(CPPDEFINES = ['SINGLE_THREAD'])
+       env.AppendUnique(CPPDEFINES = ['WITH_ARDUINO'])
+       print "setting WITH_ARDUINO"
        ca_common_src = [
-               ca_path + 'caconnectivitymanager_singlethread.c',
-               ca_path + 'cainterfacecontroller_singlethread.c',
-               ca_path + 'camessagehandler_singlethread.c',
-               ca_path + 'canetworkconfigurator.c',
-               ca_path + 'caprotocolmessage.c',
-               ca_path + 'caremotehandler.c',
-               ca_path + 'caretransmission_singlethread.c',
+               'caconnectivitymanager.c',
+               'cainterfacecontroller.c',
+               'camessagehandler_singlethread.c',
+               'canetworkconfigurator.c',
+               'caprotocolmessage.c',
+               'caretransmission.c',
                ]
 else:
-       env.AppendUnique(CPPDEFINES = ['MULTI_THREAD'])
        ca_common_src = [
-               ca_path + 'caconnectivitymanager.c',
-               ca_path + 'cainterfacecontroller.c',
-               ca_path + 'camessagehandler.c',
-               ca_path + 'canetworkconfigurator.c',
-               ca_path + 'caprotocolmessage.c',
-               ca_path + 'caqueueingthread.c',
-               ca_path + 'caremotehandler.c',
-               ca_path + 'caretransmission.c',
+               'caconnectivitymanager.c',
+               'cainterfacecontroller.c',
+               'camessagehandler.c',
+               'canetworkconfigurator.c',
+               'caprotocolmessage.c',
+               'caqueueingthread.c',
+               'caretransmission.c',
                ]
        if secured == '1':
                env.AppendUnique(CPPDEFINES = ['__WITH_DTLS__'])
-               if current_dir.find('connectivity') == -1:
-                       env.AppendUnique(CPPPATH = [current_dir + '/extlibs/tinydtls'])
-               else:
-                       env.AppendUnique(CPPPATH = [extlib_dir + '/extlibs/tinydtls'])
-env.AppendUnique(CA_SRC = ca_common_src)
+                if ca_os == 'tizen':
+                        env.AppendUnique(CPPPATH = [os.path.join(root_dir, 'extlibs/tinydtls')])
+                else:
+                        env.AppendUnique(CPPPATH = ['#extlibs/tinydtls'])
 
+ca_common_src = [
+        os.path.join(ca_path, d) for d in ca_common_src ]
 
+env.AppendUnique(CA_SRC = ca_common_src)
 
 if 'ALL' in ca_transport:
-       env.SConscript(ca_path + 'ip_adapter/SConscript')
-       env.SConscript(ca_path + 'bt_edr_adapter/SConscript')
-       env.SConscript(ca_path + 'bt_le_adapter/SConscript')
+               transports = [ 'ip_adapter', 'bt_edr_adapter', 'bt_le_adapter' ]
+               if with_ra:
+                               transports.append ('ra_adapter')
+               env.SConscript(dirs = [
+                               os.path.join(ca_path, d) for d in transports ])
 
 if 'IP' in ca_transport:
-       env.SConscript(ca_path + 'ip_adapter/SConscript')
+       env.SConscript(os.path.join(ca_path, 'ip_adapter/SConscript'))
 
 if 'BT' in ca_transport:
-       env.SConscript(ca_path + 'bt_edr_adapter/SConscript')
+       env.SConscript(os.path.join(ca_path, 'bt_edr_adapter/SConscript'))
 
 if 'BLE' in ca_transport:
-       env.SConscript(ca_path + 'bt_le_adapter/SConscript')
+       env.SConscript(os.path.join(ca_path, 'bt_le_adapter/SConscript'))
 
-print "Include path is %s" %env.get('CPPPATH')
-print "Files path is %s" %env.get('CA_SRC')
+print "Include path is %s" % env.get('CPPPATH')
+print "Files path is %s" % env.get('CA_SRC')
 if ca_os in ['android', 'tizen']:
        calib = env.SharedLibrary('connectivity_abstraction', env.get('CA_SRC'))
 else:
        calib = env.StaticLibrary('connectivity_abstraction', env.get('CA_SRC'))
 env.InstallTarget(calib, 'libconnectivity_abstraction')
+env.UserInstallTargetLib(calib, 'libconnectivity_abstraction')
 
index 562a5fa..92b40c2 100644 (file)
@@ -22,6 +22,9 @@
 #include "caipinterface.h"
 #include "dtls.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
+#include "global.h"
+#include <netdb.h>
 
 /**
  * @def NET_DTLS_TAG
@@ -42,17 +45,145 @@ static stCADtlsContext_t *g_caDtlsContext = NULL;
 static ca_mutex g_dtlsContextMutex = NULL;
 
 /**
- * @var g_dtlsListMutex
- * @brief Mutex to synchronize access to DTLS Cache.
- */
-static ca_mutex g_dtlsListMutex = NULL;
-
-/**
  * @var g_getCredentialsCallback
  * @brief callback to get DTLS credentials
  */
 static CAGetDTLSCredentialsHandler g_getCredentialsCallback = NULL;
 
+static CAEndpoint_t *GetPeerInfo(const CAEndpoint_t *peer)
+{
+    uint32_t list_index = 0;
+    uint32_t list_length = 0;
+
+    if(NULL == peer)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "CAPeerInfoListContains invalid parameters");
+        return NULL;
+    }
+
+    CAEndpoint_t *peerInfo;
+    list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
+    for (list_index = 0; list_index < list_length; list_index++)
+    {
+        peerInfo = (CAEndpoint_t *)u_arraylist_get(g_caDtlsContext->peerInfoList, list_index);
+        if (NULL == peerInfo)
+        {
+            continue;
+        }
+
+        if((0 == strncmp(peer->addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
+                (peer->port == peerInfo->port))
+        {
+            return peerInfo;
+        }
+    }
+    return NULL;
+}
+
+static CAResult_t CAAddIdToPeerInfoList(const char *peerAddr, uint32_t port,
+                                    const unsigned char *id, uint16_t id_length)
+{
+    if(NULL == peerAddr
+       || NULL == id
+       || 0 == port
+       || 0 == id_length
+       || CA_MAX_ENDPOINT_IDENTITY_LEN < id_length)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList invalid parameters");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAEndpoint_t *peer = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
+    if (NULL == peer)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfo malloc failed!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    OICStrcpy(peer->addr, sizeof(peer->addr), peerAddr);
+    peer->port = port;
+
+    memcpy(peer->identity.id, id, id_length);
+    peer->identity.id_length = id_length;
+
+    if(NULL != GetPeerInfo(peer))
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList peer already exist");
+        OICFree(peer);
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t result = u_arraylist_add(g_caDtlsContext->peerInfoList, (void *)peer);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
+        OICFree(peer);
+    }
+
+    return result;
+}
+
+static void CAFreePeerInfoList()
+{
+    uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
+    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    {
+        CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
+                                     g_caDtlsContext->peerInfoList, list_index);
+        OICFree(peerInfo);
+    }
+    u_arraylist_free(&(g_caDtlsContext->peerInfoList));
+    g_caDtlsContext->peerInfoList = NULL;
+}
+
+static void CARemovePeerFromPeerInfoList(const char * addr, uint32_t port)
+{
+    if (NULL == addr || 0 >= port)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
+        return;
+    }
+
+    uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
+    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    {
+        CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
+                                g_caDtlsContext->peerInfoList,list_index);
+        if (NULL == peerInfo)
+        {
+            continue;
+        }
+        if((0 == strncmp(addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
+                (port == peerInfo->port))
+        {
+            OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
+            return;
+        }
+    }
+}
+
+static int CASizeOfAddrInfo(stCADtlsAddrInfo_t *addrInfo)
+{
+    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "addrInfo is NULL" , DTLS_FAIL);
+
+    switch (addrInfo->addr.st.ss_family)
+    {
+    case AF_INET:
+        {
+            return sizeof (struct sockaddr_in);
+        }
+    case AF_INET6:
+        {
+            return sizeof (struct sockaddr_in6);
+        }
+    default:
+        {
+            break;
+        }
+    }
+    return sizeof (struct sockaddr_storage);
+}
+
 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
         uint8_t *data, uint32_t dataLen)
 {
@@ -67,19 +198,15 @@ static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstS
         return DTLS_FAIL;
     }
 
-    ca_mutex_lock(g_dtlsContextMutex);
     if (NULL == g_caDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
-        ca_mutex_unlock(g_dtlsContextMutex);
         return DTLS_FAIL;
     }
 
     int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
                                 dataLen);
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
-    ca_mutex_unlock(g_dtlsContextMutex);
-
     if (0 == retLen)
     {
         // A new DTLS session was initiated by tinyDTLS library and wait for callback.
@@ -110,7 +237,6 @@ static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcS
 
     eDtlsRet_t ret = DTLS_FAIL;
 
-    ///  TODO: how to protect g_caDtlsContext as dtls_handle_message is blocking call
     if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
     {
         OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
@@ -126,7 +252,6 @@ static void CAFreeCacheMsg(stCACacheMessage_t *msg)
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
     VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
 
-    OICFree(msg->destSession);
     OICFree(msg->data);
     OICFree(msg);
 
@@ -138,11 +263,9 @@ static void CAClearCacheList()
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
     uint32_t list_index = 0;
     uint32_t list_length = 0;
-    ca_mutex_lock(g_dtlsListMutex);
     if (NULL == g_caDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
-        ca_mutex_unlock(g_dtlsListMutex);
         return;
     }
     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
@@ -157,7 +280,6 @@ static void CAClearCacheList()
     }
     u_arraylist_free(&g_caDtlsContext->cacheList);
     g_caDtlsContext->cacheList = NULL;
-    ca_mutex_unlock(g_dtlsListMutex);
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
@@ -165,11 +287,9 @@ static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    ca_mutex_lock(g_dtlsListMutex);
     if (NULL == g_caDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
-        ca_mutex_unlock(g_dtlsListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -178,7 +298,6 @@ static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
     }
-    ca_mutex_unlock(g_dtlsListMutex);
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
     return result;
@@ -187,10 +306,15 @@ static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
 
 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a,  const stCADtlsAddrInfo_t *b)
 {
-    return (a->size == b->size) &&
-           (a->addr.sa.sa_family == b->addr.sa.sa_family) &&
-           (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;
+    if (a->size != b->size)
+    {
+        return false;
+    }
+    if (memcmp(&a->addr, &b->addr, a->size))
+    {
+        return false;
+    }
+    return true;
 }
 
 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
@@ -200,15 +324,14 @@ static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
 
     uint32_t list_index = 0;
     uint32_t list_length = 0;
-    ca_mutex_lock(g_dtlsListMutex);
     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
     for (list_index = 0; list_index < list_length;)
     {
         stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
                                   list_index);
-        if ((NULL != msg) && (true == CAIsAddressMatching(msg->destSession, dstSession)))
+        if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
         {
-            eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(msg->destSession,
+            eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
                              msg->data, msg->dataLen);
             if (ret == DTLS_OK)
             {
@@ -237,7 +360,6 @@ static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
             ++list_index;
         }
     }
-    ca_mutex_unlock(g_dtlsListMutex);
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
@@ -254,29 +376,35 @@ static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext,
 
     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
 
-    char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
-    uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
-    eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
+    CAEndpoint_t endpoint = { 0 };
+    CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
+    endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
+    endpoint.flags |= CA_SECURE;
+    endpoint.adapter = CA_ADAPTER_IP;
+    int type = 0;
 
-    ca_mutex_lock(g_dtlsContextMutex);
     if (NULL == g_caDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
-        ca_mutex_unlock(g_dtlsContextMutex);
         return 0;
     }
 
     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
         (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
     {
-        g_caDtlsContext->adapterCallbacks[type].recvCallback(remoteAddress, port,
-                buf,  bufLen, true);
+        // Get identity of the source of packet
+        CAEndpoint_t *peerInfo = GetPeerInfo(&endpoint);
+        if (peerInfo)
+        {
+            endpoint.identity = peerInfo->identity;
+        }
+
+        g_caDtlsContext->adapterCallbacks[type].recvCallback(&endpoint, buf, bufLen);
     }
     else
     {
         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
     }
-    ca_mutex_unlock(g_dtlsContextMutex);
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
     return 0;
@@ -300,30 +428,28 @@ static int32_t CASendSecureData(dtls_context_t *dtlsContext,
 
     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
 
-    char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
-    uint16_t port = ntohs(addrInfo->addr.sin.sin_port);
-    eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
+    CAEndpoint_t endpoint;
+    CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
+    endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
+    endpoint.flags |= CA_SECURE;
+    endpoint.adapter = CA_ADAPTER_IP;
+    int type = 0;
 
     //Mutex is not required for g_caDtlsContext. It will be called in same thread.
-    int32_t sentLen = 0;
     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
         (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
     {
-        sentLen = g_caDtlsContext->adapterCallbacks[type].sendCallback(remoteAddress, port,
-                  buf,  bufLen);
+        g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
     }
     else
     {
         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
     }
 
-    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
-
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
-    return sentLen;
+    return bufLen;
 }
 
-
 static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
                                    session_t *session,
                                    dtls_alert_level_t level,
@@ -341,6 +467,17 @@ static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
         CASendCachedMsg((stCADtlsAddrInfo_t *)session);
     }
 
+    if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
+    {
+        OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
+
+        stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
+        char *peerAddr = inet_ntoa(addrInfo->addr.sin.sin_addr);
+        uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+
+        CARemovePeerFromPeerInfoList(peerAddr, port);
+    }
+
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
     return 0;
 }
@@ -355,6 +492,11 @@ static int32_t CAGetPskCredentials(dtls_context_t *ctx,
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
     int32_t ret  = -1;
+    if(NULL == ctx || NULL == session || NULL == result)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
+        return ret;
+    }
 
     VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
     VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
@@ -391,6 +533,22 @@ static int32_t CAGetPskCredentials(dtls_context_t *ctx,
         {
             if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
             {
+                if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
+                {
+                    // TODO SRM needs identity of the remote end-point with every data packet to
+                    // perform access control management. tinyDTLS 'frees' the handshake parameters
+                    // data structure when handshake completes. Therefore, currently this is a
+                    // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
+                    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
+                    char *peerAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
+                    uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+
+                    CAResult_t result = CAAddIdToPeerInfoList(peerAddress, port, desc, descLen);
+                    if(CA_STATUS_OK != result )
+                    {
+                        OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
+                    }
+                }
                 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
                 ret = DTLS_PSK_PSK_LEN;
             }
@@ -409,7 +567,8 @@ static int32_t CAGetPskCredentials(dtls_context_t *ctx,
 }
 
 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
-                               CAPacketSendCallback sendCallback, eDtlsAdapterType_t type)
+                               CAPacketSendCallback sendCallback,
+                               CATransportAdapter_t type)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
     ca_mutex_lock(g_dtlsContextMutex);
@@ -422,8 +581,9 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
 
     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
     {
-        g_caDtlsContext->adapterCallbacks[type].recvCallback = recvCallback;
-        g_caDtlsContext->adapterCallbacks[type].sendCallback = sendCallback;
+        // TODO: change the zeros to better values.
+        g_caDtlsContext->adapterCallbacks[0].recvCallback = recvCallback;
+        g_caDtlsContext->adapterCallbacks[0].sendCallback = sendCallback;
     }
 
     ca_mutex_unlock(g_dtlsContextMutex);
@@ -433,15 +593,176 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
 
 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
 {
+    // TODO Does this method needs protection of DtlsContextMutex ?
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
     g_getCredentialsCallback = credCallback;
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
+CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
+{
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
+
+    ca_mutex_lock(g_dtlsContextMutex);
+    if (NULL == g_caDtlsContext)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
+    ca_mutex_unlock(g_dtlsContextMutex);
+
+    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
+        ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
+
+    return CA_STATUS_OK ;
+}
+
+CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
+{
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
+
+    ca_mutex_lock(g_dtlsContextMutex);
+    if (NULL == g_caDtlsContext)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    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",
+        enable ? "enabled" : "disabled");
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
+
+    return CA_STATUS_OK ;
+}
+
+CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint)
+{
+    stCADtlsAddrInfo_t dst = {};
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
+
+    if(!endpoint)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
+    dst.ifIndex = 0;
+    dst.size = CASizeOfAddrInfo(&dst);
+
+    ca_mutex_lock(g_dtlsContextMutex);
+    if(NULL == g_caDtlsContext)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    ca_mutex_unlock(g_dtlsContextMutex);
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CADtlsClose(const CAEndpoint_t *endpoint)
+{
+    stCADtlsAddrInfo_t dst = {};
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
+
+    if(!endpoint)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
+    dst.ifIndex = 0;
+    dst.size = CASizeOfAddrInfo(&dst);
+
+    ca_mutex_lock(g_dtlsContextMutex);
+    if (NULL == g_caDtlsContext)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    ca_mutex_unlock(g_dtlsContextMutex);
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
+                    const uint8_t* label, const size_t labelLen,
+                    const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
+                    const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
+                    uint8_t* ownerPSK, const size_t ownerPSKSize)
+{
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
+
+    if(!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    stCADtlsAddrInfo_t dst = {};
+
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
+    dst.ifIndex = 0;
+    dst.size = CASizeOfAddrInfo(&dst);
+
+    ca_mutex_lock(g_dtlsContextMutex);
+    if (NULL == g_caDtlsContext)
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
+                 label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
+                 provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
+    {
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
+        ca_mutex_unlock(g_dtlsContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    ca_mutex_unlock(g_dtlsContextMutex);
+
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CAAdapterNetDtlsInit()
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
+    // Initialize mutex for DtlsContext
     if (NULL == g_dtlsContextMutex)
     {
         g_dtlsContextMutex = ca_mutex_new();
@@ -454,47 +775,40 @@ CAResult_t CAAdapterNetDtlsInit()
         return CA_STATUS_OK;
     }
 
-    if (NULL == g_dtlsListMutex)
-    {
-        g_dtlsListMutex = ca_mutex_new();
-        if (NULL == g_dtlsListMutex)
-        {
-            OIC_LOG(ERROR, NET_DTLS_TAG, "g_dtlsListMutex malloc failed");
-            ca_mutex_free(g_dtlsContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-
+    // Lock DtlsContext mutex and create DtlsContext
     ca_mutex_lock(g_dtlsContextMutex);
     g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
 
     if (NULL == g_caDtlsContext)
     {
         OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
-        ca_mutex_free(g_dtlsListMutex);
         ca_mutex_unlock(g_dtlsContextMutex);
         ca_mutex_free(g_dtlsContextMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    ca_mutex_lock(g_dtlsListMutex);
+
+    // Create PeerInfoList and CacheList
+    g_caDtlsContext->peerInfoList = u_arraylist_create();
     g_caDtlsContext->cacheList = u_arraylist_create();
 
-    if (NULL == g_caDtlsContext->cacheList)
+    if( (NULL == g_caDtlsContext->peerInfoList) ||
+        (NULL == g_caDtlsContext->cacheList))
     {
-        OIC_LOG(ERROR, NET_DTLS_TAG, "cacheList initialization failed!");
-        ca_mutex_unlock(g_dtlsListMutex);
-        ca_mutex_free(g_dtlsListMutex);
-        ca_mutex_unlock(g_dtlsContextMutex);
-        ca_mutex_free(g_dtlsContextMutex);
+    OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
+        CAClearCacheList();
+        CAFreePeerInfoList();
         OICFree(g_caDtlsContext);
         g_caDtlsContext = NULL;
+        ca_mutex_unlock(g_dtlsContextMutex);
+        ca_mutex_free(g_dtlsContextMutex);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_dtlsListMutex);
+
     // Initialize clock, crypto and other global vars in tinyDTLS library
     dtls_init();
 
+    // Create tinydtls Context
     g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
 
     if (NULL ==  g_caDtlsContext->dtlsContext)
@@ -521,35 +835,41 @@ void CAAdapterNetDtlsDeInit()
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
     VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
+    VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
 
+    //Lock DtlsContext mutex
     ca_mutex_lock(g_dtlsContextMutex);
+
+    // Clear all lists
+    CAFreePeerInfoList();
     CAClearCacheList();
+
+    // De-initialize tinydtls context
     dtls_free_context(g_caDtlsContext->dtlsContext);
     g_caDtlsContext->dtlsContext = NULL;
+
+    // De-initialize DtlsContext
     OICFree(g_caDtlsContext);
     g_caDtlsContext = NULL;
-    ca_mutex_unlock(g_dtlsContextMutex);
 
+    // Unlock DtlsContext mutex and de-initialize it
+    ca_mutex_unlock(g_dtlsContextMutex);
     ca_mutex_free(g_dtlsContextMutex);
     g_dtlsContextMutex = NULL;
-    ca_mutex_free(g_dtlsListMutex);
-    g_dtlsListMutex = NULL;
+
     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
 }
 
-CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
-                                   const uint16_t port,
-                                   void *data,
-                                   uint32_t dataLen,
-                                   uint8_t *cacheFlag,
-                                   eDtlsAdapterType_t adapterType)
+CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
+                                   void *data, uint32_t dataLen)
 {
 
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG,"Param remoteAddress is NULL",CA_STATUS_FAILED);
-
-    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG,"Param remoteAddress is NULL",
+                        CA_STATUS_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" ,
+                        CA_STATUS_INVALID_PARAM);
 
     if (0 == dataLen)
     {
@@ -559,30 +879,28 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
 
     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
+    stCADtlsAddrInfo_t addrInfo = {};
 
-    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed" , CA_MEMORY_ALLOC_FAILED);
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
+    addrInfo.ifIndex = 0;
+    addrInfo.size = CASizeOfAddrInfo(&addrInfo);
 
-    addrInfo->addr.sin.sin_family = AF_INET;
-    addrInfo->addr.sin.sin_port = htons(port);
-    // Conversion from ASCII format to Network format
-    if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
+    ca_mutex_lock(g_dtlsContextMutex);
+    if(NULL == g_caDtlsContext)
     {
-        OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
-        OICFree(addrInfo);
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
         return CA_STATUS_FAILED;
     }
-    addrInfo->size = sizeof(addrInfo->addr);
-    addrInfo->ifIndex = adapterType;
 
-    eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(addrInfo, data, dataLen);
+    eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
     if (ret == DTLS_SESSION_INITIATED)
     {
         stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
         if (NULL == message)
         {
             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
-            OICFree(addrInfo);
+            ca_mutex_unlock(g_dtlsContextMutex);
             return CA_MEMORY_ALLOC_FAILED;
         }
 
@@ -590,8 +908,8 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
         if (NULL == message->data)
         {
             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
-            OICFree(addrInfo);
             OICFree(message);
+            ca_mutex_unlock(g_dtlsContextMutex);
             return CA_MEMORY_ALLOC_FAILED;
         }
         memcpy(message->data, data, dataLen);
@@ -599,63 +917,51 @@ CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
         message->destSession = addrInfo;
 
         CAResult_t result = CADtlsCacheMsg(message);
-        if (CA_STATUS_OK == result)
-        {
-            if (cacheFlag)
-            {
-                *cacheFlag = 1;
-            }
-        }
-        else
+        if (CA_STATUS_OK != result)
         {
             OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
             CAFreeCacheMsg(message);
         }
         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
+        ca_mutex_unlock(g_dtlsContextMutex);
         return result;
     }
 
-    OICFree(addrInfo);
+    ca_mutex_unlock(g_dtlsContextMutex);
 
-    if (ret == DTLS_OK)
+    if (ret != DTLS_OK)
     {
-        OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
-        return CA_STATUS_OK;
+        OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
-    return CA_STATUS_FAILED;
+    OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-
-CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
-                                   const uint16_t port,
-                                   uint8_t *data,
-                                   uint32_t dataLen,
-                                   eDtlsAdapterType_t adapterType)
+CAResult_t CAAdapterNetDtlsDecrypt(const CAEndpoint_t *endpoint,
+                                   uint8_t *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+    VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
 
-    stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
+    stCADtlsAddrInfo_t addrInfo = {};
 
-    VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "calloc failed" , CA_MEMORY_ALLOC_FAILED);
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
+    addrInfo.ifIndex = 0;
+    addrInfo.size = CASizeOfAddrInfo(&addrInfo);
 
-    addrInfo->addr.sin.sin_family = AF_INET;
-    addrInfo->addr.sin.sin_port = htons(port);
-
-    // Conversion from ASCII format to Network format
-    if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
+    ca_mutex_lock(g_dtlsContextMutex);
+    if (NULL == g_caDtlsContext)
     {
-        OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
-        OICFree(addrInfo);
+        OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+        ca_mutex_unlock(g_dtlsContextMutex);
         return CA_STATUS_FAILED;
     }
-    addrInfo->size = sizeof(addrInfo->addr);
-    addrInfo->ifIndex = adapterType;
 
-    eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(addrInfo, data, dataLen);
+    eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
+    ca_mutex_unlock(g_dtlsContextMutex);
 
-    OICFree(addrInfo);
     if (DTLS_OK == ret || DTLS_HS_MSG == ret)
     {
         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
@@ -667,4 +973,3 @@ CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
     return CA_STATUS_FAILED;
 }
 
-
index c073b62..2094a6e 100644 (file)
 
 #include <string.h>
 #include <ctype.h>
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include <errno.h>
+
+#ifndef WITH_ARDUINO
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#endif
 
 #ifdef __ANDROID__
 #include <jni.h>
 #endif
 
-#include "oic_malloc.h"
-#include "oic_string.h"
-
 #define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
 
 #ifdef __ANDROID__
@@ -60,221 +66,7 @@ void CALogPDUData(coap_pdu_t *pdu)
     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
 }
 
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address)
-{
-    CALocalConnectivity_t *info = (CALocalConnectivity_t *)
-                                  OICCalloc(1, sizeof(CALocalConnectivity_t));
-    if (NULL == info)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
-        return NULL;
-    }
-
-    info->type = type;
-    if (address && strlen(address))
-    {
-        if (CA_EDR == type)
-        {
-            strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
-            info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_LE == type)
-        {
-            strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
-            info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_IPV4 == type)
-        {
-            strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
-            info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_IPV6 == type)
-        {
-            OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
-            OICFree(info);
-            return NULL;
-        }
-        else
-        {
-            OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
-            OICFree(info);
-            return NULL;
-        }
-    }
-
-    return info;
-}
-
-CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity)
-{
-    VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL);
-
-    CALocalConnectivity_t *info = (CALocalConnectivity_t *)
-                                  OICCalloc(1, sizeof(CALocalConnectivity_t));
-    if (NULL == info)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
-        return NULL;
-    }
-
-    info->type = connectivity->type;
-    if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress))
-    {
-        strncpy(info->addressInfo.BT.btMacAddress, connectivity->addressInfo.BT.btMacAddress,
-                CA_MACADDR_SIZE - 1);
-        info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-    }
-    else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress))
-    {
-        strncpy(info->addressInfo.LE.leMacAddress, connectivity->addressInfo.LE.leMacAddress,
-                CA_MACADDR_SIZE - 1);
-        info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-    }
-    else if ((CA_IPV4 == info->type)
-
-            && strlen(connectivity->addressInfo.IP.ipAddress))
-    {
-        strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress,
-                CA_IPADDR_SIZE - 1);
-        info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
-        info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
-    }
-    else if (CA_IPV6 == info->type)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
-        OICFree(info);
-        return NULL;
-    }
-    else
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
-        OICFree(info);
-        return NULL;
-    }
-
-    info->isSecured = connectivity->isSecured;
-    return info;
-}
-
-void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint)
-{
-    OICFree(localEndpoint);
-}
-
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address,
-                                                  const char *resourceUri)
-{
-    CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
-                               OICCalloc(1, sizeof(CARemoteEndpoint_t));
-    if (NULL == info)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
-        return NULL;
-    }
-
-    info->transportType = type;
-    if (address && strlen(address))
-    {
-        if (CA_EDR == type)
-        {
-            strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
-            info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_LE == type)
-        {
-            strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
-            info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_IPV4 == type)
-        {
-            strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
-            info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
-        }
-        else if (CA_IPV6 == type)
-        {
-            OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
-            OICFree(info);
-            return NULL;
-        }
-        else
-        {
-            OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
-            OICFree(info);
-            return NULL;
-        }
-    }
-
-    if (resourceUri && strlen(resourceUri))
-    {
-        info->resourceUri = OICStrdup(resourceUri);
-    }
-
-    return info;
-}
-
-CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint)
-{
-    VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL);
-
-    CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
-                               OICCalloc(1, sizeof(CARemoteEndpoint_t));
-    if (NULL == info)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
-        return NULL;
-    }
-
-    info->transportType = remoteEndpoint->transportType;
-    if (CA_EDR == info->transportType && ('\0' != remoteEndpoint->addressInfo.BT.btMacAddress[0]))
-    {
-        strncpy(info->addressInfo.BT.btMacAddress, remoteEndpoint->addressInfo.BT.btMacAddress,
-                CA_MACADDR_SIZE - 1);
-        info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-    }
-    else if (CA_LE == info->transportType
-             && ('\0' != remoteEndpoint->addressInfo.LE.leMacAddress[0]))
-    {
-        strncpy(info->addressInfo.LE.leMacAddress, remoteEndpoint->addressInfo.LE.leMacAddress,
-                CA_MACADDR_SIZE - 1);
-        info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-    }
-    else if ((CA_IPV4 == info->transportType)
-            && ('\0' != remoteEndpoint->addressInfo.IP.ipAddress[0]))
-    {
-        strncpy(info->addressInfo.IP.ipAddress, remoteEndpoint->addressInfo.IP.ipAddress,
-                CA_IPADDR_SIZE - 1);
-        info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
-        info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port;
-    }
-    else if (CA_IPV6 == info->transportType)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
-    }
-    else
-    {
-        OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "Its not matching. May be multicast.");
-    }
-
-    //For Multicast, remote address will be null while resourceUri will have the service UUID
-
-    if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri))
-    {
-        info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
-    }
-
-    info->isSecured = remoteEndpoint->isSecured;
-    return info;
-}
-
-void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
-{
-    if (remoteEndpoint)
-    {
-        OICFree(remoteEndpoint->resourceUri);
-        OICFree(remoteEndpoint);
-    }
-}
-
+#ifdef WITH_ARDUINO
 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
                                    size_t ipAddrLen, uint16_t *port)
 {
@@ -339,238 +131,80 @@ CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
     return CA_STATUS_FAILED;
 }
 
-bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
-{
-    VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
-    VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
-    VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
-
-    uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
-    uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
-    uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
-    CAResult_t ret = CA_STATUS_OK;
-
-    /* Local Loopback Address */
-    if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
-    {
-        return true;
-    }
-
-    uint16_t parsedPort = 0;
-    ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
-    if (ret != CA_STATUS_OK)
-    {
-        OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
-        return false;
-    }
-
-    ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
-    if (ret != CA_STATUS_OK)
-    {
-        OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
-        return false;
-    }
-
-    ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
-    if (ret != CA_STATUS_OK)
-    {
-        OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
-        return false;
-    }
-
-    return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
-            == (ipList2[1] & maskList[1]))
-           && ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
-           && ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
-}
-
-
-bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
-                                const char *multicastAddress, uint16_t port)
-{
-    VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
-    VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
-    VERIFY_NON_NULL_RET(multicastAddress, CA_ADAPTER_UTILS_TAG, "multicastAddress is null", false);
-
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!info)
-        {
-            OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Info is NULL");
-            return false;
-        }
-
-        if (info->isMulticastServer && (strncmp(info->ipAddress, multicastAddress,
-                                                strlen(multicastAddress) == 0))
-            && (info->port == port) && (strncmp(info->ifAddr, ipAddress, strlen(ipAddress)) == 0))
-        {
-            return info->isServerStarted;
-        }
-    }
-    return false;
-}
-
-bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
-                              uint16_t port)
-{
-    VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
-    VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
-
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (!info->isMulticastServer && (strncmp(info->ipAddress, ipAddress,
-                                                 strlen(ipAddress)) == 0)
-            && (info->port == port))
-        {
-            return info->isServerStarted;
-        }
-    }
-    return false;
-}
-
-uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, bool isSecured)
+#else // not with_arduino
+/*
+ * These two conversion functions return void because errors can't happen
+ * (because of NI_NUMERIC), and there's nothing to do if they do happen.
+ */
+void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, char *host, uint16_t *port)
 {
-    VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", 0);
-    VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", 0);
+    VERIFY_NON_NULL_VOID(sockAddr, CA_ADAPTER_UTILS_TAG, "sockAddr is null");
+    VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
+    VERIFY_NON_NULL_VOID(port, CA_ADAPTER_UTILS_TAG, "port is null");
 
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+    int r = getnameinfo((struct sockaddr *)sockAddr,
+                        sizeof (struct sockaddr_storage),
+                        host, MAX_ADDR_STR_SIZE_CA,
+                        NULL, 0,
+                        NI_NUMERICHOST|NI_NUMERICSERV);
+    if (r)
     {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!info)
-        {
-            continue;
-        }
-        if ((strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0) &&
-                    (info->isSecured == isSecured))
+        if (EAI_SYSTEM == r)
         {
-            return info->port;
+            OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+                            "getaddrinfo failed: errno %s", strerror(errno));
         }
-    }
-
-    return 0;
-}
-
-int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress,
-                                  bool isSecured, bool isMulticast, CATransportType_t type)
-{
-    VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", -1);
-    VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", -1);
-
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (!CAAdapterIsSameSubnet(info->ipAddress, ipAddress, info->subNetMask))
-        {
-            continue;
-        }
-
-        if (!info->isMulticastServer && (info->isSecured == isSecured))
+        else
         {
-            OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG,
-                      "CAGetSocketFdForServer found socket [%d]", info->socketFd);
-            return info->socketFd;
+            OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+                            "getaddrinfo failed: %s", gai_strerror(r));
         }
-
+        return;
     }
-
-    OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG,
-            "CAGetSocketFdForServer socket fd is not found");
-    return -1;
+    *port = ntohs(((struct sockaddr_in *)sockAddr)->sin_port); // IPv4 and IPv6
 }
 
-CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info)
+void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr)
 {
-    VERIFY_NON_NULL(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
-    VERIFY_NON_NULL(info, CA_ADAPTER_UTILS_TAG, "info is null");
-
-    CAResult_t result = u_arraylist_add(serverInfoList, (void *) info);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_add failed!");
-    }
-    return result;
-}
+    VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
+    VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
 
-void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd)
-{
-    VERIFY_NON_NULL_VOID(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
+    struct addrinfo *addrs;
+    struct addrinfo hints = { 0 };
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_flags = AI_NUMERICHOST;
 
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-    for (uint32_t listIndex = 0; listIndex < listLength;)
+    int r = getaddrinfo(host, NULL, &hints, &addrs);
+    if (r)
     {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!info)
-        {
-            listIndex++;
-            continue;
-        }
-
-        if (info->socketFd == sockFd)
+        if (EAI_SYSTEM == r)
         {
-            if (u_arraylist_remove(serverInfoList, listIndex))
-            {
-                OICFree(info);
-                listLength--;
-            }
-            else
-            {
-                OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_remove failed!");
-                break;
-            }
+            OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+                            "getaddrinfo failed: errno %s", strerror(errno));
         }
         else
         {
-            listIndex++;
+            OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
+                            "getaddrinfo failed: %s", gai_strerror(r));
         }
+        return;
     }
-}
-
-void CAClearNetInterfaceInfoList(u_arraylist_t *infoList)
-{
-    uint32_t listLength = u_arraylist_length(infoList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+    // assumption: in this case, getaddrinfo will only return one addrinfo
+    // or first is the one we want.
+    if (addrs[0].ai_family == AF_INET6)
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(infoList, listIndex);
-        if (!netInfo)
-        {
-            continue;
-        }
-        OICFree(netInfo);
+        memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6));
+        ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port);
     }
-    u_arraylist_free(&infoList);
-}
-
-void CAClearServerInfoList(u_arraylist_t *serverInfoList)
-{
-    uint32_t listLength = u_arraylist_length(serverInfoList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+    else
     {
-        CAServerInfo_t *serverInfo = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
-        if (!serverInfo)
-        {
-            continue;
-        }
-        OICFree(serverInfo);
+        memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in));
+        ((struct sockaddr_in *)sockaddr)->sin_port = htons(port);
     }
-    u_arraylist_free(&serverInfoList);
+    freeaddrinfo(addrs);
 }
+#endif // WITH_ARDUINO
 
 #ifdef __ANDROID__
 void CANativeJNISetContext(JNIEnv *env, jobject context)
@@ -602,4 +236,3 @@ JavaVM *CANativeJNIGetJavaVM()
     return g_jvm;
 }
 #endif
-
  *
  ******************************************************************/
 
-#include "camsgparser.h"
-
 #include <string.h>
 #include <math.h>
 
 #include "cacommon.h"
 #include "caadapterutils.h"
+#include "cafragmentation.h"
 
 /**
- * @var CA_MSG_PARSER_TAG
- * @brief debugging tag for parser module
+ * @var CA_FRAGMENTATION_TAG
+ * @brief debugging tag for fragmentation module
  */
-#define CA_MSG_PARSER_TAG "CA_MSG_PARSER"
+#define CA_FRAGMENTATION_TAG "CA_FRAGMENTATION"
 
 CAResult_t CAGenerateHeader(char *header, uint32_t length)
 {
-    OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
+    OIC_LOG(DEBUG, CA_FRAGMENTATION_TAG, "IN");
 
-    VERIFY_NON_NULL(header, CA_MSG_PARSER_TAG, "header is NULL");
+    VERIFY_NON_NULL(header, CA_FRAGMENTATION_TAG, "header is NULL");
     memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH);
 
     if(length > MAX_DATA_LENGTH_SUPPORTED)
     {
-        OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "Given length is more than 4095.It will be truncated");
+        OIC_LOG(DEBUG, CA_FRAGMENTATION_TAG,
+                "Given length is more than 4095.It will be truncated");
     }
     //if length is more than 4095 then it will be truncated.
     header[1] = length & 0xFF;
@@ -49,20 +49,20 @@ CAResult_t CAGenerateHeader(char *header, uint32_t length)
     header[0] = length & 0x0F;
     header[0] = header[0] | 0x40; // Adding version 0100.(Not used. Future use)
 
-    OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
+    OIC_LOG(DEBUG, CA_FRAGMENTATION_TAG, "OUT");
+
     return CA_STATUS_OK;
 }
 
 uint32_t CAParseHeader(const char *header)
 {
-    OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
+    OIC_LOG(DEBUG, CA_FRAGMENTATION_TAG, "IN");
 
-    VERIFY_NON_NULL(header, CA_MSG_PARSER_TAG, "header is NULL");
+    VERIFY_NON_NULL_RET(header, CA_FRAGMENTATION_TAG, "header is NULL", 0);
 
     uint32_t dataLen = ((header[0] & 0x0F) << 8) | (header[1] & 0xFF);
 
-    OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
+    OIC_LOG(DEBUG, CA_FRAGMENTATION_TAG, "OUT");
     return dataLen;
 }
 
-
diff --git a/resource/csdk/connectivity/src/adapter_util/ifaddrs.c b/resource/csdk/connectivity/src/adapter_util/ifaddrs.c
new file mode 100644 (file)
index 0000000..4d9f9e8
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+Copyright (c) 2013, 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.
+*/
+
+#include <net/if.h>
+#include "ifaddrs.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <sys/ioctl.h>
+
+typedef struct NetlinkList
+{
+    struct NetlinkList *m_next;
+    struct nlmsghdr *m_data;
+    unsigned int m_size;
+} NetlinkList;
+
+static int netlink_socket(void)
+{
+    int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if(l_socket < 0)
+    {
+        return -1;
+    }
+
+    struct sockaddr_nl l_addr;
+    memset(&l_addr, 0, sizeof(l_addr));
+    l_addr.nl_family = AF_NETLINK;
+    if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
+    {
+        close(l_socket);
+        return -1;
+    }
+
+    return l_socket;
+}
+
+static int netlink_send(int p_socket, int p_request)
+{
+    struct
+    {
+        struct nlmsghdr m_hdr;
+        struct rtgenmsg m_msg;
+    } l_data;
+
+    memset(&l_data, 0, sizeof(l_data));
+
+    l_data.m_hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
+    l_data.m_hdr.nlmsg_type = p_request;
+    l_data.m_hdr.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+    l_data.m_hdr.nlmsg_pid = 0;
+    l_data.m_hdr.nlmsg_seq = p_socket;
+    l_data.m_msg.rtgen_family = AF_UNSPEC;
+
+    struct sockaddr_nl l_addr;
+    memset(&l_addr, 0, sizeof(l_addr));
+    l_addr.nl_family = AF_NETLINK;
+    return (sendto(p_socket, &l_data.m_hdr, l_data.m_hdr.nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
+}
+
+static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
+{
+    struct msghdr l_msg;
+    struct iovec l_iov = { p_buffer, p_len };
+    struct sockaddr_nl l_addr;
+
+    for(;;)
+    {
+        l_msg.msg_name = (void *)&l_addr;
+        l_msg.msg_namelen = sizeof(l_addr);
+        l_msg.msg_iov = &l_iov;
+        l_msg.msg_iovlen = 1;
+        l_msg.msg_control = NULL;
+        l_msg.msg_controllen = 0;
+        l_msg.msg_flags = 0;
+        int l_result = recvmsg(p_socket, &l_msg, 0);
+
+        if(l_result < 0)
+        {
+            if(errno == EINTR)
+            {
+                continue;
+            }
+            return -2;
+        }
+
+        if(l_msg.msg_flags & MSG_TRUNC)
+        { // buffer was too small
+            return -1;
+        }
+        return l_result;
+    }
+}
+
+static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
+{
+    size_t l_size = 4096;
+    void *l_buffer = NULL;
+
+    for(;;)
+    {
+        free(l_buffer);
+        l_buffer = malloc(l_size);
+        if (l_buffer == NULL)
+        {
+            return NULL;
+        }
+
+        int l_read = netlink_recv(p_socket, l_buffer, l_size);
+        *p_size = l_read;
+        if(l_read == -2)
+        {
+            free(l_buffer);
+            return NULL;
+        }
+        if(l_read >= 0)
+        {
+            pid_t l_pid = getpid();
+            struct nlmsghdr *l_hdr;
+            for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
+            {
+                if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+                {
+                    continue;
+                }
+
+                if(l_hdr->nlmsg_type == NLMSG_DONE)
+                {
+                    *p_done = 1;
+                    break;
+                }
+
+                if(l_hdr->nlmsg_type == NLMSG_ERROR)
+                {
+                    free(l_buffer);
+                    return NULL;
+                }
+            }
+            return l_buffer;
+        }
+
+        l_size *= 2;
+    }
+}
+
+static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
+{
+    NetlinkList *l_item = malloc(sizeof(NetlinkList));
+    if (l_item == NULL)
+    {
+        return NULL;
+    }
+
+    l_item->m_next = NULL;
+    l_item->m_data = p_data;
+    l_item->m_size = p_size;
+    return l_item;
+}
+
+static void freeResultList(NetlinkList *p_list)
+{
+    NetlinkList *l_cur;
+    while(p_list)
+    {
+        l_cur = p_list;
+        p_list = p_list->m_next;
+        free(l_cur->m_data);
+        free(l_cur);
+    }
+}
+
+static NetlinkList *getResultList(int p_socket, int p_request)
+{
+    if(netlink_send(p_socket, p_request) < 0)
+    {
+        return NULL;
+    }
+
+    NetlinkList *l_list = NULL;
+    NetlinkList *l_end = NULL;
+    int l_size;
+    int l_done = 0;
+    while(!l_done)
+    {
+        struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
+        if(!l_hdr)
+        { // error
+            freeResultList(l_list);
+            return NULL;
+        }
+
+        NetlinkList *l_item = newListItem(l_hdr, l_size);
+        if (!l_item)
+        {
+            freeResultList(l_list);
+            return NULL;
+        }
+        if(!l_list)
+        {
+            l_list = l_item;
+        }
+        else
+        {
+            l_end->m_next = l_item;
+        }
+        l_end = l_item;
+    }
+    return l_list;
+}
+
+static size_t maxSize(size_t a, size_t b)
+{
+    return (a > b ? a : b);
+}
+
+static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
+{
+    switch(p_family)
+    {
+        case AF_INET:
+            return sizeof(struct sockaddr_in);
+        case AF_INET6:
+            return sizeof(struct sockaddr_in6);
+        case AF_PACKET:
+            return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
+        default:
+            return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
+    }
+}
+
+static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
+{
+    switch(p_family)
+    {
+        case AF_INET:
+            memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
+            break;
+        case AF_INET6:
+            memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
+            break;
+        case AF_PACKET:
+            memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
+            ((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
+            break;
+        default:
+            memcpy(p_dest->sa_data, p_data, p_size);
+            break;
+    }
+    p_dest->sa_family = p_family;
+}
+
+static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
+{
+    if(!*p_resultList)
+    {
+        *p_resultList = p_entry;
+    }
+    else
+    {
+        struct ifaddrs *l_cur = *p_resultList;
+        while(l_cur->ifa_next)
+        {
+            l_cur = l_cur->ifa_next;
+        }
+        l_cur->ifa_next = p_entry;
+    }
+}
+
+static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
+{
+    struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
+
+    size_t l_nameSize = 0;
+    size_t l_addrSize = 0;
+    size_t l_dataSize = 0;
+
+    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+    struct rtattr *l_rta;
+    for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        //void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFLA_ADDRESS:
+            case IFLA_BROADCAST:
+                l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
+                break;
+            case IFLA_IFNAME:
+                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+                break;
+            case IFLA_STATS:
+                l_dataSize += NLMSG_ALIGN(l_rtaSize);
+                break;
+            default:
+                break;
+        }
+    }
+
+    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
+    if (l_entry == NULL)
+    {
+        return -1;
+    }
+    memset(l_entry, 0, sizeof(struct ifaddrs));
+    l_entry->ifa_name = "";
+
+    char *l_index = ((char *)l_entry) + sizeof(struct ifaddrs);
+    char *l_name = l_index + sizeof(int);
+    char *l_addr = l_name + l_nameSize;
+    char *l_data = l_addr + l_addrSize;
+
+    // save the interface index so we can look it up when handling the addresses.
+    memcpy(l_index, &l_info->ifi_index, sizeof(int));
+
+    l_entry->ifa_flags = l_info->ifi_flags;
+
+    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+    for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFLA_ADDRESS:
+            case IFLA_BROADCAST:
+            {
+                size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
+                makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
+                ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
+                ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
+                if(l_rta->rta_type == IFLA_ADDRESS)
+                {
+                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                }
+                else
+                {
+                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+                }
+                l_addr += NLMSG_ALIGN(l_addrLen);
+                break;
+            }
+            case IFLA_IFNAME:
+                strncpy(l_name, l_rtaData, l_rtaDataSize);
+                l_name[l_rtaDataSize] = '\0';
+                l_entry->ifa_name = l_name;
+                break;
+            case IFLA_STATS:
+                memcpy(l_data, l_rtaData, l_rtaDataSize);
+                l_entry->ifa_data = l_data;
+                break;
+            default:
+                break;
+        }
+    }
+
+    addToEnd(p_resultList, l_entry);
+    return 0;
+}
+
+static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
+{
+    int l_num = 0;
+    struct ifaddrs *l_cur = *p_links;
+    while(l_cur && l_num < p_numLinks)
+    {
+        char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs);
+        int l_index;
+        memcpy(&l_index, l_indexPtr, sizeof(int));
+        if(l_index == p_index)
+        {
+            return l_cur;
+        }
+
+        l_cur = l_cur->ifa_next;
+        ++l_num;
+    }
+    return NULL;
+}
+
+static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)
+{
+    struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
+    struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
+
+    if(l_info->ifa_family == AF_PACKET)
+    {
+        return 0;
+    }
+
+    size_t l_nameSize = 0;
+    size_t l_addrSize = 0;
+
+    int l_addedNetmask = 0;
+
+    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+    struct rtattr *l_rta;
+    for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        //void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+
+        switch(l_rta->rta_type)
+        {
+            case IFA_ADDRESS:
+            case IFA_LOCAL:
+                if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
+                { // make room for netmask
+                    l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
+                    l_addedNetmask = 1;
+                }
+            case IFA_BROADCAST:
+                l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
+                break;
+            case IFA_LABEL:
+                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+                break;
+            default:
+                break;
+        }
+    }
+
+    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
+    if (l_entry == NULL)
+    {
+        return -1;
+    }
+    memset(l_entry, 0, sizeof(struct ifaddrs));
+    l_entry->ifa_name = (l_interface ? l_interface->ifa_name : "");
+
+    char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
+    char *l_addr = l_name + l_nameSize;
+
+    l_entry->ifa_flags = l_info->ifa_flags;
+    if(l_interface)
+    {
+        l_entry->ifa_flags |= l_interface->ifa_flags;
+    }
+
+    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+    for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFA_ADDRESS:
+            case IFA_BROADCAST:
+            case IFA_LOCAL:
+            {
+                size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
+                makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
+                if(l_info->ifa_family == AF_INET6)
+                {
+                    if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
+                    {
+                        ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
+                    }
+                }
+
+                if(l_rta->rta_type == IFA_ADDRESS)
+                { // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
+                    if(l_entry->ifa_addr)
+                    {
+                        l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
+                    }
+                    else
+                    {
+                        l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                    }
+                }
+                else if(l_rta->rta_type == IFA_LOCAL)
+                {
+                    if(l_entry->ifa_addr)
+                    {
+                        l_entry->ifa_dstaddr = l_entry->ifa_addr;
+                    }
+                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                }
+                else
+                {
+                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+                }
+                l_addr += NLMSG_ALIGN(l_addrLen);
+                break;
+            }
+            case IFA_LABEL:
+                strncpy(l_name, l_rtaData, l_rtaDataSize);
+                l_name[l_rtaDataSize] = '\0';
+                l_entry->ifa_name = l_name;
+                break;
+            default:
+                break;
+        }
+    }
+
+    if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
+    {
+        unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
+        unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
+        char l_mask[16] = {0};
+        unsigned i;
+        for(i=0; i<(l_prefix/8); ++i)
+        {
+            l_mask[i] = 0xff;
+        }
+        if(l_prefix % 8)
+        {
+            l_mask[i] = 0xff << (8 - (l_prefix % 8));
+        }
+
+        makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
+        l_entry->ifa_netmask = (struct sockaddr *)l_addr;
+    }
+
+    addToEnd(p_resultList, l_entry);
+    return 0;
+}
+
+static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
+{
+    int l_numLinks = 0;
+    pid_t l_pid = getpid();
+    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+    {
+        unsigned int l_nlsize = p_netlinkList->m_size;
+        struct nlmsghdr *l_hdr;
+        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
+        {
+            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+            {
+                continue;
+            }
+
+            if(l_hdr->nlmsg_type == NLMSG_DONE)
+            {
+                break;
+            }
+
+            if(l_hdr->nlmsg_type == RTM_NEWLINK)
+            {
+                if(interpretLink(l_hdr, p_resultList) == -1)
+                {
+                    return -1;
+                }
+                ++l_numLinks;
+            }
+        }
+    }
+    return l_numLinks;
+}
+
+static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
+{
+    pid_t l_pid = getpid();
+    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+    {
+        unsigned int l_nlsize = p_netlinkList->m_size;
+        struct nlmsghdr *l_hdr;
+        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
+        {
+            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+            {
+                continue;
+            }
+
+            if(l_hdr->nlmsg_type == NLMSG_DONE)
+            {
+                break;
+            }
+
+            if(l_hdr->nlmsg_type == RTM_NEWADDR)
+            {
+                if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1)
+                {
+                    return -1;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+    if(!ifap)
+    {
+        return -1;
+    }
+    *ifap = NULL;
+
+    int l_socket = netlink_socket();
+    if(l_socket < 0)
+    {
+        return -1;
+    }
+
+    NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
+    if(!l_linkResults)
+    {
+        close(l_socket);
+        return -1;
+    }
+
+    NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
+    if(!l_addrResults)
+    {
+        close(l_socket);
+        freeResultList(l_linkResults);
+        return -1;
+    }
+
+    int l_result = 0;
+    int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap);
+    if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
+    {
+        l_result = -1;
+    }
+
+    freeResultList(l_linkResults);
+    freeResultList(l_addrResults);
+    close(l_socket);
+    return l_result;
+}
+
+void freeifaddrs(struct ifaddrs *ifa)
+{
+    struct ifaddrs *l_cur;
+    while(ifa)
+    {
+        l_cur = ifa;
+        ifa = ifa->ifa_next;
+        free(l_cur);
+    }
+}
+
+
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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 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.
+ */
+
+//#include <string.h>
+//#include <unistd.h>
+//#include <linux/sockios.h>
+//#include <net/if.h>
+//#include <sys/socket.h>
+//#include <sys/ioctl.h>
+
+/*
+ * Map an interface name into its corresponding index.
+ * Returns 0 on error, as 0 is not a valid index.
+ */
+unsigned int if_nametoindex(const char *ifname)
+{
+    int index;
+    int ctl_sock;
+    struct ifreq ifr;
+
+    memset(&ifr, 0, sizeof(struct ifreq));
+    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+    ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+    index = 0;
+    if ((ctl_sock = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
+        if (ioctl(ctl_sock, SIOCGIFINDEX, &ifr) >= 0) {
+            index = ifr.ifr_ifindex;
+        }
+        close(ctl_sock);
+    }
+    return index;
+}
index 4e2fa34..d7da75a 100644 (file)
@@ -1,44 +1,41 @@
 #######################################################
-#      Building BT adapter
+#      Build BT EDR adapter
 #######################################################
 
 Import('env')
+import os.path
 
-print"Reading bt adapter script"
+print "Reading BT EDR adapter script"
 
 target_os = env.get('TARGET_OS')
 
-if target_os == 'tizen':
-    env.ParseConfig("pkg-config --cflags --libs capi-network-bluetooth")
+src_dir = os.path.join(os.curdir, 'bt_edr_adapter')
 
-src_dir = './bt_edr_adapter/'
-
-#Source files to build common for all platforms
+# Source files to build common for all platforms
+common_files = []
 if target_os != 'arduino':
-       env.AppendUnique(CA_SRC=[src_dir+'caedradapter.c'])
-
-#Source files to build in Linux platform
-if target_os == 'linux':
-       env.AppendUnique(CA_SRC=[src_dir+'linux/caedradapter.c',
-                       ])
-
-#Source files to build in Tizen platform
-if target_os == 'tizen':
-       env.PrependUnique(CPPPATH = [src_dir + 'tizen'])
-       env.AppendUnique(CA_SRC=[src_dir+'tizen/caedrclient.c',
-                       src_dir+'tizen/caedrdevicelist.c',
-                       src_dir+'tizen/caedrendpoint.c',
-                       src_dir+'tizen/caedrnwmonitor.c',
-                       src_dir+'tizen/caedrserver.c',
-                       src_dir+'tizen/caedrutils.c',
-                       ])
-
-#Source files to build in Android platform
-if target_os == 'android':
-       env.AppendUnique(CA_SRC=[src_dir+'caedradapter.c',
-                       src_dir+'android/caedrclient.c',
-                       src_dir+'android/caedrutils.c',
-                       src_dir+'android/caedrnwmonitor.c',
-                       src_dir+'android/caedrserver.c',
-                       ])
-
+       common_files = [ os.path.join(src_dir, 'caedradapter.c') ]
+
+# Get list of target-specific source file base names, i.e. no parent
+# directories prepended to the path.
+#
+# Target-specific SConscript files are expected to return that list.
+target_files = []
+target_sconscript = os.path.join(target_os, 'SConscript')
+
+# Check for the existence of the platform-specific SConscript file
+# relative to the top-level source directory, not the build (variant)
+# directory, before calling that SConscript file to prevent a missing
+# file warning platforms that don't provide one.
+target_sconscript_abspath = str(File(target_sconscript).srcnode().abspath)
+if os.path.exists(target_sconscript_abspath):
+        target_files = env.SConscript(target_sconscript, exports='src_dir')
+
+# Now prepend the appropriate parent directories
+# (e.g. ./bt_edr_adapter/linux) to each of the target source files in
+# the list.
+target_files = [ os.path.join(src_dir, target_os, f) for f in target_files ]
+
+# The list of BLE adapter source files is a combination of both the
+# common and target-specific source file lists.
+env.AppendUnique(CA_SRC = common_files + target_files)
diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/SConscript b/resource/csdk/connectivity/src/bt_edr_adapter/android/SConscript
new file mode 100644 (file)
index 0000000..ab60d17
--- /dev/null
@@ -0,0 +1,15 @@
+#######################################################
+#       Build BT EDR adapter for Android
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'android') ])
+
+src_files = [ 'caedrclient.c',
+              'caedrutils.c',
+              'caedrnwmonitor.c',
+              'caedrserver.c', ]
+
+Return('src_files')
index 0065fbe..0a58c91 100644 (file)
 #include "caedrclient.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "cathreadpool.h" /* for thread pool */
 #include "camutex.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
+#include "caremotehandler.h"
 
 //#define DEBUG_MODE
 #define TAG PCF("CA_EDR_CLIENT")
@@ -43,7 +45,7 @@ static const char METHODID_BT_DEVICEPARAM[] =
         "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;";
 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
-static const char CLASSPATH_BT_INTERFACE[] = "org/iotivity/jar/caedrinterface";
+static const char CLASSPATH_BT_INTERFACE[] = "org/iotivity/ca/CaEdrInterface";
 static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket";
 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
 static const char CLASSPATH_CONTEXT[] = "android/content/Context";
@@ -96,6 +98,12 @@ static ca_mutex g_mutexStateList = NULL;
  */
 static ca_mutex g_mutexObjectList = NULL;
 
+/**
+ * @var g_edrErrorHandler
+ * @brief Error callback to update error in EDR
+ */
+static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
+
 typedef struct send_data
 {
     char* address;
@@ -120,13 +128,13 @@ typedef struct
 /**
  * implement for BT-EDR adapter common method
  */
-CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
+CAResult_t CAEDRGetInterfaceInformation(CAEndpoint_t **info)
 {
     OIC_LOG(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation");
 
     if (!info)
     {
-        OIC_LOG(ERROR, TAG, "LocalConnectivity info is null");
+        OIC_LOG(ERROR, TAG, "endpoint info is null");
         return CA_STATUS_FAILED;
     }
 
@@ -150,7 +158,8 @@ CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
     }
 
     // Create local endpoint using util function
-    CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_EDR, macAddress);
+    CAEndpoint_t *endpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_RFCOMM_BTEDR,
+                                                    macAddress, 0);
     if (NULL == endpoint)
     {
         OIC_LOG(ERROR, TAG, "Failed to create Local Endpoint!");
@@ -159,21 +168,19 @@ CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
     }
 
     // copy unicast server information
-    endpoint->isSecured = false;
-    CALocalConnectivity_t *netInfo = (CALocalConnectivity_t *) OICMalloc(
-            sizeof(CALocalConnectivity_t) * netInfoSize);
+    CAEndpoint_t *netInfo = (CAEndpoint_t *)OICMalloc(sizeof(CAEndpoint_t) * netInfoSize);
     if (NULL == netInfo)
     {
         OIC_LOG(ERROR, TAG, "Invalid input..");
         OICFree(macAddress);
-        CAAdapterFreeLocalEndpoint(endpoint);
+        CAFreeEndpoint(endpoint);
         return CA_MEMORY_ALLOC_FAILED;
     }
-    memcpy(netInfo, endpoint, sizeof(CALocalConnectivity_t));
+    *netInfo = *endpoint;
     *info = netInfo;
 
     OICFree(macAddress);
-    CAAdapterFreeLocalEndpoint(endpoint);
+    CAFreeEndpoint(endpoint);
 
     OIC_LOG(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation");
     return CA_STATUS_OK;
@@ -198,18 +205,18 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
                                       const void *data, uint32_t dataLength, uint32_t *sentLength)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
+    CAResult_t result = CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
     OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
+    return result;
 }
 
 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
                                         uint32_t dataLength, uint32_t *sentLength)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    CAEDRSendMulticastMessage((const char*) data, dataLength);
+    CAResult_t result = CAEDRSendMulticastMessage((const char*) data, dataLength);
     OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
+    return result;
 }
 
 // It will be updated when android EDR support is added
@@ -309,7 +316,7 @@ CAResult_t CAEDRCreateJNIInterfaceObject(jobject context)
     jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE);
     if (!EDRJniInterface)
     {
-        OIC_LOG(ERROR, TAG, "[EDRCore] Could not get caedrinterface class");
+        OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface class");
         return CA_STATUS_FAILED;
     }
 
@@ -317,7 +324,7 @@ CAResult_t CAEDRCreateJNIInterfaceObject(jobject context)
                                                                   "(Landroid/content/Context;)V");
     if (!EDRInterfaceConstructorMethod)
     {
-        OIC_LOG(ERROR, TAG, "[EDRCore] Could not get caedrinterface constructor method");
+        OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface constructor method");
         return CA_STATUS_FAILED;
     }
 
@@ -451,7 +458,7 @@ void CAEDRInitialize(ca_thread_pool_t handle)
 
     if (g_context)
     {
-        CAEDRCreateJNIInterfaceObject(g_context); /* create java caedrinterface instance*/
+        CAEDRCreateJNIInterfaceObject(g_context); /* create java CaEdrInterface instance*/
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -510,8 +517,8 @@ CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32
 {
     OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
 
-    CAEDRSendUnicastMessageImpl(address, data, dataLen);
-    return CA_STATUS_OK;
+    CAResult_t result = CAEDRSendUnicastMessageImpl(address, data, dataLen);
+    return result;
 }
 
 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
@@ -534,7 +541,12 @@ CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
         isAttached = true;
     }
 
-    CAEDRSendMulticastMessageImpl(env, data, dataLen);
+    CAResult_t result = CAEDRSendMulticastMessageImpl(env, data, dataLen);
+    if(CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "CAEDRSendMulticastMessage - could not send multicast message");
+        return result;
+    }
 
     OIC_LOG(DEBUG, TAG, "sent data");
 
@@ -575,7 +587,7 @@ void CAEDRGetLocalAddress(char **address)
     if (jni_address)
     {
         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
-        *address = (char*) OICMalloc(strlen(localAddress) + 1);
+        *address = OICStrdup(localAddress);
         if (*address == NULL)
         {
             if (isAttached)
@@ -584,7 +596,7 @@ void CAEDRGetLocalAddress(char **address)
             }
             return;
         }
-        memcpy(*address, localAddress, strlen(localAddress));
+
         (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
     }
 
@@ -738,7 +750,10 @@ CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t
         (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
         if (CA_STATUS_OK != res)
         {
-            return res;
+            OIC_LOG_V(ERROR, TAG, "CASendMulticastMessageImpl, failed to send message to : %s",
+                      remoteAddress);
+            g_edrErrorHandler(remoteAddress, OIC_EDR_SERVICE_ID, data, dataLen, res);
+            continue;
         }
     }
 
@@ -1073,3 +1088,8 @@ void CAEDRInitializeClient(ca_thread_pool_t handle)
     CAEDRInitialize(handle);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
+
+void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
+{
+    g_edrErrorHandler = errorHandleCallback;
+}
index e91e415..64053cc 100644 (file)
@@ -33,7 +33,7 @@
 #include "caedrserver.h"
 #include "caedrutils.h"
 
-#include "org_iotivity_jar_caedrinterface.h"
+#include "org_iotivity_ca_CaEdrInterface.h"
 
 //#define DEBUG_MODE
 #define TAG PCF("CA_EDR_MONITOR")
@@ -106,11 +106,11 @@ CAResult_t CAEDRClientSetCallbacks(void)
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caedrinterface_CAEDRStateChangedCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaEdrInterface_caEdrStateChangedCallback(JNIEnv *env, jobject obj,
                                                                jint status)
 {
     // STATE_ON:12, STATE_OFF:10
-    OIC_LOG(DEBUG, TAG, "caedrinterface - Network State Changed");
+    OIC_LOG(DEBUG, TAG, "CaEdrInterface - Network State Changed");
 
     if (NULL == g_networkChangeCb)
     {
@@ -157,10 +157,10 @@ Java_org_iotivity_jar_caedrinterface_CAEDRStateChangedCallback(JNIEnv *env, jobj
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caedrinterface_CAEDRBondStateChangedCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaEdrInterface_caEdrBondStateChangedCallback(JNIEnv *env, jobject obj,
                                                                    jstring addr)
 {
-    OIC_LOG(DEBUG, TAG, "caedrinterface - Bond State Changed");
+    OIC_LOG(DEBUG, TAG, "CaEdrInterface - Bond State Changed");
 
     if (addr)
     {
index 8705898..53ddec6 100644 (file)
@@ -32,7 +32,8 @@
 #include "camutex.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
-#include "org_iotivity_jar_caedrinterface.h"
+#include "org_iotivity_ca_CaEdrInterface.h"
+#include "oic_string.h"
 
 //#define DEBUG_MODE
 #define TAG PCF("CA_EDR_SERVER")
index 5044c58..7c8d870 100644 (file)
@@ -24,6 +24,7 @@
 #include "caedrutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "cathreadpool.h"
 #include "uarraylist.h"
 
@@ -335,7 +336,7 @@ void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address)
         OIC_LOG(ERROR, TAG, "[EDR][Native] newstate is null");
         return;
     }
-    strcpy(newstate->address, address);
+    OICStrcpy(newstate->address, sizeof(newstate->address), address);
     newstate->state = state;
 
     CAEDRNativeAddDeviceStateToList(newstate);
  * limitations under the License.
  *
  ******************************************************************/
-#ifndef OIC_STRING_H_
-#define OIC_STRING_H_
 
+#include <jni.h>
+/* Header for class org_iotivity_ca_CaEdrInterface */
+
+#ifndef Included_org_iotivity_ca_CaEdrInterface
+#define Included_org_iotivity_ca_CaEdrInterface
 #ifdef __cplusplus
 extern "C"
 {
-#endif // __cplusplus
+#endif
+/*
+ * Class:     org_iotivity_ca_CaEdrInterface
+ * Method:    caEdrStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaEdrInterface_caEdrStateChangedCallback
+(JNIEnv *, jobject, jint);
 
-/**
- * Duplicates the source string and returns it.
- *
- * NOTE: Caller needs to clear this memory by calling OICFree.
- *
- * @param str - Original valid string which needs to be duplicated
- *
- * @return
- *     on success, a pointer to the duplicated string
- *     on failure, a null pointer is returned
+/*
+ * Class:     org_iotivity_ca_CaEdrInterface
+ * Method:    caEdrBondStateChangedCallback
+ * Signature: (I)V
  */
-char *OICStrdup(const char *str);
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaEdrInterface_caEdrBondStateChangedCallback
+(JNIEnv *, jobject, jstring);
 
 #ifdef __cplusplus
 }
-#endif // __cplusplus
-#endif /* OIC_STRING_H_ */
+#endif
+#endif
diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h b/resource/csdk/connectivity/src/bt_edr_adapter/android/org_iotivity_jar_caedrinterface.h
deleted file mode 100644 (file)
index fbe3511..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <jni.h>
-/* Header for class org_iotivity_jar_caedrinterface */
-
-#ifndef Included_org_iotivity_jar_caedrinterface
-#define Included_org_iotivity_jar_caedrinterface
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/*
- * Class:     org_iotivity_jar_caedrinterface
- * Method:    CAEDRStateChangedCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caedrinterface_CAEDRStateChangedCallback
-(JNIEnv *, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caedrinterface
- * Method:    CAEDRStateChangedCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caedrinterface_CAEDRBondStateChangedCallback
-(JNIEnv *, jobject, jstring);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
index 9425988..8135659 100644 (file)
 #include "caedrinterface.h"
 #include "caadapterutils.h"
 #include "logger.h"
-#include "camsgparser.h"
+#include "cafragmentation.h"
 #include "caqueueingthread.h"
 #include "oic_malloc.h"
+#include "caremotehandler.h"
 
 /**
  * @var EDR_ADAPTER_TAG
@@ -83,10 +84,16 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
 static CANetworkChangeCallback g_networkChangeCallback = NULL;
 
 /**
+ * @var g_errorCallback
+ * @brief error Callback to CA adapter
+ */
+static CAErrorHandleCallback g_errorCallback = NULL;
+
+/**
  * @var g_localConnectivity
  * @brief Information of local Bluetooth adapter.
  */
-static CALocalConnectivity_t *g_localConnectivity = NULL;
+static CAEndpoint_t *g_localConnectivity = NULL;
 
 /**
  * @var g_serverId
@@ -114,7 +121,7 @@ void CAEDRNotifyNetworkStatus(CANetworkStatus_t status);
 void CAEDROnNetworkStatusChanged(void *context);
 CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, const void *data,
                              uint32_t dataLength, uint32_t *sentLength);
-CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CALocalConnectivity_t *connectivity,
+CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CAEndpoint_t *connectivity,
                                            CANetworkStatus_t status);
 CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUID,
                                const void *data, uint32_t dataLength, uint32_t *sentLength);
@@ -122,7 +129,7 @@ CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUI
  * @fn CACreateEDRData
  * @brief Helper function to create CAEDRData
  */
-static CAEDRData *CACreateEDRData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+static CAEDRData *CACreateEDRData(const CAEndpoint_t *remoteEndpoint, const void *data,
                                   uint32_t dataLength);
 
 /**
@@ -139,10 +146,13 @@ void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event);
 
 static void CAEDRDataDestroyer(void *data, uint32_t size);
 
+static void CAEDRErrorHandler(const char *remoteAddress, const char *serviceUUID, const void *data,
+                              uint32_t dataLength, CAResult_t result);
+
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
                            CANetworkPacketReceivedCallback packetReceivedCallback,
                            CANetworkChangeCallback networkStateChangeCallback,
-                           ca_thread_pool_t handle)
+                           CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
@@ -158,6 +168,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
     g_edrThreadPool = handle;
     g_networkPacketReceivedCallback = packetReceivedCallback;
     g_networkChangeCallback = networkStateChangeCallback;
+    g_errorCallback = errorCallback;
 
     // Initialize EDR Network Monitor
     CAResult_t err = CAEDRInitializeNetworkMonitor(handle);
@@ -170,6 +181,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
 
     CAEDRSetNetworkChangeCallback(CAEDRNotifyNetworkStatus);
     CAEDRSetPacketReceivedCallback(CAAdapterRecvData);
+    CAEDRSetErrorHandler(CAEDRErrorHandler);
     CAEDRInitializeClient(handle);
 
     CAConnectivityHandler_t handler;
@@ -182,7 +194,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
     handler.readData = CAReadEDRData;
     handler.stopAdapter = CAStopEDR;
     handler.terminate = CATerminateEDR;
-    registerCallback(handler, CA_EDR);
+    registerCallback(handler, CA_ADAPTER_RFCOMM_BTEDR);
 
     // Initialize Send/Receive data message queues
     if (CA_STATUS_OK != CAEDRInitializeQueueHandlers())
@@ -251,7 +263,7 @@ CAResult_t CAStartEDRDiscoveryServer()
     return CAStartServer();
 }
 
-int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+int32_t CASendEDRUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
                              uint32_t dataLength)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
@@ -266,7 +278,7 @@ int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const voi
         return -1;
     }
 
-    if (0 == strlen(remoteEndpoint->addressInfo.BT.btMacAddress))
+    if (0 == strlen(remoteEndpoint->addr))
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: EDR Address is empty!");
         return -1;
@@ -274,11 +286,12 @@ int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const voi
 
     uint32_t sentLength = 0;
     const char *serviceUUID = OIC_EDR_SERVICE_ID;
-    const char *address = remoteEndpoint->addressInfo.BT.btMacAddress;
+    const char *address = remoteEndpoint->addr;
     CAResult_t err = CAAdapterSendData(address, serviceUUID, data, dataLength, &sentLength);
     if (CA_STATUS_OK != err)
     {
         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err);
+        g_errorCallback(remoteEndpoint, data, dataLength, err);
         return -1;
     }
 
@@ -286,7 +299,7 @@ int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const voi
     return sentLength;
 }
 
-int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength)
+int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN - CASendEDRMulticastData");
 
@@ -305,6 +318,7 @@ int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength)
     if (CA_STATUS_OK != err)
     {
         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send multicast data failed!, error num [%d]", err);
+        g_errorCallback(endpoint, data, dataLength, err);
         return -1;
     }
 
@@ -312,8 +326,7 @@ int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength)
     return sentLen;
 }
 
-
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
@@ -392,7 +405,7 @@ void CATerminateEDR()
     CAEDRServerTerminate();
 
     // Free LocalConnectivity information
-    CAAdapterFreeLocalEndpoint(g_localConnectivity);
+    CAFreeEndpoint(g_localConnectivity);
     g_localConnectivity = NULL;
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
@@ -529,17 +542,24 @@ void CAAdapterDataSendHandler(void *context)
     }
 
     const char *remoteAddress = NULL;
-    const char *serviceUUID = NULL;
+    const char *serviceUUID = OIC_EDR_SERVICE_ID;
     uint32_t sentLength = 0;
 
     if (NULL == message->remoteEndpoint)
     {
         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "remoteEndpoint is not available");
+        return;
     }
     else
     {
-        remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
-        serviceUUID = message->remoteEndpoint->resourceUri;
+        remoteAddress = message->remoteEndpoint->addr;
+    }
+
+    if(!remoteAddress || !serviceUUID)
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDR Send Message error");
+        //Error cannot be sent if remote address is NULL
+        return;
     }
 
     uint32_t dataSegmentLength = message->dataLen + CA_HEADER_LENGTH;
@@ -554,6 +574,7 @@ void CAAdapterDataSendHandler(void *context)
     if (NULL == dataSegment)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed");
+        CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, CA_SEND_FAILED);
         OICFree(header);
         return;
     }
@@ -564,6 +585,7 @@ void CAAdapterDataSendHandler(void *context)
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Generate header failed");
         OICFree(header);
         OICFree(dataSegment);
+        CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, CA_SEND_FAILED);
         return ;
     }
 
@@ -584,13 +606,16 @@ void CAAdapterDataSendHandler(void *context)
 
     uint32_t iter = dataSegmentLength / CA_SUPPORTED_EDR_MTU_SIZE;
     uint32_t index = 0;
-    if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID, dataSegment, length,
-                                            &sentLength))
+    result = CAEDRClientSendData(remoteAddress, serviceUUID, dataSegment, length,
+                                 &sentLength);
+    if(CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
         OICFree(dataSegment);
+        CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result);
         return;
     }
+
     OICFree(dataSegment);
 
     for (index = 1; index < iter; index++)
@@ -598,11 +623,13 @@ void CAAdapterDataSendHandler(void *context)
         // Send the remaining header.
         OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Sending the chunk number [%d]", index);
 
-        if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID,
-                    message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH),
-                    CA_SUPPORTED_EDR_MTU_SIZE, &sentLength))
+        void *dataPtr = message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH);
+        result = CAEDRClientSendData(remoteAddress, serviceUUID,
+                                     dataPtr, CA_SUPPORTED_EDR_MTU_SIZE, &sentLength);
+        if(CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
+            CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result);
             return;
         }
     }
@@ -612,11 +639,13 @@ void CAAdapterDataSendHandler(void *context)
     {
         // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200)
         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Sending the last chunk");
-        if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID,
-                    message->data + (index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH,
-                    remainingLen, &sentLength))
+        void *dataPtr = message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH);
+        result = CAEDRClientSendData(remoteAddress, serviceUUID, dataPtr,
+                                     remainingLen, &sentLength);
+        if(CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed");
+            CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result);
             return;
         }
     }
@@ -628,27 +657,32 @@ CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUI
                                const void *data, uint32_t dataLength, uint32_t *sentLength)
 {
 
+    CAResult_t result = CA_SEND_FAILED;
+
     // Send the first segment with the header.
     if ((NULL != remoteAddress) && (0 < strlen(remoteAddress))) //Unicast data
     {
-        if (CA_STATUS_OK != CAEDRClientSendUnicastData(remoteAddress, serviceUUID, data,
-                                                       dataLength, sentLength))
+        result = CAEDRClientSendUnicastData(remoteAddress, serviceUUID, data,
+                                            dataLength, sentLength);
+        if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send unicast data !");
-            return CA_STATUS_FAILED;
+            return result;
         }
     }
     else
     {
         OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "sending multicast data : %s", data);
-        if (CA_STATUS_OK != CAEDRClientSendMulticastData(serviceUUID, data, dataLength,
-                                                         sentLength))
+        result = CAEDRClientSendMulticastData(serviceUUID, data, dataLength,
+                                              sentLength);
+
+        if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send multicast data !");
-            return CA_STATUS_FAILED;
+            return result;
         }
     }
-    return CA_STATUS_OK;
+    return result;
 }
 
 void CAAdapterDataReceiverHandler(void *context)
@@ -665,7 +699,7 @@ void CAAdapterDataReceiverHandler(void *context)
     static uint32_t recvDataLen = 0;
     static uint32_t totalDataLen = 0;
     static char *defragData = NULL;
-    static CARemoteEndpoint_t *remoteEndpoint = NULL;
+    static CAEndpoint_t *remoteEndpoint = NULL;
 
     if (!g_isHeaderAvailable)
     {
@@ -685,10 +719,10 @@ void CAAdapterDataReceiverHandler(void *context)
             return;
         }
 
-        const char *remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
-        const char *serviceUUID = message->remoteEndpoint->resourceUri;
+        const char *remoteAddress = message->remoteEndpoint->addr;
 
-        remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress, serviceUUID);
+        remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_RFCOMM_BTEDR,
+                                                remoteAddress, 0);
 
         memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
                message->dataLen - CA_HEADER_LENGTH);
@@ -768,10 +802,10 @@ void CAAdapterRecvData(const char *remoteAddress, const void *data, uint32_t dat
     VERIFY_NON_NULL_VOID(data, EDR_ADAPTER_TAG, "Data is null");
     VERIFY_NON_NULL_VOID(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
 
-    static const char serviceUUID[] = OIC_EDR_SERVICE_ID;
     // Create remote endpoint
-    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
-                                                                       serviceUUID);
+    CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                                          CA_ADAPTER_RFCOMM_BTEDR,
+                                                          remoteAddress, 0);
     if (NULL == remoteEndpoint)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !");
@@ -784,7 +818,32 @@ void CAAdapterRecvData(const char *remoteAddress, const void *data, uint32_t dat
     *sentLength = dataLength;
 
     // Free remote endpoint
-    CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+    CAFreeEndpoint(remoteEndpoint);
+
+    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}
+
+void CAEDRErrorHandler(const char *remoteAddress, const char *serviceUUID, const void *data,
+                       uint32_t dataLength, CAResult_t result)
+{
+    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+
+    // Input validation
+    VERIFY_NON_NULL_VOID(data, EDR_ADAPTER_TAG, "Data is null");
+
+    // Create remote endpoint
+    CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(0, CA_ADAPTER_RFCOMM_BTEDR,
+                                                           remoteAddress, 0);
+    if (!remoteEndpoint)
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !");
+        return;
+    }
+
+    g_errorCallback(remoteEndpoint, data, dataLength, result);
+
+    // Free remote endpoint
+    CAFreeEndpoint(remoteEndpoint);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
@@ -798,7 +857,7 @@ CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
         *sentLength = 0;
-        return CA_STATUS_OK;
+        return CA_ADAPTER_NOT_ENABLED;
     }
     // Input validation
     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
@@ -806,21 +865,22 @@ CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
     VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
 
     // Create remote endpoint
-    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
-                                                                       serviceUUID);
+    CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                                          CA_ADAPTER_RFCOMM_BTEDR,
+                                                          remoteAddress, 0);
     if (NULL == remoteEndpoint)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !");
-        return CA_STATUS_FAILED;
+        return CA_MEMORY_ALLOC_FAILED;
     }
 
     // Add message to data queue
     CAEDRData *edrData =  CACreateEDRData(remoteEndpoint, data, dataLength);
-    CAQueueingThreadAddData(g_sendQueueHandle, edrData, sizeof(CAEDRData));
+    CAQueueingThreadAddData(g_sendQueueHandle, edrData, sizeof (CAEDRData));
     *sentLength = dataLength;
 
     // Free remote endpoint
-    CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+    CAFreeEndpoint(remoteEndpoint);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT - CAAdapterSendData");
     return CA_STATUS_OK;
@@ -913,7 +973,7 @@ void CAEDROnNetworkStatusChanged(void *context)
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
 
-CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CALocalConnectivity_t *connectivity,
+CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CAEndpoint_t *connectivity,
                                            CANetworkStatus_t status)
 {
     VERIFY_NON_NULL_RET(connectivity, EDR_ADAPTER_TAG, "connectivity is NULL", NULL);
@@ -927,7 +987,7 @@ CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CALocalConnectivity_t *connectivity,
     }
 
     // Create duplicate of Local connectivity
-    event->info = CAAdapterCopyLocalEndpoint(connectivity);
+    event->info = CACloneEndpoint(connectivity);
     event->status = status;
     return event;
 }
@@ -936,22 +996,23 @@ void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event)
 {
     if (event)
     {
-        CAAdapterFreeLocalEndpoint(event->info);
+        CAFreeEndpoint(event->info);
         OICFree(event);
     }
 }
 
-CAEDRData *CACreateEDRData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                           uint32_t dataLength)
+CAEDRData *CACreateEDRData(const CAEndpoint_t *remoteEndpoint,
+                                        const void *data, uint32_t dataLength)
 {
-    CAEDRData *edrData = (CAEDRData *) OICMalloc(sizeof(CAEDRData));
+    CAEDRData *edrData = (CAEDRData *)OICMalloc(sizeof (CAEDRData));
     if (!edrData)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed!");
         return NULL;
     }
 
-    edrData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+    edrData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
+
     edrData->data = OICMalloc(dataLength);
     if (NULL == edrData->data)
     {
@@ -969,7 +1030,7 @@ void CAFreeEDRData(CAEDRData *edrData)
 {
     VERIFY_NON_NULL_VOID(edrData, EDR_ADAPTER_TAG, "edrData is NULL");
 
-    CAAdapterFreeRemoteEndpoint(edrData->remoteEndpoint);
+    CAFreeEndpoint(edrData->remoteEndpoint);
     OICFree(edrData->data);
     OICFree(edrData);
 }
diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/linux/SConscript b/resource/csdk/connectivity/src/bt_edr_adapter/linux/SConscript
new file mode 100644 (file)
index 0000000..0e09967
--- /dev/null
@@ -0,0 +1,9 @@
+##########################################
+#       Build BT EDR adapter for Linux
+##########################################
+
+Import('env')
+
+src_files = [ 'caedradapter.c']
+
+Return('src_files')
index a33d708..408c164 100644 (file)
@@ -31,8 +31,9 @@ static CANetworkPacketReceivedCallback g_edrReceivedCallback = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
-        CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
-        ca_thread_pool_t handle)
+                           CANetworkPacketReceivedCallback reqRespCallback,
+                           CANetworkChangeCallback networkStateChangeCallback,
+                           CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "CAInitializeEDR");
 
@@ -40,8 +41,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
     g_threadPoolHandle = handle;
 
     // register handlers
-    CAConnectivityHandler_t handler;
-    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
+    CAConnectivityHandler_t handler = {};
 
     handler.startAdapter = CAStartEDR;
     handler.startListenServer = CAStartEDRListeningServer;
@@ -53,7 +53,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
     handler.stopAdapter = CAStopEDR;
     handler.terminate = CATerminateEDR;
 
-    registerCallback(handler, CA_EDR);
+    registerCallback(handler, CA_ADAPTER_RFCOMM_BTEDR);
 
     return CA_STATUS_OK;
 }
@@ -79,7 +79,7 @@ CAResult_t CAStartEDRDiscoveryServer()
     return CA_STATUS_OK;
 }
 
-int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, const void *data,
+int32_t CASendEDRUnicastData(const CAEndpoint_t *endpoint, const void *data,
     uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "CASendEDRUnicastData");
@@ -87,14 +87,14 @@ int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, const void *dat
     return -1;
 }
 
-int32_t CASendEDRMulticastData(const void *data, uint32_t dataLen)
+int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "CASendEDRMulticastData");
 
     return -1;
 }
 
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "CAGetEDRInterfaceInformation");
 
diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/SConscript b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/SConscript
new file mode 100644 (file)
index 0000000..cb7c711
--- /dev/null
@@ -0,0 +1,21 @@
+#######################################################
+#       Build BT EDR adapter for Tizen
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'tizen'),
+                              './con/lib/tizen/ble/inc',
+                              './con/lib/tizen/ble/inc/mobile' ])
+
+env.ParseConfig("pkg-config --cflags --libs capi-network-bluetooth")
+
+src_files = [ 'caedrclient.c',
+              'caedrdevicelist.c',
+              'caedrendpoint.c',
+              'caedrnwmonitor.c',
+              'caedrserver.c',
+              'caedrutils.c' ]
+
+Return('src_files')
index b489dc3..5c7ae30 100644 (file)
@@ -56,6 +56,11 @@ static EDRDeviceList *g_edrDeviceList = NULL;
 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
 
 /**
+ * @var g_edrErrorHandler
+ * @brief Error callback to update error in EDR
+ */
+static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
+/**
  * @fn CAEDRManagerInitializeMutex
  * @brief This function creates mutex.
  */
@@ -140,6 +145,11 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall
     g_edrPacketReceivedCallback = packetReceivedCallback;
 }
 
+void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
+{
+    g_edrErrorHandler = errorHandleCallback;
+}
+
 void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
                                        bt_socket_connection_s *connection, void *userData)
 {
index 26e7402..bcf2e89 100644 (file)
@@ -48,7 +48,7 @@ CAResult_t CAEDRSendData(int serverFD, const void *data, uint32_t dataLength,
     {
         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD);
         *sentDataLen = 0;
-        return CA_STATUS_FAILED;
+        return CA_SOCKET_OPERATION_FAILED;
     }
 
     *sentDataLen = dataLen;
index f123852..3cafd34 100644 (file)
@@ -32,6 +32,7 @@
 #include "caedrutils.h"
 #include "caadapterutils.h"
 #include "caqueueingthread.h"
+#include "caremotehandler.h"
 
 /**
  * @var g_edrNetworkChangeCallback
@@ -110,7 +111,7 @@ void CAEDRSetNetworkChangeCallback(
     g_edrNetworkChangeCallback = networkChangeCallback;
 }
 
-CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
+CAResult_t CAEDRGetInterfaceInformation(CAEndpoint_t **info)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
@@ -129,7 +130,7 @@ CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
     }
 
     // Create network info
-    *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress);
+    *info = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_RFCOMM_BTEDR, localAddress, 0);
     if (NULL == *info)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create LocalConnectivity instance!");
index 62707b7..c5468a1 100644 (file)
@@ -1,53 +1,43 @@
-#######################################################
-#      Building BLE adapter
-#######################################################
+################################
+#       Build BLE adapter
+################################
 
 Import('env')
-
-print"Reading ble adapter script"
+import os.path
 
 target_os = env.get('TARGET_OS')
 
-if target_os == 'tizen':
-    env.ParseConfig("pkg-config --cflags --libs capi-network-bluetooth")
-
-src_dir = './bt_le_adapter/'
-
-#Source files to build common for all platforms
-if target_os != 'arduino':
-       env.AppendUnique(CA_SRC=[src_dir+'caleadapter.c'])
-else:
-       env.AppendUnique(CA_SRC=[src_dir+'caleadapter_singlethread.c'])
-
-#Source files to build in Linux platform
-if target_os == 'linux':
-       env.AppendUnique(CA_SRC=[src_dir+'linux/caleadapter.c',
-                       ])
-
-#Source files to build in Tizen platform
-if target_os == 'tizen':
-       env.PrependUnique(CPPPATH = [src_dir + 'tizen'])
-       env.PrependUnique(CFLAGS = ['-I'+ './con/lib/tizen/ble/inc'])
-       env.PrependUnique(CFLAGS = ['-I'+ './con/lib/tizen/ble/inc/mobile'])
-       env.AppendUnique(CA_SRC=[src_dir+'tizen/cableclient.c',
-                       src_dir+'tizen/cableserver.c',
-                       src_dir+'tizen/cableutil.c',
-                       src_dir+'tizen/cablenwmonitor.c',
-                       ])
-
-#Source files to build in Arduino platform
-if target_os == 'arduino':
-       env.PrependUnique(CPPPATH = [src_dir + 'arduino'])
-       env.AppendUnique(CA_SRC=[src_dir+'arduino/cableserver.cpp',
-                       src_dir+'arduino/cablenwmonitor.cpp',
-                       ])
-
-#Source files to build in Android platform
-if target_os == 'android':
-       env.PrependUnique(CPPPATH = [src_dir + 'android'])
-       env.AppendUnique(CA_SRC=[
-                       src_dir+'android/caleclient.c',
-                       src_dir+'android/caleserver.c',
-                       src_dir+'android/calenwmonitor.c',
-                       src_dir+'android/caleutils.c'
-                       ])
+print "Reading BLE adapter script for", target_os
+
+src_dir = os.path.join(os.curdir, 'bt_le_adapter')
+
+# Source files to build common for all platforms.
+common_files = None
+common_files = [ os.path.join(src_dir,
+                                      'caleadapter.c') ]
+
+
+# Get list of target-specific source file base names, i.e. no parent
+# directories prepended to the path.
+#
+# Target-specific SConscript files are expected to return that list.
+target_files = []
+target_sconscript = os.path.join(target_os, 'SConscript')
+
+# Check for the existence of the platform-specific SConscript file
+# relative to the top-level source directory, not the build (variant)
+# directory, before calling that SConscript file to prevent a missing
+# file warning platforms that don't provide one.
+target_sconscript_abspath = str(File(target_sconscript).srcnode().abspath)
+if os.path.exists(target_sconscript_abspath):
+        target_files = env.SConscript(target_sconscript, exports='src_dir')
+
+# Now prepend the appropriate parent directories
+# (e.g. ./bt_le_adapter/linux) to each of the target source files in
+# the list.
+target_files = [ os.path.join(src_dir, target_os, f) for f in target_files ]
+
+# The list of BLE adapter source files is a combination of both the
+# common and target-specific source file lists.
+env.AppendUnique(CA_SRC = common_files + target_files)
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript
new file mode 100644 (file)
index 0000000..7ee11e6
--- /dev/null
@@ -0,0 +1,15 @@
+#######################################################
+#       Build BLE adapter for Android
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'android') ])
+
+src_files = [ 'caleclient.c',
+              'caleserver.c',
+              'calenwmonitor.c',
+              'caleutils.c' ]
+
+Return('src_files')
index 06c1c05..adaf0d5 100644 (file)
@@ -34,7 +34,7 @@
 #include "cathreadpool.h" /* for thread pool */
 #include "camutex.h"
 #include "uarraylist.h"
-#include "org_iotivity_jar_caleclientinterface.h"
+#include "org_iotivity_ca_CaLeClientInterface.h"
 
 #define TAG PCF("CA_LE_CLIENT")
 
@@ -49,6 +49,7 @@ static u_arraylist_t *g_gattObjectList = NULL;
 static u_arraylist_t *g_deviceStateList = NULL;
 
 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
+static CABLEErrorHandleCallback g_clientErrorCallback;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 static jobject g_leScanCallback = NULL;
 static jobject g_leGattCallback = NULL;
@@ -64,19 +65,11 @@ 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 = false;
+static ca_mutex g_SendFinishMutex = NULL;
 static ca_mutex g_threadMutex = NULL;
 static ca_cond g_threadCond = NULL;
 
-static bool g_isRequestedSend = false;
-static bool g_isReceivedWriteCB = false;
-static ca_mutex g_writeCharacteristicCBMutex = false;
-static ca_mutex g_theSendRequestMutex = false;
-static ca_mutex g_threadSendCBMutex = NULL;
-static ca_cond g_threadSendCBCond = NULL;
-
 static ca_mutex g_threadSendMutex = NULL;
-static ca_cond g_threadSendCond = NULL;
 
 static ca_mutex g_bleReqRespClientCbMutex = NULL;
 static ca_mutex g_bleServerBDAddressMutex = NULL;
@@ -132,10 +125,10 @@ CAResult_t CALECreateJniInterfaceObject()
         isAttached = true;
     }
 
-    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/jar/caleclientinterface");
+    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
     if (!jni_LEInterface)
     {
-        OIC_LOG(ERROR, TAG, "Could not get caleclientinterface class");
+        OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
         goto error_exit;
     }
 
@@ -143,12 +136,12 @@ CAResult_t CALECreateJniInterfaceObject()
                                                                  "(Landroid/content/Context;)V");
     if (!LeInterfaceConstructorMethod)
     {
-        OIC_LOG(ERROR, TAG, "Could not get caleclientinterface constructor method");
+        OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
         goto error_exit;
     }
 
     (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
-    OIC_LOG(DEBUG, TAG, "Create instance for caleclientinterface");
+    OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
 
     if (isAttached)
     {
@@ -226,8 +219,6 @@ CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
 
     // init mutex for send logic
     g_threadCond = ca_cond_new();
-    g_threadSendCond = ca_cond_new();
-    g_threadSendCBCond = ca_cond_new();
 
     CALEClientCreateDeviceList();
     CALEClientJNISetContext();
@@ -329,14 +320,10 @@ void CALEClientTerminate()
     g_isStartedMulticastServer = false;
     g_isStartedScan = false;
     CALEClientSetSendFinishFlag(false);
-    CALEClientSetTheSendRequestFlag(false);
-    CALEClientSetWriteCharacteristicCBFlag(false);
 
     CALEClientTerminateGattMutexVariables();
 
     ca_cond_free(g_threadCond);
-    ca_cond_free(g_threadSendCond);
-    ca_cond_free(g_threadSendCBCond);
 
     if (isAttached)
     {
@@ -487,6 +474,11 @@ void CALEClientSetCallback(CAPacketReceiveCallback callback)
     g_packetReceiveCallback = callback;
 }
 
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_clientErrorCallback = callback;
+}
+
 CAResult_t CALEClientGetInterfaceInfo(char **address)
 {
     OIC_LOG(INFO, TAG, "CALEClientGetInterfaceInfo is not supported");
@@ -579,21 +571,6 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const char* dat
                     OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
                     goto error_exit;
                 }
-                else
-                {
-                    CALEClientSetTheSendRequestFlag(true);
-                    ca_cond_signal(g_threadSendCBCond);
-
-                    if (!g_isReceivedWriteCB)
-                    {
-                        OIC_LOG(INFO, TAG, "wait..(unicast)");
-                        ca_cond_wait(g_threadSendCond, g_threadSendMutex);
-                    }
-                    else
-                    {
-                        CALEClientSetWriteCharacteristicCBFlag(false);
-                    }
-                }
 
                 OIC_LOG(INFO, TAG, "wake up");
                 break;
@@ -689,13 +666,12 @@ CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
         goto error_exit;
     }
 
-    uint32_t index = 0;
-    while (index < length)
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            OIC_LOG(ERROR, TAG, "jarrayObj is not available");
             continue;
         }
 
@@ -704,47 +680,31 @@ CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
         {
             OIC_LOG(ERROR, TAG, "BT device[%d] - send has failed");
         }
-        else
-        {
-            CALEClientSetTheSendRequestFlag(true);
-            ca_cond_signal(g_threadSendCBCond);
-
-            if (!g_isReceivedWriteCB)
-            {
-                OIC_LOG(INFO, TAG, "wait..(multicast)");
-                ca_cond_wait(g_threadSendCond, g_threadSendMutex);
-            }
-            else
-            {
-                CALEClientSetWriteCharacteristicCBFlag(false);
-            }
-        }
 
         jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
         if (!jni_address)
         {
             OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
-            goto error_exit;
+            continue;
         }
 
         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
         if (!address)
         {
             OIC_LOG(ERROR, TAG, "address is not available");
-            goto error_exit;
+            continue;
         }
 
         res = CALECheckSendState(address);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "send has failed");
+            OIC_LOG_V(INFO, TAG, "multicast : send has failed for this device[%s]", address);
+            g_clientErrorCallback(address, data, dataLen, res);
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
-            goto error_exit;
+            continue;
         }
 
         (*env)->ReleaseStringUTFChars(env, jni_address, address);
-
-        index++;
     }
 
     OIC_LOG(DEBUG, TAG, "connection routine is finished");
@@ -1006,7 +966,7 @@ CAResult_t CALEClientStartScan()
     // scan gatt server with UUID
     if (g_leScanCallback && g_uuidList)
     {
-#ifndef FULL_SCAN
+#ifdef UUID_SCAN
         ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
         if(CA_STATUS_OK != ret)
         {
@@ -1492,7 +1452,6 @@ CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
     if (!jni_obj_character)
     {
         CALEClientSendFinish(env, gatt);
-        ca_cond_signal(g_threadSendCond);
         return CA_STATUS_FAILED;
     }
 
@@ -1500,7 +1459,6 @@ CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
     if (CA_STATUS_OK != ret)
     {
         CALEClientSendFinish(env, gatt);
-        ca_cond_signal(g_threadSendCond);
         return ret;
     }
 
@@ -2617,7 +2575,7 @@ CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedSt
         return CA_STATUS_FAILED;
     }
 
-    strcpy(newstate->address, address);
+    OICStrcpy(newstate->address, sizeof(newstate->address), address);
     newstate->connectedState = connectedState;
     newstate->notificationState = notificationState;
     newstate->sendState = sendState;
@@ -3018,16 +2976,6 @@ CAResult_t CALEClientInitGattMutexVaraibles()
         }
     }
 
-    if (NULL == g_threadSendCBMutex)
-    {
-        g_threadSendCBMutex = ca_mutex_new();
-        if (NULL == g_threadSendCBMutex)
-        {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
     if (NULL == g_deviceListMutex)
     {
         g_deviceListMutex = ca_mutex_new();
@@ -3068,26 +3016,6 @@ CAResult_t CALEClientInitGattMutexVaraibles()
         }
     }
 
-    if (NULL == g_writeCharacteristicCBMutex)
-    {
-        g_writeCharacteristicCBMutex = ca_mutex_new();
-        if (NULL == g_writeCharacteristicCBMutex)
-        {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == g_theSendRequestMutex)
-    {
-        g_theSendRequestMutex = ca_mutex_new();
-        if (NULL == g_theSendRequestMutex)
-        {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -3108,21 +3036,12 @@ void CALEClientTerminateGattMutexVariables()
     ca_mutex_free(g_threadSendMutex);
     g_threadSendMutex = NULL;
 
-    ca_mutex_free(g_threadSendCBMutex);
-    g_threadSendCBMutex = NULL;
-
     ca_mutex_free(g_deviceListMutex);
     g_deviceListMutex = NULL;
 
     ca_mutex_free(g_SendFinishMutex);
     g_SendFinishMutex = NULL;
 
-    ca_mutex_free(g_writeCharacteristicCBMutex);
-    g_writeCharacteristicCBMutex = NULL;
-
-    ca_mutex_free(g_theSendRequestMutex);
-    g_theSendRequestMutex = NULL;
-
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -3135,29 +3054,11 @@ void CALEClientSetSendFinishFlag(bool flag)
     ca_mutex_unlock(g_SendFinishMutex);
 }
 
-void CALEClientSetWriteCharacteristicCBFlag(bool flag)
-{
-    OIC_LOG_V(DEBUG, TAG, "g_isReceivedWriteCB is %d", flag);
-
-    ca_mutex_lock(g_writeCharacteristicCBMutex);
-    g_isReceivedWriteCB = flag;
-    ca_mutex_unlock(g_writeCharacteristicCBMutex);
-}
-
-void CALEClientSetTheSendRequestFlag(bool flag)
-{
-    OIC_LOG_V(DEBUG, TAG, "g_isRequestedSend is %d", flag);
-
-    ca_mutex_lock(g_theSendRequestMutex);
-    g_isRequestedSend = flag;
-    ca_mutex_unlock(g_theSendRequestMutex);
-}
-
 /**
  * adapter common
  */
 
-CAResult_t CAStartBLEGattClient()
+CAResult_t CAStartLEGattClient()
 {
     CAResult_t res = CALEClientStartMulticastServer();
     if (CA_STATUS_OK != res)
@@ -3172,7 +3073,7 @@ CAResult_t CAStartBLEGattClient()
     return res;
 }
 
-void CAStopBLEGattClient()
+void CAStopLEGattClient()
 {
     OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
 
@@ -3211,8 +3112,6 @@ void CAStopBLEGattClient()
     }
 
     ca_cond_signal(g_threadCond);
-    ca_cond_signal(g_threadSendCond);
-    g_isStartedLEClient = false;
 
     if (isAttached)
     {
@@ -3221,7 +3120,7 @@ void CAStopBLEGattClient()
 
 }
 
-void CATerminateBLEGattClient()
+void CATerminateLEGattClient()
 {
     OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
     CALEClientTerminate();
@@ -3246,7 +3145,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t da
     return CALEClientSendMulticastMessage(data, dataLen);
 }
 
-void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
+void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -3257,7 +3156,7 @@ void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -3282,10 +3181,10 @@ CAResult_t CAGetLEAddress(char **local_address)
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CARegisterLeScanCallback(JNIEnv *env, jobject obj,
-                                                                   jobject callback)
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
+                                                                    jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterLeScanCallback");
+    OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
@@ -3293,10 +3192,10 @@ Java_org_iotivity_jar_caleclientinterface_CARegisterLeScanCallback(JNIEnv *env,
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CARegisterLeGattCallback(JNIEnv *env, jobject obj,
-                                                                   jobject callback)
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
+                                                                  jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterLeGattCallback");
+    OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
@@ -3304,7 +3203,7 @@ Java_org_iotivity_jar_caleclientinterface_CARegisterLeGattCallback(JNIEnv *env,
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeScanCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
                                                            jobject device, jint rssi,
                                                            jbyteArray scanRecord)
 {
@@ -3319,12 +3218,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeScanCallback(JNIEnv *env, jobject
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
                                                                                 jobject obj,
                                                                                 jobject gatt,
                                                                                 jint status,
@@ -3404,8 +3303,6 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback(
         {
             OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
         }
-
-        ca_cond_signal(g_threadSendCond);
     }
     else // error
     {
@@ -3431,6 +3328,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback(
         }
         (*env)->ReleaseStringUTFChars(env, jni_address, address);
 
+        CAResult_t res = CALEClientGattClose(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
+        }
+
         goto error_exit;
     }
     return;
@@ -3439,17 +3342,16 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback(
 error_exit:
 
     CALEClientSendFinish(env, gatt);
-    ca_cond_signal(g_threadSendCond);
     return;
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattServicesDiscoveredCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
                                                                              jobject obj,
                                                                              jobject gatt,
                                                                              jint status)
@@ -3461,7 +3363,6 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNI
     if (0 != status) // discovery error
     {
         CALEClientSendFinish(env, gatt);
-        ca_cond_signal(g_threadSendCond);
         return;
     }
 
@@ -3469,7 +3370,6 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNI
     if (!jni_address)
     {
         CALEClientSendFinish(env, gatt);
-        ca_cond_signal(g_threadSendCond);
         return;
     }
 
@@ -3477,7 +3377,6 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNI
     if (!address)
     {
         CALEClientSendFinish(env, gatt);
-        ca_cond_signal(g_threadSendCond);
         return;
     }
 
@@ -3536,17 +3435,16 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNI
 error_exit:
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
     CALEClientSendFinish(env, gatt);
-    ca_cond_signal(g_threadSendCond);
     return;
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattCharacteristicReadCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicReadCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicReadCallback(JNIEnv *env,
                                                                              jobject obj,
                                                                              jobject gatt,
                                                                              jobject characteristic,
@@ -3557,12 +3455,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicReadCallback(JNI
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattCharacteristicWritjclasseCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback(
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
         JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data,
         jint status)
 {
@@ -3570,14 +3468,6 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback(
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
 
-    ca_mutex_lock(g_threadSendCBMutex);
-    if (!g_isRequestedSend)
-    {
-        OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - waiting");
-        ca_cond_wait(g_threadSendCBCond, g_threadSendCBMutex);
-    }
-    ca_mutex_unlock(g_threadSendCBMutex);
-
     jboolean isCopy;
     char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
 
@@ -3619,29 +3509,23 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback(
         CALEClientUpdateSendCnt(env);
     }
 
-    CALEClientSetWriteCharacteristicCBFlag(true);
-    CALEClientSetTheSendRequestFlag(false);
-    ca_cond_signal(g_threadSendCond);
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
     return;
 
     // error label.
 error_exit:
 
-    CALEClientSetWriteCharacteristicCBFlag(true);
-    CALEClientSetTheSendRequestFlag(false);
     CALEClientSendFinish(env, gatt);
-    ca_cond_signal(g_threadSendCond);
     return;
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattCharacteristicChangedCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicChangedCallback(
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
         JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data)
 {
     OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
@@ -3698,12 +3582,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicChangedCallback(
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattDescriptorReadCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
                                                                          jobject gatt,
                                                                          jobject descriptor,
                                                                          jint status)
@@ -3712,12 +3596,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorReadCallback(JNIEnv
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattDescriptorWriteCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
                                                                           jobject gatt,
                                                                           jobject descriptor,
                                                                           jint status)
@@ -3738,17 +3622,16 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorWriteCallback(JNIEnv
 error_exit:
 
     CALEClientSendFinish(env, gatt);
-    ca_cond_signal(g_threadSendCond);
     return;
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattReliableWriteCompletedCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattReliableWriteCompletedCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattReliableWriteCompletedCallback(JNIEnv *env,
                                                                                  jobject obj,
                                                                                  jobject gatt,
                                                                                  jint status)
@@ -3757,12 +3640,12 @@ Java_org_iotivity_jar_caleclientinterface_CALeGattReliableWriteCompletedCallback
 }
 
 /*
- * Class:     org_iotivity_jar_caleinterface
+ * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattReadRemoteRssiCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
                                                                          jobject gatt, jint rssi,
                                                                          jint status)
 {
index edfec61..ad1ad8c 100644 (file)
@@ -576,20 +576,6 @@ void CALEClientTerminateGattMutexVariables();
  */
 void CALEClientSetSendFinishFlag(bool flag);
 
-/**
- * @brief   set the flag whether WriteCharacteristicCB is called
- * @param   flag                  [IN] flag
- * @return  None
- */
-void CALEClientSetWriteCharacteristicCBFlag(bool flag);
-
-/**
- * @brief   set the flag whether Send Request is called
- * @param   flag                  [IN] flag
- * @return  None
- */
-void CALEClientSetTheSendRequestFlag(bool flag);
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index d6874fa..28da4db 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "camutex.h"
 
-#include "org_iotivity_jar_caleclientinterface.h"
+#include "org_iotivity_ca_CaLeClientInterface.h"
 
 #define TAG PCF("CA_LE_MONITOR")
 
@@ -203,13 +203,13 @@ CAResult_t CAUnSetLEAdapterStateChangedCb()
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeStateChangedCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
                                                                    jint status)
 {
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
 
 
-    OIC_LOG(DEBUG, TAG, "caleclientinterface - Network State Changed");
+    OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Network State Changed");
 
     if (!gCALEDeviceStateChangedCallback)
     {
@@ -249,10 +249,10 @@ Java_org_iotivity_jar_caleclientinterface_CALeStateChangedCallback(JNIEnv *env,
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeBondStateChangedCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
                                                                        jstring addr)
 {
-    OIC_LOG(DEBUG, TAG, "caleclientinterface - Bond State Changed");
+    OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(addr, TAG, "addr is null");
 
index dec1409..e9680c5 100644 (file)
@@ -33,7 +33,7 @@
 #include "cathreadpool.h"
 #include "camutex.h"
 #include "uarraylist.h"
-#include "org_iotivity_jar_caleserverinterface.h"
+#include "org_iotivity_ca_CaLeServerInterface.h"
 
 #define TAG PCF("CA_LE_SERVER")
 
@@ -44,6 +44,8 @@ static jobject g_bluetoothGattServerCallback = NULL;
 static jobject g_leAdvertiseCallback = NULL;
 
 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
+static CABLEErrorHandleCallback g_serverErrorCallback;
+
 static u_arraylist_t *g_connectedDeviceList = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
@@ -99,10 +101,10 @@ CAResult_t CALEServerCreateJniInterfaceObject()
         isAttached = true;
     }
 
-    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/jar/caleserverinterface");
+    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
     if (!jni_LEInterface)
     {
-        OIC_LOG(ERROR, TAG, "Could not get caleserverinterface class");
+        OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
         goto exit;
     }
 
@@ -110,12 +112,12 @@ CAResult_t CALEServerCreateJniInterfaceObject()
                                                                  "()V");
     if (!LeInterfaceConstructorMethod)
     {
-        OIC_LOG(ERROR, TAG, "Could not get caleserverinterface constructor method");
+        OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
         goto exit;
     }
 
     (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
-    OIC_LOG(DEBUG, TAG, "Create instance for caleserverinterface");
+    OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
 
     if (isAttached)
     {
@@ -1296,6 +1298,44 @@ CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
     return CA_STATUS_OK;
 }
 
+CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
+{
+    // GATT CLOSE
+    OIC_LOG(DEBUG, TAG, "GattServer Close");
+    VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
+    if (!jni_mid_closeGatt)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
+        return CA_STATUS_OK;
+    }
+
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "request to close GATT");
+    (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
+
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "closeGATT has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
 {
     OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
@@ -1616,7 +1656,7 @@ CAResult_t CALEServerStartMulticastServer()
     ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
     }
 
     if (isAttached)
@@ -1663,7 +1703,7 @@ CAResult_t CALEServerStopMulticastServer()
     CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+        OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
     }
 
     g_isStartServer = false;
@@ -2041,10 +2081,10 @@ CAResult_t CALEServerReorderinglist(uint32_t index)
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CARegisterLeGattServerCallback(JNIEnv *env, jobject obj,
+Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
                                                                          jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Register Le Gatt Server Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Gatt Server Callback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
@@ -2052,11 +2092,11 @@ Java_org_iotivity_jar_caleserverinterface_CARegisterLeGattServerCallback(JNIEnv
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CARegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
-                                                                                 jobject obj,
-                                                                                 jobject callback)
+Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
+                                                                                  jobject obj,
+                                                                                  jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Register Le Advertise Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Advertise Callback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
@@ -2064,10 +2104,10 @@ Java_org_iotivity_jar_caleserverinterface_CARegisterBluetoothLeAdvertiseCallback
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server ConnectionStateChange Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server ConnectionStateChange Callback");
     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
 
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
@@ -2133,6 +2173,11 @@ Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCal
     else if (newState == jni_int_state_disconnected)
     {
         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
+        CAResult_t res = CALEServerGattClose(env, g_bluetoothGattServer);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
+        }
     }
     else
     {
@@ -2142,20 +2187,20 @@ Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCal
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerServiceAddedCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
                                                                              jobject obj,
                                                                              jint status,
                                                                              jobject gattService)
 {
-    OIC_LOG_V(DEBUG, TAG, "caleserverinterface - Gatt Service Added Callback(%d)", status);
+    OIC_LOG_V(DEBUG, TAG, "CaLeServerInterface - Gatt Service Added Callback(%d)", status);
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicReadRequestCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset,
         jobject characteristic, jbyteArray data)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Characteristic Read Request Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Read Request Callback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
 
@@ -2166,12 +2211,12 @@ Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicReadReques
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicWriteRequestCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic,
         jbyteArray data, jboolean preparedWrite, jboolean responseNeeded, jint offset,
         jbyteArray value)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Characteristic Write Request Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Write Request Callback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
     VERIFY_NON_NULL_VOID(value, TAG, "value is null");
@@ -2227,28 +2272,28 @@ Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicWriteReque
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorReadRequestCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorReadRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerDescriptorReadRequestCallback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorReadRequestCallback");
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorWriteRequestCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorWriteRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerDescriptorWriteRequestCallback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorWriteRequestCallback");
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerExecuteWriteCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerExecuteWriteCallback(JNIEnv *env,
                                                                              jobject obj,
                                                                              jobject device,
                                                                              jint requestId,
                                                                              jboolean execute)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerExecuteWriteCallback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerExecuteWriteCallback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
 
@@ -2256,27 +2301,27 @@ Java_org_iotivity_jar_caleserverinterface_CALeGattServerExecuteWriteCallback(JNI
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerNotificationSentCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
                                                                                  jobject obj,
                                                                                  jobject device,
                                                                                  jint status)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Notification Sent Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Notification Sent Callback");
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartSuccessCallback(
+Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(
         JNIEnv *env, jobject obj, jobject settingsInEffect)
 {
-    OIC_LOG(DEBUG, TAG, "caleserverinterface - LE Advertise Start Success Callback");
+    OIC_LOG(DEBUG, TAG, "CaLeServerInterface - LE Advertise Start Success Callback");
 }
 
 JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartFailureCallback(JNIEnv *env,
+Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
                                                                             jobject obj,
                                                                             jint errorCode)
 {
-    OIC_LOG_V(ERROR, TAG, "caleserverinterface - LE Advertise Start Failure Callback(%)",
+    OIC_LOG_V(ERROR, TAG, "CaLeServerInterface - LE Advertise Start Failure Callback(%)",
               errorCode);
 }
 
@@ -2284,7 +2329,7 @@ Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartFailureCallback(JNIE
  * adapter common
  */
 
-CAResult_t CAStartBleGattServer()
+CAResult_t CAStartLEGattServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -2311,7 +2356,7 @@ CAResult_t CAStartBleGattServer()
     return CA_STATUS_OK;
 }
 
-CAResult_t CAStopBleGattServer()
+CAResult_t CAStopLEGattServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -2319,7 +2364,7 @@ CAResult_t CAStopBleGattServer()
     return CA_STATUS_OK;
 }
 
-void CATerminateBleGattServer()
+void CATerminateLEGattServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -2329,7 +2374,7 @@ void CATerminateBleGattServer()
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
+void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -2340,9 +2385,15 @@ void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_serverErrorCallback = callback;
+}
+
 CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *charValue,
                                                const uint32_t charValueLen)
 {
+    CAResult_t result = CA_SEND_FAILED;
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL(address, TAG, "env is null");
     VERIFY_NON_NULL(charValue, TAG, "device is null");
@@ -2350,28 +2401,28 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *
     if (address)
     {
         OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
-        CALEServerSendUnicastMessage(address, charValue, charValueLen);
+        result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
 
-    return CA_STATUS_OK;
+    return result;
 }
 
 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
-                                                   const uint32_t charValueLen)
+                                                   uint32_t charValueLen)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL(charValue, TAG, "device is null");
 
     OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
-    CALEServerSendMulticastMessage(charValue, charValueLen);
+    CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
 
     OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
+    return result;
 }
 
-void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle)
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
index 99230ed..2966e5e 100644 (file)
@@ -193,6 +193,13 @@ CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback);
 
 /**
+ * @brief   close gatt server
+ * @param   env                  [IN] JNI interface pointer
+ * @param   bluetoothGattServer  [IN] Gatt Server object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer);
+/**
  * @brief   send data
  * @param   env                  [IN] JNI interface pointer
  * @param   bluetoothDevice      [IN] bluetooth device object
index 4e25589..b56bcd7 100644 (file)
@@ -36,9 +36,9 @@ extern "C"
 #endif
 
 /* Service UUID */
-static const char OIC_GATT_SERVICE_UUID[] = "713d0000-503e-4c75-ba94-3148f18d941e";
-static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = "713d0002-503e-4c75-ba94-3148f18d941e";
-static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = "713d0003-503e-4c75-ba94-3148f18d941e";
+static const char OIC_GATT_SERVICE_UUID[] = "ADE3D529-C784-4F63-A987-EB69F70EE816";
+static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = "AD7B334F-4637-4B86-90B6-9D787F03D218";
+static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = "E9241982-4580-42C4-8831-95048216B256";
 static const char OIC_GATT_CHARACTERISTIC_CONFIG_UUID[] = "00002902-0000-1000-8000-00805f9b34fb";
 
 static const uint32_t GATT_SUCCESS = 0;
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeClientInterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeClientInterface.h
new file mode 100644 (file)
index 0000000..91491bc
--- /dev/null
@@ -0,0 +1,161 @@
+/******************************************************************
+ *
+ * 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 <jni.h>
+/* Header for class org_iotivity_ca_caLeClientInterface */
+
+#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
+ * Method:    caLeRegisterLeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeRegisterLeScanCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeRegisterGattCallback
+ * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeRegisterGattCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeScanCallback
+(JNIEnv *, jobject, jobject, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattConnectionStateChangeCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattServicesDiscoveredCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattCharacteristicReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattCharacteristicReadCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattCharacteristicWritjclasseCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattCharacteristicWriteCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattCharacteristicChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattCharacteristicChangedCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattDescriptorReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattDescriptorReadCallback
+(JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattDescriptorWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattDescriptorWriteCallback
+(JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattReliableWriteCompletedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattReliableWriteCompletedCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeGattReadRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeGattReadRemoteRssiCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeStateChangedCallback
+(JNIEnv *, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caLeBondStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeClientInterface_caLeBondStateChangedCallback
+(JNIEnv *, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeServerInterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeServerInterface.h
new file mode 100644 (file)
index 0000000..10c4abe
--- /dev/null
@@ -0,0 +1,149 @@
+/******************************************************************
+ *
+ * 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 <jni.h>
+/* Header for class org_iotivity_ca_caLeServerInterface */
+
+#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
+ * Method:    caLeRegisterGattServerCallback
+ * Signature: (Landroid/bluetooth/BluetoothGattServerCallback;)V
+ */
+JNIEXPORT void JNICALL
+
+Java_org_iotivity_ca_caLeServerInterface_caLeRegisterGattServerCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeRegisterBluetoothLeAdvertiseCallback
+ * Signature: (Landroid/bluetooth/le/AdvertiseCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerConnectionStateChangeCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerServiceAddedCallback
+ * Signature: (ILandroid/bluetooth/BluetoothGattService;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerServiceAddedCallback
+(JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerCharacteristicReadRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/
+ * bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerCharacteristicReadRequestCallback
+(JNIEnv *, jobject, jobject, jint, jint, jobject, jbyteArray);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerCharacteristicWriteRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
+ * BluetoothGattCharacteristic;ZZI[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback
+(JNIEnv *, jobject, jobject, jint, jobject, jbyteArray, jboolean, jboolean, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerDescriptorReadRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/bluetooth/
+ * BluetoothGattDescriptor;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerDescriptorReadRequestCallback
+(JNIEnv *, jobject, jobject, jint, jint, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerDescriptorWriteRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
+ * BluetoothGattDescriptor;ZZI[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerDescriptorWriteRequestCallback
+(JNIEnv *, jobject, jobject, jint, jobject, jboolean, jboolean, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerExecuteWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerExecuteWriteCallback
+(JNIEnv *, jobject, jobject, jint, jboolean);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeGattServerNotificationSentCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeGattServerNotificationSentCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeAdvertiseStartSuccessCallback
+ * Signature: (Landroid/bluetooth/le/AdvertiseSettings;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeAdvertiseStartSuccessCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_caLeServerInterface
+ * Method:    caLeAdvertiseStartFailureCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_caLeServerInterface_caLeAdvertiseStartFailureCallback
+(JNIEnv *, jobject, jint);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h
deleted file mode 100644 (file)
index e57b2d1..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-#include <jni.h>
-/* Header for class org_iotivity_jar_caleclientinterface */
-
-#ifndef CA_Included_org_iotivity_jar_caleclientinterface_H_
-#define CA_Included_org_iotivity_jar_caleclientinterface_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CARegisterLeScanCallback
- * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CARegisterLeScanCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CARegisterLeGattCallback
- * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CARegisterLeGattCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeScanCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeScanCallback
-(JNIEnv *, jobject, jobject, jint, jbyteArray);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattConnectionStateChangeCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattServicesDiscoveredCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattCharacteristicReadCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicReadCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattCharacteristicWritjclasseCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattCharacteristicChangedCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicChangedCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattDescriptorReadCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorReadCallback
-(JNIEnv *, jobject, jobject, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattDescriptorWriteCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorWriteCallback
-(JNIEnv *, jobject, jobject, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattReliableWriteCompletedCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattReliableWriteCompletedCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeGattReadRemoteRssiCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeGattReadRemoteRssiCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeStateChangedCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeStateChangedCallback
-(JNIEnv *, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleclientinterface
- * Method:    CALeBondStateChangedCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleclientinterface_CALeBondStateChangedCallback
-(JNIEnv *, jobject, jstring);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h
deleted file mode 100644 (file)
index 2f82092..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#include <jni.h>
-/* Header for class org_iotivity_jar_caleserverinterface */
-
-#ifndef CA_Included_org_iotivity_jar_caleserverinterface_H_
-#define CA_Included_org_iotivity_jar_caleserverinterface_H_
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CARegisterLeGattServerCallback
- * Signature: (Landroid/bluetooth/BluetoothGattServerCallback;)V
- */
-JNIEXPORT void JNICALL
-
-Java_org_iotivity_jar_caleserverinterface_CARegisterLeGattServerCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CARegisterBluetoothLeAdvertiseCallback
- * Signature: (Landroid/bluetooth/le/AdvertiseCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CARegisterBluetoothLeAdvertiseCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerConnectionStateChangeCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerServiceAddedCallback
- * Signature: (ILandroid/bluetooth/BluetoothGattService;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerServiceAddedCallback
-(JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerCharacteristicReadRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/
- * bluetooth/BluetoothGattCharacteristic;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicReadRequestCallback
-(JNIEnv *, jobject, jobject, jint, jint, jobject, jbyteArray);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerCharacteristicWriteRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
- * BluetoothGattCharacteristic;ZZI[B)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicWriteRequestCallback
-(JNIEnv *, jobject, jobject, jint, jobject, jbyteArray, jboolean, jboolean, jint, jbyteArray);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerDescriptorReadRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/bluetooth/
- * BluetoothGattDescriptor;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorReadRequestCallback
-(JNIEnv *, jobject, jobject, jint, jint, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerDescriptorWriteRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
- * BluetoothGattDescriptor;ZZI[B)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorWriteRequestCallback
-(JNIEnv *, jobject, jobject, jint, jobject, jboolean, jboolean, jint, jbyteArray);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerExecuteWriteCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IZ)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerExecuteWriteCallback
-(JNIEnv *, jobject, jobject, jint, jboolean);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeGattServerNotificationSentCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeGattServerNotificationSentCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeAdvertiseStartSuccessCallback
- * Signature: (Landroid/bluetooth/le/AdvertiseSettings;)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartSuccessCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     org_iotivity_jar_caleserverinterface
- * Method:    CALeAdvertiseStartFailureCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartFailureCallback
-(JNIEnv *, jobject, jint);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/arduino/SConscript
new file mode 100644 (file)
index 0000000..9de983f
--- /dev/null
@@ -0,0 +1,14 @@
+#######################################################
+#       Build BLE adapter for Arduino
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'arduino') ])
+
+src_files = [ 'cableserver.cpp',
+              'cablenwmonitor.cpp',
+              'cableclient.cpp']
+
+Return('src_files')
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/cableclient.cpp b/resource/csdk/connectivity/src/bt_le_adapter/arduino/cableclient.cpp
new file mode 100644 (file)
index 0000000..6ea6967
--- /dev/null
@@ -0,0 +1,61 @@
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+
+
+//logger.h included first to avoid conflict with RBL library PROGMEM attribute
+#include "logger.h"
+#include "caleinterface.h"
+
+#define TAG "LEC"
+
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAStartLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+void CAStopLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CATerminateLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
index a61c483..2740a70 100644 (file)
 //logger.h included first to avoid conflict with RBL library PROGMEM attribute
 #include "logger.h"
 
-#include "caleinterface_singlethread.h"
+#include "caleinterface.h"
 
 #include <Arduino.h>
 #include <SPI.h>
 #include <boards.h>
 #include <RBL_nRF8001.h>
 
-#include "caleadapter_singlethread.h"
+#include "caleadapter.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
 
@@ -50,19 +50,26 @@ static CALEDeviceStateChangedCallback g_caLEDeviceStateChangedCallback = NULL;
  */
 static unsigned char *g_leAddress = NULL;
 
-CAResult_t CALEInitializeNetworkMonitor()
+CAResult_t CAInitializeLENetworkMonitor()
 {
     OIC_LOG(DEBUG, TAG, "IN");
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void CALETerminateNetworkMonitor()
+void CATerminateLENetworkMonitor()
 {
     OIC_LOG(DEBUG, TAG, "IN");
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+CAResult_t CAInitializeLEAdapter()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
 CAResult_t CAGetLEAdapterState()
 {
     OIC_LOG(DEBUG, TAG, "IN");
index 1ad39b3..74f9b14 100644 (file)
 #include <boards.h>
 #include <RBL_nRF8001.h>
 
-#include "caleinterface_singlethread.h"
+#include "caleinterface.h"
 #include "oic_malloc.h"
 #include "caadapterutils.h"
+#include "cafragmentation.h"
 
 #define TAG "LES"
 
-CAResult_t CAInitializeBle()
+/**
+ * @var    g_bleServerDataReceivedCallback
+ * @brief  Maintains the callback to be notified on receival of network packets from other
+ *           BLE devices
+ */
+static CABLEServerDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
+
+/**
+ * @def MAX_EVENT_COUNT
+ * @brief Maximum number of tries to get the event on BLE Shield address.
+ */
+#define MAX_EVENT_COUNT 20
+
+static bool g_serverRunning = false;
+static char *g_coapBuffer = NULL;
+
+/**
+ * @var g_receivedDataLen
+ * @brief Actual length of data received.
+ */
+static uint32_t g_receivedDataLen = 0;
+
+/**
+ * @var g_packetDataLen
+ * @brief Total Length of data that is being fragmented.
+ */
+static uint32_t g_packetDataLen = 0;
+
+void CACheckLEDataInternal()
+{
+    CALEDoEvents();
+
+    if (CAIsLEDataAvailable())
+    {
+        // Allocate Memory for COAP Buffer and do ParseHeader
+        if (NULL == g_coapBuffer)
+        {
+            OIC_LOG(DEBUG, TAG, "IN");
+            char headerArray[CA_HEADER_LENGTH] = "";
+            while (CAIsLEDataAvailable() && g_receivedDataLen < CA_HEADER_LENGTH)
+            {
+                headerArray[g_receivedDataLen++] = CALEReadData();
+            }
+
+            g_packetDataLen = CAParseHeader(headerArray);
+
+            if (g_packetDataLen > COAP_MAX_PDU_SIZE)
+            {
+                OIC_LOG(ERROR, TAG, "len > pdu_size");
+                return;
+            }
+
+            g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
+            if (NULL == g_coapBuffer)
+            {
+                OIC_LOG(ERROR, TAG, "malloc");
+                return;
+            }
+
+            OIC_LOG(DEBUG, TAG, "OUT");
+            g_receivedDataLen = 0;
+        }
+
+        OIC_LOG(DEBUG, TAG, "IN");
+        while (CAIsLEDataAvailable())
+        {
+            OIC_LOG(DEBUG, TAG, "In While loop");
+            g_coapBuffer[g_receivedDataLen++] = CALEReadData();
+            if (g_receivedDataLen == g_packetDataLen)
+            {
+                OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
+                g_coapBuffer[g_receivedDataLen] = '\0';
+                if (g_receivedDataLen > 0)
+                {
+                    OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_receivedDataLen);
+                    uint32_t sentLength = 0;
+                    // g_coapBuffer getting freed by CAMesssageHandler
+                    g_bleServerDataReceivedCallback("", "", g_coapBuffer,
+                                                    g_receivedDataLen, &sentLength);
+                }
+
+                g_receivedDataLen = 0;
+                g_coapBuffer = NULL;
+                break;
+            }
+        }
+        OIC_LOG(DEBUG, TAG, "OUT");
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "NoData");
+    }
+    return;
+}
+
+CAResult_t CALEInitialize()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -50,37 +146,40 @@ CAResult_t CAInitializeBle()
     return CA_STATUS_OK;
 }
 
-CAResult_t CATerminateBle()
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ble_radio_reset();
     OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
+}
 
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-unsigned char CAIsBleDataAvailable()
+unsigned char CAIsLEDataAvailable()
 {
     return ble_available();
 }
 
-unsigned char CAIsBleConnected()
+unsigned char CAIsLEConnected()
 {
     return ble_connected();
 }
-char CAReadBleData()
+char CALEReadData()
 {
     return (char)ble_read();
 }
 
-CAResult_t CABleDoEvents()
+CAResult_t CALEDoEvents()
 {
     ble_do_events();
     return CA_STATUS_OK;
 }
 
 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *char_value,
-                                                   uint8_t valueLength)
+                                                   uint32_t valueLength)
 {
     // ble_write_bytes() api can send only max of 255 bytes at a time
     // This function shall never be called to send more than 255 bytes by the fragmentation logic.
@@ -89,4 +188,59 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *char_value,
     return CA_STATUS_OK;
 }
 
+void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    g_bleServerDataReceivedCallback = callback;
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
 
+CAResult_t CAStartLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t result = CALEInitialize();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
+        return CA_STATUS_FAILED;
+    }
+    /**
+     * Below for loop is to process the BLE Events received from BLE Shield.
+     * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
+     */
+    for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
+    {
+        CACheckLEDataInternal();
+    }
+
+    g_serverRunning = true;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    // There is no server running to stop.
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CATerminateLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    ble_radio_reset();
+    g_serverRunning = false;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return;
+}
+
+void CACheckLEData()
+{
+    if (false == g_serverRunning)
+    {
+        OIC_LOG(ERROR, TAG, "Server is not running");
+        return;
+    }
+    CACheckLEDataInternal();
+}
index 60e19b2..df0750a 100644 (file)
@@ -42,48 +42,31 @@ extern "C"
  * @brief API to initialize Arduino BLE module and advertise the service
  * @return #CA_STATUS_OK or Appropriate error code
  */
-CAResult_t CAInitializeBle();
-
-/**
- * @brief API to Terminate Arduino BLE module and advertise the service
- * @return #CA_STATUS_OK or Appropriate error code
- */
-CAResult_t CATerminateBle();
-
-/**
- * @brief Send the received data to Connectivity Abstraction layer.
- * @param data       [IN] Data received from BLE characteristics
- * @param dataLen    [IN] Received data Length
- * @param senderAdrs [IN] Sender Address.
- * @param senderPort [IN] Sender port
- * @return #CA_STATUS_OK or Appropriate error code
- */
-void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs,
-                      int32_t senderPort);
+CAResult_t CALEInitialize();
 
 /**
  * @brief API to check whether data is available in BLE shield
  * @return - Received buffer length
  */
-unsigned char CAIsBleDataAvailable();
+unsigned char CAIsLEDataAvailable();
 
 /**
  * @brief API to check whether client is connected with BLE Shield
  * @return - Connection state
  */
-unsigned char CAIsBleConnected();
+unsigned char CAIsLEConnected();
 
 /**
  * @brief API to read data from BLE shield
  * @return - Data read
  */
-char CAReadBleData();
+char CALEReadData();
 
 /**
  * @brief API to perform BLE events
  * @return #CA_STATUS_OK or Appropriate error code
  */
-CAResult_t CABleDoEvents();
+CAResult_t CALEDoEvents();
 
 #ifdef __cplusplus
 } /* extern "C" */
index 282cf88..afd362e 100644 (file)
 #include "cacommon.h"
 #include "camutex.h"
 #include "caadapterutils.h"
+#ifndef SINGLE_THREAD
 #include "caqueueingthread.h"
-#include "camsgparser.h"
+#endif
+#include "cafragmentation.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
+#include "caremotehandler.h"
 
 /**
  * @var CALEADAPTER_TAG
  * @brief Logging tag for module name.
  */
-#define CALEADAPTER_TAG "CA_BLE_ADAPTER"
+#define CALEADAPTER_TAG "LAD"
 
 /**
  * @var g_networkCallback
@@ -44,9 +48,10 @@ static CANetworkChangeCallback g_networkCallback = NULL;
 
 /**
  * @var g_localBLEAddress
- * @brief bleAddress of the local adapter. Value will be initialized to zero, and will be updated later.
+ * @brief bleAddress of the local adapter. Value will be initialized to zero, and will
+ *        be updated later.
  */
-static char g_localBLEAddress[16] = {0};
+static char g_localBLEAddress[18] = {0};
 
 /**
  * @var g_isServer
@@ -85,18 +90,6 @@ static ca_thread_pool_t g_bleAdapterThreadPool = NULL;
 static ca_mutex g_bleAdapterThreadPoolMutex = NULL;
 
 /**
- * @var g_bleClientSendQueueHandle
- * @brief Queue to process the outgoing packets from GATTClient.
- */
-static CAQueueingThread_t *g_bleClientSendQueueHandle = NULL;
-
-/**
- * @var g_bleClientReceiverQueue
- * @brief Queue to process the incoming packets to GATT Client.
- */
-static CAQueueingThread_t *g_bleClientReceiverQueue = NULL;
-
-/**
  * @var g_bleClientSendDataMutex
  * @brief Mutex to synchronize the queing of the data from SenderQueue.
  */
@@ -108,23 +101,6 @@ static ca_mutex g_bleClientSendDataMutex = NULL;
  */
 static ca_mutex g_bleClientReceiveDataMutex = NULL;
 
-/**
- * @var g_dataReceiverHandlerState
- * @brief Stop condition of recvhandler.
- */
-static bool g_dataReceiverHandlerState = false;
-
-/**
- * @var g_sendQueueHandle
- * @brief Queue to process the outgoing packets from GATTServer.
- */
-static CAQueueingThread_t *g_sendQueueHandle = NULL;
-
-/**
- * @var g_bleServerReceiverQueue
- * @brief Queue to process the incoming packets to GATTServer
- */
-static CAQueueingThread_t *g_bleServerReceiverQueue = NULL;
 
 /**
  * @var g_bleServerSendDataMutex
@@ -151,6 +127,18 @@ static ca_mutex g_bleAdapterReqRespCbMutex = NULL;
 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
 
 /**
+ * @var g_errorHandler
+ * @brief Callback to notify error from the BLE adapter
+ */
+static CAErrorHandleCallback g_errorHandler = NULL;
+
+/**
+ * @var g_bleAdapterState
+ * @brief Storing Adapter state information
+ */
+static CAAdapterState_t g_bleAdapterState = CA_ADAPTER_DISABLED;
+
+/**
  * @ENUM CALeServerStatus
  * @brief status of BLE Server Status
  *  This ENUM provides information of LE Adapter Server status
@@ -186,12 +174,13 @@ CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
 * @fn  CASetBleAdapterThreadPoolHandle
 * @brief  Used to Set the gThreadPool handle which is required for spawning new thread.
 *
-* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
+* @param[in] handle - Thread pool handle which is given by above layer for using thread
+*                     creation task.
 *
 * @return  void
 *
 */
-void CASetBleAdapterThreadPoolHandle(ca_thread_pool_t handle);
+void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle);
 
 /**
 * @fn  CALEDeviceStateChangedCb
@@ -215,7 +204,7 @@ void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state);
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CAInitBleAdapterMutex();
+CAResult_t CAInitLEAdapterMutex();
 
 /**
 * @fn  CATerminateBleAdapterMutex
@@ -223,7 +212,47 @@ CAResult_t CAInitBleAdapterMutex();
 *
 * @return  void
 */
-void CATerminateBleAdapterMutex();
+void CATerminateLEAdapterMutex();
+
+/**
+* @fn  CALEErrorHandler
+* @brief  prepares and notify error through error callback
+*
+* @return  void
+*/
+static void CALEErrorHandler(const char *remoteAddress, const void *data, uint32_t dataLen,
+                             CAResult_t result);
+
+#ifndef SINGLE_THREAD
+/**
+ * @var g_dataReceiverHandlerState
+ * @brief Stop condition of recvhandler.
+ */
+static bool g_dataReceiverHandlerState = false;
+
+/**
+ * @var g_bleClientSendQueueHandle
+ * @brief Queue to process the outgoing packets from GATTClient.
+ */
+static CAQueueingThread_t *g_bleClientSendQueueHandle = NULL;
+
+/**
+ * @var g_bleClientReceiverQueue
+ * @brief Queue to process the incoming packets to GATT Client.
+ */
+static CAQueueingThread_t *g_bleClientReceiverQueue = NULL;
+
+/**
+ * @var g_bleServerSendQueueHandle
+ * @brief Queue to process the outgoing packets from GATTServer.
+ */
+static CAQueueingThread_t *g_bleServerSendQueueHandle = NULL;
+
+/**
+ * @var g_bleServerReceiverQueue
+ * @brief Queue to process the incoming packets to GATTServer
+ */
+static CAQueueingThread_t *g_bleServerReceiverQueue = NULL;
 
 /**
 * @fn  CALEDataDestroyer
@@ -233,1405 +262,1454 @@ void CATerminateBleAdapterMutex();
 */
 static void CALEDataDestroyer(void *data, uint32_t size);
 
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback,
-                          ca_thread_pool_t handle)
+void CAInitLEQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    //Input validation
-    VERIFY_NON_NULL(registerCallback, NULL, "RegisterConnectivity callback is null");
-    VERIFY_NON_NULL(reqRespCallback, NULL, "PacketReceived Callback is null");
-    VERIFY_NON_NULL(netCallback, NULL, "NetworkChange Callback is null");
-
-    CAResult_t result = CAInitBleAdapterMutex();
+    CAResult_t result = CAInitLEServerQueues();
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!");
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerQueues failed");
+        return;
     }
 
-    result = CAInitializeLENetworkMonitor();
+    result = CAInitLEClientQueues();
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLENetworkMonitor() failed");
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+        return;
     }
 
-    CAInitializeLEAdapter();
-
-    CASetBleClientThreadPoolHandle(handle);
-    CASetBleServerThreadPoolHandle(handle);
-    CASetBleAdapterThreadPoolHandle(handle);
-    CASetBLEReqRespServerCallback(CABLEServerReceivedData);
-    CASetBLEReqRespClientCallback(CABLEClientReceivedData);
-    CASetBLEReqRespAdapterCallback(reqRespCallback);
-
-    CALERegisterNetworkNotifications(netCallback);
-
-    CAConnectivityHandler_t connHandler;
-    connHandler.startAdapter = CAStartLE;
-    connHandler.stopAdapter = CAStopLE;
-    connHandler.startListenServer = CAStartLEListeningServer;
-    connHandler.startDiscoveryServer = CAStartLEDiscoveryServer;
-    connHandler.sendData = CASendLEUnicastData;
-    connHandler.sendDataToAll = CASendLEMulticastData;
-    connHandler.GetnetInfo = CAGetLEInterfaceInformation;
-    connHandler.readData = CAReadLEData;
-    connHandler.terminate = CATerminateLE;
-    registerCallback(connHandler, CA_LE);
-
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLE()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, CALEADAPTER_TAG,
-        "There is no concept of unicast/multicast in LE. So This function is not implemented");
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-CAResult_t CAStopLE()
+CAResult_t CAInitLEServerQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CAStopBleQueues();
+    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
 
-    ca_mutex_lock(g_bleIsServerMutex);
-    if (true == g_isServer)
+    CAResult_t result = CAInitLEServerSenderQueue();
+    if (CA_STATUS_OK != result)
     {
-        CAStopBleGattServer();
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerSenderQueue failed");
+        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        return CA_STATUS_FAILED;
     }
-    else
+
+    result = CAInitLEServerReceiverQueue();
+    if (CA_STATUS_OK != result)
     {
-        CAStopBLEGattClient();
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerReceiverQueue failed");
+        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    g_dataReceiverHandlerState = true;
+
+    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
 
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void CATerminateLE()
+CAResult_t CAInitLEClientQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CASetBLEReqRespServerCallback(NULL);
-    CASetBLEReqRespClientCallback(NULL);
-    CALERegisterNetworkNotifications(NULL);
-    CASetBLEReqRespAdapterCallback(NULL);
-    CATerminateLENetworkMonitor();
+    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
 
-    ca_mutex_lock(g_bleIsServerMutex);
-    if (true == g_isServer)
+    CAResult_t result = CAInitLEClientSenderQueue();
+    if (CA_STATUS_OK != result)
     {
-        CATerminateBleGattServer();
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientSenderQueue failed");
+        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        return CA_STATUS_FAILED;
     }
-    else
+
+    result = CAInitLEClientReceiverQueue();
+    if (CA_STATUS_OK != result)
     {
-        CATerminateBLEGattClient();
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientReceiverQueue failed");
+        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
 
-    CATerminateBleQueues();
+    g_dataReceiverHandlerState = true;
 
-    CATerminateBleAdapterMutex();
+    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-CAResult_t CAStartLEListeningServer()
+CAResult_t CAInitLEServerSenderQueue()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    CAResult_t result = CAInitBleServerQueues();
-    if (CA_STATUS_OK != result)
+    // Check if the message queue is already initialized
+    if (g_bleServerSendQueueHandle)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
-        return CA_STATUS_FAILED;
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Queue is already initialized!");
+        return CA_STATUS_OK;
     }
 
-    result = CAGetLEAdapterState();
-    if (CA_ADAPTER_NOT_ENABLED == result)
+    // Create send message queue
+    g_bleServerSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+    if (!g_bleServerSendQueueHandle)
     {
-        gLeServerStatus = CA_LISTENING_SERVER;
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
-        return CA_STATUS_OK;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        return CA_MEMORY_ALLOC_FAILED;
     }
 
-    if (CA_STATUS_FAILED == result)
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerSendQueueHandle,
+                                                   g_bleAdapterThreadPool,
+                                                   CALEServerSendDataThread, CALEDataDestroyer))
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+        OICFree(g_bleServerSendQueueHandle);
+        g_bleServerSendQueueHandle = NULL;
         return CA_STATUS_FAILED;
     }
 
-    CAStartBleGattServer();
-
-    ca_mutex_lock(g_bleIsServerMutex);
-    g_isServer = true;
-    ca_mutex_unlock(g_bleIsServerMutex);
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerSendQueueHandle))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
+        OICFree(g_bleServerSendQueueHandle);
+        g_bleServerSendQueueHandle = NULL;
+        return CA_STATUS_FAILED;
+    }
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAStartLEDiscoveryServer()
+CAResult_t CAInitLEClientSenderQueue()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CAResult_t result = CAInitBleClientQueues();
-    if (CA_STATUS_OK != result)
+    if (g_bleClientSendQueueHandle)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
-        return CA_STATUS_FAILED;
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+        return CA_STATUS_OK;
     }
 
-    result = CAGetLEAdapterState();
-    if (CA_ADAPTER_NOT_ENABLED == result)
+    // Create send message queue
+    g_bleClientSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+    if (!g_bleClientSendQueueHandle)
     {
-        gLeServerStatus = CA_DISCOVERY_SERVER;
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
-        return CA_STATUS_OK;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        return CA_MEMORY_ALLOC_FAILED;
     }
 
-    if (CA_STATUS_FAILED == result)
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientSendQueueHandle,
+                                                   g_bleAdapterThreadPool,
+                                                   CALEClientSendDataThread, CALEDataDestroyer))
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+        OICFree(g_bleClientSendQueueHandle);
+        g_bleClientSendQueueHandle = NULL;
         return CA_STATUS_FAILED;
     }
 
-    CAStartBLEGattClient();
-
-    ca_mutex_lock(g_bleIsServerMutex);
-    g_isServer = false;
-    ca_mutex_unlock(g_bleIsServerMutex);
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientSendQueueHandle))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
+        OICFree(g_bleClientSendQueueHandle);
+        g_bleClientSendQueueHandle = NULL;
+        return CA_STATUS_FAILED;
+    }
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAStartLENotifyServer()
+CAResult_t CAInitLEServerReceiverQueue()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    // Check if the message queue is already initialized
+    if (g_bleServerReceiverQueue)
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+        return CA_STATUS_OK;
+    }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    // Create send message queue
+    g_bleServerReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+    if (!g_bleServerReceiverQueue)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        OICFree(g_bleServerSendQueueHandle);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return 0;
-}
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerReceiverQueue, g_bleAdapterThreadPool,
+            CALEServerDataReceiverHandler, CALEDataDestroyer))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+        OICFree(g_bleServerReceiverQueue);
+        g_bleServerReceiverQueue = NULL;
+        return CA_STATUS_FAILED;
+    }
 
-CAResult_t CAReadLEData()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    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;
 }
 
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t dataLen)
+CAResult_t CAInitLEClientReceiverQueue()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    //Input validation
-    VERIFY_NON_NULL_RET(endpoint, NULL, "Remote endpoint is null", -1);
-    VERIFY_NON_NULL_RET(data, NULL, "Data is null", -1);
-
-    CAResult_t result = CA_STATUS_FAILED;
-
-    ca_mutex_lock(g_bleIsServerMutex);
-    if (true  == g_isServer)
+    // Check if the message queue is already initialized
+    if (g_bleClientReceiverQueue)
     {
-        result = CABLEServerSendData(endpoint, data, dataLen);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG,
-                    "[SendLEUnicastData] CABleServerSenderQueueEnqueueMessage failed \n");
-            ca_mutex_unlock(g_bleIsServerMutex);
-            return -1;
-        }
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
     }
     else
     {
-        result = CABLEClientSendData(endpoint, data, dataLen);
-        if (CA_STATUS_OK != result)
+        // Create send message queue
+        g_bleClientReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+        if (!g_bleClientReceiverQueue)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG,
-                    "[SendLEUnicastData] CABleClientSenderQueueEnqueueMessage failed \n");
-            ca_mutex_unlock(g_bleIsServerMutex);
-            return -1;
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+            OICFree(g_bleClientSendQueueHandle);
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+
+        if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientReceiverQueue,
+                                                       g_bleAdapterThreadPool,
+                                                       CALEClientDataReceiverHandler, NULL))
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+            OICFree(g_bleClientSendQueueHandle);
+            OICFree(g_bleClientReceiverQueue);
+            g_bleClientReceiverQueue = NULL;
+            return CA_STATUS_FAILED;
         }
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientReceiverQueue))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
+        OICFree(g_bleClientReceiverQueue);
+        g_bleClientReceiverQueue = NULL;
+        return CA_STATUS_FAILED;
+    }
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return dataLen;
+    return CA_STATUS_OK;
 }
 
-int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
+void CAStopLEQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    //Input validation
-    VERIFY_NON_NULL_RET(data, NULL, "Data is null", -1);
-
-    if (0 >= dataLen)
+    ca_mutex_lock(g_bleClientSendDataMutex);
+    if (NULL != g_bleClientSendQueueHandle)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid Parameter");
-        return -1;
+        CAQueueingThreadStop(g_bleClientSendQueueHandle);
     }
+    ca_mutex_unlock(g_bleClientSendDataMutex);
 
-    CAResult_t result = CA_STATUS_FAILED;
+    ca_mutex_lock(g_bleClientReceiveDataMutex);
+    if (NULL != g_bleClientReceiverQueue)
+    {
+        CAQueueingThreadStop(g_bleClientReceiverQueue);
+    }
+    ca_mutex_unlock(g_bleClientReceiveDataMutex);
 
-    ca_mutex_lock(g_bleIsServerMutex);
-    if (true  == g_isServer)
+    ca_mutex_lock(g_bleServerSendDataMutex);
+    if (NULL != g_bleServerSendQueueHandle)
     {
-        result = CABLEServerSendData(NULL, data, dataLen);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG,
-                    "[SendLEMulticastDataToAll] CABleServerSenderQueueEnqueueMessage failed" );
-            ca_mutex_unlock(g_bleIsServerMutex);
-            return -1;
-        }
+        CAQueueingThreadStop(g_bleServerSendQueueHandle);
     }
-    else
+    ca_mutex_unlock(g_bleServerSendDataMutex);
+
+    ca_mutex_lock(g_bleServerReceiveDataMutex);
+    if (NULL != g_bleServerReceiverQueue)
     {
-        result = CABLEClientSendData(NULL, data, dataLen);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG,
-                    "[SendLEMulticastDataToAll] CABleClientSenderQueueEnqueueMessage failed" );
-            ca_mutex_unlock(g_bleIsServerMutex);
-            return -1;
-        }
+        CAQueueingThreadStop(g_bleServerReceiverQueue);
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    ca_mutex_unlock(g_bleServerReceiveDataMutex);
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return dataLen;
 }
 
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+void CATerminateLEQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    VERIFY_NON_NULL(info, NULL, "CALocalConnectivity info is null");
-
-    char *local_address = NULL;
-
-    CAResult_t res = CAGetLEAddress(&local_address);
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAGetLEAddress has failed");
-        return res;
-    }
+    CAQueueingThreadDestroy(g_bleClientSendQueueHandle);
+    OICFree(g_bleClientSendQueueHandle);
+    g_bleClientSendQueueHandle = NULL;
 
-    if (NULL == local_address)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "local_address is NULL");
-        return CA_STATUS_FAILED;
-    }
 
-    *size = 0;
-    (*info) = (CALocalConnectivity_t *) OICCalloc(1, sizeof(CALocalConnectivity_t));
-    if (NULL == (*info))
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failure!");
-        OICFree(local_address);
-        return CA_STATUS_FAILED;
-    }
+    CAQueueingThreadDestroy(g_bleClientReceiverQueue);
+    OICFree(g_bleClientReceiverQueue);
+    g_bleClientReceiverQueue = NULL;
 
-    size_t local_address_len = strlen(local_address);
 
-    if(local_address_len >= sizeof(g_localBLEAddress) ||
-            local_address_len >= sizeof((*info)->addressInfo.BT.btMacAddress))
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "local_address is too long");
-        OICFree(*info);
-        OICFree(local_address);
-        return CA_STATUS_FAILED;
-    }
+    CAQueueingThreadDestroy(g_bleServerSendQueueHandle);
+    OICFree(g_bleServerSendQueueHandle);
+    g_bleServerSendQueueHandle = NULL;
 
-    strncpy((*info)->addressInfo.BT.btMacAddress, local_address,
-            sizeof((*info)->addressInfo.BT.btMacAddress) - 1);
-    (*info)->addressInfo.BT.btMacAddress[sizeof((*info)->addressInfo.BT.btMacAddress)-1] = '\0';
-    ca_mutex_lock(g_bleLocalAddressMutex);
-    strncpy(g_localBLEAddress, local_address, sizeof(g_localBLEAddress) - 1);
-    g_localBLEAddress[sizeof(g_localBLEAddress)-1] = '\0';
-    ca_mutex_unlock(g_bleLocalAddressMutex);
 
-    (*info)->type = CA_LE;
-    *size = 1;
-    OICFree(local_address);
+    CAQueueingThreadDestroy(g_bleServerReceiverQueue);
+    OICFree(g_bleServerReceiverQueue);
+    g_bleServerReceiverQueue = NULL;
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
+void CALEServerDataReceiverHandler(void *threadData)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    ca_mutex_lock(g_bleNetworkCbMutex);
-    g_networkCallback = netCallback;
-    ca_mutex_unlock(g_bleNetworkCbMutex);
-    CAResult_t res = CA_STATUS_OK;
-    if (netCallback)
+    static uint32_t recvDataLen = 0;
+    static uint32_t totalDataLen = 0;
+    static char *defragData = NULL;
+    static bool isHeaderAvailable = false;
+    static CAEndpoint_t *remoteEndpoint = NULL;
+
+    ca_mutex_lock(g_bleServerReceiveDataMutex);
+
+    if (g_dataReceiverHandlerState)
     {
-        res = CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCb);
-        if (CA_STATUS_OK != res)
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+        CALEData_t *bleData = (CALEData_t *) threadData;
+        if (!bleData)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bleData!");
+            return;
         }
-    }
-    else
-    {
-        res = CAUnSetLEAdapterStateChangedCb();
-        if (CA_STATUS_OK != res)
+
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+        if (!isHeaderAvailable)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
-        }
-    }
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
+            totalDataLen = CAParseHeader((char*)bleData->data);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return res;
-}
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%d] bytes", bleData->dataLen);
 
-void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state)
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+            defragData = (char *) OICCalloc(totalDataLen + 1, sizeof(char));
+            if (NULL == defragData)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
+                return;
+            }
 
-    VERIFY_NON_NULL_VOID(g_localBLEAddress, NULL, "g_localBLEAddress is null");
-    CALocalConnectivity_t localEndpoint = {};
+            const char *remoteAddress = bleData->remoteEndpoint->addr;
 
-    ca_mutex_lock(g_bleLocalAddressMutex);
-    strncpy(localEndpoint.addressInfo.BT.btMacAddress, g_localBLEAddress, strlen(g_localBLEAddress));
-    ca_mutex_unlock(g_bleLocalAddressMutex);
+            remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE,
+                                                    remoteAddress, 0);
 
-    // Start a GattServer/Client if gLeServerStatus is SET
-    if (CA_LISTENING_SERVER == gLeServerStatus)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattServer");
-        CAStartBleGattServer();
-    }
-    else if (CA_DISCOVERY_SERVER == gLeServerStatus)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattClient");
-        CAStartBLEGattClient();
-    }
-    gLeServerStatus = CA_SERVER_NOTSTARTED;
+            memcpy(defragData + recvDataLen, bleData->data + CA_HEADER_LENGTH,
+                   bleData->dataLen - CA_HEADER_LENGTH);
+            recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
+            isHeaderAvailable = true;
+        }
+        else
+        {
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
+            memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
+            recvDataLen += bleData->dataLen ;
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] recveived Datalen [%d]",
+                      totalDataLen, recvDataLen);
+        }
+        if (totalDataLen == recvDataLen)
+        {
+            ca_mutex_lock(g_bleAdapterReqRespCbMutex);
+            if (NULL == g_networkPacketReceivedCallback)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
+                ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
+                return;
+            }
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !");
+            g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+            recvDataLen = 0;
+            totalDataLen = 0;
+            isHeaderAvailable = false;
+            remoteEndpoint = NULL;
+            defragData = NULL;
+            ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
+        }
 
-    ca_mutex_lock(g_bleNetworkCbMutex);
-    if (NULL != g_networkCallback)
-    {
-        g_networkCallback(&localEndpoint, adapter_state);
-    }
-    else
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "g_networkCallback is NULL");
+        if (false == g_dataReceiverHandlerState)
+        {
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
+            recvDataLen = 0;
+            totalDataLen = 0;
+            isHeaderAvailable = false;
+            OICFree(defragData);
+            CAFreeEndpoint(remoteEndpoint);
+            ca_mutex_unlock(g_bleServerReceiveDataMutex);
+            return;
+        }
     }
-    ca_mutex_unlock(g_bleNetworkCbMutex);
-
+    ca_mutex_unlock(g_bleServerReceiveDataMutex);
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
-CAResult_t CAInitBleAdapterMutex()
+void CALEClientDataReceiverHandler(void *threadData)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    if (NULL == g_bleIsServerMutex)
-    {
-        g_bleIsServerMutex = ca_mutex_new();
-        if (NULL == g_bleIsServerMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+    static const char *remoteAddress = NULL;
+    static uint32_t recvDataLen = 0;
+    static uint32_t totalDataLen = 0;
+    static char *defragData = NULL;
+    static bool isHeaderAvailable = false;
+    static CAEndpoint_t *remoteEndpoint = NULL;
 
-    if (NULL == g_bleNetworkCbMutex)
+    ca_mutex_lock(g_bleClientReceiveDataMutex);
+
+    if (g_dataReceiverHandlerState)
     {
-        g_bleNetworkCbMutex = ca_mutex_new();
-        if (NULL == g_bleNetworkCbMutex)
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+        CALEData_t *bleData = (CALEData_t *) threadData;
+        if (!bleData)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid wifidata!");
+            return;
         }
-    }
 
-    if (NULL == g_bleLocalAddressMutex)
-    {
-        g_bleLocalAddressMutex = ca_mutex_new();
-        if (NULL == g_bleLocalAddressMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
 
-    if (NULL == g_bleAdapterThreadPoolMutex)
-    {
-        g_bleAdapterThreadPoolMutex = ca_mutex_new();
-        if (NULL == g_bleAdapterThreadPoolMutex)
+        if (!isHeaderAvailable)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
 
-    if (NULL == g_bleClientSendDataMutex)
-    {
-        g_bleClientSendDataMutex = ca_mutex_new();
-        if (NULL == g_bleClientSendDataMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+            totalDataLen = CAParseHeader(bleData->data);
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes",
+                      totalDataLen);
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received in the first packet [%d] bytes",
+                      bleData->dataLen);
 
-    if (NULL == g_bleClientReceiveDataMutex)
-    {
-        g_bleClientReceiveDataMutex = ca_mutex_new();
-        if (NULL == g_bleClientReceiveDataMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+            defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+            if (NULL == defragData)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
+                return;
+            }
 
-    if (NULL == g_bleServerSendDataMutex)
-    {
-        g_bleServerSendDataMutex = ca_mutex_new();
-        if (NULL == g_bleServerSendDataMutex)
+            remoteAddress = bleData->remoteEndpoint->addr;
+
+            remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE,
+                                                    remoteAddress, 0);
+
+            memcpy(defragData, bleData->data + CA_HEADER_LENGTH,
+                   bleData->dataLen - CA_HEADER_LENGTH);
+            recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
+            isHeaderAvailable = true;
+        }
+        else
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
+            memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
+            recvDataLen += bleData->dataLen ;
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] recveived Datalen [%d]",
+                      totalDataLen, recvDataLen);
         }
-    }
-
-    if (NULL == g_bleServerReceiveDataMutex)
-    {
-        g_bleServerReceiveDataMutex = ca_mutex_new();
-        if (NULL == g_bleServerReceiveDataMutex)
+        if (totalDataLen == recvDataLen)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
+            ca_mutex_lock(g_bleAdapterReqRespCbMutex);
+            if (NULL == g_networkPacketReceivedCallback)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
+                ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
+                return;
+            }
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !");
+            g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+            recvDataLen = 0;
+            totalDataLen = 0;
+            isHeaderAvailable = false;
+            remoteEndpoint = NULL;
+            defragData = NULL;
+            ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
         }
-    }
 
-    if (NULL == g_bleAdapterReqRespCbMutex)
-    {
-        g_bleAdapterReqRespCbMutex = ca_mutex_new();
-        if (NULL == g_bleAdapterReqRespCbMutex)
+        if (false == g_dataReceiverHandlerState)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
-            return CA_STATUS_FAILED;
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
+            OICFree(defragData);
+            CAFreeEndpoint(remoteEndpoint);
+            ca_mutex_unlock(g_bleClientReceiveDataMutex);
+            return;
         }
     }
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-    return CA_STATUS_OK;
-}
-
-void CATerminateBleAdapterMutex()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_free(g_bleIsServerMutex);
-    g_bleIsServerMutex = NULL;
-
-    ca_mutex_free(g_bleNetworkCbMutex);
-    g_bleNetworkCbMutex = NULL;
-
-    ca_mutex_free(g_bleLocalAddressMutex);
-    g_bleLocalAddressMutex = NULL;
-
-    ca_mutex_free(g_bleAdapterThreadPoolMutex);
-    g_bleAdapterThreadPoolMutex = NULL;
-
-    ca_mutex_free(g_bleClientSendDataMutex);
-    g_bleClientSendDataMutex = NULL;
-
-    ca_mutex_free(g_bleClientReceiveDataMutex);
-    g_bleClientReceiveDataMutex = NULL;
-
-    ca_mutex_free(g_bleServerSendDataMutex);
-    g_bleServerSendDataMutex = NULL;
-
-    ca_mutex_free(g_bleServerReceiveDataMutex);
-    g_bleServerReceiveDataMutex = NULL;
-
-    ca_mutex_free(g_bleAdapterReqRespCbMutex);
-    g_bleAdapterReqRespCbMutex = NULL;
-
+    ca_mutex_unlock(g_bleClientReceiveDataMutex);
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
-void CAInitBleQueues()
+void CALEServerSendDataThread(void *threadData)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CAResult_t result = CAInitBleServerQueues();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerQueues failed");
-        return;
-    }
-
-    result = CAInitBleClientQueues();
-    if (CA_STATUS_OK != result)
+    CALEData_t *bleData = (CALEData_t *) threadData;
+    if (!bleData)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
         return;
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-}
-
-CAResult_t CAInitBleServerQueues()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
-
-    CAResult_t result = CAInitBleServerSenderQueue();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerSenderQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    result = CAInitBleServerReceiverQueue();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerReceiverQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    g_dataReceiverHandlerState = true;
-
-    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAInitBleClientQueues()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char));
+    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
 
-    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
+    int32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
 
-    CAResult_t result = CAInitBleClientSenderQueue();
-    if (CA_STATUS_OK != result)
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server total Data length with header is [%d]", totalLength);
+    char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char));
+    if (NULL == dataSegment)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientSenderQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+        OICFree(header);
+        return;
     }
 
-    result = CAInitBleClientReceiverQueue();
-    if (CA_STATUS_OK != result)
+    CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
+    if (CA_STATUS_OK != result )
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientReceiverQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
+        OICFree(header);
+        OICFree(dataSegment);
+        return ;
     }
 
-    g_dataReceiverHandlerState = true;
-
-    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAInitBleServerSenderQueue()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-    // Check if the message queue is already initialized
-    if (g_sendQueueHandle)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Queue is already initialized!");
-        return CA_STATUS_OK;
-    }
+    memcpy(dataSegment, header, CA_HEADER_LENGTH);
+    OICFree(header);
 
-    // Create send message queue
-    g_sendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
-    if (!g_sendQueueHandle)
+    int32_t length = 0;
+    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-        return CA_MEMORY_ALLOC_FAILED;
+        length = totalLength;
+        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
     }
-
-    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_bleAdapterThreadPool,
-            CABLEServerSendDataThread, CALEDataDestroyer))
+    else
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
-        OICFree(g_sendQueueHandle);
-        g_sendQueueHandle = NULL;
-        return CA_STATUS_FAILED;
+        length =  CA_SUPPORTED_BLE_MTU_SIZE;
+        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
+               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
     }
 
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
+    int32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
+    int32_t index = 0;
+    // Send the first segment with the header.
+     if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
-        OICFree(g_sendQueueHandle);
-        g_sendQueueHandle = NULL;
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Unicast Data");
+        result = CAUpdateCharacteristicsToGattClient(
+                    bleData->remoteEndpoint->addr, dataSegment, length);
+        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);
+            OICFree(dataSegment);
+            return;
+        }
 
-CAResult_t CAInitBleClientSenderQueue()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    if (g_bleClientSendQueueHandle)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
-        return CA_STATUS_OK;
-    }
-
-    // Create send message queue
-    g_bleClientSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
-    if (!g_bleClientSendQueueHandle)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
+        for (index = 1; index < iter; index++)
+        {
+            // Send the remaining header.
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
+            result = CAUpdateCharacteristicsToGattClient(
+                         bleData->remoteEndpoint->addr,
+                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+                         CA_SUPPORTED_BLE_MTU_SIZE);
+            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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]",
+                                               CA_SUPPORTED_BLE_MTU_SIZE);
+        }
 
-    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientSendQueueHandle, g_bleAdapterThreadPool,
-            CABLEClientSendDataThread, CALEDataDestroyer))
+        int32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToGattClient(
+                         bleData->remoteEndpoint->addr,
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         remainingLen);
+            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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
+        }
+     }
+    else
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
-        OICFree(g_bleClientSendQueueHandle);
-        g_bleClientSendQueueHandle = NULL;
-        return CA_STATUS_FAILED;
-    }
+        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);
+            OICFree(dataSegment);
+            return;
+        }
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
+        for (index = 1; index < iter; index++)
+        {
+            // Send the remaining header.
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
+            result = CAUpdateCharacteristicsToAllGattClients(
+                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+                         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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", CA_SUPPORTED_BLE_MTU_SIZE);
+        }
 
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientSendQueueHandle))
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
-        OICFree(g_bleClientSendQueueHandle);
-        g_bleClientSendQueueHandle = NULL;
-        return CA_STATUS_FAILED;
+        int32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToAllGattClients(
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         remainingLen);
+            if (CA_STATUS_OK != result)
+            {
+                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
+                          result);
+                CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
+        }
     }
+    OICFree(dataSegment);
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-CAResult_t CAInitBleServerReceiverQueue()
+void CALEClientSendDataThread(void *threadData)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-    // Check if the message queue is already initialized
-    if (g_bleServerReceiverQueue)
+
+    CALEData_t *bleData = (CALEData_t *) threadData;
+    if (!bleData)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
-        return CA_STATUS_OK;
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
+        return;
     }
 
-    // Create send message queue
-    g_bleServerReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
-    if (!g_bleServerReceiverQueue)
+    char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char));
+    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
+
+    uint32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
+    char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char));
+    if (NULL == dataSegment)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-        OICFree(g_sendQueueHandle);
-        return CA_MEMORY_ALLOC_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+        OICFree(header);
+        return;
     }
 
-    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerReceiverQueue, g_bleAdapterThreadPool,
-            CABLEServerDataReceiverHandler, CALEDataDestroyer))
+    CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
+    if (CA_STATUS_OK != result )
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
-        OICFree(g_bleServerReceiverQueue);
-        g_bleServerReceiverQueue = NULL;
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
+        OICFree(header);
+        OICFree(dataSegment);
+        return ;
     }
+    memcpy(dataSegment, header, CA_HEADER_LENGTH);
+    OICFree(header);
 
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerReceiverQueue))
+    uint32_t length = 0;
+    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
-        OICFree(g_bleServerReceiverQueue);
-        g_bleServerReceiverQueue = NULL;
-        return CA_STATUS_FAILED;
+        length = totalLength;
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
+        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+    }
+    else
+    {
+        length = CA_SUPPORTED_BLE_MTU_SIZE;
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length  [%d]", length);
+        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
+               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
+    uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
+    uint32_t index = 0;
+    if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Unicast Data");
+        // Send the first segment with the header.
+        result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addr,
+                 dataSegment,
+                 length,
+                 LE_UNICAST, 0);
 
-CAResult_t CAInitBleClientReceiverQueue()
-{
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+        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);
+            OICFree(dataSegment);
+            return ;
+        }
 
-    // Check if the message queue is already initialized
-    if (g_bleClientReceiverQueue)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", length);
+        for (index = 1; index < iter; index++)
+        {
+            // Send the remaining header.
+            result = CAUpdateCharacteristicsToGattServer(
+                     bleData->remoteEndpoint->addr,
+                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                     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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]",
+                                               CA_SUPPORTED_BLE_MTU_SIZE);
+        }
+
+        uint32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToGattServer(
+                     bleData->remoteEndpoint->addr,
+                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                     remainingLen,
+                     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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", remainingLen);
+        }
     }
     else
     {
-        // Create send message queue
-        g_bleClientReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
-        if (!g_bleClientReceiverQueue)
+        //Sending Mulitcast Data
+        // Send the first segment with the header.
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Multicast Data");
+        result = CAUpdateCharacteristicsToAllGattServers(dataSegment, length);
+        if (CA_STATUS_OK != result)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-            OICFree(g_bleClientSendQueueHandle);
-            return CA_MEMORY_ALLOC_FAILED;
+            OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+                      "Update characteristics (all) failed, result [%d]", result);
+            CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
+            OICFree(dataSegment);
+            return ;
+        }
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", length);
+        // Send the remaining header.
+        for (index = 1; index < iter; index++)
+        {
+            result = CAUpdateCharacteristicsToAllGattServers(
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         CA_SUPPORTED_BLE_MTU_SIZE);
+            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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]",
+                      CA_SUPPORTED_BLE_MTU_SIZE);
         }
 
-        if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientReceiverQueue, g_bleAdapterThreadPool,
-                CABLEClientDataReceiverHandler, NULL))
+        uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
+        if ( remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
-            OICFree(g_bleClientSendQueueHandle);
-            OICFree(g_bleClientReceiverQueue);
-            g_bleClientReceiverQueue = NULL;
-            return CA_STATUS_FAILED;
+            // 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 = CAUpdateCharacteristicsToAllGattServers(
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                          remainingLen);
+            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);
+                OICFree(dataSegment);
+                return;
+            }
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", remainingLen);
         }
-    }
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientReceiverQueue))
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
-        OICFree(g_bleClientReceiverQueue);
-        g_bleClientReceiverQueue = NULL;
-        return CA_STATUS_FAILED;
+
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
+    OICFree(dataSegment);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CABLEClientSendDataThread");
 }
 
-void CAStopBleQueues()
+CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, const void *data,
+                           uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleClientSendDataMutex);
-    if (NULL != g_bleClientSendQueueHandle)
-    {
-        CAQueueingThreadStop(g_bleClientSendQueueHandle);
-    }
-    ca_mutex_unlock(g_bleClientSendDataMutex);
-
-    ca_mutex_lock(g_bleClientReceiveDataMutex);
-    if (NULL != g_bleClientReceiverQueue)
-    {
-        CAQueueingThreadStop(g_bleClientReceiverQueue);
-    }
-    ca_mutex_unlock(g_bleClientReceiveDataMutex);
-
-    ca_mutex_lock(g_bleServerSendDataMutex);
-    if (NULL != g_sendQueueHandle)
+    CALEData_t *bleData = (CALEData_t *) OICMalloc(sizeof(CALEData_t));
+    if (!bleData)
     {
-        CAQueueingThreadStop(g_sendQueueHandle);
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        return NULL;
     }
-    ca_mutex_unlock(g_bleServerSendDataMutex);
 
-    ca_mutex_lock(g_bleServerReceiveDataMutex);
-    if (NULL != g_bleServerReceiverQueue)
+    bleData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
+    bleData->data = (void *)OICCalloc(dataLength + 1, 1);
+    if (NULL == bleData->data)
     {
-        CAQueueingThreadStop(g_bleServerReceiverQueue);
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        CAFreeLEData(bleData);
+        return NULL;
     }
-    ca_mutex_unlock(g_bleServerReceiveDataMutex);
+    memcpy(bleData->data, data, dataLength);
+    bleData->dataLen = dataLength;
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return bleData;
 }
 
-void CATerminateBleQueues()
+void CAFreeLEData(CALEData_t *bleData)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    CAQueueingThreadDestroy(g_bleClientSendQueueHandle);
-    OICFree(g_bleClientSendQueueHandle);
-    g_bleClientSendQueueHandle = NULL;
-
-
-    CAQueueingThreadDestroy(g_bleClientReceiverQueue);
-    OICFree(g_bleClientReceiverQueue);
-    g_bleClientReceiverQueue = NULL;
-
-
-    CAQueueingThreadDestroy(g_sendQueueHandle);
-    OICFree(g_sendQueueHandle);
-    g_sendQueueHandle = NULL;
+    VERIFY_NON_NULL_VOID(bleData, CALEADAPTER_TAG, "Param bleData is NULL");
 
+    CAFreeEndpoint(bleData->remoteEndpoint);
+    OICFree(bleData->data);
+    OICFree(bleData);
+}
 
-    CAQueueingThreadDestroy(g_bleServerReceiverQueue);
-    OICFree(g_bleServerReceiverQueue);
-    g_bleServerReceiverQueue = NULL;
+void CALEDataDestroyer(void *data, uint32_t size)
+{
+    CALEData_t *ledata = (CALEData_t *) data;
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    CAFreeLEData(ledata);
 }
-void CABLEServerDataReceiverHandler(void *threadData)
+#endif
+
+CAResult_t CAInitLEAdapterMutex()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    static uint32_t recvDataLen = 0;
-    static uint32_t totalDataLen = 0;
-    static char *defragData = NULL;
-    static bool isHeaderAvailable = false;
-    static CARemoteEndpoint_t *remoteEndpoint = NULL;
+    if (NULL == g_bleIsServerMutex)
+    {
+        g_bleIsServerMutex = ca_mutex_new();
+        if (NULL == g_bleIsServerMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
 
-    ca_mutex_lock(g_bleServerReceiveDataMutex);
+    if (NULL == g_bleNetworkCbMutex)
+    {
+        g_bleNetworkCbMutex = ca_mutex_new();
+        if (NULL == g_bleNetworkCbMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
+        }
+    }
 
-    if (g_dataReceiverHandlerState)
+    if (NULL == g_bleLocalAddressMutex)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
-
-        CALEData_t *bleData = (CALEData_t *) threadData;
-        if (!bleData)
+        g_bleLocalAddressMutex = ca_mutex_new();
+        if (NULL == g_bleLocalAddressMutex)
         {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bleData!");
-            return;
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
         }
+    }
 
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
-
-        if (!isHeaderAvailable)
+    if (NULL == g_bleAdapterThreadPoolMutex)
+    {
+        g_bleAdapterThreadPoolMutex = ca_mutex_new();
+        if (NULL == g_bleAdapterThreadPoolMutex)
         {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
-            totalDataLen = CAParseHeader((char*)bleData->data);
-
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%d] bytes", bleData->dataLen);
-
-            defragData = (char *) OICCalloc(totalDataLen + 1, sizeof(char));
-            if (NULL == defragData)
-            {
-                OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
-                return;
-            }
-
-            const char *remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
-            const char *serviceUUID = bleData->remoteEndpoint->resourceUri;
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
+        }
+    }
 
-            remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
-                             serviceUUID);
+    if (NULL == g_bleClientSendDataMutex)
+    {
+        g_bleClientSendDataMutex = ca_mutex_new();
+        if (NULL == g_bleClientSendDataMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
+        }
+    }
 
-            memcpy(defragData + recvDataLen, bleData->data + CA_HEADER_LENGTH,
-                   bleData->dataLen - CA_HEADER_LENGTH);
-            recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
-            isHeaderAvailable = true;
+    if (NULL == g_bleClientReceiveDataMutex)
+    {
+        g_bleClientReceiveDataMutex = ca_mutex_new();
+        if (NULL == g_bleClientReceiveDataMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
         }
-        else
+    }
+
+    if (NULL == g_bleServerSendDataMutex)
+    {
+        g_bleServerSendDataMutex = ca_mutex_new();
+        if (NULL == g_bleServerSendDataMutex)
         {
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
-            memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
-            recvDataLen += bleData->dataLen ;
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] recveived Datalen [%d]",
-                      totalDataLen, recvDataLen);
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
         }
-        if (totalDataLen == recvDataLen)
+    }
+
+    if (NULL == g_bleServerReceiveDataMutex)
+    {
+        g_bleServerReceiveDataMutex = ca_mutex_new();
+        if (NULL == g_bleServerReceiveDataMutex)
         {
-            ca_mutex_lock(g_bleAdapterReqRespCbMutex);
-            if (NULL == g_networkPacketReceivedCallback)
-            {
-                OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
-                ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
-                return;
-            }
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !");
-            g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
-            recvDataLen = 0;
-            totalDataLen = 0;
-            isHeaderAvailable = false;
-            remoteEndpoint = NULL;
-            defragData = NULL;
-            ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
         }
+    }
 
-        if (false == g_dataReceiverHandlerState)
+    if (NULL == g_bleAdapterReqRespCbMutex)
+    {
+        g_bleAdapterReqRespCbMutex = ca_mutex_new();
+        if (NULL == g_bleAdapterReqRespCbMutex)
         {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
-            recvDataLen = 0;
-            totalDataLen = 0;
-            isHeaderAvailable = false;
-            OICFree(defragData);
-            CAAdapterFreeRemoteEndpoint(remoteEndpoint);
-            ca_mutex_unlock(g_bleServerReceiveDataMutex);
-            return;
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            CATerminateLEAdapterMutex();
+            return CA_STATUS_FAILED;
         }
     }
-    ca_mutex_unlock(g_bleServerReceiveDataMutex);
+
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-void CABLEClientDataReceiverHandler(void *threadData)
+void CATerminateLEAdapterMutex()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    static const char *remoteAddress = NULL;
-    static const char *serviceUUID = NULL;
-    static uint32_t recvDataLen = 0;
-    static uint32_t totalDataLen = 0;
-    static char *defragData = NULL;
-    static bool isHeaderAvailable = false;
-    static CARemoteEndpoint_t *remoteEndpoint = NULL;
-
-    ca_mutex_lock(g_bleClientReceiveDataMutex);
-
-    if (g_dataReceiverHandlerState)
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+    ca_mutex_free(g_bleIsServerMutex);
+    g_bleIsServerMutex = NULL;
 
-        CALEData_t *bleData = (CALEData_t *) threadData;
-        if (!bleData)
-        {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid wifidata!");
-            return;
-        }
+    ca_mutex_free(g_bleNetworkCbMutex);
+    g_bleNetworkCbMutex = NULL;
 
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+    ca_mutex_free(g_bleLocalAddressMutex);
+    g_bleLocalAddressMutex = NULL;
 
-        if (!isHeaderAvailable)
-        {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
+    ca_mutex_free(g_bleAdapterThreadPoolMutex);
+    g_bleAdapterThreadPoolMutex = NULL;
 
-            totalDataLen = CAParseHeader(bleData->data);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes",
-                      totalDataLen);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received in the first packet [%d] bytes",
-                      bleData->dataLen);
+    ca_mutex_free(g_bleClientSendDataMutex);
+    g_bleClientSendDataMutex = NULL;
 
-            defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
-            if (NULL == defragData)
-            {
-                OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
-                return;
-            }
+    ca_mutex_free(g_bleClientReceiveDataMutex);
+    g_bleClientReceiveDataMutex = NULL;
 
-            remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
-            serviceUUID = bleData->remoteEndpoint->resourceUri;
+    ca_mutex_free(g_bleServerSendDataMutex);
+    g_bleServerSendDataMutex = NULL;
 
-            remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
-                                                           serviceUUID);
+    ca_mutex_free(g_bleServerReceiveDataMutex);
+    g_bleServerReceiveDataMutex = NULL;
 
-            memcpy(defragData, bleData->data + CA_HEADER_LENGTH,
-                   bleData->dataLen - CA_HEADER_LENGTH);
-            recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
-            isHeaderAvailable = true;
-        }
-        else
-        {
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
-            memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
-            recvDataLen += bleData->dataLen ;
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] recveived Datalen [%d]",
-                      totalDataLen, recvDataLen);
-        }
-        if (totalDataLen == recvDataLen)
-        {
-            ca_mutex_lock(g_bleAdapterReqRespCbMutex);
-            if (NULL == g_networkPacketReceivedCallback)
-            {
-                OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
-                ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
-                return;
-            }
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !");
-            g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
-            recvDataLen = 0;
-            totalDataLen = 0;
-            isHeaderAvailable = false;
-            remoteEndpoint = NULL;
-            defragData = NULL;
-            ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
-        }
+    ca_mutex_free(g_bleAdapterReqRespCbMutex);
+    g_bleAdapterReqRespCbMutex = NULL;
 
-        if (false == g_dataReceiverHandlerState)
-        {
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
-            OICFree(defragData);
-            CAAdapterFreeRemoteEndpoint(remoteEndpoint);
-            ca_mutex_unlock(g_bleClientReceiveDataMutex);
-            return;
-        }
-    }
-    ca_mutex_unlock(g_bleClientReceiveDataMutex);
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
-void CABLEServerSendDataThread(void *threadData)
+CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
+                          CANetworkPacketReceivedCallback reqRespCallback,
+                          CANetworkChangeCallback netCallback,
+                          CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CALEData_t *bleData = (CALEData_t *) threadData;
-    if (!bleData)
+    //Input validation
+    VERIFY_NON_NULL(registerCallback, CALEADAPTER_TAG, "RegisterConnectivity callback is null");
+    VERIFY_NON_NULL(reqRespCallback, CALEADAPTER_TAG, "PacketReceived Callback is null");
+    VERIFY_NON_NULL(netCallback, CALEADAPTER_TAG, "NetworkChange Callback is null");
+
+    CAResult_t result = CA_STATUS_OK;
+    result = CAInitLEAdapterMutex();
+    if (CA_STATUS_OK != result)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
-        return;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!");
+        return CA_STATUS_FAILED;
+    }
+    result = CAInitializeLENetworkMonitor();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLENetworkMonitor() failed");
+        return CA_STATUS_FAILED;
     }
 
-    char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char));
-    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
+    CAInitializeLEAdapter();
 
-    int32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
+    CASetLEClientThreadPoolHandle(handle);
+    CASetLEReqRespClientCallback(CALEAdapterClientReceivedData);
+    CASetLEServerThreadPoolHandle(handle);
+    CASetLEAdapterThreadPoolHandle(handle);
+    CASetLEReqRespServerCallback(CALEAdapterServerReceivedData);
+    CASetLEReqRespAdapterCallback(reqRespCallback);
 
-    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server total Data length with header is [%d]", totalLength);
-    char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char));
-    if (NULL == dataSegment)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
-        OICFree(header);
-        return;
-    }
+    CASetBLEClientErrorHandleCallback(CALEErrorHandler);
+    CASetBLEServerErrorHandleCallback(CALEErrorHandler);
+    CALERegisterNetworkNotifications(netCallback);
+
+    g_errorHandler = errorCallback;
+
+    CAConnectivityHandler_t connHandler;
+    connHandler.startAdapter = CAStartLE;
+    connHandler.stopAdapter = CAStopLE;
+    connHandler.startListenServer = CAStartLEListeningServer;
+    connHandler.startDiscoveryServer = CAStartLEDiscoveryServer;
+    connHandler.sendData = CASendLEUnicastData;
+    connHandler.sendDataToAll = CASendLEMulticastData;
+    connHandler.GetnetInfo = CAGetLEInterfaceInformation;
+    connHandler.readData = CAReadLEData;
+    connHandler.terminate = CATerminateLE;
+    registerCallback(connHandler, CA_ADAPTER_GATT_BTLE);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+
+    return CA_STATUS_OK;
+}
 
-    CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
-    if (CA_STATUS_OK != result )
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
-        OICFree(header);
-        OICFree(dataSegment);
-        return ;
-    }
+CAResult_t CAStartLE()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CAStartLE, not implemented");
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-    memcpy(dataSegment, header, CA_HEADER_LENGTH);
-    OICFree(header);
+CAResult_t CAStopLE()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+#ifndef SINGLE_THREAD
+    CAStopLEQueues();
+#endif
 
-    int32_t length = 0;
-    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+    ca_mutex_lock(g_bleIsServerMutex);
+    if (true == g_isServer)
     {
-        length = totalLength;
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+        CAStopLEGattServer();
     }
     else
     {
-        length =  CA_SUPPORTED_BLE_MTU_SIZE;
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
-               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+        CAStopLEGattClient();
     }
+    ca_mutex_unlock(g_bleIsServerMutex);
 
-    int32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
-    int32_t index = 0;
-    // Send the first segment with the header.
-     if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
-    {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Unicast Data");
-        result = CAUpdateCharacteristicsToGattClient(
-                    bleData->remoteEndpoint->addressInfo.LE.leMacAddress, dataSegment, length);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", result);
-            OICFree(dataSegment);
-            return;
-        }
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
-        for (index = 1; index < iter; index++)
-        {
-            // Send the remaining header.
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
-            result = CAUpdateCharacteristicsToGattClient(
-                         bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
-                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
-                         CA_SUPPORTED_BLE_MTU_SIZE);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                            "Update characteristics failed, result [%d]", result);
-                OICFree(dataSegment);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]",
-                                               CA_SUPPORTED_BLE_MTU_SIZE);
-        }
+    return CA_STATUS_OK;
+}
 
-        int32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToGattClient(
-                         bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                         remainingLen);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                                                   result);
-                OICFree(dataSegment);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
-        }
-     }
+void CATerminateLE()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    CASetLEReqRespServerCallback(NULL);
+    CASetLEReqRespClientCallback(NULL);
+    CALERegisterNetworkNotifications(NULL);
+    CASetLEReqRespAdapterCallback(NULL);
+    CATerminateLENetworkMonitor();
+
+    ca_mutex_lock(g_bleIsServerMutex);
+    if (true == g_isServer)
+    {
+        CATerminateLEGattServer();
+    }
     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);
-            OICFree(dataSegment);
-            return;
-        }
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
-        for (index = 1; index < iter; index++)
-        {
-            // Send the remaining header.
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
-            result = CAUpdateCharacteristicsToAllGattClients(
-                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
-                         CA_SUPPORTED_BLE_MTU_SIZE);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", result);
-                OICFree(dataSegment);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", CA_SUPPORTED_BLE_MTU_SIZE);
-        }
-
-        int32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToAllGattClients(
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                         remainingLen);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                                                   result);
-                OICFree(dataSegment);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
-        }
+        CATerminateLEGattClient();
     }
-    OICFree(dataSegment);
+    ca_mutex_unlock(g_bleIsServerMutex);
+
+#ifndef SINGLE_THREAD
+    CATerminateLEQueues();
+#endif
+    CATerminateLEAdapterMutex();
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
-void CABLEClientSendDataThread(void *threadData)
+CAResult_t CAStartLEListeningServer()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    CALEData_t *bleData = (CALEData_t *) threadData;
-    if (!bleData)
+    CAResult_t result = CA_STATUS_OK;
+#ifndef SINGLE_THREAD
+    result = CAInitLEServerQueues();
+    if (CA_STATUS_OK != result)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
-        return;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEServerQueues failed");
+        return CA_STATUS_FAILED;
     }
+#endif
 
-    char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char));
-    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
-
-    uint32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
-    char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char));
-    if (NULL == dataSegment)
+    result = CAGetLEAdapterState();
+    if (CA_ADAPTER_NOT_ENABLED == result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
-        OICFree(header);
-        return;
+        gLeServerStatus = CA_LISTENING_SERVER;
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
+        return CA_STATUS_OK;
     }
 
-    CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
-    if (CA_STATUS_OK != result )
+    if (CA_STATUS_FAILED == result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
-        OICFree(header);
-        OICFree(dataSegment);
-        return ;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+        return CA_STATUS_FAILED;
     }
-    memcpy(dataSegment, header, CA_HEADER_LENGTH);
-    OICFree(header);
 
-    uint32_t length = 0;
-    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+    CAStartLEGattServer();
+
+    ca_mutex_lock(g_bleIsServerMutex);
+    g_isServer = true;
+    ca_mutex_unlock(g_bleIsServerMutex);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLEDiscoveryServer()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    CAResult_t result = CA_STATUS_OK;
+#ifndef SINGLE_THREAD
+    result = CAInitLEClientQueues();
+    if (CA_STATUS_OK != result)
     {
-        length = totalLength;
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEClientQueues failed");
+        return CA_STATUS_FAILED;
     }
-    else
+#endif
+    result = CAGetLEAdapterState();
+    if (CA_ADAPTER_NOT_ENABLED == result)
     {
-        length = CA_SUPPORTED_BLE_MTU_SIZE;
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length  [%d]", length);
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
-               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+        gLeServerStatus = CA_DISCOVERY_SERVER;
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
+        return CA_STATUS_OK;
     }
 
-    uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
-    uint32_t index = 0;
-    if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
+    if (CA_STATUS_FAILED == result)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Unicast Data");
-        // Send the first segment with the header.
-        result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
-                 dataSegment,
-                 length,
-                 LE_UNICAST, 0);
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!");
+        return CA_STATUS_FAILED;
+    }
 
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", result);
-            OICFree(dataSegment);
-            return ;
-        }
+    CAStartLEGattClient();
 
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", length);
-        for (index = 1; index < iter; index++)
-        {
-            // Send the remaining header.
-            result = CAUpdateCharacteristicsToGattServer(
-                     bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
-                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                     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);
-                OICFree(dataSegment);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]",
-                                               CA_SUPPORTED_BLE_MTU_SIZE);
-        }
+    ca_mutex_lock(g_bleIsServerMutex);
+    g_isServer = false;
+    ca_mutex_unlock(g_bleIsServerMutex);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLENotifyServer()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+uint32_t CASendLENotification(const CAEndpoint_t *endpoint, const void *data,
+                              uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return 0;
+}
 
-        uint32_t remainingLen = totalLength % 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 = CAUpdateCharacteristicsToGattServer(
-                     bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
-                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                     remainingLen,
-                     LE_UNICAST, 0);
+CAResult_t CAReadLEData()
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+#ifdef SINGLE_THREAD
+    CACheckLEData();
+#endif
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-            if (CA_STATUS_OK != result)
+int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL_RET(endpoint, CALEADAPTER_TAG, "Remote endpoint is null", -1);
+    VERIFY_NON_NULL_RET(data, CALEADAPTER_TAG, "Data is null", -1);
+
+    CAResult_t result = CA_STATUS_FAILED;
+
+    ca_mutex_lock(g_bleIsServerMutex);
+    if (true  == g_isServer)
+    {
+        result = CALEAdapterServerSendData(endpoint, data, dataLen);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data failed\n");
+            if (g_errorHandler)
             {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                                                   result);
-                OICFree(dataSegment);
-                return;
+                g_errorHandler((void *) endpoint, (void *) data, dataLen, result);
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", remainingLen);
+            ca_mutex_unlock(g_bleIsServerMutex);
+            return -1;
         }
     }
     else
     {
-        //Sending Mulitcast Data
-        // Send the first segment with the header.
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Multicast Data");
-        result = CAUpdateCharacteristicsToAllGattServers(dataSegment, length);
+        result = CALEAdapterClientSendData(endpoint, data, dataLen);
         if (CA_STATUS_OK != result)
         {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed (all), result [%d]", result);
-            OICFree(dataSegment);
-            return ;
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data failed \n");
+            if (g_errorHandler)
+            {
+                g_errorHandler(endpoint, data, dataLen, result);
+            }
+            ca_mutex_unlock(g_bleIsServerMutex);
+            return -1;
         }
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", length);
-        // Send the remaining header.
-        for (index = 1; index < iter; index++)
+    }
+    ca_mutex_unlock(g_bleIsServerMutex);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return dataLen;
+}
+
+int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL_RET(data, CALEADAPTER_TAG, "Data is null", -1);
+
+    if (0 >= dataLen)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid Parameter");
+        return -1;
+    }
+
+    CAResult_t result = CA_STATUS_FAILED;
+
+    ca_mutex_lock(g_bleIsServerMutex);
+    if (true  == g_isServer)
+    {
+        result = CALEAdapterServerSendData(NULL, data, dataLen);
+        if (CA_STATUS_OK != result)
         {
-            result = CAUpdateCharacteristicsToAllGattServers(
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                         CA_SUPPORTED_BLE_MTU_SIZE);
-            if (CA_STATUS_OK != result)
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send multicast data failed" );
+
+            ca_mutex_unlock(g_bleIsServerMutex);
+            if (g_errorHandler)
             {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics (all) failed, result [%d]", result);
-                OICFree(dataSegment);
-                return;
+                g_errorHandler(endpoint, data, dataLen, result);
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", CA_SUPPORTED_BLE_MTU_SIZE);
+            return -1;
         }
-
-        uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
-        if ( remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+    }
+    else
+    {
+        result = CALEAdapterClientSendData(NULL, data, dataLen);
+        if (CA_STATUS_OK != result)
         {
-            // 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 = CAUpdateCharacteristicsToAllGattServers(
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
-                          remainingLen);
-            if (CA_STATUS_OK != result)
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send Multicast data failed" );
+            if (g_errorHandler)
             {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics (all) failed, result [%d]", result);
-                OICFree(dataSegment);
-                return;
+                g_errorHandler(endpoint, data, dataLen, result);
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", remainingLen);
+            ca_mutex_unlock(g_bleIsServerMutex);
+            return -1;
         }
-
     }
+    ca_mutex_unlock(g_bleIsServerMutex);
 
-    OICFree(dataSegment);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CABLEClientSendDataThread");
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return dataLen;
 }
 
-CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                           uint32_t dataLength)
+CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
-    CALEData_t *bleData = (CALEData_t *) OICMalloc(sizeof(CALEData_t));
-    if (!bleData)
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+    VERIFY_NON_NULL(info, CALEADAPTER_TAG, "CALocalConnectivity info is null");
+
+    char *local_address = NULL;
+
+    CAResult_t res = CAGetLEAddress(&local_address);
+    if (CA_STATUS_OK != res)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-        return NULL;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAGetLEAddress has failed");
+        return res;
     }
 
-    bleData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
-    bleData->data = (void *)OICCalloc(dataLength + 1, 1);
-    if (NULL == bleData->data)
+    if (NULL == local_address)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
-        CAFreeBLEData(bleData);
-        return NULL;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "local_address is NULL");
+        return CA_STATUS_FAILED;
     }
-    memcpy(bleData->data, data, dataLength);
-    bleData->dataLen = dataLength;
 
-    return bleData;
+    *size = 0;
+    (*info) = (CAEndpoint_t *) OICCalloc(1, sizeof(CAEndpoint_t));
+    if (NULL == (*info))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failure!");
+        OICFree(local_address);
+        return CA_STATUS_FAILED;
+    }
+
+    size_t local_address_len = strlen(local_address);
+
+    if(local_address_len >= sizeof(g_localBLEAddress) ||
+            local_address_len >= MAX_ADDR_STR_SIZE_CA - 1)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "local_address is too long");
+        OICFree(*info);
+        OICFree(local_address);
+        return CA_STATUS_FAILED;
+    }
+
+    OICStrcpy((*info)->addr, sizeof((*info)->addr), local_address);
+    ca_mutex_lock(g_bleLocalAddressMutex);
+    OICStrcpy(g_localBLEAddress, sizeof(g_localBLEAddress), local_address);
+    ca_mutex_unlock(g_bleLocalAddressMutex);
+
+    (*info)->adapter = CA_ADAPTER_GATT_BTLE;
+    *size = 1;
+    OICFree(local_address);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-void CAFreeBLEData(CALEData_t *bleData)
+CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
 {
-    VERIFY_NON_NULL_VOID(bleData, NULL, "Param bleData is NULL");
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CAAdapterFreeRemoteEndpoint(bleData->remoteEndpoint);
-    OICFree(bleData->data);
-    OICFree(bleData);
+    ca_mutex_lock(g_bleNetworkCbMutex);
+    g_networkCallback = netCallback;
+    ca_mutex_unlock(g_bleNetworkCbMutex);
+    CAResult_t res = CA_STATUS_OK;
+    if (netCallback)
+    {
+        res = CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCb);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
+        }
+    }
+    else
+    {
+        res = CAUnSetLEAdapterStateChangedCb();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!");
+        }
+    }
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    return res;
 }
 
-void CALEDataDestroyer(void *data, uint32_t size)
+void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state)
 {
-    CALEData_t *ledata = (CALEData_t *) data;
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    CAFreeBLEData(ledata);
-}
+    VERIFY_NON_NULL_VOID(g_localBLEAddress, CALEADAPTER_TAG, "g_localBLEAddress is null");
+    CAEndpoint_t localEndpoint = {};
+
+    ca_mutex_lock(g_bleLocalAddressMutex);
+    OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), g_localBLEAddress);
+    ca_mutex_unlock(g_bleLocalAddressMutex);
+
+    g_bleAdapterState = adapter_state;
+    // Start a GattServer/Client if gLeServerStatus is SET
+    if (CA_LISTENING_SERVER == gLeServerStatus)
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartLEGattServer");
+        CAStartLEGattServer();
+    }
+    else if (CA_DISCOVERY_SERVER == gLeServerStatus)
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattClient");
+        CAStartLEGattClient();
+    }
+    gLeServerStatus = CA_SERVER_NOTSTARTED;
+
+    ca_mutex_lock(g_bleNetworkCbMutex);
+    if (NULL != g_networkCallback)
+    {
+        g_networkCallback(&localEndpoint, adapter_state);
+    }
+    else
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "g_networkCallback is NULL");
+    }
+    ca_mutex_unlock(g_bleNetworkCbMutex);
 
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
 
-CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data,
-                               uint32_t dataLen)
+CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
+                                     const void *data,
+                                     uint32_t dataLen)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    VERIFY_NON_NULL(data, NULL, "Param data is NULL");
-
+    VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
+#ifndef SINGLE_THREAD
     VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG,
                         "g_bleClientSendQueueHandle is  NULL",
                         CA_STATUS_FAILED);
@@ -1644,7 +1722,7 @@ CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
 
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen);
 
-    CALEData_t *bleData = CACreateBLEData(remoteEndpoint, data, dataLen);
+    CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen);
     if (!bleData)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
@@ -1654,33 +1732,85 @@ CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
     ca_mutex_lock(g_bleClientSendDataMutex);
     CAQueueingThreadAddData(g_bleClientSendQueueHandle, bleData, sizeof(CALEData_t));
     ca_mutex_unlock(g_bleClientSendDataMutex);
-
+#endif
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 
-CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
-                               const void *data,
-                               uint32_t dataLen)
+CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
+                                     const void *data,
+                                     uint32_t dataLen)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
-    VERIFY_NON_NULL(data, NULL, "Param data is NULL");
+    VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
+
+#ifdef SINGLE_THREAD
+    char header[CA_HEADER_LENGTH] = {0};
+
+    CAResult_t result = CAGenerateHeader(header, dataLen);
+
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
+        return -1;
+    }
+
+    if (!CAIsLEConnected())
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "le not conn");
+        return -1;
+    }
+
+    result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
+        return -1;
+    }
+
+    int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
+    for (int32_t iter = 0; iter < dataLimit; iter++)
+    {
+        result = CAUpdateCharacteristicsToAllGattClients((data +
+                                                         (iter * CA_SUPPORTED_BLE_MTU_SIZE)),
+                                                         CA_SUPPORTED_BLE_MTU_SIZE);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
+            return -1;
+        }
+        CALEDoEvents();
+    }
 
-    VERIFY_NON_NULL_RET(g_sendQueueHandle, CALEADAPTER_TAG,
+    uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
+    if(remainingLen)
+    {
+        result = CAUpdateCharacteristicsToAllGattClients((data +
+                                                         (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)),
+                                                         remainingLen);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
+            return -1;
+        }
+        CALEDoEvents();
+    }
+#else
+    VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG,
                         "BleClientReceiverQueue is NULL",
                         CA_STATUS_FAILED);
     VERIFY_NON_NULL_RET(g_bleServerSendDataMutex, CALEADAPTER_TAG,
                         "BleClientSendDataMutex is NULL",
                         CA_STATUS_FAILED);
 
-    VERIFY_NON_NULL_RET(g_sendQueueHandle, CALEADAPTER_TAG, "sendQueueHandle",
+    VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG, "sendQueueHandle",
                         CA_STATUS_FAILED);
 
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen);
 
-    CALEData_t *bleData = CACreateBLEData(remoteEndpoint, data, dataLen);
+    CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen);
     if (!bleData)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
@@ -1688,15 +1818,16 @@ CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
     }
     // Add message to send queue
     ca_mutex_lock(g_bleServerSendDataMutex);
-    CAQueueingThreadAddData(g_sendQueueHandle, bleData, sizeof(CALEData_t));
+    CAQueueingThreadAddData(g_bleServerSendQueueHandle, bleData, sizeof(CALEData_t));
     ca_mutex_unlock(g_bleServerSendDataMutex);
-
+#endif
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength)
+CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                         const void *data, uint32_t dataLength,
+                                         uint32_t *sentLength)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
@@ -1704,12 +1835,22 @@ CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *servic
     VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null");
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null");
     VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null");
+
+#ifdef SINGLE_THREAD
+    if(g_networkPacketReceivedCallback)
+    {
+        CAEndpoint_t endPoint = { 0 };   // will be filled by upper layer
+        endPoint.adapter = CA_ADAPTER_GATT_BTLE;
+        g_networkPacketReceivedCallback(&endPoint, data, dataLength);
+    }
+#else
     VERIFY_NON_NULL_RET(g_bleServerReceiverQueue, CALEADAPTER_TAG, "g_bleServerReceiverQueue",
                         CA_STATUS_FAILED);
 
     //Add message to data queue
-    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
-                                         serviceUUID);
+    CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                                          CA_ADAPTER_GATT_BTLE,
+                                                          remoteAddress, 0);
     if (NULL == remoteEndpoint)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create remote endpoint !");
@@ -1719,26 +1860,27 @@ CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *servic
     // Create bleData to add to queue
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength);
 
-    CALEData_t *bleData = CACreateBLEData(remoteEndpoint, data, dataLength);
+    CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLength);
     if (!bleData)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
-        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+        CAFreeEndpoint(remoteEndpoint);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+    CAFreeEndpoint(remoteEndpoint);
     // Add message to send queue
     CAQueueingThreadAddData(g_bleServerReceiverQueue, bleData, sizeof(CALEData_t));
 
     *sentLength = dataLength;
-
+#endif
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
-                                   const void *data, uint32_t dataLength, uint32_t *sentLength)
+CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, const char *serviceUUID,
+                                         const void *data, uint32_t dataLength,
+                                         uint32_t *sentLength)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
@@ -1746,12 +1888,14 @@ CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *servic
     VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null");
     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_bleClientReceiverQueue, CALEADAPTER_TAG, "g_bleClientReceiverQueue",
                         CA_STATUS_FAILED);
 
     //Add message to data queue
-    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
-                                         serviceUUID);
+    CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                                          CA_ADAPTER_GATT_BTLE,
+                                                          remoteAddress, 0);
     if (NULL == remoteEndpoint)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create remote endpoint !");
@@ -1761,25 +1905,25 @@ CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *servic
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength);
 
     // Create bleData to add to queue
-    CALEData_t *bleData = CACreateBLEData(remoteEndpoint, data, dataLength);
+    CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLength);
     if (!bleData)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
-        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+        CAFreeEndpoint(remoteEndpoint);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+    CAFreeEndpoint(remoteEndpoint);
     // Add message to send queue
     CAQueueingThreadAddData(g_bleClientReceiverQueue, bleData, sizeof(CALEData_t));
 
     *sentLength = dataLength;
-
+#endif
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void CASetBleAdapterThreadPoolHandle(ca_thread_pool_t handle)
+void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
@@ -1790,7 +1934,7 @@ void CASetBleAdapterThreadPoolHandle(ca_thread_pool_t handle)
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
-void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
+void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
@@ -1803,3 +1947,17 @@ void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 }
 
+void CALEErrorHandler(const char *remoteAddress, const void *data, uint32_t dataLen,
+                      CAResult_t result)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler IN");
+
+    VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "Data is null");
+    CAEndpoint_t *rep = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE,
+                                               remoteAddress, 0);
+    //if required, will be used to build remote end point
+    g_errorHandler(rep, data, dataLen, result);
+
+    CAFreeEndpoint(rep);
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler OUT");
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter_singlethread.c b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter_singlethread.c
deleted file mode 100644 (file)
index 7e6c1af..0000000
+++ /dev/null
@@ -1,429 +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.
-*
-******************************************************************/
-#include "caleadapter_singlethread.h"
-
-#include "caleinterface_singlethread.h"
-#include "cableserver.h"
-#include "logger.h"
-#include "caadapterutils.h"
-#include "camsgparser.h"
-
-#define TAG "LAD"
-
-/**
- * @def MAX_EVENT_COUNT
- * @brief Maximum number of tries to get the event on BLE Shield address.
- */
-#define MAX_EVENT_COUNT 20
-
-static CANetworkChangeCallback g_networkCallback = NULL;
-static bool g_serverRunning = false;
-static CANetworkPacketReceivedCallback g_respCallback;
-static char *g_coapBuffer = NULL;
-static uint32_t g_dataLen = 0;
-static uint32_t g_packetDataLen = 0;
-
-/**
- * @brief API to register for BLE network notification.
- * @param net_callback - network notification callback.
- * @return - Error Code
- */
-CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
-
-/**
- * @brief API to send received data to upper layer.
- * @param[in] data - data received from BLE characteristics.
- * @param[in] dataLen - received data Length.
- * @param[in] senderAdrs - sender Address.
- * @param[in] senderPort - sender port.
- * @return - Error Code
- */
-void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs,
-                      int32_t senderPort);
-
-/**
- * @brief API to read the data from characteristics and invoke notifyCallback.
- * @return - void
- */
-void CACheckData();
-
-/**
- * @brief API to Send the data.
- * @return - Number of bytes sent. -1 on error.
- */
-int32_t CASendLEData(const void *data, uint32_t dataLen);
-
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == registerCallback || NULL == reqRespCallback || NULL == netCallback)
-    {
-        OIC_LOG(ERROR, TAG, "i/p null");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    CAResult_t result = CALEInitializeNetworkMonitor();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TAG, "n/w init fail: %d", result);
-        return CA_STATUS_FAILED;
-    }
-
-    g_respCallback = reqRespCallback;
-    LERegisterNetworkNotifications(netCallback);
-    CAConnectivityHandler_t connHandler;
-    connHandler.startAdapter = CAStartLE;
-    connHandler.startListenServer = CAStartLEListeningServer;
-    connHandler.startDiscoveryServer = CAStartLEDiscoveryServer;
-    connHandler.sendData = CASendLEUnicastData;
-    connHandler.sendDataToAll = CASendLEMulticastData;
-    connHandler.GetnetInfo = CAGetLEInterfaceInformation;
-    connHandler.readData = CAReadLEData;
-    connHandler.stopAdapter = CAStopLE;
-    connHandler.terminate = CATerminateLE;
-    registerCallback(connHandler, CA_LE);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLE()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLEListeningServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    CAResult_t result = CAInitializeBle();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
-        return CA_STATUS_FAILED;
-    }
-    /**
-     * Below for loop is to process the BLE Events received from BLE Shield.
-     * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
-     */
-    for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
-    {
-        CACheckData();
-    }
-
-    g_serverRunning = true;
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLEDiscoveryServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLENotifyServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data,
-                              uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return 1;
-}
-
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                            uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == remoteEndpoint || NULL == data || dataLen == 0)
-    {
-        OIC_LOG(ERROR, TAG, "i/p null");
-        return -1;
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CASendLEData(data, dataLen);
-}
-
-int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == data || 0 == dataLen)
-    {
-        OIC_LOG(ERROR, TAG, "i/p null");
-        return -1;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CASendLEData(data, dataLen);
-}
-
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    if (NULL == info || NULL == size)
-    {
-        OIC_LOG(ERROR, TAG, "i/p null");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    char *leAddress = NULL;
-    CAResult_t res = CAGetLEAddress(&leAddress);
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, TAG, "CAGetLEAddress has failed");
-        return res;
-    }
-
-    if (NULL == leAddress)
-    {
-        OIC_LOG(ERROR, TAG, "Failed to get Le addr");
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "leAddress = %s", leAddress);
-
-    /**
-     * Create local endpoint using util function
-     */
-    (*info) = CAAdapterCreateLocalEndpoint(CA_LE, leAddress);
-    if (NULL == (*info))
-    {
-        OIC_LOG(ERROR, TAG, "malloc fail");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    (*size) = 1;
-    if (*leAddress)
-    {
-        OICFree(leAddress);
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadLEData()
-{
-    if (true == g_serverRunning)
-    {
-        CACheckData();
-    }
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopLE()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    CAStopBleGattServer();
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CATerminateLE()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    g_respCallback = NULL;
-    LERegisterNetworkNotifications(NULL);
-    CAResult_t result = CATerminateBle();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, TAG, "ble terminate fail");
-        return;
-    }
-
-    CALETerminateNetworkMonitor();
-    g_serverRunning = false;
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return;
-}
-
-CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    g_networkCallback = netCallback;
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartBleGattServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    // Done at time of setup i.e. in initializeBle api
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopBleGattServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    // There is no server running to stop.
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs, int32_t senderPort)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (g_respCallback)
-    {
-
-        /* Cannot get Address as of now */
-        CARemoteEndpoint_t endPoint;
-        endPoint.resourceUri = "";     // will be filled by upper layer
-        endPoint.transportType= CA_LE;
-
-        g_respCallback(&endPoint, data, dataLen);
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CACheckData()
-{
-    CABleDoEvents();
-
-    if (CAIsBleDataAvailable())
-    {
-        // Allocate Memory for COAP Buffer and do ParseHeader
-        if (NULL == g_coapBuffer)
-        {
-            OIC_LOG(DEBUG, TAG, "IN");
-            char headerArray[CA_HEADER_LENGTH] = "";
-            while (CAIsBleDataAvailable() && g_dataLen < CA_HEADER_LENGTH)
-            {
-                headerArray[g_dataLen++] = CAReadBleData();
-            }
-
-            g_packetDataLen = CAParseHeader(headerArray);
-
-            if (g_packetDataLen > COAP_MAX_PDU_SIZE)
-            {
-                OIC_LOG(ERROR, TAG, "len > pdu_size");
-                return;
-            }
-
-            g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
-            if (NULL == g_coapBuffer)
-            {
-                OIC_LOG(ERROR, TAG, "malloc");
-                return;
-            }
-
-            OIC_LOG(DEBUG, TAG, "OUT");
-            g_dataLen = 0;
-        }
-
-        OIC_LOG(DEBUG, TAG, "IN");
-        while (CAIsBleDataAvailable())
-        {
-            OIC_LOG(DEBUG, TAG, "In While loop");
-            g_coapBuffer[g_dataLen++] = CAReadBleData();
-            if (g_dataLen == g_packetDataLen)
-            {
-                OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
-                g_coapBuffer[g_dataLen] = '\0';
-                if (g_dataLen > 0)
-                {
-                    OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_dataLen);
-                    CANotifyCallback((void *)g_coapBuffer, g_dataLen, "", 0);
-                }
-                g_dataLen = 0;
-                OICFree(g_coapBuffer);
-                g_coapBuffer = NULL;
-                break;
-            }
-        }
-        OIC_LOG(DEBUG, TAG, "OUT");
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "NoData");
-    }
-    return;
-}
-
-int32_t CASendLEData(const void *data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    char header[CA_HEADER_LENGTH] = {0};
-
-    CAResult_t result = CAGenerateHeader(header, dataLen);
-
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, TAG, "Generate header failed");
-        return -1;
-    }
-
-    if (!CAIsBleConnected())
-    {
-        OIC_LOG(ERROR, TAG, "le not conn");
-        return -1;
-    }
-
-    result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, TAG, "Update characteristics failed");
-        return -1;
-    }
-
-    int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
-    for (int32_t iter = 0; iter < dataLimit; iter++)
-    {
-        result = CAUpdateCharacteristicsToAllGattClients((data +
-                                                         (iter * CA_SUPPORTED_BLE_MTU_SIZE)),
-                                                         CA_SUPPORTED_BLE_MTU_SIZE);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, TAG, "Update characteristics failed");
-            return -1;
-        }
-        CABleDoEvents();
-    }
-
-    uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
-    if(remainingLen)
-    {
-        result = CAUpdateCharacteristicsToAllGattClients((data +
-                                                         (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)),
-                                                         remainingLen);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, TAG, "Update characteristics failed");
-            return -1;
-        }
-        CABleDoEvents();
-    }
-
-    OIC_LOG(DEBUG, TAG, "writebytes done");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    // Arduino BLEWrite doesnot return value. So, Return the received DataLength
-    return dataLen;
-}
-
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/linux/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/linux/SConscript
new file mode 100644 (file)
index 0000000..825d145
--- /dev/null
@@ -0,0 +1,9 @@
+##########################################
+#       Build BLE adapter for Linux
+##########################################
+
+Import('env')
+
+src_files = [ 'caleadapter.c']
+
+Return('src_files')
index 92d1990..3e8d709 100644 (file)
@@ -31,8 +31,9 @@ static CANetworkPacketReceivedCallback g_leReceivedCallback = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
-                          ca_thread_pool_t handle)
+                          CANetworkPacketReceivedCallback reqRespCallback,
+                          CANetworkChangeCallback netCallback,
+                          CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "CAInitializeLE");
 
@@ -40,8 +41,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
     g_threadPoolHandle = handle;
 
     // register handlers
-    CAConnectivityHandler_t handler;
-    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
+    CAConnectivityHandler_t handler = {};
 
     handler.startAdapter = CAStartLE;
     handler.startListenServer = CAStartLEListeningServer;
@@ -53,7 +53,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
     handler.stopAdapter = CAStopLE;
     handler.terminate = CATerminateLE;
 
-    registerCallback(handler, CA_LE);
+    registerCallback(handler, CA_ADAPTER_GATT_BTLE);
 
     return CA_STATUS_OK;
 }
@@ -79,21 +79,21 @@ CAResult_t CAStartLEDiscoveryServer()
     return CA_STATUS_OK;
 }
 
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t dataLen)
+int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "CASendLEUnicastData");
 
     return -1;
 }
 
-int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
+int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "CASendLEMulticastData");
 
     return -1;
 }
 
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "CAGetLEInterfaceInformation");
 
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript
new file mode 100644 (file)
index 0000000..6ca670e
--- /dev/null
@@ -0,0 +1,20 @@
+#######################################################
+#       Build BLE adapter for Tizen
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+root_dir = os.pardir
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'tizen'),
+                              os.path.join(root_dir, 'lib/tizen/ble/inc'),
+                              os.path.join(root_dir, 'lib/tizen/ble/inc/mobile')])
+
+env.ParseConfig("pkg-config --cflags --libs capi-network-bluetooth")
+
+src_files = [ 'cableclient.c',
+              'cableserver.c',
+              'cableutil.c',
+              'cablenwmonitor.c']
+
+Return('src_files')
index 30199fa..1fba87b 100644 (file)
@@ -34,7 +34,7 @@
 #include "uarraylist.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
-#include "camsgparser.h"
+#include "cafragmentation.h"
 #include "oic_string.h"
 #include "oic_malloc.h"
 
@@ -116,6 +116,12 @@ static ca_mutex g_bleClientThreadPoolMutex = NULL;
 static CABLEClientDataReceivedCallback g_bleClientDataReceivedCallback = NULL;
 
 /**
+ * @var g_clientErrorCallback
+ * @brief callback to update the error to le adapter
+ */
+static CABLEErrorHandleCallback g_clientErrorCallback;
+
+/**
  * @var g_eventLoop
  * @brief gmainLoop to manage the threads to receive the callback from the platfrom.
  */
@@ -289,8 +295,7 @@ bool CABleGattCharacteristicsDiscoveredCb(int result,
 
         VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
 
-        size_t len = strlen(bdAddress);
-        stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
+        stTemp->address = OICStrdup(bdAddress);
         if (NULL == stTemp->address)
         {
             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
@@ -298,7 +303,6 @@ bool CABleGattCharacteristicsDiscoveredCb(int result,
             return false;
         }
 
-        strncpy(stTemp->address, bdAddress, len + 1);
         bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
 
         ca_mutex_lock(g_bleClientThreadPoolMutex);
@@ -338,6 +342,12 @@ bool CABleGattCharacteristicsDiscoveredCb(int result,
             return false;
         }
     }
+    else
+    {
+        OICFree(uuid);
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN");
+        return false;
+    }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
     return true;
@@ -376,9 +386,8 @@ bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count
         VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
 
         char *bdAddress = (char *)userData;
-        size_t len = strlen(bdAddress);
 
-        stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
+        stTemp->address = OICStrdup(bdAddress);
         if (NULL == stTemp->address)
         {
             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
@@ -386,8 +395,6 @@ bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count
             return false;
         }
 
-        strncpy(stTemp->address, bdAddress, len + 1);
-
         BLEServiceInfo *bleServiceInfo = NULL;
 
         result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
@@ -567,12 +574,8 @@ void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
                 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
                 if (CA_STATUS_OK == res)
                 {
-
-                    size_t len = strlen(discoveryInfo->remote_address);
-
-                    char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
+                    char *addr = OICStrdup(discoveryInfo->remote_address);
                     VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
-                    strncpy(addr, discoveryInfo->remote_address, len + 1);
 
                     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
                               "Trying to do Gatt connection to [%s]", addr);
@@ -637,7 +640,7 @@ void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *di
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
@@ -648,7 +651,7 @@ void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
+void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
@@ -661,7 +664,13 @@ void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-CAResult_t CAStartBLEGattClient()
+
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_clientErrorCallback = callback;
+}
+
+CAResult_t CAStartLEGattClient()
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
@@ -716,7 +725,7 @@ void CAStartBleGattClientThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
         ca_mutex_unlock(g_bleClientStateMutex);
-        CATerminateBLEGattClient();
+        CATerminateLEGattClient();
         return;
     }
 
@@ -725,7 +734,7 @@ void CAStartBleGattClientThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
         ca_mutex_unlock(g_bleClientStateMutex);
-        CATerminateBLEGattClient();
+        CATerminateLEGattClient();
         return;
     }
 
@@ -736,7 +745,7 @@ void CAStartBleGattClientThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
         ca_mutex_unlock(g_bleClientStateMutex);
-        CATerminateBLEGattClient();
+        CATerminateLEGattClient();
         return;
     }
 
@@ -757,7 +766,7 @@ void CAStartBleGattClientThread(void *data)
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-void CAStopBLEGattClient()
+void CAStopLEGattClient()
 {
     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
 
@@ -802,7 +811,7 @@ void CAStopBLEGattClient()
     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-void CATerminateBLEGattClient()
+void CATerminateLEGattClient()
 {
     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
     ca_mutex_lock(g_bleClientStateMutex);
@@ -1192,12 +1201,9 @@ CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
                         "remote address is NULL", CA_STATUS_FAILED);
 
-    size_t len = strlen(remoteAddress);
-    char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
+    char *addr = OICStrdup(remoteAddress);
     VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
 
-    strncpy(addr, remoteAddress, len + 1);
-
     int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
                   (void *)addr); // addr memory will be free in callback.
     if (BT_ERROR_NONE != ret)
@@ -1250,15 +1256,12 @@ CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
-
-    VERIFY_NON_NULL_RET(remoteAddress, NULL, "remoteAddress is NULL", CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
 
-    size_t len = strlen(remoteAddress);
+    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL", CA_STATUS_FAILED);
 
-    char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
+    char *addr = OICStrdup(remoteAddress);
     VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
-    strncpy(addr, remoteAddress, len + 1);
 
     int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
                   (void *)addr); // addr will be freed in callback.
@@ -1304,7 +1307,7 @@ CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
 
     int ret = bt_gatt_discover_characteristic_descriptor(service,
                   CABleGattDescriptorDiscoveredCb, NULL);
@@ -1396,7 +1399,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL(data, NULL, "data is NULL");
+    VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
 
     if (0 >= dataLen)
     {
@@ -1411,7 +1414,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
     ca_mutex_lock(g_bleServiceListMutex);
     if ( LE_UNICAST == type)
     {
-        VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL");
+        VERIFY_NON_NULL(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL");
 
         ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
     }
@@ -1427,7 +1430,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
         return CA_STATUS_FAILED;
     }
 
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "bleServiceInfo is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_TAG, "bleServiceInfo is NULL");
 
     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
               bleServiceInfo->bdAddress);
@@ -1458,7 +1461,7 @@ CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data,
 {
     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL(data, NULL, "data is NULL");
+    VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
 
     if (0 >= dataLen)
     {
@@ -1473,12 +1476,14 @@ CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data,
         /*remoteAddress will be NULL.
           Since we have to send to all destinations. pos will be used for getting remote address.
          */
-        int32_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
+        CAResult_t  ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
 
         if (CA_STATUS_OK != ret)
         {
             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
                       "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
+            g_clientErrorCallback(NULL, data, dataLen, ret);
+            continue;
         }
     }
 
index 9985153..b220a01 100644 (file)
@@ -372,7 +372,7 @@ CAResult_t CASetCharacteristicDescriptorValue
  * @retval #CA_STATUS_FAILED Operation failed
  */
 CAResult_t CABleClientSenderQueueEnqueueMessage
-                            (const CARemoteEndpoint_t *remoteEndpoint,
+                            (const CAEndpoint_t *remoteEndpoint,
                                                 const void *data, uint32_t dataLen);
 
 /**
index 36889f2..98e709c 100644 (file)
@@ -30,7 +30,7 @@
 #include "camutex.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
-#include "camsgparser.h"
+#include "cafragmentation.h"
 #include "cableutil.h"
 #include "oic_string.h"
 #include "oic_malloc.h"
 #define TZ_BLE_SERVER_TAG "TZ_BLE_GATT_SERVER"
 
 /**
- * @def CA_BLE_SERVICE_UUID
- * @brief UUID of OIC service. This UUID is common across all platform for LE transport.
- */
-#define CA_BLE_SERVICE_UUID  "713D0000-503E-4C75-BA94-3148F18D941E"
-
-/**
  * @def CA_BLE_INITIAL_BUF_SIZE
  * @brief Initial buffer size for Gatt Server.
  */
@@ -85,6 +79,12 @@ static bt_advertiser_h g_hAdvertiser = NULL;
 static CABLEServerDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
 
 /**
+ * @var g_serverErrorCallback
+ * @brief callback to update the error to le adapter
+ */
+static CABLEErrorHandleCallback g_serverErrorCallback;
+
+/**
  * @var g_isBleGattServerStarted
  * @brief Boolean variable to keep the state of the GATTServer
  */
@@ -150,7 +150,7 @@ void CABleGattServerConnectionStateChangedCb(int result, bool connected,
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
 }
 
-CAResult_t CAStartBleGattServer()
+CAResult_t CAStartLEGattServer()
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
@@ -192,7 +192,7 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Gatt Server is already running");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -201,20 +201,20 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_init_service failed");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
     sleep(5); // Sleep is must because of the platform issue.
 
-    char *serviceUUID = CA_BLE_SERVICE_UUID;
+    char *serviceUUID = OIC_BLE_SERVICE_ID;
 
     ret  = CAAddNewBleServiceInGattServer(serviceUUID);
     if (CA_STATUS_OK != ret )
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewBleServiceInGattServer failed");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -227,7 +227,7 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -241,7 +241,7 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -250,7 +250,7 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CARegisterBleServicewithGattServer failed");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -269,7 +269,7 @@ void CAStartBleGattServerThread(void *data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_hAdvertiser is NULL");
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -279,7 +279,7 @@ void CAStartBleGattServerThread(void *data)
         OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_adapter_le_start_advertising failed with ret [%d] ",
                   res);
         ca_mutex_unlock(g_bleServerStateMutex);
-        CATerminateBleGattServer();
+        CATerminateLEGattServer();
         return;
     }
 
@@ -303,7 +303,7 @@ void CAStartBleGattServerThread(void *data)
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
 }
 
-CAResult_t CAStopBleGattServer()
+CAResult_t CAStopLEGattServer()
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
@@ -375,7 +375,7 @@ CAResult_t CAStopBleGattServer()
     return CA_STATUS_OK;
 }
 
-void CATerminateBleGattServer()
+void CATerminateLEGattServer()
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
@@ -496,7 +496,7 @@ CAResult_t CADeInitBleGattService()
     return CA_STATUS_OK;
 }
 
-void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle)
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
     ca_mutex_lock(g_bleServerThreadPoolMutex);
@@ -509,7 +509,7 @@ CAResult_t CAAddNewBleServiceInGattServer(const char *serviceUUID)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceUUID, NULL, "Param serviceUUID is NULL");
+    VERIFY_NON_NULL(serviceUUID, TZ_BLE_SERVER_TAG, "Param serviceUUID is NULL");
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "service uuid %s", serviceUUID);
 
@@ -547,7 +547,7 @@ CAResult_t CARemoveBleServiceFromGattServer(const char *svcPath)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL");
+    VERIFY_NON_NULL(svcPath, TZ_BLE_SERVER_TAG, "Param svcPath is NULL");
 
     int ret = bt_gatt_remove_service(svcPath);
 
@@ -590,14 +590,14 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath,
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "charPath = [%s] charValue = [%s] len [%d]", charPath,
               charValue, charValueLen);
 
-    char *data = (char *)OICMalloc(sizeof(char) * charValueLen);
+    char *data = (char *)OICMalloc(sizeof(char) * charValueLen + 1);
     if (NULL == data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!");
         return;
     }
 
-    strncpy(data, (char *)charValue, charValueLen);
+    OICStrcpy(data, charValueLen + 1, charValue);
 
     ca_mutex_lock(g_bleReqRespCbMutex);
     if (NULL == g_bleServerDataReceivedCallback)
@@ -623,7 +623,7 @@ CAResult_t CARegisterBleServicewithGattServer(const char *svcPath)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL");
+    VERIFY_NON_NULL(svcPath, TZ_BLE_SERVER_TAG, "Param svcPath is NULL");
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "svcPath:%s", svcPath);
 
@@ -710,9 +710,9 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    VERIFY_NON_NULL(charValue, NULL, "Param charValue is NULL");
+    VERIFY_NON_NULL(charValue, TZ_BLE_SERVER_TAG, "Param charValue is NULL");
 
-    VERIFY_NON_NULL(address, NULL, "Param address is NULL");
+    VERIFY_NON_NULL(address, TZ_BLE_SERVER_TAG, "Param address is NULL");
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Client's Unicast address for sending data [%s]", address);
 
@@ -725,16 +725,15 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *
         return CA_STATUS_FAILED;
     }
 
-    char *data = (char *) OICMalloc(sizeof(char) * (charValueLen + 1));
+    char *data = (char *) OICCalloc(sizeof(char), (charValueLen + 1));
     if (NULL == data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "malloc failed!");
         ca_mutex_unlock(g_bleCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
-    memset(data, 0x0, (charValueLen + 1));
 
-    strncpy(data, charValue, charValueLen);
+    OICStrcpy(data, charValueLen + 1, charValue);
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "updating characteristics char [%s] data [%s] dataLen [%d]",
               (const char *)g_gattReadCharPath, data, charValueLen);
@@ -756,12 +755,11 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *
     return CA_STATUS_OK;
 }
 
-CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
-        const uint32_t charValueLen)
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue, uint32_t charValueLen)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    VERIFY_NON_NULL(charValue, NULL, "Param charValue is NULL");
+    VERIFY_NON_NULL(charValue, TZ_BLE_SERVER_TAG, "Param charValue is NULL");
 
     ca_mutex_lock(g_bleCharacteristicMutex);
 
@@ -780,7 +778,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
         return CA_STATUS_FAILED;
     }
 
-    strncpy(data, charValue, charValueLen + 1);
+    OICStrcpy(data, charValueLen + 1, charValue);
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "updating characteristics char [%s] data [%s] dataLen [%d]",
               (const char *)g_gattReadCharPath, data, charValueLen);
@@ -802,7 +800,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
     return CA_STATUS_OK;
 }
 
-void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
+void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
@@ -814,3 +812,8 @@ void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
 
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
 }
+
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_serverErrorCallback = callback;
+}
index fc087ae..9d83d93 100644 (file)
@@ -212,7 +212,7 @@ CAResult_t CALEReadDataFromLEServer();
  * @retval #CA_STATUS_FAILED Operation failed
  */
 CAResult_t CABleServerSenderQueueEnqueueMessage
-                (const CARemoteEndpoint_t *remoteEndpoint, const void *data, uint32_t dataLen);
+                (const CAEndpoint_t *remoteEndpoint, const void *data, uint32_t dataLen);
 
 /**
  * @brief  This is the thread which will be used for processing receiver queue.
index cc2eb81..1f8da50 100644 (file)
@@ -70,9 +70,9 @@ CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h ser
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL");
-    VERIFY_NON_NULL(service, NULL, "Param service is NULL");
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL");
+    VERIFY_NON_NULL(bdAddress, TZ_BLE_CLIENT_UTIL_TAG, "Param bdAddress is NULL");
+    VERIFY_NON_NULL(service, TZ_BLE_CLIENT_UTIL_TAG, "Param service is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_UTIL_TAG, "Param bleServiceInfo is NULL");
 
     *bleServiceInfo = (BLEServiceInfo *) OICCalloc(1, sizeof(BLEServiceInfo));
     if (NULL == *bleServiceInfo)
@@ -81,8 +81,7 @@ CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h ser
         return CA_STATUS_FAILED;
     }
 
-    size_t len = strlen(bdAddress);
-    (*bleServiceInfo)->bdAddress = (char *) OICMalloc(sizeof(char) * (len + 1));
+    (*bleServiceInfo)->bdAddress = OICStrdup(bdAddress);
 
     if (NULL == (*bleServiceInfo)->bdAddress)
     {
@@ -91,8 +90,6 @@ CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h ser
         return CA_STATUS_FAILED;
     }
 
-    strncpy((*bleServiceInfo)->bdAddress, bdAddress, len + 1);
-
     if (service)
     {
         int32_t ret = bt_gatt_clone_attribute_handle(&((*bleServiceInfo)->service_clone), service);
@@ -117,8 +114,8 @@ CAResult_t CAAppendBLECharInfo( bt_gatt_attribute_h characteristic, CHAR_TYPE ty
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(characteristic, NULL, "Param characteristic is NULL");
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL");
+    VERIFY_NON_NULL(characteristic, TZ_BLE_CLIENT_UTIL_TAG, "Param characteristic is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_UTIL_TAG, "Param bleServiceInfo is NULL");
 
     if (BLE_GATT_READ_CHAR == type )
     {
@@ -154,8 +151,8 @@ CAResult_t CAAddBLEServiceInfoToList(BLEServiceList **serviceList,
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL");
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL");
+    VERIFY_NON_NULL(serviceList, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceList is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_UTIL_TAG, "Param bleServiceInfo is NULL");
 
     BLEServiceList *node = (BLEServiceList *) OICCalloc(1, sizeof(BLEServiceList));
     if (NULL == node)
@@ -194,9 +191,9 @@ CAResult_t CARemoveBLEServiceInfoToList(BLEServiceList **serviceList,
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL");
-    VERIFY_NON_NULL(*serviceList, NULL, "Param *serviceList is NULL");
-    VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL");
+    VERIFY_NON_NULL(serviceList, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceList is NULL");
+    VERIFY_NON_NULL(*serviceList, TZ_BLE_CLIENT_UTIL_TAG, "Param *serviceList is NULL");
+    VERIFY_NON_NULL(bdAddress, TZ_BLE_CLIENT_UTIL_TAG, "Param bdAddress is NULL");
 
     BLEServiceList *prev = NULL;
     BLEServiceList *cur = *serviceList;
@@ -241,9 +238,9 @@ CAResult_t CAGetBLEServiceInfo(BLEServiceList *serviceList, const char *bdAddres
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL");
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL");
-    VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL");
+    VERIFY_NON_NULL(serviceList, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceList is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_UTIL_TAG, "Param bleServiceInfo is NULL");
+    VERIFY_NON_NULL(bdAddress, TZ_BLE_CLIENT_UTIL_TAG, "Param bdAddress is NULL");
 
 
     BLEServiceList *cur = serviceList;
@@ -269,8 +266,8 @@ CAResult_t CAGetBLEServiceInfoByPosition(BLEServiceList *serviceList, int32_t po
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL");
-    VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL");
+    VERIFY_NON_NULL(serviceList, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceList is NULL");
+    VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_UTIL_TAG, "Param bleServiceInfo is NULL");
 
     if (0 > position)
     {
@@ -330,7 +327,7 @@ CAResult_t CAVerifyOICServiceByUUID(const char* serviceUUID)
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceUUID, NULL, "Param serviceHandle is NULL");
+    VERIFY_NON_NULL(serviceUUID, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceHandle is NULL");
 
     if (strcasecmp(serviceUUID, OIC_BLE_SERVICE_ID) != 0)
     {
@@ -345,7 +342,7 @@ CAResult_t CAVerifyOICServiceByServiceHandle(bt_gatt_attribute_h serviceHandle)
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN");
 
-    VERIFY_NON_NULL(serviceHandle, NULL, "Param serviceHandle is NULL");
+    VERIFY_NON_NULL(serviceHandle, TZ_BLE_CLIENT_UTIL_TAG, "Param serviceHandle is NULL");
 
     char *uuid = NULL;
     int ret = bt_gatt_get_service_uuid(serviceHandle, &uuid);
index b390f78..cfa63b1 100644 (file)
@@ -91,20 +91,20 @@ typedef struct gattCharDescriptor
     int total;                          /**< The total number of descriptor in a characteristic */
 } stGattCharDescriptor_t;
 
-#define OIC_BLE_SERVICE_ID "713D0000-503E-4C75-BA94-3148F18D941E"
+#define OIC_BLE_SERVICE_ID "ADE3D529-C784-4F63-A987-EB69F70EE816"
 ///TODO: OIC_BLE_SERVICE_ID  will be generated by invoking API in future.
 
 /**
  * @def CA_BLE_READ_CHAR_UUID
  * @brief UUID of read characteristic. This UUID is common across all platform for LE transport.
  */
-#define CA_BLE_READ_CHAR_UUID "713D0002-503E-4C75-BA94-3148F18D941E"
+#define CA_BLE_READ_CHAR_UUID "E9241982-4580-42C4-8831-95048216B256"
 
 /**
  * @def CA_BLE_WRITE_CHAR_UUID
  * @brief UUID of write characteristic. This UUID is common across all platform for LE transport.
  */
-#define CA_BLE_WRITE_CHAR_UUID "713D0003-503E-4C75-BA94-3148F18D941E"
+#define CA_BLE_WRITE_CHAR_UUID "AD7B334F-4637-4B86-90B6-9D787F03D218"
 
 /**
  * @brief  Used to increment the registered service count.
index 1eabcec..98b3ffd 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "cainterface.h"
 #include "caremotehandler.h"
 #include "canetworkconfigurator.h"
 #include "cainterfacecontroller.h"
 #include "logger.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
+
+CAGlobals_t caglobals = { 0 };
+
+#define TAG "CA_CONN_MGR"
 
-#define TAG PCF("CA")
+static bool g_isInitialized = false;
 
 #ifdef __WITH_DTLS__
 // CAAdapterNetDTLS will register the callback.
@@ -42,22 +50,41 @@ CAResult_t CAInitialize()
 {
     OIC_LOG(DEBUG, TAG, "CAInitialize");
 
-    return CAInitializeMessageHandler();;
+    if (!g_isInitialized)
+    {
+        CAResult_t res = CAInitializeMessageHandler();
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG(ERROR, TAG, "CAInitialize has failed");
+            return res;
+        }
+        g_isInitialized = true;
+    }
+    return CA_STATUS_OK;
 }
 
 void CATerminate()
 {
     OIC_LOG(DEBUG, TAG, "CATerminate");
 
-    CATerminateMessageHandler();
+    if (g_isInitialized)
+    {
+        CATerminateMessageHandler();
+        CATerminateNetworkType();
 
-    CATerminateNetworkType();
+        g_isInitialized = false;
+    }
 }
 
 CAResult_t CAStartListeningServer()
 {
     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
 
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
     return CAStartListeningServerAdapters();
 }
 
@@ -65,55 +92,79 @@ CAResult_t CAStartDiscoveryServer()
 {
     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
 
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
     return CAStartDiscoveryServerAdapters();
 }
 
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                       CAErrorCallback ErrorHandler)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
 
-    CASetRequestResponseCallbacks(ReqHandler, RespHandler);
+    if(!g_isInitialized)
+    {
+        OIC_LOG(DEBUG, TAG, "CA is not initialized");
+        return;
+    }
+
+    CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
 }
 
 #ifdef __WITH_DTLS__
-CAResult_t CARegisterDTLSCredentialsHandler(
-                                             CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
+CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
+
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
     return CA_STATUS_OK;
 }
 #endif //__WITH_DTLS__
 
-CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, const CATransportType_t transportType,
-                                  CARemoteEndpoint_t **remoteEndpoint)
+CAResult_t CACreateEndpoint(CATransportFlags_t flags,
+                            CATransportAdapter_t adapter,
+                            const char *addr,
+                            uint16_t port,
+                            CAEndpoint_t **object)
 {
-    OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpoint");
-
-    CARemoteEndpoint_t *remote = CACreateRemoteEndpointUriInternal(uri, transportType);
+    if (!object)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid Parameter");
+        return CA_STATUS_INVALID_PARAM;
+    }
 
-    if (remote == NULL)
+    CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
+    if (!endpoint)
     {
-        OIC_LOG(DEBUG, TAG, "remote is NULL!");
         return CA_STATUS_FAILED;
     }
-
-    *remoteEndpoint = remote;
-
+    *object = endpoint;
     return CA_STATUS_OK;
 }
 
-void CADestroyRemoteEndpoint(CARemoteEndpoint_t *rep)
+void CADestroyEndpoint(CAEndpoint_t *rep)
 {
-    OIC_LOG(DEBUG, TAG, "CADestroyRemoteEndpoint");
+    OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
 
-    CADestroyRemoteEndpointInternal(rep);
+    CAFreeEndpoint(rep);
 }
 
 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
 {
     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
 
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
     return CAGenerateTokenInternal(token, tokenLength);
 }
 
@@ -122,137 +173,242 @@ void CADestroyToken(CAToken_t token)
     OIC_LOG(DEBUG, TAG, "CADestroyToken");
 
     CADestroyTokenInternal(token);
-}
 
-CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
-
-    return CAGetNetworkInformationInternal(info, size);
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength)
+CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
 {
-    OIC_LOG(DEBUG, TAG, "CAFindResource");
+    OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
 
-    return CADetachMessageResourceUri(resourceUri, token, tokenLength, NULL, 0);
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
 
+    return CAGetNetworkInformationInternal(info, size);
 }
 
-CAResult_t CASendRequest(const CARemoteEndpoint_t *object,const CARequestInfo_t *requestInfo)
+CAResult_t CASendRequest(const CAEndpoint_t *object,const CARequestInfo_t *requestInfo)
 {
     OIC_LOG(DEBUG, TAG, "CASendGetRequest");
 
-    return CADetachRequestMessage(object, requestInfo);
-}
-
-CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
-                              const CARequestInfo_t *requestInfo)
-{
-    OIC_LOG(DEBUG, TAG, "CASendRequestToAll");
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
 
-    return CADetachRequestToAllMessage(object, requestInfo);
+    return CADetachRequestMessage(object, requestInfo);
 }
 
-CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
-    const CAResponseInfo_t *responseInfo)
+CAResult_t CASendNotification(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
     OIC_LOG(DEBUG, TAG, "CASendNotification");
 
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
     return CADetachResponseMessage(object, responseInfo);
 
 }
 
-CAResult_t CASendResponse(const CARemoteEndpoint_t *object,
-    const CAResponseInfo_t *responseInfo)
+CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
     OIC_LOG(DEBUG, TAG, "CASendResponse");
 
-    return CADetachResponseMessage(object, responseInfo);
-
-}
-
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token,
-                               uint8_t tokenLength, const CAHeaderOption_t *options,
-                               const uint8_t numOptions)
-{
-    OIC_LOG(DEBUG, TAG, "CAAdvertiseResource");
+    if(!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
 
-    return CADetachMessageResourceUri(resourceUri, token, tokenLength, options, numOptions);
+    return CADetachResponseMessage(object, responseInfo);
 
 }
 
-CAResult_t CASelectNetwork(const uint32_t interestedNetwork)
+CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
 {
     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
 
-    if (!(interestedNetwork & 0xf))
+    if(!g_isInitialized)
     {
-        return CA_NOT_SUPPORTED;
+        return CA_STATUS_NOT_INITIALIZED;
     }
 
     CAResult_t res = CA_STATUS_OK;
 
-    if (interestedNetwork & CA_IPV4)
+    if (interestedNetwork & CA_ADAPTER_IP)
     {
-        res = CAAddNetworkType(CA_IPV4);
-        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IPV4) function returns error : %d", res);
+        res = CAAddNetworkType(CA_ADAPTER_IP);
+        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
     }
-
-    if (interestedNetwork & CA_EDR)
+    else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
     {
-        res = CAAddNetworkType(CA_EDR);
-        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_EDR) function returns error : %d", res);
+        res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
+        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
     }
-
-    if (interestedNetwork & CA_LE)
+    else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
     {
-        res = CAAddNetworkType(CA_LE);
-        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_LE) function returns error : %d", res);
+        res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
+        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
     }
 
+    #ifdef RA_ADAPTER
+    else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+    {
+        res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+        OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
+                                                                    res);
+    }
+    #endif
+    else
+    {
+        res = CA_NOT_SUPPORTED;
+    }
     return res;
 }
 
-CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork)
+CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
 {
     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
 
-    if (!(nonInterestedNetwork & 0xf))
+    if(!g_isInitialized)
     {
-        return CA_NOT_SUPPORTED;
+        return CA_STATUS_NOT_INITIALIZED;
     }
 
     CAResult_t res = CA_STATUS_OK;
 
-    if (nonInterestedNetwork & CA_IPV4)
+    if (nonInterestedNetwork & CA_ADAPTER_IP)
     {
-        res = CARemoveNetworkType(CA_IPV4);
-        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IPV4) function returns error : %d", res);
+        res = CARemoveNetworkType(CA_ADAPTER_IP);
+        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
     }
-
-    if (nonInterestedNetwork & CA_EDR)
+    else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
     {
-        res = CARemoveNetworkType(CA_EDR);
-        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_EDR) function returns error : %d", res);
+        res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
+        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
     }
-
-    if (nonInterestedNetwork & CA_LE)
+    else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
     {
-        res = CARemoveNetworkType(CA_LE);
-        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_LE) function returns error : %d", res);
+        res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
+        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
+    }
+    #ifdef RA_ADAPTER
+    else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+    {
+        res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+        OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
+                                                res);
+    }
+    #endif
+    else
+    {
+        res = CA_STATUS_FAILED;
     }
-
     return res;
 }
 
 CAResult_t CAHandleRequestResponse()
 {
-    OIC_LOG(DEBUG, TAG, "CAHandleRequestResponse");
+    if (!g_isInitialized)
+    {
+        OIC_LOG(ERROR, TAG, "not initialized");
+        return CA_STATUS_NOT_INITIALIZED;
+    }
 
     CAHandleRequestResponseCallbacks();
 
     return CA_STATUS_OK;
 }
 
+#ifdef __WITH_DTLS__
+
+CAResult_t CASelectCipherSuite(const uint16_t cipher)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
+
+    return CADtlsSelectCipherSuite(cipher);
+}
+
+CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
+{
+    OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
+
+    return CADtlsEnableAnonECDHCipherSuite(enable);
+}
+
+CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
+                    const uint8_t* label, const size_t labelLen,
+                    const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
+                    const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
+                    uint8_t* ownerPSK, const size_t ownerPSKSize)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
+
+    CAResult_t res = CA_STATUS_OK;
+
+    //newOwnerLabel and prevOwnerLabe can be NULL
+    if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
+                                  rsrcServerDeviceID, rsrcServerDeviceIDLen,
+                                  provServerDeviceID, provServerDeviceIDLen,
+                                  ownerPSK, ownerPSKSize);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
+
+    return res;
+}
+
+CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
+    CAResult_t res = CA_STATUS_OK;
+
+    if (!endpoint)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    res = CADtlsInitiateHandshake(endpoint);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
+
+    return res;
+}
+
+CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
+    CAResult_t res = CA_STATUS_OK;
+
+    if (!endpoint)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    res = CADtlsClose(endpoint);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
+
+    return res;
+}
 
+#endif /* __WITH_DTLS__ */
diff --git a/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c b/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c
deleted file mode 100644 (file)
index 8d25223..0000000
+++ /dev/null
@@ -1,245 +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.
- *
- ******************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include "cainterface.h"
-#include "caremotehandler.h"
-#include "caprotocolmessage.h"
-#include "canetworkconfigurator.h"
-#include "logger.h"
-
-#include "cainterfacecontroller_singlethread.h"
-#include "camessagehandler_singlethread.h"
-
-#define TAG "CM_ST"
-
-CAResult_t CAInitialize()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    return CAInitializeMessageHandler();
-}
-
-void CATerminate()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    CASetRequestResponseCallbacks(NULL, NULL);
-    CATerminateMessageHandler();
-
-    CATerminateNetworkType();
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAStartListeningServer()
-{
-    return CAStartListeningServerAdapters();
-}
-
-CAResult_t CAStartDiscoveryServer()
-{
-    return CAStartDiscoveryServerAdapters();
-}
-
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    CASetRequestResponseCallbacks(ReqHandler, RespHandler);
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, const CATransportType_t transportType,
-                                  CARemoteEndpoint_t **remoteEndpoint)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CARemoteEndpoint_t *remote = CACreateRemoteEndpointUriInternal(uri, transportType);
-
-    if (remote == NULL)
-    {
-        OIC_LOG(ERROR, TAG, "remote endpoint is NULL");
-        return CA_STATUS_FAILED;
-    }
-
-    *remoteEndpoint = remote;
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CADestroyRemoteEndpoint(CARemoteEndpoint_t *rep)
-{
-    CADestroyRemoteEndpointInternal(rep);
-}
-
-CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
-{
-    return CAGenerateTokenInternal(token, tokenLength);
-}
-
-void CADestroyToken(CAToken_t token)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    CADestroyTokenInternal(token);
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    return CAGetNetworkInformationInternal(info, size);
-}
-
-CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    return CADetachMessageResourceUri(resourceUri, token, tokenLength, NULL, 0);
-}
-
-CAResult_t CASendRequest(const CARemoteEndpoint_t *object,const CARequestInfo_t *requestInfo)
-{
-    return CADetachRequestMessage(object, requestInfo);
-}
-
-CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
-                              const CARequestInfo_t *requestInfo)
-{
-    OIC_LOG(DEBUG, TAG, "CASendRequestToAll");
-
-    return CADetachRequestToAllMessage(object, requestInfo);
-}
-
-CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
-    const CAResponseInfo_t *responseInfo)
-{
-    return CADetachResponseMessage(object, responseInfo);
-}
-
-CAResult_t CASendResponse(const CARemoteEndpoint_t *object,
-    const CAResponseInfo_t *responseInfo)
-{
-    return CADetachResponseMessage(object, responseInfo);
-}
-
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token,
-                               uint8_t tokenLength, const CAHeaderOption_t *options,
-                               const uint8_t numOptions)
-{
-    return CADetachMessageResourceUri(resourceUri, token, tokenLength, options, numOptions);
-}
-
-CAResult_t CASelectNetwork(const uint32_t interestedNetwork)
-{
-    OIC_LOG_V(DEBUG, TAG, "Selected n/W=%d", interestedNetwork);
-
-    if (!(interestedNetwork & 0xf))
-    {
-        OIC_LOG(ERROR, TAG, "not supported");
-        return CA_NOT_SUPPORTED;
-    }
-    CAResult_t res = CA_STATUS_OK;
-
-    if (interestedNetwork & CA_IPV4)
-    {
-        res = CAAddNetworkType(CA_IPV4);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to Add n/w type");
-            return res;
-        }
-    }
-
-    if (interestedNetwork & CA_EDR)
-    {
-        res = CAAddNetworkType(CA_EDR);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to Add n/w type");
-            return res;
-        }
-    }
-
-    if (interestedNetwork & CA_LE)
-    {
-        res = CAAddNetworkType(CA_LE);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to Add n/w type");
-            return res;
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return res;
-}
-
-CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork)
-{
-    OIC_LOG_V(DEBUG, TAG, "unselected n/w=%d", nonInterestedNetwork);
-
-    if (!(nonInterestedNetwork & 0xf))
-    {
-        OIC_LOG(ERROR, TAG, "not supported");
-        return CA_NOT_SUPPORTED;
-    }
-
-    CAResult_t res = CA_STATUS_OK;
-
-    if (nonInterestedNetwork & CA_IPV4)
-    {
-        res = CARemoveNetworkType(CA_IPV4);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to remove n/w type");
-            return res;
-        }
-    }
-
-    if (nonInterestedNetwork & CA_EDR)
-    {
-        res = CARemoveNetworkType(CA_EDR);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to remove n/w type");
-            return res;
-        }
-    }
-
-    if (nonInterestedNetwork & CA_LE)
-    {
-        res = CARemoveNetworkType(CA_LE);
-        if (res != CA_STATUS_OK)
-        {
-            OIC_LOG(ERROR, TAG, "Failed to remove n/w type");
-            return res;
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return res;
-}
-
-CAResult_t CAHandleRequestResponse()
-{
-    CAHandleRequestResponseCallbacks();
-    return CA_STATUS_OK;
-}
-
-
index 2abc0a8..6c4a81f 100644 (file)
 #include <string.h>
 #include <inttypes.h>
 
+#include "logger.h"
+#include "oic_malloc.h"
+#include "caadapterutils.h"
+#include "canetworkconfigurator.h"
 #include "cainterfacecontroller.h"
-#include "caipadapter.h"
 #include "caedradapter.h"
 #include "caleadapter.h"
-#include "canetworkconfigurator.h"
 #include "caremotehandler.h"
-#include "oic_malloc.h"
-#include "logger.h"
 #include "cathreadpool.h"
+#include "caipadapter.h"
+#include "cainterface.h"
+
+#ifdef RA_ADAPTER
+#include "caraadapter.h"
+#endif
+
+#define TAG "CA_INTRFC_CNTRLR"
+#ifdef RA_ADAPTER
+#include "caraadapter.h"
+#endif
 
-#define TAG PCF("CA")
 
 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
     {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
 
+#ifdef RA_ADAPTER
 #define CA_TRANSPORT_TYPE_NUM   4
+#else
+#define CA_TRANSPORT_TYPE_NUM   3
+#endif
 
-static CAConnectivityHandler_t g_adapterHandler[CA_TRANSPORT_TYPE_NUM];
+static CAConnectivityHandler_t g_adapterHandler[CA_TRANSPORT_TYPE_NUM] = {};
 
 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
 
 static CANetworkChangeCallback g_networkChangeCallback = NULL;
 
-static int CAGetAdapterIndex(CATransportType_t cType)
+static CAErrorHandleCallback g_errorHandleCallback = NULL;
+
+static int CAGetAdapterIndex(CATransportAdapter_t cType)
 {
     switch (cType)
     {
-        case CA_IPV4:
+        case CA_ADAPTER_IP:
             return 0;
-        case CA_IPV6:
+        case CA_ADAPTER_GATT_BTLE:
             return 1;
-        case CA_EDR:
+        case CA_ADAPTER_RFCOMM_BTEDR:
             return 2;
-        case CA_LE:
-            return 3;
-    }
 
-    OIC_LOG(DEBUG, TAG, "CA_TRANSPORT_TYPE_NUM is not 4");
+        #ifdef RA_ADAPTER
+        case CA_ADAPTER_REMOTE_ACCESS:
+            return 3;
+        #endif
 
+        default:
+            break;
+    }
     return -1;
 }
 
-static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportType_t cType)
+static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportAdapter_t cType)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterCallback - Entry");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     if(handler.startAdapter == NULL ||
         handler.startListenServer == NULL ||
@@ -91,15 +110,22 @@ static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportType_
         return;
     }
 
-    memcpy(&g_adapterHandler[index], &handler, sizeof(CAConnectivityHandler_t));
+    g_adapterHandler[index] = handler;
 
     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", cType);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+#ifdef RA_ADAPTER
+CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
+{
+    return CASetRAInfo(caraInfo);
 }
+#endif
 
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
-                                     uint32_t dataLen)
+static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, uint32_t dataLen)
 {
-    OIC_LOG(DEBUG, TAG, "receivedPacketCallback in interface controller");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     // Call the callback.
     if (g_networkPacketReceivedCallback != NULL)
@@ -108,25 +134,38 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
     }
     else
     {
-        OICFree(endpoint);
-        endpoint = NULL;
         OICFree(data);
-        data = NULL;
 
         OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static void CANetworkChangedCallback(CALocalConnectivity_t *info,
-                                     CANetworkStatus_t status)
+static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
 {
-    OIC_LOG(DEBUG, TAG, "Network Changed callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     // Call the callback.
     if (g_networkChangeCallback != NULL)
     {
         g_networkChangeCallback(info, status);
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
+                                         const void *data, uint32_t dataLen,
+                                         CAResult_t result)
+{
+    OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
+
+    // Call the callback.
+    if (g_errorHandleCallback != NULL)
+    {
+        g_errorHandleCallback(endpoint, data, dataLen, result);
+    }
 }
 
 void CAInitializeAdapters(ca_thread_pool_t handle)
@@ -138,36 +177,52 @@ void CAInitializeAdapters(ca_thread_pool_t handle)
     // Initialize adapters and register callback.
 #ifdef IP_ADAPTER
     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
-                         handle);
+                   CAAdapterErrorHandleCallback, handle);
 #endif /* IP_ADAPTER */
 
 #ifdef EDR_ADAPTER
     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
-                    handle);
+                    CAAdapterErrorHandleCallback, handle);
 #endif /* EDR_ADAPTER */
 
 #ifdef LE_ADAPTER
     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
-                   handle);
+                   CAAdapterErrorHandleCallback, handle);
 #endif /* LE_ADAPTER */
 
+#ifdef RA_ADAPTER
+    CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
+                   handle);
+#endif /* RA_ADAPTER */
+
+
 }
 
 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
 {
-    OIC_LOG(DEBUG, TAG, "Set packet received callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     g_networkPacketReceivedCallback = callback;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
 {
-    OIC_LOG(DEBUG, TAG, "Set network change callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     g_networkChangeCallback = callback;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
+{
+    OIC_LOG(DEBUG, TAG, "Set error handle callback");
+    g_errorHandleCallback = errorCallback;
 }
 
-CAResult_t CAStartAdapter(CATransportType_t transportType)
+CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
 {
     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
 
@@ -187,7 +242,7 @@ CAResult_t CAStartAdapter(CATransportType_t transportType)
     return CA_STATUS_OK;
 }
 
-void CAStopAdapter(CATransportType_t transportType)
+void CAStopAdapter(CATransportAdapter_t transportType)
 {
     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
 
@@ -205,14 +260,14 @@ void CAStopAdapter(CATransportType_t transportType)
     }
 }
 
-CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
 {
     if (info == NULL || size == NULL)
     {
         return CA_STATUS_INVALID_PARAM;
     }
 
-    CALocalConnectivity_t *tempInfo[CA_TRANSPORT_TYPE_NUM] = { 0 };
+    CAEndpoint_t *tempInfo[CA_TRANSPORT_TYPE_NUM] = { 0 };
     uint32_t tempSize[CA_TRANSPORT_TYPE_NUM] = { 0 };
 
     CAResult_t res = CA_STATUS_FAILED;
@@ -253,8 +308,7 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
 
     // #3. add data into result
     // memory allocation
-
-    CALocalConnectivity_t * resInfo = OICCalloc(resSize, sizeof(*resInfo));
+    CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
     CA_MEMORY_ALLOC_CHECK(resInfo);
 
     // #4. save data
@@ -296,9 +350,9 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length)
+CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
 {
-    OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface..");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     CAResult_t res = CA_STATUS_FAILED;
 
@@ -308,7 +362,7 @@ CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *dat
         return CA_STATUS_INVALID_PARAM;
     }
 
-    CATransportType_t type = endpoint->transportType;
+    CATransportAdapter_t type = endpoint->adapter;
 
     int index = CAGetAdapterIndex(type);
 
@@ -329,20 +383,22 @@ CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *dat
     {
         res = CA_STATUS_OK;
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
     return res;
 }
 
-CAResult_t CASendMulticastData(const void *data, uint32_t length)
+CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
 {
-    OIC_LOG(DEBUG, TAG, "Send multicast data to enabled interface..");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    CAResult_t res = CA_STATUS_FAILED;
+    CAResult_t res = CA_SEND_FAILED;
     u_arraylist_t *list = CAGetSelectedNetworkList();
 
     if (!list)
     {
         OIC_LOG(DEBUG, TAG, "No selected network");
-        return CA_STATUS_FAILED;
+        return CA_SEND_FAILED;
     }
 
     int i = 0;
@@ -355,7 +411,7 @@ CAResult_t CASendMulticastData(const void *data, uint32_t length)
             continue;
         }
 
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
+        CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
 
         int index = CAGetAdapterIndex(connType);
 
@@ -376,7 +432,7 @@ CAResult_t CASendMulticastData(const void *data, uint32_t length)
                 return CA_MEMORY_ALLOC_FAILED;
             }
             memcpy(payload, data, length);
-            sentDataLen = g_adapterHandler[index].sendDataToAll(payload, length);
+            sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
             OICFree(payload);
         }
 
@@ -390,12 +446,14 @@ CAResult_t CASendMulticastData(const void *data, uint32_t length)
         }
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT");
+
     return res;
 }
 
 CAResult_t CAStartListeningServerAdapters()
 {
-    OIC_LOG(DEBUG, TAG, "Start listening server from adapters..");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     u_arraylist_t *list = CAGetSelectedNetworkList();
     if (!list)
@@ -414,7 +472,7 @@ CAResult_t CAStartListeningServerAdapters()
             continue;
         }
 
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
+        CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
 
         int index = CAGetAdapterIndex(connType);
         if (index == -1)
@@ -429,12 +487,13 @@ CAResult_t CAStartListeningServerAdapters()
         }
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAStartDiscoveryServerAdapters()
 {
-    OIC_LOG(DEBUG, TAG, "Start discovery server from adapters..");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     u_arraylist_t *list = CAGetSelectedNetworkList();
 
@@ -454,7 +513,7 @@ CAResult_t CAStartDiscoveryServerAdapters()
             continue;
         }
 
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
+        CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
 
         int index = CAGetAdapterIndex(connType);
 
@@ -470,12 +529,13 @@ CAResult_t CAStartDiscoveryServerAdapters()
         }
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CATerminateAdapters()
 {
-    OIC_LOG(DEBUG, TAG, "terminate all adapters..");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     uint32_t index;
     for (index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
@@ -485,4 +545,49 @@ void CATerminateAdapters()
             g_adapterHandler[index].terminate();
         }
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
+
+#ifdef SINGLE_THREAD
+CAResult_t CAReadData()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    u_arraylist_t *list = CAGetSelectedNetworkList();
+
+    if (!list)
+    {
+        return CA_STATUS_FAILED;
+    }
+
+    uint8_t i = 0;
+    for (i = 0; i < u_arraylist_length(list); i++)
+    {
+        void *ptrType = u_arraylist_get(list, i);
+        if (NULL == ptrType)
+        {
+            OIC_LOG(ERROR, TAG, "get list fail");
+            return CA_STATUS_FAILED;
+        }
+
+        CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
+
+        int index = CAGetAdapterIndex(connType);
+
+        if (-1 == index)
+        {
+            OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
+            continue;
+        }
+
+        if (g_adapterHandler[index].readData != NULL)
+        {
+            g_adapterHandler[index].readData();
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+#endif
+
diff --git a/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c b/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c
deleted file mode 100644 (file)
index 169ee7e..0000000
+++ /dev/null
@@ -1,512 +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.
- *
- ******************************************************************/
-
-#include "cainterfacecontroller_singlethread.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "caipadapter_singlethread.h"
-#include "caedradapter_singlethread.h"
-#include "caleadapter_singlethread.h"
-#include "caadapterutils.h"
-
-#include "canetworkconfigurator.h"
-#include "oic_malloc.h"
-#include "logger.h"
-
-#define TAG "CAIFCNT_ST"
-
-#define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG(ERROR, TAG, "Out of memory");\
-    goto memory_error_exit;} }
-
-#define CA_CONNECTIVITY_TYPE_NUM   4
-
-static CAConnectivityHandler_t g_adapterHandler[CA_CONNECTIVITY_TYPE_NUM];
-
-static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
-
-static CANetworkChangeCallback g_networkChangeCallback = NULL;
-
-static int CAGetAdapterIndex(CATransportType_t cType)
-{
-    switch (cType)
-    {
-        case CA_IPV4:
-            return 0;
-        case CA_IPV6:
-            return 1;
-        case CA_EDR:
-            return 2;
-        case CA_LE:
-            return 3;
-    }
-
-    OIC_LOG(DEBUG, TAG, "CA_CONNECTIVITY_TYPE_NUM is not 4");
-
-    return -1;
-}
-
-static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportType_t cType)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    if(handler.startAdapter == NULL ||
-        handler.startListenServer == NULL ||
-        handler.startDiscoveryServer == NULL ||
-        handler.sendData == NULL ||
-        handler.sendDataToAll == NULL ||
-        handler.GetnetInfo == NULL ||
-        handler.readData == NULL ||
-        handler.stopAdapter == NULL ||
-        handler.terminate == NULL)
-    {
-        OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
-        return;
-    }
-
-    int index = CAGetAdapterIndex(cType);
-
-    if (index == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-        return;
-    }
-
-    memcpy(&g_adapterHandler[index], &handler, sizeof(CAConnectivityHandler_t));
-
-    OIC_LOG_V(DEBUG, TAG, "%d type adapter", cType);
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
-    uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    // Call the callback.
-    if (g_networkPacketReceivedCallback != NULL)
-    {
-        g_networkPacketReceivedCallback(endpoint, data, dataLen);
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    // Call the callback.
-    if (g_networkChangeCallback != NULL)
-    {
-        g_networkChangeCallback(info, status);
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CAInitializeAdapters()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    memset(g_adapterHandler, 0, sizeof(CAConnectivityHandler_t) * CA_CONNECTIVITY_TYPE_NUM);
-
-    // Initialize adapters and register callback.
-#ifdef IP_ADAPTER
-    CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
-#endif /* IP_ADAPTER */
-
-#ifdef EDR_ADAPTER
-    CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
-#endif /* EDR_ADAPTER */
-
-#ifdef LE_ADAPTER
-    CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
-#endif /* LE_ADAPTER */
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    g_networkPacketReceivedCallback = callback;
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    g_networkChangeCallback = callback;
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAStartAdapter(CATransportType_t transportType)
-{
-    OIC_LOG_V(DEBUG, TAG, "transportType[%d]", transportType);
-
-    int index = CAGetAdapterIndex(transportType);
-
-    if (index == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-        return CA_STATUS_FAILED;
-    }
-
-    if (g_adapterHandler[index].startAdapter != NULL)
-    {
-        g_adapterHandler[index].startAdapter();
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAStopAdapter(CATransportType_t transportType)
-{
-    OIC_LOG_V(DEBUG, TAG, "transportType[%d]", transportType);
-
-    int index = CAGetAdapterIndex(transportType);
-
-    if (index == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-        return;
-    }
-
-    if (g_adapterHandler[index].stopAdapter != NULL)
-    {
-        g_adapterHandler[index].stopAdapter();
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(info, TAG, "info");
-    VERIFY_NON_NULL(size, TAG, "size");
-
-    CALocalConnectivity_t *tempInfo[CA_CONNECTIVITY_TYPE_NUM] = { 0 };
-    uint32_t tempSize[CA_CONNECTIVITY_TYPE_NUM] = { 0 };
-
-    CAResult_t res = CA_STATUS_FAILED;
-    // #1. get information each adapter
-    for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
-    {
-        if (g_adapterHandler[index].GetnetInfo != NULL)
-        {
-            res = g_adapterHandler[index].GetnetInfo(&tempInfo[index], &tempSize[index]);
-
-            OIC_LOG_V (DEBUG, TAG, "%d adapter network info size is %d", index, tempSize[index]);
-        }
-    }
-
-    uint32_t resSize = 0;
-    for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
-    {
-        // check information
-        if (tempInfo[index] == NULL || tempSize[index] <= 0)
-        {
-            continue;
-        }
-
-        // #2. total size
-        resSize += tempSize[index];
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
-
-    if (resSize <= 0)
-    {
-        if (CA_ADAPTER_NOT_ENABLED == res || CA_NOT_SUPPORTED == res)
-        {
-            return res;
-        }
-        return CA_STATUS_FAILED;
-    }
-
-    // #3. add data into result
-    // memory allocation
-    CALocalConnectivity_t *resInfo =
-        (CALocalConnectivity_t *) OICCalloc(resSize, sizeof(CALocalConnectivity_t));
-    CA_MEMORY_ALLOC_CHECK(resInfo);
-
-    uint8_t i = 0;
-    for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
-    {
-        // check information
-        if (tempInfo[index] == NULL || tempSize[index] <= 0)
-        {
-            continue;
-        }
-
-        memcpy(resInfo + i, tempInfo[index], sizeof(CALocalConnectivity_t) * tempSize[index]);
-
-        i += tempSize[index];
-
-        // free adapter data
-        OICFree(tempInfo[index]);
-    }
-
-    // #5. save data
-    *info = resInfo;
-    *size = resSize;
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-
-    return res;
-
-    // memory error label.
-memory_error_exit:
-
-    for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
-    {
-
-        OICFree(tempInfo[index]);
-    }
-
-    return CA_MEMORY_ALLOC_FAILED;
-}
-
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAResult_t res = CA_STATUS_FAILED;
-
-    if (endpoint == NULL)
-    {
-        OIC_LOG(DEBUG, TAG, "RemoteEndpoint is NULL");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    CATransportType_t type = endpoint->transportType;
-
-    int index = CAGetAdapterIndex(type);
-
-    if (index == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    uint32_t sentDataLen = 0;
-    if (g_adapterHandler[index].sendData != NULL)
-    {
-        sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
-    }
-
-    if (sentDataLen == length)
-    {
-        res = CA_STATUS_OK;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return res;
-}
-
-CAResult_t CASendMulticastData(const void *data, uint32_t length)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAResult_t res = CA_STATUS_FAILED;
-    u_arraylist_t *list = CAGetSelectedNetworkList();
-
-    if (!list)
-    {
-        OIC_LOG(DEBUG, TAG, "No selected network");
-        return res;
-    }
-
-    for (uint8_t i = 0; i < u_arraylist_length(list); i++)
-    {
-        void* ptrType = u_arraylist_get(list, i);
-        if (NULL == ptrType)
-        {
-            continue;
-        }
-
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
-
-        int index = CAGetAdapterIndex(connType);
-
-        if (index == -1)
-        {
-            OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-            continue;
-        }
-
-        uint32_t sentDataLen = 0;
-        if (g_adapterHandler[index].sendDataToAll != NULL)
-        {
-            sentDataLen = g_adapterHandler[index].sendDataToAll(data, length);
-        }
-
-        if (sentDataLen == length)
-        {
-            res = CA_STATUS_OK;
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return res;
-}
-
-CAResult_t CAStartListeningServerAdapters()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    u_arraylist_t *list = CAGetSelectedNetworkList();
-
-    if (!list)
-    {
-        OIC_LOG(DEBUG, TAG, "No selected network");
-        return CA_STATUS_FAILED;
-    }
-
-    for (uint8_t i = 0; i < u_arraylist_length(list); i++)
-    {
-        void* ptrType = u_arraylist_get(list, i);
-        if (NULL == ptrType)
-        {
-            OIC_LOG(ERROR, TAG, "Invalid conn type");
-            continue;
-        }
-
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
-
-        int index = CAGetAdapterIndex(connType);
-
-        if (index == -1)
-        {
-            OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-            continue;
-        }
-
-        if (g_adapterHandler[index].startListenServer != NULL)
-        {
-            g_adapterHandler[index].startListenServer();
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartDiscoveryServerAdapters()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    u_arraylist_t *list = CAGetSelectedNetworkList();
-
-    if (!list)
-    {
-        OIC_LOG(DEBUG, TAG, "No selected network");
-        return CA_STATUS_FAILED;
-    }
-
-    for (uint8_t i = 0; i < u_arraylist_length(list); i++)
-    {
-        void* ptrType = u_arraylist_get(list, i);
-        if (NULL == ptrType)
-        {
-            continue;
-        }
-
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
-
-        int index = CAGetAdapterIndex(connType);
-
-        if (index == -1)
-        {
-            OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-            continue;
-        }
-
-        if (g_adapterHandler[index].startDiscoveryServer != NULL)
-        {
-            g_adapterHandler[index].startDiscoveryServer();
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CATerminateAdapters()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    uint8_t index;
-
-    for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
-    {
-        if (g_adapterHandler[index].stopAdapter != NULL)
-        {
-            g_adapterHandler[index].stopAdapter();
-        }
-        if (g_adapterHandler[index].terminate != NULL)
-        {
-            g_adapterHandler[index].terminate();
-        }
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAReadData()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    u_arraylist_t *list = CAGetSelectedNetworkList();
-
-    if (!list)
-    {
-        return CA_STATUS_FAILED;
-    }
-
-    for (uint8_t i = 0; i < u_arraylist_length(list); i++)
-    {
-        void *ptrType = u_arraylist_get(list, i);
-        if (NULL == ptrType)
-        {
-            OIC_LOG(ERROR, TAG, "get list fail");
-            return CA_STATUS_FAILED;
-        }
-
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
-
-        int index = CAGetAdapterIndex(connType);
-
-        if (-1 == index)
-        {
-            OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
-            continue;
-        }
-
-        if (g_adapterHandler[index].readData != NULL)
-        {
-            g_adapterHandler[index].readData();
-        }
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
index 635289c..9695e2f 100644 (file)
 #include "caqueueingthread.h"
 #include "camutex.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "canetworkconfigurator.h"
 
-#define TAG PCF("CA")
+#define TAG PCF("CA_MSG_HNDLR")
 #define SINGLE_HANDLE
 
 #define MAX_THREAD_POOL_SIZE    20
@@ -49,13 +50,22 @@ typedef enum
     SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST
 } CASendDataType_t;
 
+typedef enum
+{
+    CA_REQUEST_DATA = 1,
+    CA_RESPONSE_DATA = 2,
+    CA_ERROR_DATA = 3,
+} CADataType_t;
+
 typedef struct
 {
     CASendDataType_t type;
-    CARemoteEndpoint_t *remoteEndpoint;
+    CAEndpoint_t *remoteEndpoint;
     CARequestInfo_t *requestInfo;
     CAResponseInfo_t *responseInfo;
+    CAErrorInfo_t *errorInfo;
     CAHeaderOption_t *options;
+    CADataType_t dataType;
     uint8_t numOptions;
 } CAData_t;
 
@@ -71,6 +81,11 @@ static CARetransmission_t g_retransmissionContext;
 // handler field
 static CARequestCallback g_requestHandler = NULL;
 static CAResponseCallback g_responseHandler = NULL;
+static CAErrorCallback g_errorHandler = NULL;
+
+static void CAErrorHandler(const CAEndpoint_t *endpoint,
+                           const void *data, uint32_t dataLen,
+                           CAResult_t result);
 
 static bool CAIsSelectedNetworkAvailable()
 {
@@ -84,25 +99,25 @@ static bool CAIsSelectedNetworkAvailable()
     return true;
 }
 
-static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size)
+static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
 
-    CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint);
+    CAEndpoint_t* ep = CACloneEndpoint(endpoint);
     if (NULL == ep)
     {
         OIC_LOG(ERROR, TAG, "clone failed");
         return;
     }
 
-    CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
+    CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
 
     if (NULL == resInfo)
     {
         OIC_LOG(ERROR, TAG, "calloc failed");
-        CADestroyRemoteEndpointInternal(ep);
+        CAFreeEndpoint(ep);
         return;
     }
 
@@ -115,7 +130,7 @@ static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pd
         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
         OICFree(resInfo->info.token);
         OICFree(resInfo);
-        CADestroyRemoteEndpointInternal(ep);
+        CAFreeEndpoint(ep);
         return;
     }
 
@@ -123,7 +138,7 @@ static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pd
     if (NULL == cadata)
     {
         OIC_LOG(ERROR, TAG, "memory allocation failed !");
-        CADestroyRemoteEndpointInternal(ep);
+        CAFreeEndpoint(ep);
         OICFree(resInfo);
         return;
     }
@@ -150,7 +165,7 @@ static void CADataDestroyer(void *data, uint32_t size)
 
     if (NULL != cadata->remoteEndpoint)
     {
-        CADestroyRemoteEndpointInternal((CARemoteEndpoint_t *) cadata->remoteEndpoint);
+        CAFreeEndpoint(cadata->remoteEndpoint);
     }
 
     if (NULL != cadata->requestInfo)
@@ -163,7 +178,16 @@ static void CADataDestroyer(void *data, uint32_t size)
         CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo);
     }
 
-    OICFree(cadata->options);
+    if (NULL != cadata->errorInfo)
+    {
+       CAInfo_t *info = &cadata->errorInfo->info;
+       OICFree(info->token);
+       OICFree(info->options);
+       OICFree(info->payload);
+       OICFree(info->resourceUri);
+       OICFree(cadata->errorInfo);
+    }
+
     OICFree(cadata);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -185,7 +209,7 @@ static void CAReceiveThreadProcess(void *threadData)
     // parse the data and call the callbacks.
     // #1 parse the data
     // #2 get endpoint
-    CARemoteEndpoint_t *rep = (CARemoteEndpoint_t *)(data->remoteEndpoint);
+    CAEndpoint_t *rep = (CAEndpoint_t *)(data->remoteEndpoint);
 
     if (NULL == rep)
     {
@@ -193,22 +217,20 @@ static void CAReceiveThreadProcess(void *threadData)
         return;
     }
 
-    if (NULL != data->requestInfo)
+    if (data->requestInfo && g_requestHandler)
     {
-        if (g_requestHandler)
-        {
-            g_requestHandler(rep, data->requestInfo);
-        }
+        g_requestHandler(rep, data->requestInfo);
     }
-
-    if (NULL != data->responseInfo)
+    else if (data->responseInfo && g_responseHandler)
     {
-        if (g_responseHandler)
-        {
-            g_responseHandler(rep, data->responseInfo);
-        }
+        g_responseHandler(rep, data->responseInfo);
     }
-#endif
+    else if (data->errorInfo && g_errorHandler)
+    {
+        g_errorHandler(rep, data->errorInfo);
+    }
+
+#endif /* SINGLE_HANDLE */
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -224,29 +246,28 @@ static void CASendThreadProcess(void *threadData)
 
     CASendDataType_t type = data->type;
 
+    coap_pdu_t *pdu = NULL;
+
     if (SEND_TYPE_UNICAST == type)
     {
-        coap_pdu_t *pdu = NULL;
 
+        OIC_LOG(DEBUG,TAG,"Unicast message");
         if (NULL != data->requestInfo)
         {
             OIC_LOG(DEBUG, TAG, "requestInfo is available..");
 
-            pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
-                                               data->requestInfo->method,
-                                               data->requestInfo->info);
+            pdu = CAGeneratePDU(data->requestInfo->method, &data->requestInfo->info);
         }
         else if (NULL != data->responseInfo)
         {
             OIC_LOG(DEBUG, TAG, "responseInfo is available..");
 
-            pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
-                                               data->responseInfo->result,
-                                               data->responseInfo->info);
+            pdu = CAGeneratePDU(data->responseInfo->result, &data->responseInfo->info);
         }
         else
         {
             OIC_LOG(DEBUG, TAG, "request info, response info is empty");
+            return;
         }
 
         // interface controller function call.
@@ -273,39 +294,93 @@ static void CASendThreadProcess(void *threadData)
 
             coap_delete_pdu(pdu);
         }
+        else
+        {
+            OIC_LOG_V(ERROR,TAG,"Failed to generate unicast PDU");
+            return;
+        }
     }
     else if (SEND_TYPE_MULTICAST == type)
     {
-        OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available");
-
-        CAInfo_t info = data->requestInfo->info;
+        OIC_LOG(DEBUG,TAG,"Multicast message");
+        if (NULL != data->requestInfo)
+        {
+            OIC_LOG(DEBUG, TAG, "requestInfo is available..");
+            CAInfo_t *info = &data->requestInfo->info;
 
-        info.options = data->options;
-        info.numOptions = data->numOptions;
+            info->options = data->options;
+            info->numOptions = data->numOptions;
 
-        coap_pdu_t *pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, CA_GET,
-                                                       info);
+            pdu = CAGeneratePDU(CA_GET, info);
+            if (NULL != pdu)
+            {
+                CALogPDUInfo(pdu);
 
-        if (NULL != pdu)
-        {
-            CALogPDUInfo(pdu);
+                res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+                if (CA_STATUS_OK != res)
+                {
+                    OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+                    coap_delete_pdu(pdu);
+                    return;
+                }
 
-            res = CASendMulticastData(pdu->hdr, pdu->length);
-            if(CA_STATUS_OK != res)
-            {
-                OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
                 coap_delete_pdu(pdu);
-                return;
             }
-
-            coap_delete_pdu(pdu);
+            else
+            {
+                OIC_LOG_V(ERROR,TAG,"Failed to generate multicast PDU");
+            }
+        }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "request info is empty");
         }
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
+/*
+ * If a second message arrives with the same token and the other address
+ * family, drop it.  Typically, IPv6 beats IPv4, so the IPv4 message is dropped.
+ * This can be made more robust (for instance, another message could arrive
+ * in between), but it is good enough for now.
+ */
+static bool CADropSecondRequest(const CAEndpoint_t *endpoint, uint16_t messageId)
+{
+    if (!endpoint)
+    {
+        return true;
+    }
+    if (endpoint->adapter != CA_ADAPTER_IP)
+    {
+        return false;
+    }
+
+    bool ret = false;
+    CATransportFlags_t familyFlags = endpoint->flags & CA_IPFAMILY_MASK;
+
+    if (messageId == caglobals.ca.previousRequestMessageId)
+    {
+        if ((familyFlags ^ caglobals.ca.previousRequestFlags) == CA_IPFAMILY_MASK)
+        {
+            if (familyFlags & CA_IPV6)
+            {
+                OIC_LOG(INFO, TAG, PCF("IPv6 duplicate response ignored"));
+            }
+            else
+            {
+                OIC_LOG(INFO, TAG, PCF("IPv4 duplicate response ignored"));
+            }
+            ret = true;
+        }
+    }
+    caglobals.ca.previousRequestFlags = familyFlags;
+    caglobals.ca.previousRequestMessageId = messageId;
+    return ret;
+}
+
+static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
@@ -318,13 +393,9 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     if (NULL == pdu)
     {
         OIC_LOG(ERROR, TAG, "Parse PDU failed");
-        CAAdapterFreeRemoteEndpoint(endpoint);
         return;
     }
 
-    char uri[CA_MAX_URI_LENGTH] = { 0, };
-    uint32_t bufLen = sizeof(uri);
-
     if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
     {
         CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
@@ -332,17 +403,22 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
             return;
         }
 
-        CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo, uri, bufLen);
+        CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res);
             OICFree(ReqInfo);
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
+            return;
+        }
+
+        if (CADropSecondRequest(endpoint, ReqInfo->info.messageId))
+        {
+            OICFree(ReqInfo);
+            coap_delete_pdu(pdu);
             return;
         }
 
@@ -357,10 +433,6 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
             }
         }
 
-        if (NULL != ReqInfo->info.payload)
-        {
-            OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
-        }
         OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
         if (NULL != ReqInfo->info.token)
         {
@@ -369,39 +441,20 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
                            ReqInfo->info.tokenLength);
         }
 
-        OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
-        OIC_LOG(DEBUG, TAG, "Request- token");
-        OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN);
         OIC_LOG_V(DEBUG, TAG, "Request- msgID : %d", ReqInfo->info.messageId);
-        if (NULL != endpoint)
-        {
-            endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
-            if (NULL == endpoint->resourceUri)
-            {
-                OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
-                OICFree(ReqInfo);
-                coap_delete_pdu(pdu);
-                CAAdapterFreeRemoteEndpoint(endpoint);
-                return;
-            }
-            memcpy(endpoint->resourceUri, uri, bufLen);
-            endpoint->resourceUri[bufLen] = '\0';
-            OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
-        }
         // store the data at queue.
         CAData_t *cadata = NULL;
         cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
         if (NULL == cadata)
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
-            OICFree(ReqInfo);
+            CADestroyRequestInfoInternal(ReqInfo);
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
             return;
         }
 
         cadata->type = SEND_TYPE_UNICAST;
-        cadata->remoteEndpoint = endpoint;
+        cadata->remoteEndpoint = CACloneEndpoint(endpoint);
         cadata->requestInfo = ReqInfo;
         cadata->responseInfo = NULL;
         CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
@@ -413,17 +466,15 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
             return;
         }
 
-        CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo, uri, bufLen);
+        CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res);
             OICFree(ResInfo);
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
             return;
         }
 
@@ -440,41 +491,30 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
 
         if (NULL != ResInfo->info.payload)
         {
-            OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload);
+            OIC_LOG_V(DEBUG, TAG, "Response- payload: %p(%u) from %s", ResInfo->info.payload,
+                    ResInfo->info.payloadSize, endpoint->addr);
         }
         OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
-        OIC_LOG_V(DEBUG, TAG, "Response- token : %s", ResInfo->info.token);
-        OIC_LOG_V(DEBUG, TAG, "Response- msgID: %d", ResInfo->info.messageId);
-
-        if (NULL != endpoint)
+        if (NULL != ResInfo->info.token)
         {
-            endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
-            if (NULL == endpoint->resourceUri)
-            {
-                OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
-                OICFree(ResInfo);
-                coap_delete_pdu(pdu);
-                CAAdapterFreeRemoteEndpoint(endpoint);
-                return;
-            }
-            memcpy(endpoint->resourceUri, uri, bufLen);
-            endpoint->resourceUri[bufLen] = '\0';
-            OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
+            OIC_LOG(DEBUG, TAG, "Response- token:");
+            OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ResInfo->info.token,
+                           ResInfo->info.tokenLength);
         }
+        OIC_LOG_V(DEBUG, TAG, "Response- msgID: %d", ResInfo->info.messageId);
 
         // store the data at queue.
         CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
         if (NULL == cadata)
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
-            OICFree(ResInfo);
+            CADestroyResponseInfoInternal(ResInfo);
             coap_delete_pdu(pdu);
-            CAAdapterFreeRemoteEndpoint(endpoint);
             return;
         }
 
         cadata->type = SEND_TYPE_UNICAST;
-        cadata->remoteEndpoint = endpoint;
+        cadata->remoteEndpoint = CACloneEndpoint(endpoint);
         cadata->requestInfo = NULL;
 
         // for retransmission
@@ -506,7 +546,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
+static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -515,7 +555,6 @@ static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatu
 
 void CAHandleRequestResponseCallbacks()
 {
-    OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks IN");
 
 #ifdef SINGLE_HANDLE
     // parse the data and call the callbacks.
@@ -543,37 +582,31 @@ void CAHandleRequestResponseCallbacks()
 
     // get endpoint
     CAData_t *td = (CAData_t *) msg;
-    CARemoteEndpoint_t *rep = td->remoteEndpoint;
 
-    if (NULL == rep)
+    if (td->requestInfo && g_requestHandler)
     {
-        return;
+        OIC_LOG_V(DEBUG, TAG, "request callback : %d", td->requestInfo->info.numOptions);
+        g_requestHandler(td->remoteEndpoint, td->requestInfo);
     }
-
-    if (NULL != td->requestInfo)
+    else if (td->responseInfo && g_responseHandler)
     {
-        if (g_requestHandler)
-        {
-            OIC_LOG_V(DEBUG, TAG, "callback will be sent : %d", td->requestInfo->info.numOptions);
-            g_requestHandler(rep, td->requestInfo);
-        }
+        OIC_LOG_V(DEBUG, TAG, "response callback : %d", td->responseInfo->info.numOptions);
+        g_responseHandler(td->remoteEndpoint, td->responseInfo);
     }
-
-    if (NULL != td->responseInfo)
+    else if (td->errorInfo && g_errorHandler)
     {
-        if (g_responseHandler)
-        {
-            g_responseHandler(rep, td->responseInfo);
-        }
-
+        OIC_LOG_V(DEBUG, TAG, "error callback error: %d", td->errorInfo->result);
+        g_errorHandler(td->remoteEndpoint, td->errorInfo);
     }
+
     CADataDestroyer(msg, sizeof(CAData_t));
+    OICFree(item);
 
 #endif
     OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks OUT");
 }
 
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
+CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInfo_t *request)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -585,13 +618,13 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
         return CA_STATUS_FAILED;
     }
 
-    CARemoteEndpoint_t *remoteEndpoint = NULL;
+    CAEndpoint_t *remoteEndpoint = NULL;
     CARequestInfo_t *requestInfo = NULL;
     CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
     CA_MEMORY_ALLOC_CHECK(data);
 
     // clone remote endpoint
-    remoteEndpoint = CACloneRemoteEndpoint(object);
+    remoteEndpoint = CACloneEndpoint(object);
     CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
 
     // clone request info
@@ -599,86 +632,42 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
     CA_MEMORY_ALLOC_CHECK(requestInfo);
 
     // save data
-    data->type = SEND_TYPE_UNICAST;
+    data->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
     data->remoteEndpoint = remoteEndpoint;
     data->requestInfo = requestInfo;
     data->responseInfo = NULL;
-
-    // add thread
-    CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-
-// memory error label.
-memory_error_exit:
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
-    CADestroyRequestInfoInternal(requestInfo);
-
-    OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_MEMORY_ALLOC_FAILED;
-}
-
-CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
-                                       const CARequestInfo_t *request)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    if (NULL == object || NULL == request || NULL == object->resourceUri)
+    data->options = NULL;
+    data->numOptions = 0;
+    if (NULL != requestInfo->info.options && 0 < requestInfo->info.numOptions)
     {
-        return CA_STATUS_INVALID_PARAM;
-    }
+        uint8_t numOptions = requestInfo->info.numOptions;
+        // copy data
+        CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t)
+                                                                        * numOptions);
+        CA_MEMORY_ALLOC_CHECK(headerOption);
 
-    if ((request->method < CA_GET) || (request->method > CA_DELETE))
-    {
-        OIC_LOG(ERROR, TAG, "Invalid method type!");
+        memcpy(headerOption, requestInfo->info.options, sizeof(CAHeaderOption_t) * numOptions);
 
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    if (false == CAIsSelectedNetworkAvailable())
-    {
-        return CA_STATUS_FAILED;
+        data->options = headerOption;
+        data->numOptions = numOptions;
     }
 
-    CARemoteEndpoint_t *remoteEndpoint = NULL;
-    CARequestInfo_t *requestInfo = NULL;
-
-    // allocate & initialize
-    CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
-    CA_MEMORY_ALLOC_CHECK(data);
-
-    CAAddress_t addr = {};
-    remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
-                                                    object->transportType);
-
-    // clone request info
-    requestInfo = CACloneRequestInfo(request);
-    CA_MEMORY_ALLOC_CHECK(requestInfo);
-
-    // save data
-    data->type = SEND_TYPE_MULTICAST;
-    data->remoteEndpoint = remoteEndpoint;
-    data->requestInfo = requestInfo;
-    data->responseInfo = NULL;
-
     // add thread
     CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
-
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 
 // memory error label.
 memory_error_exit:
-
+    CAFreeEndpoint(remoteEndpoint);
     CADestroyRequestInfoInternal(requestInfo);
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
+
     OICFree(data);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
+CAResult_t CADetachResponseMessage(const CAEndpoint_t *object,
                                    const CAResponseInfo_t *response)
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -690,7 +679,7 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
         return CA_STATUS_FAILED;
     }
 
-    CARemoteEndpoint_t *remoteEndpoint = NULL;
+    CAEndpoint_t *remoteEndpoint = NULL;
     CAResponseInfo_t *responseInfo = NULL;
 
     // allocate & initialize
@@ -698,7 +687,7 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
     CA_MEMORY_ALLOC_CHECK(data);
 
     // clone remote endpoint
-    remoteEndpoint = CACloneRemoteEndpoint(object);
+    remoteEndpoint = CACloneEndpoint(object);
     CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
 
     // clone response info
@@ -710,83 +699,17 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
     data->remoteEndpoint = remoteEndpoint;
     data->requestInfo = NULL;
     data->responseInfo = responseInfo;
-
-    // add thread
-    CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-
-// memory error label.
-memory_error_exit:
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
-    CADestroyResponseInfoInternal(responseInfo);
-    OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
-
-    return CA_MEMORY_ALLOC_FAILED;
-}
-
-CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
-                                      uint8_t tokenLength, const CAHeaderOption_t *options,
-                                      uint8_t numOptions)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(resourceUri, TAG, "resourceUri is NULL");
-    VERIFY_NON_NULL(token, TAG, "Token is NULL");
-
-    if (false == CAIsSelectedNetworkAvailable())
-    {
-        return CA_STATUS_FAILED;
-    }
-
-    CARemoteEndpoint_t *remoteEndpoint = NULL;
-    CARequestInfo_t *reqInfo = NULL;
-    char *tempToken = NULL;
-
-    // allocate & initialize
-    CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
-    CA_MEMORY_ALLOC_CHECK(data);
-
-    CAAddress_t addr = {};
-    remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
-                                                    CA_IPV4 | CA_EDR | CA_LE);
-
-    // create request info
-    reqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
-    CA_MEMORY_ALLOC_CHECK(reqInfo);
-
-    if (tokenLength)
-    {
-        // copy token value
-        tempToken = (char *) OICMalloc(tokenLength);
-        CA_MEMORY_ALLOC_CHECK(tempToken);
-        memcpy(tempToken, token, tokenLength);
-    }
-
-    // save request info data
-    reqInfo->method = CA_GET;
-    reqInfo->info.type = CA_MSG_NONCONFIRM;
-
-    reqInfo->info.token = tempToken;
-    reqInfo->info.tokenLength = tokenLength;
-
-    // save data
-    data->type = SEND_TYPE_MULTICAST;
-    data->remoteEndpoint = remoteEndpoint;
-    data->requestInfo = reqInfo;
-
-    data->responseInfo = NULL;
     data->options = NULL;
     data->numOptions = 0;
-    if (NULL != options && 0 < numOptions)
+    if (NULL != responseInfo->info.options && 0 < responseInfo->info.numOptions)
     {
+        uint8_t numOptions = responseInfo->info.numOptions;
         // copy data
         CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t)
                                                                         * numOptions);
         CA_MEMORY_ALLOC_CHECK(headerOption);
 
-        memcpy(headerOption, options, sizeof(CAHeaderOption_t) * numOptions);
+        memcpy(headerOption, responseInfo->info.options, sizeof(CAHeaderOption_t) * numOptions);
 
         data->options = headerOption;
         data->numOptions = numOptions;
@@ -800,21 +723,28 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
 
 // memory error label.
 memory_error_exit:
-
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
-
-    OICFree(tempToken);
-    OICFree(reqInfo);
+    CAFreeEndpoint(remoteEndpoint);
+    CADestroyResponseInfoInternal(responseInfo);
     OICFree(data);
     OIC_LOG(DEBUG, TAG, "OUT");
+
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
+                                      uint8_t tokenLength, const CAHeaderOption_t *options,
+                                      uint8_t numOptions)
+{
+    return CA_NOT_SUPPORTED;
+}
+
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback errroHandler)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     g_requestHandler = ReqHandler;
     g_responseHandler = RespHandler;
+    g_errorHandler = errroHandler;
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -824,6 +754,7 @@ CAResult_t CAInitializeMessageHandler()
     CASetPacketReceivedCallback(CAReceivedPacketCallback);
 
     CASetNetworkChangeCallback(CANetworkChangedCallback);
+    CASetErrorHandleCallback(CAErrorHandler);
 
     // create thread pool
     CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
@@ -894,7 +825,7 @@ CAResult_t CAInitializeMessageHandler()
 void CATerminateMessageHandler()
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    CATransportType_t connType;
+    CATransportAdapter_t connType;
     u_arraylist_t *list = CAGetSelectedNetworkList();
     uint32_t length = u_arraylist_length(list);
 
@@ -908,7 +839,7 @@ void CATerminateMessageHandler()
             continue;
         }
 
-        connType = *(CATransportType_t *) ptrType;
+        connType = *(CATransportAdapter_t *)ptrType;
         CAStopAdapter(connType);
     }
 
@@ -967,3 +898,84 @@ void CALogPDUInfo(coap_pdu_t *pdu)
 
     OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
 }
+
+void CAErrorHandler(const CAEndpoint_t *endpoint,
+                    const void *data, uint32_t dataLen,
+                    CAResult_t result)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint");
+    VERIFY_NON_NULL_VOID(data, TAG, "data");
+
+    uint32_t code = CA_NOT_FOUND;
+    //Do not free remoteEndpoint and data. Currently they will be freed in data thread
+    //Get PDU data
+    coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code);
+    if (NULL == pdu)
+    {
+        OIC_LOG(ERROR, TAG, "Parse PDU failed");
+        return;
+    }
+
+    CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
+    if (NULL == errorInfo)
+    {
+        OIC_LOG(ERROR, TAG, "CAErrorHandler, Memory allocation failed!");
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    CAResult_t res = CAGetErrorInfoFromPDU(pdu, errorInfo);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAGetErrorInfoFromPDU failed : %d", res);
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+       return;
+    }
+
+    errorInfo->result = result;
+    OIC_LOG_V(DEBUG, TAG, "error : %d", result);
+    if (NULL != errorInfo->info.payload)
+    {
+        OIC_LOG_V(DEBUG, TAG, "error, payload: %s", errorInfo->info.payload);
+    }
+
+    OIC_LOG(DEBUG, TAG, "error, token");
+    OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) errorInfo->info.token,
+                   errorInfo->info.tokenLength);
+    OIC_LOG_V(DEBUG, TAG, "CAErrorHandler, msgID : %d", errorInfo->info.messageId);
+
+    CAEndpoint_t *rep = NULL;
+    rep = CACloneEndpoint(endpoint);
+    if (!rep)
+    {
+        OIC_LOG(ERROR, TAG, "CAErrorHandler, CloneEndpoint Failed");
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    // store the data at queue.
+    CAData_t *cadata = NULL;
+    cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
+    if (NULL == cadata)
+    {
+        OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+        CAFreeEndpoint(rep);
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    cadata->remoteEndpoint = rep;
+    cadata->requestInfo = NULL;
+    cadata->responseInfo = NULL;
+    cadata->errorInfo = errorInfo;
+    cadata->dataType = CA_ERROR_DATA;
+
+    CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
+    coap_delete_pdu(pdu);
+
+    return;
+}
index 6bad8a3..a5c1293 100644 (file)
@@ -26,9 +26,9 @@
 #include "cainterface.h"
 #include "camessagehandler_singlethread.h"
 #include "caremotehandler.h"
-#include "cainterfacecontroller_singlethread.h"
+#include "cainterfacecontroller.h"
 #include "caprotocolmessage.h"
-#include "caretransmission_singlethread.h"
+#include "caretransmission.h"
 #include "logger.h"
 #include "config.h" /* for coap protocol */
 #include "oic_malloc.h"
@@ -45,7 +45,7 @@ typedef enum
 typedef struct
 {
     CASendDataType_t type;
-    CARemoteEndpoint_t *remoteEndpoint;
+    CAEndpoint_t *remoteEndpoint;
     CARequestInfo_t *requestInfo;
     CAResponseInfo_t *responseInfo;
     CAHeaderOption_t *options;
@@ -58,11 +58,12 @@ static CARetransmission_t g_retransmissionContext;
 // handler field
 static CARequestCallback g_requestHandler = NULL;
 static CAResponseCallback g_responseHandler = NULL;
+static CAErrorCallback g_errorHandler = NULL;
 
-static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size)
+static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint);
+    CAEndpoint_t* ep = CACloneEndpoint(endpoint);
     if (NULL == ep)
     {
         OIC_LOG(ERROR, TAG, "clone failed");
@@ -74,7 +75,7 @@ static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pd
     if (NULL == resInfo)
     {
         OIC_LOG(ERROR, TAG, "calloc failed");
-        CADestroyRemoteEndpointInternal(ep);
+        CAFreeEndpoint(ep);
         return;
     }
 
@@ -87,7 +88,7 @@ static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pd
         g_responseHandler(ep, resInfo);
     }
 
-    CADestroyRemoteEndpointInternal(ep);
+    CAFreeEndpoint(ep);
     OICFree(resInfo);
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -104,27 +105,25 @@ static void CAProcessData(const CAData_t *data)
 
     if (SEND_TYPE_UNICAST == type)
     {
+        OIC_LOG(DEBUG,TAG,"Unicast Message");
         coap_pdu_t *pdu = NULL;
 
         if (NULL != data->requestInfo)
         {
             OIC_LOG(DEBUG, TAG, "reqInfo avlbl");
 
-            pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
-                                               data->requestInfo->method,
-                                               data->requestInfo->info);
+            pdu = (coap_pdu_t *)CAGeneratePDU(data->requestInfo->method, &data->requestInfo->info);
         }
         else if (NULL != data->responseInfo)
         {
             OIC_LOG(DEBUG, TAG, "resInfo avlbl");
 
-            pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
-                                               data->responseInfo->result,
-                                               data->responseInfo->info);
+            pdu = (coap_pdu_t *)CAGeneratePDU(data->responseInfo->result, &data->responseInfo->info);
         }
         else
         {
             OIC_LOG(DEBUG, TAG, "request info, response info is empty");
+            return;
         }
 
         // interface controller function call.
@@ -151,52 +150,67 @@ static void CAProcessData(const CAData_t *data)
 
             coap_delete_pdu(pdu);
         }
+        else
+        {
+            OIC_LOG(ERROR,TAG, "Failed to Generate Unicast PDU");
+            return;
+        }
     }
     else if (SEND_TYPE_MULTICAST == type)
     {
-        OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available");
+        OIC_LOG(DEBUG,TAG,"Multicast Message");
+        if (NULL != data->requestInfo)
+        {
+            OIC_LOG(DEBUG, TAG, "reqInfo avlbl");
 
-        CAInfo_t info = data->requestInfo->info;
+            CAInfo_t *info = &data->requestInfo->info;
 
-        info.options = data->options;
-        info.numOptions = data->numOptions;
+            info->options = data->options;
+            info->numOptions = data->numOptions;
 
-        coap_pdu_t *pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, CA_GET,
-                                                       info);
+            coap_pdu_t *pdu = (coap_pdu_t *)CAGeneratePDU(CA_GET, info);
 
-        if (NULL != pdu)
-        {
-            CALogPDUInfo(pdu);
-            res = CASendMulticastData(pdu->hdr, pdu->length);
-            if(CA_STATUS_OK != res)
+            if (NULL != pdu)
             {
-                OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+                CALogPDUInfo(pdu);
+                res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+                if(CA_STATUS_OK != res)
+                {
+                    OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+                    coap_delete_pdu(pdu);
+                    return;
+                }
                 coap_delete_pdu(pdu);
-                return;
             }
-            coap_delete_pdu(pdu);
+            else
+            {
+                OIC_LOG(ERROR,TAG,"Failed to Generate Multicast PDU");
+            }
+        }
+        else
+        {
+            OIC_LOG(ERROR,TAG,"requestInfo is empty");
         }
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
+static void CAReceivedPacketCallback(CAEndpoint_t *endpoint, void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL_VOID(data, TAG, "data");
 
     uint32_t code = CA_NOT_FOUND;
     coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
-
+    OICFree(data);
     if (NULL == pdu)
     {
         OIC_LOG(ERROR, TAG, "Parse PDU failed");
         return;
     }
 
-    char uri[CA_MAX_URI_LENGTH] = { 0, };
-    uint32_t bufLen = sizeof(uri);
+    char uri[CA_MAX_URI_LENGTH] = { };
 
     if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
     {
@@ -208,7 +222,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
             return;
         }
 
-        CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo, uri, bufLen);
+        CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res);
@@ -235,30 +249,13 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         OIC_LOG_V(DEBUG, TAG, "code: %d", ReqInfo->method);
         OIC_LOG(DEBUG, TAG, "token:");
         OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN);
-        if (NULL != endpoint)
-        {
-            endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
-            if (NULL == endpoint->resourceUri)
-            {
-                OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
-                OICFree(ReqInfo);
-                coap_delete_pdu(pdu);
-                return;
-            }
-            memcpy(endpoint->resourceUri, uri, bufLen);
-            endpoint->resourceUri[bufLen] = '\0';
-            OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
-        }
 
-        if (ReqInfo)
+        if (g_requestHandler)
         {
-            if (g_requestHandler)
-            {
-                g_requestHandler(endpoint, ReqInfo);
-            }
-
-            CADestroyRequestInfoInternal(ReqInfo);
+            g_requestHandler(endpoint, ReqInfo);
         }
+
+        CADestroyRequestInfoInternal(ReqInfo);
     }
     else
     {
@@ -270,7 +267,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
             return;
         }
 
-        CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo, uri, bufLen);
+        CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res);
@@ -295,21 +292,6 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         }
         OIC_LOG_V(DEBUG, TAG, "code: %d", ResInfo->result);
 
-        if (NULL != endpoint)
-        {
-            endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
-            if (NULL == endpoint->resourceUri)
-            {
-                OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
-                OICFree(ResInfo);
-                coap_delete_pdu(pdu);
-                return;
-            }
-            memcpy(endpoint->resourceUri, uri, bufLen);
-            endpoint->resourceUri[bufLen] = '\0';
-            OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
-        }
-
         // for retransmission
         void *retransmissionPdu = NULL;
         CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length,
@@ -338,11 +320,6 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         }
     }
 
-    if (endpoint && endpoint->resourceUri)
-    {
-        OICFree(endpoint->resourceUri);
-        endpoint->resourceUri = NULL;
-    }
     if (pdu)
     {
         coap_delete_pdu(pdu);
@@ -350,7 +327,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
+static void CANetworkChangedCallback(CAEndpoint_t *info, CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -363,7 +340,7 @@ void CAHandleRequestResponseCallbacks()
     CARetransmissionBaseRoutine((void *)&g_retransmissionContext);
 }
 
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
+CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInfo_t *request)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -382,7 +359,7 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
     CA_MEMORY_ALLOC_CHECK(data);
 
     // save data
-    data->type = SEND_TYPE_UNICAST;
+    data->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
     data->remoteEndpoint = object;
     data->requestInfo = request;
     data->responseInfo = NULL;
@@ -399,53 +376,7 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
-                                       const CARequestInfo_t *request)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    if (NULL == object || NULL == request || NULL == object->resourceUri)
-    {
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    if ((request->method < CA_GET) || (request->method > CA_DELETE))
-    {
-        OIC_LOG(ERROR, TAG, "Invalid method type!");
-
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    // allocate & initialize
-    CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
-    CA_MEMORY_ALLOC_CHECK(data);
-
-    CAAddress_t addr = {0};
-    CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
-                                                                        object->transportType);
-
-    // save data
-    data->type = SEND_TYPE_MULTICAST;
-    data->remoteEndpoint = remoteEndpoint;
-    data->requestInfo = request;
-    data->responseInfo = NULL;
-
-    CAProcessData(data);
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
-
-    OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-
-// memory error label.
-memory_error_exit:
-
-    OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_MEMORY_ALLOC_FAILED;
-}
-
-CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
+CAResult_t CADetachResponseMessage(const CAEndpoint_t *object,
                                    const CAResponseInfo_t *response)
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -476,78 +407,13 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
-                                      uint8_t tokenLength, const CAHeaderOption_t *options,
-                                      uint8_t numOptions)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(resourceUri, TAG, "resourceUri is NULL");
-    VERIFY_NON_NULL(token, TAG, "Token is NULL");
-
-    // allocate & initialize
-    CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
-    CA_MEMORY_ALLOC_CHECK(data);
-
-    CAAddress_t addr = {0};
-    CARemoteEndpoint_t *remoteEndpoint =
-            CACreateRemoteEndpointInternal(resourceUri, addr, CA_IPV4 | CA_EDR | CA_LE);
-
-    // create request info
-    CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
-    CA_MEMORY_ALLOC_CHECK(reqInfo);
-
-    // save request info data
-    reqInfo->method = CA_GET;
-    reqInfo->info.type = CA_MSG_NONCONFIRM;
-
-    reqInfo->info.token = token;
-    reqInfo->info.tokenLength = tokenLength;
-
-    // save data
-    data->type = SEND_TYPE_MULTICAST;
-    data->remoteEndpoint = remoteEndpoint;
-    data->requestInfo = reqInfo;
-
-    data->responseInfo = NULL;
-    data->options = NULL;
-    data->numOptions = 0;
-    CAHeaderOption_t *headerOption = NULL;
-    if (NULL != options && numOptions > 0)
-    {
-        // copy data
-        headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * numOptions);
-        CA_MEMORY_ALLOC_CHECK(headerOption);
-        memcpy(headerOption, options, sizeof(CAHeaderOption_t) * numOptions);
-
-        data->options = headerOption;
-        data->numOptions = numOptions;
-    }
-
-    CAProcessData(data);
-
-    CADestroyRemoteEndpoint(remoteEndpoint);
-    OICFree(headerOption);
-    OICFree(data);
-    OICFree(reqInfo);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-
-// memory error label.
-memory_error_exit:
-
-    CADestroyRemoteEndpointInternal(remoteEndpoint);
-
-    OICFree(reqInfo);
-    OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_MEMORY_ALLOC_FAILED;
-}
-
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler,
+                CAResponseCallback RespHandler, CAErrorCallback errorHandler)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     g_requestHandler = ReqHandler;
     g_responseHandler = RespHandler;
+    g_errorHandler = errorHandler;
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -559,10 +425,10 @@ CAResult_t CAInitializeMessageHandler()
     CASetNetworkChangeCallback(CANetworkChangedCallback);
 
     // retransmission initialize
-    CARetransmissionInitialize(&g_retransmissionContext, CASendUnicastData,
+    CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData,
                                CATimeoutCallback, NULL);
 
-    CAInitializeAdapters();
+    CAInitializeAdapters(NULL);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
index c5a89bc..01e9d4d 100644 (file)
 #include <stdlib.h>
 
 #include "canetworkconfigurator.h"
-#include "cainterfacecontroller_singlethread.h"
+#include "cainterfacecontroller.h"
 #include "uarraylist.h"
 #include "logger.h"
 
-#define TAG "CANW"
+#define TAG "CA_NW_CONFIG"
 
 static u_arraylist_t *g_selectedNetworkList = NULL;
-static uint32_t NETWORK_IP = CA_IPV4;
-static uint32_t NETWORK_EDR = CA_EDR;
-static uint32_t NETWORK_LE = CA_LE;
+static uint32_t NETWORK_IP = CA_ADAPTER_IP;
+static uint32_t NETWORK_RFCOMM = CA_ADAPTER_RFCOMM_BTEDR;
+static uint32_t NETWORK_GATT = CA_ADAPTER_GATT_BTLE;
 
+#ifdef RA_ADAPTER
+static uint32_t NETWORK_RA = CA_ADAPTER_REMOTE_ACCESS;
+#endif
 
-CAResult_t CAAddNetworkType(CATransportType_t transportType)
+CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     if (NULL == g_selectedNetworkList)
@@ -50,9 +53,7 @@ CAResult_t CAAddNetworkType(CATransportType_t transportType)
     CAResult_t res = CA_STATUS_OK;
     switch (transportType)
     {
-        case CA_IPV4:
-        {
-
+        case CA_ADAPTER_IP:
 #ifndef IP_ADAPTER
             OIC_LOG(DEBUG, TAG, "Add network type(IP) - Not Supported");
             return CA_NOT_SUPPORTED;
@@ -64,48 +65,50 @@ CAResult_t CAAddNetworkType(CATransportType_t transportType)
                 goto exit;
             }
             res = u_arraylist_add(g_selectedNetworkList, &NETWORK_IP);
-        }
-        break;
-        case CA_IPV6:
-        {
-            OIC_LOG(ERROR, TAG, "Currently IPV6 is not supported");
-            return CA_NOT_SUPPORTED;
-        }
-
-        case CA_EDR:
-        {
+            break;
 
+        case CA_ADAPTER_RFCOMM_BTEDR:
 #ifndef EDR_ADAPTER
             OIC_LOG(DEBUG, TAG, "Add network type(EDR) - Not Supported");
             return CA_NOT_SUPPORTED;
 #endif /* EDR_ADAPTER */
 
             OIC_LOG(DEBUG, TAG, "Add network type(EDR)");
-            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_EDR))
+            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_RFCOMM))
             {
                 goto exit;
             }
-            res = u_arraylist_add(g_selectedNetworkList, &NETWORK_EDR);
-        }
-        break;
-
-        case CA_LE:
-        {
+            res = u_arraylist_add(g_selectedNetworkList, &NETWORK_RFCOMM);
+            break;
 
+        case CA_ADAPTER_GATT_BTLE:
 #ifndef LE_ADAPTER
             OIC_LOG(DEBUG, TAG, "Add network type(LE) - Not Supported");
             return CA_NOT_SUPPORTED;
 #endif /* LE_ADAPTER */
 
             OIC_LOG(DEBUG, TAG, "Add network type(LE)");
-            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_LE))
+            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_GATT))
             {
                 goto exit;
             }
-            res = u_arraylist_add(g_selectedNetworkList, &NETWORK_LE);
-        }
-        break;
-
+            res = u_arraylist_add(g_selectedNetworkList, &NETWORK_GATT);
+            break;
+
+#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;
+           }
+           res = u_arraylist_add(g_selectedNetworkList, &NETWORK_RA);
+           break;
+#endif /* RA_ADAPTER */
+
+        default:
+            break;
     }
 
     if (CA_STATUS_OK != res)
@@ -114,7 +117,7 @@ CAResult_t CAAddNetworkType(CATransportType_t transportType)
         return res;
     }
     // start selected interface adapter
-    res = CAStartAdapter((CATransportType_t)transportType);
+    res = CAStartAdapter(transportType);
     OIC_LOG(DEBUG, TAG, "OUT");
     return res;
 
@@ -123,7 +126,7 @@ exit:
     return CA_STATUS_OK;
 }
 
-CAResult_t CARemoveNetworkType(CATransportType_t transportType)
+CAResult_t CARemoveNetworkType(CATransportAdapter_t transportType)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -143,14 +146,13 @@ CAResult_t CARemoveNetworkType(CATransportType_t transportType)
             continue;
         }
 
-        CATransportType_t connType = *(CATransportType_t *) ptrType;
+        CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
 
         if (transportType == connType)
         {
             switch (transportType)
             {
-                case CA_IPV4:
-
+                case CA_ADAPTER_IP:
 #ifndef IP_ADAPTER
                     OIC_LOG(DEBUG, TAG, "Remove network type(IP) - Not Supported");
                     return CA_NOT_SUPPORTED;
@@ -161,14 +163,7 @@ CAResult_t CARemoveNetworkType(CATransportType_t transportType)
 #endif /* IP_ADAPTER */
                     break;
 
-                case CA_IPV6:
-                {
-                    OIC_LOG(ERROR, TAG, "Currently IPV6 is not supported");
-                    return CA_NOT_SUPPORTED;
-                }
-
-                case CA_EDR:
-
+                case CA_ADAPTER_RFCOMM_BTEDR:
 #ifndef EDR_ADAPTER
                     OIC_LOG(DEBUG, TAG, "Remove network type(EDR) - Not Supported");
                     return CA_NOT_SUPPORTED;
@@ -176,11 +171,9 @@ CAResult_t CARemoveNetworkType(CATransportType_t transportType)
                     OIC_LOG(DEBUG, TAG, "Remove network type(EDR)");
                     u_arraylist_remove(g_selectedNetworkList, index);
 #endif /* EDR_ADAPTER */
-
                     break;
 
-                case CA_LE:
-
+                case CA_ADAPTER_GATT_BTLE:
 #ifndef LE_ADAPTER
                     OIC_LOG(DEBUG, TAG, "Remove network type(LE) - Not Supported");
                     return CA_NOT_SUPPORTED;
@@ -190,6 +183,15 @@ CAResult_t CARemoveNetworkType(CATransportType_t transportType)
 #endif /* LE_ADAPTER */
 
                     break;
+#ifdef RA_ADAPTER
+                case CA_ADAPTER_REMOTE_ACCESS:
+                    OIC_LOG(DEBUG, TAG, "Remove network type(RA)");
+                    u_arraylist_remove(g_selectedNetworkList, index);
+                    break;
+#endif /* RA_ADAPTER */
+
+                default:
+                    break;
             }
 
             // stop selected interface adapter
@@ -206,7 +208,7 @@ u_arraylist_t *CAGetSelectedNetworkList()
     return g_selectedNetworkList;
 }
 
-CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetNetworkInformationInternal(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "get network information.");
 
index 23bd47c..b6e3b05 100644 (file)
 #define _DEFAULT_SOURCE
 #define _BSD_SOURCE
 
-// Include files from the arduino platform do not provide these conversions:
-#ifdef ARDUINO
-#define htons(x) ( ((x)<< 8 & 0xFF00) | ((x)>> 8 & 0x00FF) )
-#define ntohs(x) htons(x)
-#else
-#define HAVE_TIME_H 1
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "caprotocolmessage.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 
 // ARM GCC compiler doesnt define srandom function.
 #if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
 #define HAVE_SRANDOM 1
 #endif
 
-#define TAG "CA"
+#define TAG "CA_PRTCL_MSG"
+
+/**
+ * @def VERIFY_NON_NULL_RET
+ * @brief Macro to verify the validity of input argument
+ */
+#define VERIFY_NON_NULL_RET(arg, log_tag, log_message,ret) \
+    if (NULL == arg ){ \
+        OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \
+        return ret; \
+    }
 
 #define CA_BUFSIZE (128)
 #define CA_PDU_MIN_SIZE (4)
@@ -65,45 +68,59 @@ static const char COAP_URI_HEADER[] = "coap://[::]/";
 
 static uint32_t SEED = 0;
 
-CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
-                                   char *outUri, uint32_t buflen)
+CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    if (NULL == pdu || NULL == outReqInfo || NULL == outUri)
+    if (NULL == pdu || NULL == outReqInfo)
     {
         OIC_LOG(ERROR, TAG, "parameter is null");
         return CA_STATUS_INVALID_PARAM;
     }
 
     uint32_t code = CA_NOT_FOUND;
-
-    OIC_LOG_V(DEBUG, TAG, "buffer length : %d", buflen);
-    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info), outUri, buflen);
+    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info));
     outReqInfo->method = code;
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return ret;
 }
 
-CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
-                                    char *outUri, uint32_t buflen)
+CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    if (NULL == pdu || NULL == outResInfo || NULL == outUri)
+    if (NULL == pdu || NULL == outResInfo)
     {
         OIC_LOG(ERROR, TAG, "parameter is null");
         return CA_STATUS_INVALID_PARAM;
     }
 
     uint32_t code = CA_NOT_FOUND;
-    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outResInfo->info), outUri, buflen);
+    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outResInfo->info));
     outResInfo->result = code;
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return ret;
 }
 
-coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
+CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (!pdu)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    uint32_t code = 0;
+    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &errorInfo->info);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ret;
+}
+
+coap_pdu_t *CAGeneratePDU(uint32_t code, const CAInfo_t *info)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -111,7 +128,7 @@ coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
 
     // RESET have to use only 4byte (empty message)
     // and ACKNOWLEDGE can use empty message when code is empty.
-    if (CA_MSG_RESET == info.type || (CA_EMPTY == code && CA_MSG_ACKNOWLEDGE == info.type))
+    if (CA_MSG_RESET == info->type || (CA_EMPTY == code && CA_MSG_ACKNOWLEDGE == info->type))
     {
         OIC_LOG(DEBUG, TAG, "code is empty");
         if (!(pdu = CAGeneratePDUImpl((code_t) code, NULL, info, NULL, 0)))
@@ -124,8 +141,9 @@ coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
     {
         coap_list_t *optlist = NULL;
 
-        if (CA_MSG_ACKNOWLEDGE != info.type)
+        if (CA_MSG_ACKNOWLEDGE != info->type)
         {
+            const char *uri = info->resourceUri;
             if (NULL == uri)
             {
                 OIC_LOG(ERROR, TAG, "uri NULL");
@@ -146,8 +164,8 @@ coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
                 OIC_LOG(ERROR, TAG, "out of memory");
                 return NULL;
             }
-            strcat(coapUri, COAP_URI_HEADER);
-            strcat(coapUri, uri);
+            OICStrcat(coapUri, uriLength, COAP_URI_HEADER);
+            OICStrcat(coapUri, uriLength, uri);
 
             // parsing options in URI
             CAResult_t res = CAParseURI(coapUri, &optlist);
@@ -170,8 +188,7 @@ coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
             coap_delete_list(optlist);
             return NULL;
         }
-        size_t lenPayload = info.payload ? strlen(info.payload) : 0;
-        pdu = CAGeneratePDUImpl((code_t) code, optlist, info, info.payload, lenPayload);
+        pdu = CAGeneratePDUImpl((code_t)code, optlist, info, info->payload, info->payloadSize);
         if (NULL == pdu)
         {
             OIC_LOG(ERROR, TAG, "pdu NULL");
@@ -221,10 +238,11 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)
     return outpdu;
 }
 
-coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t info,
-                              const char *payload, size_t payloadSize)
+coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t *info,
+                              const uint8_t *payload, size_t payloadSize)
 {
     OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_RET(info, TAG, "info is NULL", NULL);
 
     coap_pdu_t *pdu = coap_new_pdu();
 
@@ -234,9 +252,9 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t
         return NULL;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "msgID is %d", info.messageId);
+    OIC_LOG_V(DEBUG, TAG, "msgID is %d", info->messageId);
     uint16_t message_id;
-    if (0 == info.messageId)
+    if (0 == info->messageId)
     {
         /* initialize message id */
         prng((uint8_t * ) &message_id, sizeof(message_id));
@@ -246,21 +264,21 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t
     else
     {
         /* use saved message id */
-        message_id = info.messageId;
+        message_id = info->messageId;
     }
     pdu->hdr->id = message_id;
     OIC_LOG_V(DEBUG, TAG, "messageId in pdu is %d, %d", message_id, pdu->hdr->id);
 
-    pdu->hdr->type = info.type;
+    pdu->hdr->type = info->type;
     pdu->hdr->code = COAP_RESPONSE_CODE(code);
 
-    if (info.token && CA_EMPTY != code)
+    if (info->token && CA_EMPTY != code)
     {
-        uint32_t tokenLength = info.tokenLength;
+        uint32_t tokenLength = info->tokenLength;
         OIC_LOG_V(DEBUG, TAG, "token info token length: %d, token :", tokenLength);
-        OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)info.token, tokenLength);
+        OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)info->token, tokenLength);
 
-        int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *) info.token);
+        int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *)info->token);
         if (0 == ret)
         {
             OIC_LOG(ERROR, TAG, "can't add token");
@@ -281,7 +299,6 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t
 
     if (NULL != payload)
     {
-        OIC_LOG_V(DEBUG, TAG, "add data, payload:%s", payload);
         coap_add_data(pdu, payloadSize, (const unsigned char *) payload);
     }
 
@@ -317,7 +334,7 @@ CAResult_t CAParseURI(const char *uriInfo, coap_list_t **optlist)
         int ret = coap_insert(optlist,
                               CACreateNewOptionNode(COAP_OPTION_URI_PORT,
                                                     coap_encode_var_bytes(portbuf, uri.port),
-                                                    portbuf),
+                                                    (char *)portbuf),
                               CAOrderOpts);
         if (ret <= 0)
         {
@@ -327,8 +344,8 @@ CAResult_t CAParseURI(const char *uriInfo, coap_list_t **optlist)
 
     if (uri.path.s && uri.path.length)
     {
-        CAResult_t ret = CAParseUriPartial(uri.path.s, uri.path.length, COAP_OPTION_URI_PATH,
-                                           optlist);
+        CAResult_t ret = CAParseUriPartial(uri.path.s, uri.path.length,
+                                           COAP_OPTION_URI_PATH, optlist);
         if (CA_STATUS_OK != ret)
         {
             OIC_LOG(ERROR, TAG, "CAParseUriPartial failed(uri path)");
@@ -381,7 +398,7 @@ CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target
             {
                 int ret = coap_insert(optlist,
                                       CACreateNewOptionNode(target, COAP_OPT_LENGTH(pBuf),
-                                                            COAP_OPT_VALUE(pBuf)),
+                                                            (char *)COAP_OPT_VALUE(pBuf)),
                                       CAOrderOpts);
                 if (ret <= 0)
                 {
@@ -411,11 +428,12 @@ CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target
     return CA_STATUS_OK;
 }
 
-CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist)
+CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **optlist)
 {
     OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_RET(info, TAG, "info is NULL", CA_STATUS_INVALID_PARAM);
 
-    OIC_LOG_V(DEBUG, TAG, "parse Head Opt: %d", info.numOptions);
+    OIC_LOG_V(DEBUG, TAG, "parse Head Opt: %d", info->numOptions);
 
     if (!optlist)
     {
@@ -423,29 +441,29 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **o
         return CA_STATUS_INVALID_PARAM;
     }
 
-    for (uint32_t i = 0; i < info.numOptions; i++)
+    for (uint32_t i = 0; i < info->numOptions; i++)
     {
-        if(!(info.options + i))
+        if(!(info->options + i))
         {
             OIC_LOG(ERROR, TAG, "options is not available");
             return CA_STATUS_FAILED;
         }
 
-        uint32_t id = (info.options + i)->optionID;
+        uint32_t id = (info->options + i)->optionID;
         if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id)
         {
             OIC_LOG_V(DEBUG, TAG, "not Header Opt: %d", id);
         }
         else
         {
-            if ((info.options + i)->optionData && (info.options + i)->optionLength > 0)
+            if ((info->options + i)->optionData && (info->options + i)->optionLength > 0)
             {
                 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 data: %s", (info->options + i)->optionData);
+                OIC_LOG_V(DEBUG, TAG, "Head opt length: %d", (info->options + i)->optionLength);
                 int ret = coap_insert(optlist,
-                                      CACreateNewOptionNode(id, (info.options + i)->optionLength,
-                                                            (info.options + i)->optionData),
+                                      CACreateNewOptionNode(id, (info->options + i)->optionLength,
+                                                            (info->options + i)->optionData),
                                       CAOrderOpts);
                 if (ret <= 0)
                 {
@@ -459,7 +477,7 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **o
     return CA_STATUS_OK;
 }
 
-coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const uint8_t *data)
+coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const char *data)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -530,12 +548,11 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
     return count;
 }
 
-CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
-                            char *outUri, uint32_t buflen)
+CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    if (!pdu || !outCode || !outInfo || !outUri)
+    if (!pdu || !outCode || !outInfo)
     {
         OIC_LOG(ERROR, TAG, "NULL pointer param");
         return CA_STATUS_INVALID_PARAM;
@@ -640,7 +657,7 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
                             // Make sure there is enough room in the optionResult buffer
                             if (optionLength < sizeof(optionResult))
                             {
-                                optionResult[optionLength] = '&';
+                                optionResult[optionLength] = ';';
                                 optionLength++;
                             }
                             else
@@ -697,11 +714,12 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
     outInfo->tokenLength = pdu->hdr->token_length;
 
     // set payload data
-    if (NULL != pdu->data)
+    size_t dataSize;
+    uint8_t *data;
+    if (coap_get_data(pdu, &dataSize, &data))
     {
-        uint32_t payloadLength = strlen((char*) pdu->data);
         OIC_LOG(DEBUG, TAG, "inside pdu->data");
-        outInfo->payload = (char *) OICMalloc(payloadLength + 1);
+        outInfo->payload = (uint8_t *) OICMalloc(dataSize);
         if (NULL == outInfo->payload)
         {
             OIC_LOG(ERROR, TAG, "Out of memory");
@@ -709,22 +727,25 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
             OICFree(outInfo->token);
             return CA_MEMORY_ALLOC_FAILED;
         }
-        memcpy(outInfo->payload, pdu->data, payloadLength);
-        outInfo->payload[payloadLength] = '\0';
+        memcpy(outInfo->payload, pdu->data, dataSize);
+        outInfo->payloadSize = dataSize;
     }
 
     uint32_t length = strlen(optionResult);
-    OIC_LOG_V(DEBUG, TAG, "URL length:%d,%d,%d", length, buflen, strlen(outUri));
-    if (buflen >= length)
+    OIC_LOG_V(DEBUG, TAG, "URL length:%d", length);
+
+    outInfo->resourceUri = OICMalloc(length + 1);
+    if (!outInfo->resourceUri)
     {
-        memcpy(outUri, optionResult, length);
-        outUri[length] = '\0';
-#ifdef ARDUINO
-        OIC_LOG_V(DEBUG, TAG, "made URL:%s\n", optionResult);
-#else
-        OIC_LOG_V(DEBUG, TAG, "made URL : %s, %s", optionResult, outUri);
-#endif
+        OIC_LOG(ERROR, TAG, "Out of memory");
+        OICFree(outInfo->options);
+        OICFree(outInfo->token);
+        return CA_MEMORY_ALLOC_FAILED;
     }
+    memcpy(outInfo->resourceUri, optionResult, length);
+    outInfo->resourceUri[length] = '\0';
+    OIC_LOG_V(DEBUG, TAG, "made URL : %s, %s", optionResult, outInfo->resourceUri);
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 
index 01bed4b..c410be9 100644 (file)
@@ -29,7 +29,7 @@
 #include "oic_malloc.h"
 #include "logger.h"
 
-#define TAG PCF("CA")
+#define TAG PCF("CA_QING")
 
 static void CAQueueingThreadBaseRoutine(void *threadValue)
 {
@@ -146,8 +146,28 @@ CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, ca_thread_pool
     thread->isStop = true;
     thread->threadTask = task;
     thread->destroy = destroy;
+    if(NULL == thread->dataQueue || NULL == thread->threadMutex || NULL == thread->threadCond)
+        goto ERROR_MEM_FAILURE;
 
     return CA_STATUS_OK;
+    ERROR_MEM_FAILURE:
+    if(thread->dataQueue)
+    {
+        u_queue_delete(thread->dataQueue);
+        thread->dataQueue = NULL;
+    }
+    if(thread->threadMutex)
+    {
+        ca_mutex_free(thread->threadMutex);
+        thread->threadMutex = NULL;
+    }
+    if(thread->threadCond)
+    {
+        ca_cond_free(thread->threadCond);
+        thread->threadCond = NULL;
+    }
+    return CA_MEMORY_ALLOC_FAILED;
+
 }
 
 CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread)
diff --git a/resource/csdk/connectivity/src/caremotehandler.c b/resource/csdk/connectivity/src/caremotehandler.c
deleted file mode 100644 (file)
index 9bf509a..0000000
+++ /dev/null
@@ -1,532 +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.
- *
- ******************************************************************/
-
-#include <string.h>
-
-#include "oic_malloc.h"
-#include "caremotehandler.h"
-#include "logger.h"
-
-#define TAG "CA"
-
-CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return NULL;
-    }
-
-    // allocate the remote end point structure.
-    CARemoteEndpoint_t *clone = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t));
-    if (NULL == clone)
-    {
-        OIC_LOG(ERROR, TAG, "CACloneRemoteEndpoint Out of memory");
-        return NULL;
-    }
-    memcpy(clone, rep, sizeof(CARemoteEndpoint_t));
-
-    if (NULL != rep->resourceUri)
-    {
-        // allocate reference uri field
-        size_t len = strlen(rep->resourceUri);
-
-        char *temp = (char *) OICCalloc(len + 1, sizeof(char));
-        if (NULL == temp)
-        {
-            OIC_LOG(ERROR, TAG, "CACloneRemoteEndpoint Out of memory");
-
-            CADestroyRemoteEndpointInternal(clone);
-
-            return NULL;
-        }
-
-        strncpy(temp, rep->resourceUri, len);
-
-        // save the uri
-        clone->resourceUri = temp;
-    }
-
-    return clone;
-}
-
-#define COAP_PREFIX         "coap://"
-#define COAP_PREFIX_LEN     7
-#define COAPS_PREFIX         "coaps://"
-#define COAPS_PREFIX_LEN     8
-
-
-// return 1 : ip
-// return 0 : mac
-static int32_t getCAAddress(const char *pAddress, CAAddress_t *outAddress)
-{
-    if (NULL == pAddress || NULL == outAddress)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return -1;
-    }
-
-    // simple parse, it will be change.
-    // 10.11.12.13:4545 (ip)
-    // 10:11:12:13:45:45 (mac)
-
-    int32_t len = strlen(pAddress);
-
-    int32_t isIp = 0;
-    int32_t ipLen = 0;
-
-    int i = 0;
-    for (i = 0; i < len; i++)
-    {
-        if (pAddress[i] == '.')
-        {
-            isIp = 1;
-        }
-
-        // found port number start index
-        if (isIp && pAddress[i] == ':')
-        {
-            ipLen = i;
-            break;
-        }
-    }
-
-    if (isIp)
-    {
-        if(ipLen && ipLen < sizeof(outAddress->IP.ipAddress))
-        {
-            strncpy(outAddress->IP.ipAddress, pAddress, ipLen);
-            outAddress->IP.ipAddress[ipLen] = '\0';
-        }
-        else if (!ipLen && len < sizeof(outAddress->IP.ipAddress))
-        {
-            strncpy(outAddress->IP.ipAddress, pAddress, len);
-            outAddress->IP.ipAddress[len] = '\0';
-        }
-        else
-        {
-            OIC_LOG_V(ERROR, TAG, "IP Address too long: %d", ipLen==0 ? len : ipLen);
-            return -1;
-        }
-
-
-        if (ipLen > 0)
-        {
-            outAddress->IP.port = atoi(pAddress + ipLen + 1);
-        }
-
-        OIC_LOG_V(DEBUG, TAG, "ip: %s, port: %d", outAddress->IP.ipAddress, outAddress->IP.port);
-    }
-    else
-    {
-        strncpy(outAddress->BT.btMacAddress, pAddress, CA_MACADDR_SIZE - 1);
-
-        OIC_LOG_V(DEBUG, TAG, "mac address : %s", outAddress->BT.btMacAddress);
-    }
-
-    return isIp;
-}
-
-CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri,
-                                                      const CATransportType_t transportType)
-{
-    // support URI type
-    // coap://10.11.12.13:4545/resource_uri
-    // coap://10:11:12:13:45:45/resource_uri
-
-    if (NULL == uri)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return NULL;
-    }
-
-    // parse uri
-    // #1. check prefix
-    int startIndex = 0;
-    bool secured = false;
-    if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
-    {
-        OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAP_PREFIX);
-        startIndex = COAP_PREFIX_LEN;
-    }
-
-    if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
-    {
-        OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAPS_PREFIX);
-        startIndex = COAPS_PREFIX_LEN;
-        secured = true;
-    }
-
-    // #2. copy uri for parse
-    int32_t len = strlen(uri) - startIndex;
-
-    if (len <= 0)
-    {
-        OIC_LOG(ERROR, TAG, "uri length is 0!");
-        return NULL;
-    }
-
-    char *cloneUri = (char *) OICCalloc(len + 1, sizeof(char));
-    if (NULL == cloneUri)
-    {
-        OIC_LOG(ERROR, TAG, "CACreateRemoteEndpointUriInternal Out of memory");
-        return NULL;
-    }
-
-    memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
-    cloneUri[len] = '\0';
-
-    // #3. parse address
-    // #4. parse resource uri
-    char *pAddress = cloneUri;
-    char *pResourceUri = NULL;
-
-    int32_t i = 0;
-    for (i = 0; i < len; i++)
-    {
-        if (cloneUri[i] == '/')
-        {
-            // separate
-            cloneUri[i] = 0;
-
-            pResourceUri = &cloneUri[i + 1];
-
-            break;
-        }
-
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "pAddress : %s", pAddress);
-
-    OIC_LOG_V(DEBUG, TAG, "pResourceUri : %s", pResourceUri == NULL ? "" : pResourceUri);
-
-    // address
-    CAAddress_t address = {};
-
-    int resType = getCAAddress(pAddress, &address);
-    if (resType == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "address parse error");
-
-        OICFree(cloneUri);
-        return NULL;
-    }
-
-    // resource uri
-    CAURI_t resourceUri = pResourceUri;
-
-    CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, address,
-                                                                        transportType);
-    if (NULL == remoteEndpoint)
-    {
-        OIC_LOG(ERROR, TAG, "create remote endpoint fail");
-
-        OICFree(cloneUri);
-        return NULL;
-    }
-    remoteEndpoint->isSecured = secured;
-
-    OICFree(cloneUri);
-
-    OIC_LOG_V(DEBUG, TAG, "Remote endpoint successfully created [%d]!", remoteEndpoint->isSecured);
-    return remoteEndpoint;
-}
-
-CARemoteEndpoint_t *CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
-                                                   const CAAddress_t addr,
-                                                   const CATransportType_t type)
-{
-    if (NULL == resourceUri)
-    {
-        OIC_LOG(ERROR, TAG, "uri is null value");
-        return NULL;
-    }
-
-    // allocate the remote end point structure.
-    CARemoteEndpoint_t *rep = (CARemoteEndpoint_t *) OICCalloc(1, sizeof(CARemoteEndpoint_t));
-
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "CACreateRemoteEndpointInternal of memory");
-        return NULL;
-    }
-
-    // allocate reference uri field
-    size_t len = strlen(resourceUri);
-
-    char *temp = (char *) OICMalloc(sizeof(char) * (len + 1));
-    if (NULL == temp)
-    {
-        OIC_LOG(ERROR, TAG, "CACreateRemoteEndpointInternal Out of memory");
-
-        CADestroyRemoteEndpointInternal(rep);
-
-        return NULL;
-    }
-    strncpy(temp, resourceUri, len);
-    temp[len] = '\0';
-
-    // save the uri
-    rep->resourceUri = temp;
-
-    // save the addressInfo
-    memcpy(&(rep->addressInfo), &addr, sizeof(CAAddress_t));
-
-    // save the type
-    rep->transportType = type;
-
-    return rep;
-}
-
-CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return NULL;
-    }
-
-    // allocate the request info structure.
-    CARequestInfo_t *clone = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
-    if (!clone)
-    {
-        OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
-        return NULL;
-    }
-
-    memcpy(clone, rep, sizeof(CARequestInfo_t));
-
-    if (rep->info.token)
-    {
-        char *temp = NULL;
-
-        // allocate token field
-        uint8_t len = rep->info.tokenLength;
-
-        if (len)
-        {
-            temp = (char *) OICCalloc(len, sizeof(char));
-            if (!temp)
-            {
-                OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
-
-                CADestroyRequestInfoInternal(clone);
-
-                return NULL;
-            }
-            memcpy(temp, rep->info.token, len);
-        }
-
-        // save the token
-        clone->info.token = temp;
-        clone->info.tokenLength = len;
-    }
-
-    if (NULL != rep->info.options && 0 < rep->info.numOptions)
-    {
-        // save the options
-        clone->info.options =
-            (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
-        if (NULL == clone->info.options)
-        {
-            OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
-            OICFree(clone->info.token);
-            OICFree(clone);
-            return NULL;
-        }
-        memcpy(clone->info.options, rep->info.options,
-               sizeof(CAHeaderOption_t) * rep->info.numOptions);
-    }
-    else
-    {
-        clone->info.options = NULL;
-        clone->info.numOptions = 0;
-    }
-
-    if (NULL != rep->info.payload)
-    {
-        // allocate payload field
-        size_t len = strlen(rep->info.payload);
-
-        char *temp = (char *) OICMalloc(sizeof(char) * (len + 1));
-        if (NULL == temp)
-        {
-            OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
-
-            CADestroyRequestInfoInternal(clone);
-
-            return NULL;
-        }
-        strncpy(temp, rep->info.payload, len);
-        temp[len] = '\0';
-
-        // save the payload
-        clone->info.payload = temp;
-    }
-
-    return clone;
-}
-
-CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "Response pointer is NULL");
-        return NULL;
-    }
-
-    // allocate the response info structure.
-    CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
-    if (NULL == clone)
-    {
-        OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
-        return NULL;
-    }
-    memcpy(clone, rep, sizeof(CAResponseInfo_t));
-
-    if (rep->info.token)
-    {
-        char *temp = NULL;
-
-        // allocate token field
-        uint8_t len = rep->info.tokenLength;
-
-        if (len)
-        {
-            temp = (char *) OICCalloc(len, sizeof(char));
-            if (!temp)
-            {
-                OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
-
-                CADestroyResponseInfoInternal(clone);
-
-                return NULL;
-            }
-            memcpy(temp, rep->info.token, len);
-        }
-        // save the token
-        clone->info.token = temp;
-        clone->info.tokenLength = len;
-    }
-
-    if (NULL != rep->info.options && rep->info.numOptions)
-    {
-        // save the options
-        clone->info.options =
-                (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
-
-        if (NULL == clone->info.options)
-        {
-            OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
-
-            OICFree(clone->info.token);
-            OICFree(clone);
-            return NULL;
-        }
-        memcpy(clone->info.options, rep->info.options,
-                sizeof(CAHeaderOption_t) * rep->info.numOptions);
-    }
-    else
-    {
-        clone->info.options = NULL;
-        clone->info.numOptions = 0;
-    }
-
-    if (NULL != rep->info.payload)
-    {
-        // allocate payload field
-        int32_t len = strlen(rep->info.payload);
-
-        char *temp = (char *) OICCalloc(len + 1, sizeof(char));
-        if (NULL == temp)
-        {
-            OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
-
-            CADestroyResponseInfoInternal(clone);
-
-            return NULL;
-        }
-        strncpy(temp, rep->info.payload, len);
-
-        // save the payload
-        clone->info.payload = temp;
-    }
-
-    return clone;
-}
-
-void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return;
-    }
-
-    // free uri field
-    OICFree((char *) rep->resourceUri);
-
-    // free remote end point structure.
-    OICFree(rep);
-}
-
-void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return;
-    }
-
-    // free token field
-    OICFree(rep->info.token);
-
-    // free options field
-    OICFree((CAHeaderOption_t *) rep->info.options);
-
-    // free payload field
-    OICFree((char *) rep->info.payload);
-
-    OICFree(rep);
-}
-
-void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
-{
-    if (NULL == rep)
-    {
-        OIC_LOG(ERROR, TAG, "parameter is null");
-        return;
-    }
-
-    // free token field
-    OICFree(rep->info.token);
-
-    // free options field
-    if (rep->info.options != NULL && rep->info.numOptions)
-    {
-        OICFree((CAHeaderOption_t *) rep->info.options);
-    }
-
-    // free payload field
-    OICFree((char *) rep->info.payload);
-
-    OICFree(rep);
-}
-
index aeb2b5d..2b130c2 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifndef SINGLE_THREAD
 #include <unistd.h>
 #include <time.h>
 #include <sys/time.h>
+#endif
 
 #if defined(__ANDROID__)
 #include <linux/time.h>
 #include "oic_malloc.h"
 #include "logger.h"
 
-#define TAG PCF("CA")
+#define TAG "CA_RETRANS"
 
 typedef struct
 {
     uint64_t timeStamp;                 /**< last sent time. microseconds */
+#ifndef SINGLE_THREAD
     uint64_t timeout;                   /**< timeout value. microseconds */
+#endif
     uint8_t triedCount;                 /**< retransmission count */
     uint16_t messageId;                 /**< coap PDU message id */
-    CARemoteEndpoint_t *endpoint;       /**< remote endpoint */
+    CAEndpoint_t *endpoint;             /**< remote endpoint */
     void *pdu;                          /**< coap PDU */
     uint32_t size;                      /**< coap PDU size */
 } CARetransmissionData_t;
@@ -80,48 +85,85 @@ static const uint64_t USECS_PER_SEC = 1000000;
  */
 uint64_t getCurrentTimeInMicroSeconds();
 
+#ifndef SINGLE_THREAD
+/**
+ * @brief   timeout value is
+ *          between DEFAULT_ACK_TIMEOUT_SEC and
+ *          (DEFAULT_ACK_TIMEOUT_SEC * DEFAULT_RANDOM_FACTOR) second.
+ *          DEFAULT_RANDOM_FACTOR       1.5 (CoAP)
+ * @return  microseconds.
+ */
+static uint64_t CAGetTimeoutValue()
+{
+    return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * (random() & 0xFF)) >> 8)) *
+            (uint64_t) 1000;
+}
+
+CAResult_t CARetransmissionStart(CARetransmission_t *context)
+{
+    if (NULL == context)
+    {
+        OIC_LOG(ERROR, TAG, "context is empty");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (NULL == context->threadPool)
+    {
+        OIC_LOG(ERROR, TAG, "thread pool handle is empty..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAResult_t res = ca_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine,
+                                             context);
+
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "thread pool add task error(send thread).");
+        return res;
+    }
+
+    return res;
+}
+#endif
+
 /**
  * @brief   check timeout routine
  * @param   currentTime     [IN]microseconds
- * @param   timeStamp       [IN]microseconds
- * @param   timeoutValue    [IN]microseconds
- * @param   triedCount      [IN]Number of retransmission tried
+ * @param   retData         [IN]retransmission data
  * @return  true if the timeout period has elapsed, false otherwise
  */
-static bool CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint64_t timeoutValue,
-                           uint8_t triedCount)
+static bool CACheckTimeout(uint64_t currentTime, CARetransmissionData_t *retData)
 {
+#ifndef SINGLE_THREAD
     // #1. calculate timeout
-    uint32_t milliTimeoutValue = timeoutValue * 0.001;
-    uint64_t timeout = (milliTimeoutValue << triedCount) * (uint64_t) 1000;
+    uint32_t milliTimeoutValue = retData->timeout * 0.001;
+    uint64_t timeout = (milliTimeoutValue << retData->triedCount) * (uint64_t) 1000;
 
-    if (currentTime >= timeStamp + timeout)
+    if (currentTime >= retData->timeStamp + timeout)
     {
-        OIC_LOG_V(DEBUG, TAG, "%d microseconds time out!!, tried count(%d)", timeout, triedCount);
+        OIC_LOG_V(DEBUG, TAG, "%d microseconds time out!!, tried count(%ld)",
+                  timeout, retData->triedCount);
         return true;
     }
+#else
+    // #1. calculate timeout
+    uint64_t timeOut = (2 << retData->triedCount) * 1000000;
 
+    if (currentTime >= retData->timeStamp + timeOut)
+    {
+        OIC_LOG_V(DEBUG, TAG, "timeout=%d, tried cnt=%d",
+                  (2 << retData->triedCount), retData->triedCount);
+        return true;
+    }
+#endif
     return false;
 }
 
-/**
- * @brief   timeout value is
- *          between DEFAULT_ACK_TIMEOUT_SEC and
- *          (DEFAULT_ACK_TIMEOUT_SEC * DEFAULT_RANDOM_FACTOR) second.
- *          DEFAULT_RANDOM_FACTOR       1.5 (CoAP)
- * @return  microseconds.
- */
-static uint64_t CAGetTimeoutValue()
-{
-    return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * (random() & 0xFF)) >> 8)) *
-            (uint64_t) 1000;
-}
-
 static void CACheckRetransmissionList(CARetransmission_t *context)
 {
     if (NULL == context)
     {
-        OIC_LOG(ERROR, TAG, "context is null..");
+        OIC_LOG(ERROR, TAG, "context is null");
         return;
     }
 
@@ -142,12 +184,12 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
 
         uint64_t currentTime = getCurrentTimeInMicroSeconds();
 
-        if (CACheckTimeout(currentTime, retData->timeStamp, retData->timeout, retData->triedCount))
+        if (CACheckTimeout(currentTime, retData))
         {
             // #2. if time's up, send the data.
             if (NULL != context->dataSendMethod)
             {
-                OIC_LOG_V(DEBUG, TAG, "retransmission CON data!!, message id(%d)",
+                OIC_LOG_V(DEBUG, TAG, "retransmission CON data!!, msgid=%d",
                           retData->messageId);
                 context->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
             }
@@ -161,34 +203,31 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
         if (retData->triedCount >= context->config.tryingCount)
         {
             CARetransmissionData_t *removedData = u_arraylist_remove(context->dataList, i);
-
-            if (NULL != removedData)
+            if (NULL == removedData)
             {
-                OIC_LOG_V(DEBUG, TAG, "max trying count, remove retransmission CON data!!,\
-                          message id(%d)", removedData->messageId);
-
-                // callback for retransmit timeout
-                if (NULL != context->timeoutCallback)
-                {
-                    context->timeoutCallback(removedData->endpoint, removedData->pdu,
-                                             removedData->size);
-                }
-
-                CADestroyRemoteEndpointInternal(removedData->endpoint);
-                OICFree(removedData->pdu);
-
-                OICFree(removedData);
-
-                // modify loop value.
-                len = u_arraylist_length(context->dataList);
-
-                --i;
+                OIC_LOG(ERROR, TAG, "Removed data is NULL");
+                // mutex unlock
+                ca_mutex_unlock(context->threadMutex);
+                return;
             }
-            else
+            OIC_LOG_V(DEBUG, TAG, "max trying count, remove RTCON data,"
+                      "msgid=%d", removedData->messageId);
+
+            // callback for retransmit timeout
+            if (NULL != context->timeoutCallback)
             {
-                OIC_LOG(ERROR, TAG, "arraylist remove error");
+                context->timeoutCallback(removedData->endpoint, removedData->pdu,
+                                         removedData->size);
             }
 
+            CAFreeEndpoint(removedData->endpoint);
+            OICFree(removedData->pdu);
+
+            OICFree(removedData);
+
+            // modify loop value.
+            len = u_arraylist_length(context->dataList);
+            --i;
         }
     }
 
@@ -196,18 +235,27 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
     ca_mutex_unlock(context->threadMutex);
 }
 
-static void CARetransmissionBaseRoutine(void *threadValue)
+void CARetransmissionBaseRoutine(void *threadValue)
 {
-    OIC_LOG(DEBUG, TAG, "retransmission main thread start..");
+    OIC_LOG(DEBUG, TAG, "retransmission main thread start");
 
     CARetransmission_t *context = (CARetransmission_t *) threadValue;
 
     if (NULL == context)
     {
-        OIC_LOG(ERROR, TAG, "thread data passing error!!");
+        OIC_LOG(ERROR, TAG, "thread data passing error");
+
+        return;
+    }
 
+#ifdef SINGLE_THREAD
+    if (true == context->isStop)
+    {
+        OIC_LOG(DEBUG, TAG, "thread stopped");
         return;
     }
+    CACheckRetransmissionList(context);
+#else
 
     while (!context->isStop)
     {
@@ -227,7 +275,7 @@ static void CARetransmissionBaseRoutine(void *threadValue)
         else if (!context->isStop)
         {
             // check each RETRANSMISSION_CHECK_PERIOD_SEC time.
-            OIC_LOG_V(DEBUG, TAG, "wait..(%d)microseconds",
+            OIC_LOG_V(DEBUG, TAG, "wait..(%ld)microseconds",
                       RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) USECS_PER_SEC);
 
             // wait
@@ -255,28 +303,30 @@ static void CARetransmissionBaseRoutine(void *threadValue)
     ca_cond_signal(context->threadCond);
     ca_mutex_unlock(context->threadMutex);
 
-    OIC_LOG(DEBUG, TAG, "retransmission main thread end..");
+#endif
+    OIC_LOG(DEBUG, TAG, "retransmission main thread end");
 
 }
 
-CAResult_t CARetransmissionInitialize(CARetransmission_t *context, ca_thread_pool_t handle,
+CAResult_t CARetransmissionInitialize(CARetransmission_t *context,
+                                      ca_thread_pool_t handle,
                                       CADataSendMethod_t retransmissionSendMethod,
                                       CATimeoutCallback_t timeoutCallback,
                                       CARetransmissionConfig_t* config)
 {
     if (NULL == context)
     {
-        OIC_LOG(ERROR, TAG, "thread instance is empty..");
+        OIC_LOG(ERROR, TAG, "thread instance is empty");
         return CA_STATUS_INVALID_PARAM;
     }
-
+#ifndef SINGLE_THREAD
     if (NULL == handle)
     {
-        OIC_LOG(ERROR, TAG, "thread pool handle is empty..");
+        OIC_LOG(ERROR, TAG, "thread pool handle is empty");
         return CA_STATUS_INVALID_PARAM;
     }
-
-    OIC_LOG(DEBUG, TAG, "thread initialize..");
+#endif
+    OIC_LOG(DEBUG, TAG, "thread initialize");
 
     memset(context, 0, sizeof(CARetransmission_t));
 
@@ -286,7 +336,7 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, ca_thread_poo
     {
         // setDefault
         cfg.supportType = DEFAULT_RETRANSMISSION_TYPE;
-        cfg.tryingCount = DEFAULT_MAX_RETRANSMIT;
+        cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT;
     }
     else
     {
@@ -306,47 +356,20 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, ca_thread_poo
     return CA_STATUS_OK;
 }
 
-CAResult_t CARetransmissionStart(CARetransmission_t *context)
-{
-    if (NULL == context)
-    {
-        OIC_LOG(ERROR, TAG, "context is empty..");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    if (NULL == context->threadPool)
-    {
-        OIC_LOG(ERROR, TAG, "thread pool handle is empty..");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    CAResult_t res = ca_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine,
-                                            context);
-
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, TAG, "thread pool add task error(send thread).");
-        return res;
-    }
-
-    return res;
-}
-
 CAResult_t CARetransmissionSentData(CARetransmission_t *context,
-                                    const CARemoteEndpoint_t* endpoint, const void* pdu,
-                                    uint32_t size)
+                                    const CAEndpoint_t *endpoint,
+                                    const void *pdu, uint32_t size)
 {
     if (NULL == context || NULL == endpoint || NULL == pdu)
     {
-        OIC_LOG(ERROR, TAG, "invalid parameter..");
+        OIC_LOG(ERROR, TAG, "invalid parameter");
         return CA_STATUS_INVALID_PARAM;
     }
 
     // #0. check support transport type
-    if (!(context->config.supportType & endpoint->transportType))
+    if (!(context->config.supportType & endpoint->adapter))
     {
-        OIC_LOG_V(DEBUG, TAG, "not supported transport type for retransmission..(%d)",
-                  endpoint->transportType);
+        OIC_LOG_V(DEBUG, TAG, "not supported transport type=%d", endpoint->adapter);
         return CA_NOT_SUPPORTED;
     }
 
@@ -354,11 +377,11 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
     CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
     uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
 
-    OIC_LOG_V(DEBUG, TAG, "sent pdu, message type(%d), message id(%d)", type, messageId);
+    OIC_LOG_V(DEBUG, TAG, "sent pdu, msgtype=%d, msgid=%d", type, messageId);
 
     if (CA_MSG_CONFIRM != type)
     {
-        OIC_LOG(DEBUG, TAG, "not supported message type for retransmission..");
+        OIC_LOG(DEBUG, TAG, "not supported message type");
         return CA_NOT_SUPPORTED;
     }
 
@@ -368,7 +391,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
 
     if (NULL == retData)
     {
-        OIC_LOG(ERROR, TAG, "memory error!!");
+        OIC_LOG(ERROR, TAG, "memory error");
         return CA_MEMORY_ALLOC_FAILED;
     }
 
@@ -377,30 +400,32 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
     if (NULL == pduData)
     {
         OICFree(retData);
-        OIC_LOG(ERROR, TAG, "memory error!!");
+        OIC_LOG(ERROR, TAG, "memory error");
         return CA_MEMORY_ALLOC_FAILED;
     }
     memcpy(pduData, pdu, size);
 
     // clone remote endpoint
-    CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(endpoint);
+    CAEndpoint_t *remoteEndpoint = CACloneEndpoint(endpoint);
     if (NULL == remoteEndpoint)
     {
         OICFree(retData);
         OICFree(pduData);
-        OIC_LOG(ERROR, TAG, "memory error!!");
+        OIC_LOG(ERROR, TAG, "memory error");
         return CA_MEMORY_ALLOC_FAILED;
     }
 
     // #2. add additional information. (time stamp, retransmission count...)
     retData->timeStamp = getCurrentTimeInMicroSeconds();
+#ifndef SINGLE_THREAD
     retData->timeout = CAGetTimeoutValue();
+#endif
     retData->triedCount = 0;
     retData->messageId = messageId;
     retData->endpoint = remoteEndpoint;
     retData->pdu = pduData;
     retData->size = size;
-
+#ifndef SINGLE_THREAD
     // mutex lock
     ca_mutex_lock(context->threadMutex);
 
@@ -419,7 +444,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
 
         // found index
         if (NULL != currData->endpoint && currData->messageId == messageId
-            && (currData->endpoint->transportType == endpoint->transportType))
+            && (currData->endpoint->adapter == endpoint->adapter))
         {
             OIC_LOG(ERROR, TAG, "Duplicate message ID");
 
@@ -441,25 +466,29 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
     // mutex unlock
     ca_mutex_unlock(context->threadMutex);
 
+#else
+    u_arraylist_add(context->dataList, (void *) retData);
+
+    CACheckRetransmissionList(context);
+#endif
     return CA_STATUS_OK;
 }
 
 CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
-                                        const CARemoteEndpoint_t *endpoint, const void *pdu,
+                                        const CAEndpoint_t *endpoint, const void *pdu,
                                         uint32_t size, void **retransmissionPdu)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CARetransmissionReceivedData");
+    OIC_LOG(DEBUG, TAG, "IN");
     if (NULL == context || NULL == endpoint || NULL == pdu || NULL == retransmissionPdu)
     {
-        OIC_LOG(ERROR, TAG, "invalid parameter..");
+        OIC_LOG(ERROR, TAG, "invalid parameter");
         return CA_STATUS_INVALID_PARAM;
     }
 
     // #0. check support transport type
-    if (!(context->config.supportType & endpoint->transportType))
+    if (!(context->config.supportType & endpoint->adapter))
     {
-        OIC_LOG_V(DEBUG, TAG, "not supported transport type for retransmission..(%d)",
-                  endpoint->transportType);
+        OIC_LOG_V(DEBUG, TAG, "not supported transport type=%d", endpoint->adapter);
         return CA_STATUS_OK;
     }
 
@@ -468,7 +497,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
     CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
     uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
 
-    OIC_LOG_V(DEBUG, TAG, "received pdu, message type(%d), message id(%d)", type, messageId);
+    OIC_LOG_V(DEBUG, TAG, "received pdu, msgtype=%d, msgid=%d", type, messageId);
 
     if ((CA_MSG_ACKNOWLEDGE != type) && (CA_MSG_RESET != type))
     {
@@ -493,13 +522,13 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
 
         // found index
         if (NULL != retData->endpoint && retData->messageId == messageId
-            && (retData->endpoint->transportType == endpoint->transportType))
+            && (retData->endpoint->adapter == endpoint->adapter))
         {
             // get pdu data for getting token when CA_EMPTY(RST/ACK) is received from remote device
             // if retransmission was finish..token will be unavailable.
             if (CA_EMPTY == CAGetCodeFromPduBinaryData(pdu, size))
             {
-                OIC_LOG(DEBUG, TAG, "code is CA_EMPTY..");
+                OIC_LOG(DEBUG, TAG, "code is CA_EMPTY");
 
                 if (NULL == retData->pdu)
                 {
@@ -516,7 +545,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                 if ((*retransmissionPdu) == NULL)
                 {
                     OICFree(retData);
-                    OIC_LOG(ERROR, TAG, "memory error!!");
+                    OIC_LOG(ERROR, TAG, "memory error");
 
                     // mutex unlock
                     ca_mutex_unlock(context->threadMutex);
@@ -538,10 +567,9 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                 return CA_STATUS_FAILED;
             }
 
-            OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)",
-                      messageId);
+            OIC_LOG_V(DEBUG, TAG, "remove RTCON data!!, msgid=%d", messageId);
 
-            CADestroyRemoteEndpointInternal(removedData->endpoint);
+            CAFreeEndpoint(removedData->endpoint);
             OICFree(removedData->pdu);
             OICFree(removedData);
 
@@ -552,7 +580,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
     // mutex unlock
     ca_mutex_unlock(context->threadMutex);
 
-    OIC_LOG(DEBUG, TAG, "OUT - CARetransmissionReceivedData");
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -612,7 +640,10 @@ uint64_t getCurrentTimeInMicroSeconds()
     clock_gettime(CLOCK_MONOTONIC, &getTs);
 
     currentTime = (getTs.tv_sec * (uint64_t)1000000000 + getTs.tv_nsec)/1000;
-    OIC_LOG_V(DEBUG, TAG, "current time = %d", currentTime);
+    OIC_LOG_V(DEBUG, TAG, "current time = %ld", currentTime);
+#elif defined __ARDUINO__
+    currentTime = millis() * 1000;
+    OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
 #else
 #if _POSIX_TIMERS > 0
     struct timespec ts;
diff --git a/resource/csdk/connectivity/src/caretransmission_singlethread.c b/resource/csdk/connectivity/src/caretransmission_singlethread.c
deleted file mode 100644 (file)
index e419278..0000000
+++ /dev/null
@@ -1,440 +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.
- *
- ******************************************************************/
-#include "caretransmission_singlethread.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "caremotehandler.h"
-#include "caprotocolmessage.h"
-#include "oic_malloc.h"
-#include "logger.h"
-
-#ifndef __ARDUINO__
-#include <sys/time.h>
-#endif
-
-#define TAG "RT"
-
-typedef struct
-{
-    /** last sent time. microseconds **/
-    uint64_t timeStamp;
-
-    /** retransmission count **/
-    uint8_t triedCount;
-
-    /** coap PDU message id **/
-    uint16_t messageId;
-
-    /** remote endpoint **/
-    CARemoteEndpoint_t *endpoint;
-
-    /** coap PDU **/
-    void *pdu;
-
-    /** coap PDU size**/
-    uint32_t size;
-
-} CARetransmissionData_t;
-
-static CARetransmission_t *g_retransmissionPtr = NULL;
-
-/**
- * getCurrent monotonic time.
- *
- * @return current time in microseconds.
- */
-uint64_t getCurrentTimeInMicroSeconds();
-
-/**
- * @brief   check timeout routine
- * @param   currentTime     [IN]microseconds
- * @param   timeStamp       [IN]microseconds
- * @param   triedCount      [IN]Number of retransmission tried.
- * @return  true if the timeout period has elapsed, false otherwise.
- */
-static bool CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint8_t triedCount)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    // #1. calculate timeout
-    uint64_t timeOut = (2 << triedCount) * 1000000;
-
-    if (currentTime >= timeStamp + timeOut)
-    {
-        OIC_LOG_V(DEBUG, TAG, "timeout=%d, tried cnt=%d", (2 << triedCount), triedCount);
-        return true;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return false;
-}
-
-void CACheckRetransmissionList()
-{
-    uint32_t len = u_arraylist_length(g_retransmissionPtr->dataList);
-
-    OIC_LOG_V(DEBUG, TAG, "len=%d", len);
-    for (uint32_t i = 0; i < len; i++)
-    {
-        CARetransmissionData_t *retData =
-                (CARetransmissionData_t *) u_arraylist_get(g_retransmissionPtr->dataList, i);
-
-        if (NULL == retData)
-        {
-            continue;
-        }
-
-        uint64_t currentTime = getCurrentTimeInMicroSeconds();
-
-        OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
-        if (CACheckTimeout(currentTime, retData->timeStamp, retData->triedCount))
-        {
-
-            OIC_LOG(DEBUG, TAG, "RTdata-Success");
-            // #2. if time's up, send the data.
-            if (NULL != g_retransmissionPtr->dataSendMethod)
-            {
-                OIC_LOG_V(DEBUG, TAG, "retry CON data-msgid=%d", retData->messageId);
-                g_retransmissionPtr->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
-            }
-
-            // #3. increase the retransmission count and update timestamp.
-            retData->timeStamp = currentTime;
-            retData->triedCount++;
-        }
-
-        // #4. if tried count is max, remove the retransmission data from list.
-        if (retData->triedCount >= g_retransmissionPtr->config.tryingCount)
-        {
-            CARetransmissionData_t *removedData = (CARetransmissionData_t *) u_arraylist_remove(
-                    g_retransmissionPtr->dataList, i);
-            if (NULL == removedData)
-            {
-                OIC_LOG(ERROR, TAG, "Removed data is NULL");
-                return;
-            }
-
-            OIC_LOG(DEBUG, TAG, "max trycount rchd");
-
-            OIC_LOG_V(DEBUG, TAG, "max trycount, remove retransmission CON data!!, messageid=%d",
-                      removedData->messageId);
-
-            // callback for retransmit timeout
-            if (NULL != g_retransmissionPtr->timeoutCallback)
-            {
-                g_retransmissionPtr->timeoutCallback(removedData->endpoint, removedData->pdu,
-                                                     removedData->size);
-            }
-
-            CADestroyRemoteEndpointInternal(removedData->endpoint);
-            OICFree(removedData->pdu);
-
-            OICFree(removedData);
-
-            // modify loop value.
-            len = u_arraylist_length(g_retransmissionPtr->dataList);
-            --i;
-        }
-    }
-}
-
-void CARetransmissionBaseRoutine(void *threadValue)
-{
-    CARetransmission_t *context = (CARetransmission_t *) threadValue;
-
-    if (NULL == context)
-    {
-        OIC_LOG(ERROR, TAG, "cnxt null");
-        return;
-    }
-
-    if (true == context->isStop)
-    {
-        OIC_LOG(DEBUG, TAG, "thread stopped");
-        return;
-    }
-    g_retransmissionPtr = context;
-    CACheckRetransmissionList();
-}
-
-CAResult_t CARetransmissionInitialize(CARetransmission_t *context,
-                                      CADataSendMethod_t retransmissionSendMethod,
-                                      CATimeoutCallback_t timeoutCallback,
-                                      CARetransmissionConfig_t *config)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == context)
-    {
-        OIC_LOG(ERROR, TAG, "cnxt null");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    memset(context, 0, sizeof(CARetransmission_t));
-
-    CARetransmissionConfig_t cfg;
-    memset(&cfg, 0, sizeof(CARetransmissionConfig_t));
-
-    if (NULL == config)
-    {
-        // setDefault
-        cfg.supportType = (CATransportType_t) DEFAULT_RETRANSMISSION_TYPE;
-        cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT;
-    }
-    else
-    {
-        cfg = *config;
-    }
-
-    // set send thread data
-    context->dataSendMethod = retransmissionSendMethod;
-    context->timeoutCallback = timeoutCallback;
-    context->config = cfg;
-    context->isStop = false;
-    context->dataList = u_arraylist_create();
-
-    // Enable TimedAction for CACheckRetransmissionList API
-    g_retransmissionPtr = context;
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CARetransmissionSentData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint,
-                                    const void *pdu, uint32_t size)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == context || NULL == endpoint || NULL == pdu)
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    // #0. check support connectivity type
-    if (!(context->config.supportType & endpoint->transportType))
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        OIC_LOG_V(ERROR, TAG, "not supported conntype=%d", endpoint->transportType);
-        return CA_NOT_SUPPORTED;
-    }
-
-    // #1. check PDU method type and get message id.
-    CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
-    uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
-
-    OIC_LOG_V(DEBUG, TAG, "sent pdu, msgtype=%d,msgid=%d", type, messageId);
-
-    if (CA_MSG_CONFIRM != type)
-    {
-        OIC_LOG(DEBUG, TAG, "not supported message type");
-        return CA_NOT_SUPPORTED;
-    }
-
-    // create retransmission data
-    CARetransmissionData_t *retData = (CARetransmissionData_t *) OICCalloc(
-            1, sizeof(CARetransmissionData_t));
-
-    if (NULL == retData)
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    // copy PDU data
-    void *pduData = (void *) OICMalloc(size);
-    if (NULL == pduData)
-    {
-        OICFree(retData);
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    memcpy(pduData, pdu, size);
-
-    // clone remote endpoint
-    CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(endpoint);
-    if (NULL == remoteEndpoint)
-    {
-        OICFree(retData);
-        OICFree(pduData);
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    // #2. add additional information. (time stamp, retransmission count...)
-    retData->timeStamp = getCurrentTimeInMicroSeconds();
-    retData->triedCount = 0;
-    retData->messageId = messageId;
-    retData->endpoint = remoteEndpoint;
-    retData->pdu = pduData;
-    retData->size = size;
-
-    // #3. add data into list
-    u_arraylist_add(context->dataList, (void *) retData);
-
-    // #4. Initiate Re-transmission for added entry
-    g_retransmissionPtr = context;
-    CACheckRetransmissionList();
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
-                                        const CARemoteEndpoint_t *endpoint, const void *pdu,
-                                        uint32_t size, void **retransmissionPdu)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == context || NULL == endpoint || NULL == pdu || NULL == retransmissionPdu)
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    // #0. check support connectivity type
-    if (!(context->config.supportType & endpoint->transportType))
-    {
-        OIC_LOG_V(DEBUG, TAG, "not supp conntype=%d", endpoint->transportType);
-        return CA_STATUS_OK;
-    }
-
-    // #1. check PDU method type and get message id.
-    // ACK, RST --> remove the CON data
-    CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
-    uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
-
-    OIC_LOG_V(DEBUG, TAG, "recv pdu, msgtype=%d,msgid=%d", type, messageId);
-
-    if (CA_MSG_ACKNOWLEDGE != type && CA_MSG_RESET != type)
-    {
-        return CA_STATUS_OK;
-    }
-
-    uint32_t len = u_arraylist_length(context->dataList);
-
-    // find index
-    for (uint32_t i = 0; i < len; i++)
-    {
-        CARetransmissionData_t *retData = (CARetransmissionData_t *) u_arraylist_get(
-                context->dataList, i);
-
-        if (NULL == retData)
-        {
-            continue;
-        }
-
-        // found index
-        if (NULL != retData->endpoint && retData->messageId == messageId
-            && (retData->endpoint->transportType == endpoint->transportType))
-        {
-            // get pdu data for getting token when CA_EMPTY(RST/ACK) is received from remote device
-            // if retransmission was finish..token will be unavailable.
-            if (CA_EMPTY == CAGetCodeFromPduBinaryData(pdu, size))
-            {
-                OIC_LOG(DEBUG, TAG, "CA_EMPTY");
-
-                if (NULL == retData->pdu)
-                {
-                    OIC_LOG(ERROR, TAG, "retData->pdu is null");
-                    OICFree(retData);
-                    return CA_STATUS_FAILED;
-                }
-
-                // copy PDU data
-                (*retransmissionPdu) = (void *) OICCalloc(1, retData->size);
-                if (NULL == (*retransmissionPdu))
-                {
-                    OICFree(retData);
-                    OIC_LOG(ERROR, TAG, "error");
-                    return CA_MEMORY_ALLOC_FAILED;
-                }
-                memcpy((*retransmissionPdu), retData->pdu, retData->size);
-            }
-
-            // #2. remove data from list
-            CARetransmissionData_t *removedData = (CARetransmissionData_t *) u_arraylist_remove(
-                    context->dataList, i);
-            if (NULL == removedData)
-            {
-                OIC_LOG(ERROR, TAG, "Removed data is NULL");
-                return CA_STATUS_FAILED;
-            }
-
-            OIC_LOG_V(DEBUG, TAG, "remove RTCON data, msgid=%d", messageId);
-
-            CADestroyRemoteEndpointInternal(removedData->endpoint);
-            OICFree(removedData->pdu);
-
-            OICFree(removedData);
-
-            break;
-        }
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CARetransmissionStop(CARetransmission_t *context)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == context)
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    // set stop flag
-    context->isStop = true;
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CARetransmissionDestroy(CARetransmission_t *context)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    if (NULL == context)
-    {
-        OIC_LOG(ERROR, TAG, "error");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    u_arraylist_free(&context->dataList);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-uint64_t getCurrentTimeInMicroSeconds()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    uint64_t currentTime = 0;
-
-#ifdef __ARDUINO__
-    currentTime = millis() * 1000;
-
-    OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
-#else
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    currentTime = tv.tv_sec * USECS_PER_SEC + tv.tv_usec;
-#endif
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return currentTime;
-}
-
index 2320380..5cc3798 100644 (file)
@@ -1,48 +1,53 @@
 #######################################################
-#      Building IP adapter
+#      Build IP adapter
 #######################################################
 
 Import('env')
+import os.path
 
 print "Reading IP adapter script"
 
 target_os = env.get('TARGET_OS')
 inc_files = env.get('CPPPATH')
+secured = env.get('SECURED')
 src_dir = './ip_adapter/'
 
-if target_os == 'tizen':
-    env.ParseConfig("pkg-config --cflags --libs capi-network-wifi")
 
-#Source files to build common for all platforms
+# Source files to build common for all platforms
+common_files = None
 if target_os == 'arduino':
-       env.AppendUnique(CA_SRC=[src_dir+'caipadapter_singlethread.c'])
-       env.AppendUnique(CPPPATH=[src_dir+'arduino/'])
+    common_files = [ os.path.join(src_dir,
+                                  'caipadapter.c') ]
 else:
-      env.AppendUnique(CA_SRC=[src_dir+'caipadapter.c'])
-      env.AppendUnique(CA_SRC=[src_dir+'caipclient.c'])
-      env.AppendUnique(CA_SRC=[src_dir+'caipserver.c'])
-
-#Source files to build in Linux platform
-if target_os == 'linux':
-       env.AppendUnique(CA_SRC=[src_dir+'linux/caipnwmonitor.c'])
-
-if target_os == 'tizen':
-       env.AppendUnique(CA_SRC=[src_dir+'tizen/caipnwmonitor.c'])
-
-#Source files to build in Arduino platform
-if target_os == 'arduino':
-       env.AppendUnique(CA_SRC=[src_dir+'arduino/caipnwmonitor.cpp'])
-       if env.get('SHIELD') == 'WIFI':
-               env.AppendUnique(CA_SRC=[src_dir+'arduino/caipclient_wifi.cpp',
-                               src_dir+'arduino/caipserver_wifi.cpp',
-                               ])
-       else:
-               env.AppendUnique(CA_SRC=[src_dir+'arduino/caipadapterutils_eth.cpp',
-                               src_dir+'arduino/caipclient_eth.cpp',
-                               src_dir+'arduino/caipserver_eth.cpp',
-                               ])
-
-#Source files to build in android platform
-if target_os == 'android':
-       env.AppendUnique(CA_SRC=[src_dir+'android/caipnwmonitor.c'])
-       env.AppendUnique(CPPPATH=[src_dir+'android/'])
+    common_files = [
+        os.path.join(src_dir, 'caipadapter.c'),
+       os.path.join(src_dir, 'caipserver.c') ]
+
+# Get list of target-specific source file base names, i.e. no parent
+# directories prepended to the path.
+#
+# Target-specific SConscript files are expected to return that list.
+target_files = []
+target_sconscript = os.path.join(target_os, 'SConscript')
+
+# Check for the existence of the platform-specific SConscript file
+# relative to the top-level source directory, not the build (variant)
+# directory, before calling that SConscript file to prevent a missing
+# file warning platforms that don't provide one.
+target_sconscript_abspath = str(File(target_sconscript).srcnode().abspath)
+if os.path.exists(target_sconscript_abspath):
+        target_files = env.SConscript(target_sconscript, exports='src_dir')
+
+# Now prepend the appropriate parent directories
+# (e.g. ./ip_adapter/android) to each of the target source files in
+# the list.
+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']:
+    target_files += [ os.path.join(src_dir,
+                                   'linux/caipnwmonitor.c') ]
+
+# The list of BLE adapter source files is a combination of both the
+# common and target-specific source file lists.
+env.AppendUnique(CA_SRC = common_files + target_files)
diff --git a/resource/csdk/connectivity/src/ip_adapter/android/SConscript b/resource/csdk/connectivity/src/ip_adapter/android/SConscript
new file mode 100644 (file)
index 0000000..b411c2e
--- /dev/null
@@ -0,0 +1,12 @@
+#######################################################
+#       Build IP adapter for Android
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.AppendUnique(CPPPATH = [ os.path.join(src_dir, 'android') ])
+
+src_files = [ 'caipnwmonitor.c' ]
+
+Return('src_files')
index 4272e65..2f4b5d5 100644 (file)
 /******************************************************************
- *
- * 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.
- *
- ******************************************************************/
+*
+* 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 <string.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <linux/if.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <sys/socket.h>
 #include <netdb.h>
+#include <string.h>
 #include <errno.h>
 #include <unistd.h>
 
+#include <arpa/inet.h>
+#include <linux/if.h>
+
 #include "caadapterutils.h"
-#include "camutex.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
-#include "org_iotivity_ca_CaIpInterface.h"
-
-#define IP_MONITOR_TAG "IP_MONITOR"
-#define MAX_INTERFACE_INFO_LENGTH (1024)
-
-/**
- * @var g_stopNetworkMonitor
- * @brief  Used to stop the network monitor thread.
- */
-static bool g_stopNetworkMonitor = false;
-
-/**
- * @var g_stopNetworkMonitorMutex
- * @brief  Mutex for synchronizing access to g_stopNetworkMonitor flag.
- */
-static ca_mutex g_stopNetworkMonitorMutex = NULL;
-
-/**
- * @struct CAIPNwMonitorContext
- * @brief  Used for storing network monitor context information.
- */
-typedef struct
-{
-    u_arraylist_t *netInterfaceList;
-    ca_thread_pool_t threadPool;
-    CANetworkStatus_t nwConnectivityStatus;
-    CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
-
-/**
- * @var g_networkMonitorContext
- * @brief  network monitor context.
- */
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
-
-/**
- * @var g_networkMonitorContextMutex
- * @brief  Mutex for synchronizing access to cached interface and IP address information.
- */
-static ca_mutex g_networkMonitorContextMutex = NULL;
-
-/**
- * @var g_jvm
- * @brief pointer to store JavaVM
- */
-static JavaVM *g_jvm = NULL;
-
-/**
- * @var g_context
- * @brief pointer to store Application Context
- */
-static jobject g_context = NULL;
 
-/**
- * @fn CAIPUpdateInterfaceInformation
- * @brief This methods gets local interface name and IP address information.
- */
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList);
-/**
- * @fn CACreateIPJNIInterfaceObject
- * @brief creates new instance of caipinterface through JNI
- */
-static CAResult_t CACreateIPJNIInterfaceObject(jobject context);
+#define TAG "IP_MONITOR"
 
-/**
- * @fn CAIPSendNetworkChangeCallback
- * @brief updates network status to IP adapter
- */
-static void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
+char *getHostIPAddress(const char *ifa_name) {
+    static char address[INET_ADDRSTRLEN] = {};
+    memset(&address, 0, INET_ADDRSTRLEN);
+    struct ifreq ifr;
+    int sck, status, len = sizeof(ifr.ifr_name) - 1;
+    char *ip;
 
-CAResult_t CAIPJniInit()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniInit");
-    g_jvm = CANativeJNIGetJavaVM();
-
-    if (!g_jvm)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "JNI initialize error");
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPJniSetContext()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniSetContext");
-    g_context = (jobject) CANativeJNIGetContext();
-
-    if (!g_context)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to get application context");
-        return CA_STATUS_FAILED;
+    if ((sck = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        return NULL;
     }
 
-    return CA_STATUS_OK;
-}
-
-CAResult_t CACreateIPJNIInterfaceObject(jobject context)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACreateIPJNIInterfaceObject");
-
-    VERIFY_NON_NULL(context, IP_MONITOR_TAG, "context");
-
-    JNIEnv* env;
-
-    if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get JNIEnv pointer");
-        return CA_STATUS_FAILED;
-    }
-
-    //getApplicationContext
-    jclass contextClass = (*env)->FindClass(env, "android/content/Context");
-    if (!contextClass)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get context object class");
-        return CA_STATUS_FAILED;
-    }
-
-    jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
-                                                                "getApplicationContext",
-                                                                "()Landroid/content/Context;");
-    if (!getApplicationContextMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext method");
-        return CA_STATUS_FAILED;
-    }
-
-    jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
-                                                           getApplicationContextMethod);
-    if (!getApplicationContextMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext");
-        return CA_STATUS_FAILED;
-    }
-
-    //Create caipinterface jni instance
-    jclass IPJniInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
-    if (!IPJniInterface)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get caipinterface class");
-        return CA_STATUS_FAILED;
-    }
-
-    jmethodID IPInterfaceConstructorMethod = (*env)->GetMethodID(env, IPJniInterface, "<init>",
-                                                                   "(Landroid/content/Context;)V");
-    if (!IPInterfaceConstructorMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get caipinterface constructor method");
-        return CA_STATUS_FAILED;
-    }
-
-    (*env)->NewObject(env, IPJniInterface, IPInterfaceConstructorMethod, gApplicationContext);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "Create caipinterface instance, success");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
-    /* Get a socket handle. */
-    int sck = -1;
-#ifdef SOCK_CLOEXEC
-    sck = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
-#endif
-
-    if ( -1 == sck)
-    {
-        sck=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-    }
-
-    if (sck < 0)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Error in socket creation");
-        return CA_STATUS_FAILED;
-    }
-
-    char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
-    struct ifconf ifc;
-
-    /* Query available interfaces. */
-    ifc.ifc_len = MAX_INTERFACE_INFO_LENGTH;
-    ifc.ifc_buf = buf;
-
-    if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
-    {
+    strncpy(ifr.ifr_name, ifa_name, len);
+    ifr.ifr_name[len] = '\0';
+    if ((status = ioctl(sck, SIOCGIFADDR, &ifr)) < 0) {
         close(sck);
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get interface info");
-        return CA_STATUS_FAILED;
+        return NULL;
     }
-
-    /* Iterate through the list of interfaces. */
-    struct ifreq* ifr = ifc.ifc_req;
-    int32_t interfaces = ifc.ifc_len / sizeof(struct ifreq);
-
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPUpdateInterfaceInformation : %d", interfaces);
-
-    for (int32_t i = 0; i < interfaces; i++)
-    {
-        struct ifreq temp_ifr = { 0 };
-        struct ifreq* item = &ifr[i];
-
-        char interfaceAddress[CA_IPADDR_SIZE] = { 0 };
-        char interfaceSubnetMask[CA_IPADDR_SIZE] = { 0 };
-        socklen_t len = sizeof(struct sockaddr_in);
-
-        strcpy(temp_ifr.ifr_name, item->ifr_name);
-
-        if (ioctl(sck, SIOCGIFFLAGS, &temp_ifr))
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG,
-                    "CAIPUpdateInterfaceInformation, SIOCGIFFLAGS Failed");
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
-
-        if ((temp_ifr.ifr_flags & IFF_LOOPBACK)
-            || !(temp_ifr.ifr_flags & IFF_UP) || !(temp_ifr.ifr_flags & IFF_RUNNING))
-        {
-            continue;
-        }
-
-        if (AF_INET != ((struct sockaddr_in*) &item->ifr_addr)->sin_family)
-        {
-            continue;
-        }
-
-        //get the interface ip address
-        if (0 != getnameinfo(&item->ifr_addr, len, interfaceAddress, sizeof(interfaceAddress),
-                             NULL, 0, NI_NUMERICHOST))
-        {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
-                    strerror(errno));
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
-
-        if (ioctl((int) sck, SIOCGIFNETMASK, item) < 0)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG,
-                    "CAIPUpdateInterfaceInformation, SIOCGIFNETMASK Failed");
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
-
-        // get the interface subnet mask
-        if (0 != getnameinfo(&item->ifr_netmask, len, interfaceSubnetMask,
-                             sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
-        {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
-                    strerror(errno));
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
-
-        CANetInfo_t *netInfo = (CANetInfo_t *) OICCalloc(1, sizeof(CANetInfo_t));
-        if (!netInfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
-            close(sck);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        // set interface name
-        strncpy(netInfo->interfaceName, item->ifr_name, strlen(item->ifr_name));
-
-        // set local ip address
-        strncpy(netInfo->ipAddress, interfaceAddress, strlen(interfaceAddress));
-
-        // set subnet mask
-        strncpy(netInfo->subnetMask, interfaceSubnetMask, strlen(interfaceSubnetMask));
-
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) netInfo);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!Thread exiting.");
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
-
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "ipAddress : %s, interfaceName : %s, subnetmask : %s",
-                netInfo->ipAddress, netInfo->interfaceName, netInfo->subnetMask);
-        close(sck);
-        return CA_STATUS_OK;
-
-        break;
-    }
-
     close(sck);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_FAILED;
+    ip = inet_ntoa(((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr);
+    len = sizeof(address) - 1;
+    strncpy(address, ip, len);
+    address[len] = '\0';
+    return address;
 }
 
-static bool CACheckIsAnyInterfaceDown(const u_arraylist_t *netInterfaceList,
-                                      const CANetInfo_t *info)
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
 {
-    VERIFY_NON_NULL_RET(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null", false);
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
-
-    uint32_t list_length = u_arraylist_length(netInterfaceList);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, list_index);
-        if (!netInfo)
-        {
-            continue;
-        }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
-        {
-            return false;
-        }
+        OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+        return NULL;
     }
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-    return true;
-}
-
-static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    char* ipAddr = getHostIPAddress("wlan0");
+    if (NULL == ipAddr)
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(
-                               g_networkMonitorContext->netInterfaceList, list_index);
-        if (!netInfo)
-        {
-            continue;
-        }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
-        {
-            if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
-            {
-                ca_mutex_unlock(g_networkMonitorContextMutex);
-                return false;
-            }
-            else
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
-                if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
-                {
-                    if (g_networkMonitorContext->networkChangeCb)
-                    {
-                        g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
-                                                                 CA_INTERFACE_DOWN);
-                    }
-                    OICFree(netInfo);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                }
-                break;
-            }
-        }
-    }
+        OIC_LOG_V(ERROR, TAG, "Failed to get ifaddrs: %s", strerror(errno));
+        u_arraylist_destroy(iflist);
+        return NULL;
+    } 
+    OIC_LOG_V(DEBUG, TAG, "Got ifaddrs:: %s", ipAddr);
 
-    CANetInfo_t *newNetInfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-    if (!newNetInfo)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    memcpy(newNetInfo, info, sizeof(*newNetInfo));
+    struct in_addr inaddr;
+    inet_pton(AF_INET, ipAddr, &(inaddr));
 
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));;
+    OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, "wlan0");
+    ifitem->index = 0; //if_nametoindex("wlan0");
+    ifitem->family = AF_INET; //we support ipv4 only
+    ifitem->ipv4addr = inaddr.s_addr;
+    ifitem->flags = IFF_UP|IFF_RUNNING;
 
-    CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
-                                        (void *) newNetInfo);
+    CAResult_t result = u_arraylist_add(iflist, ifitem);
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-        OICFree(newNetInfo);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    /*Callback will be unset only at the time of termination. By that time, all the threads will be
-      stopped gracefully. This callback is properly protected*/
-    if (g_networkMonitorContext->networkChangeCb)
-    {
-        g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
-    }
-
-    return true;
-}
-
-static CAResult_t CAInitializeNetworkMonitorMutexes()
-{
-    if (!g_networkMonitorContextMutex)
-    {
-        g_networkMonitorContextMutex = ca_mutex_new();
-        if (!g_networkMonitorContextMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc  failed");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+        goto exit;
     }
 
-    if (!g_stopNetworkMonitorMutex)
-    {
-        g_stopNetworkMonitorMutex = ca_mutex_new();
-        if (!g_stopNetworkMonitorMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_stopNetworkMonitorMutex Malloc  failed");
-            ca_mutex_free(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-    return CA_STATUS_OK;
-}
+    OIC_LOG_V(ERROR, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
 
-static void CADestroyNetworkMonitorMutexes()
-{
-    ca_mutex_free(g_networkMonitorContextMutex);
-    g_networkMonitorContextMutex = NULL;
-
-    ca_mutex_free(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitorMutex = NULL;
-}
-
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPInitializeNetworkMonitor IN");
-
-    VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
-    CAResult_t ret = CAIPJniInit();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Initialization failed");
-        return ret;
-    }
-
-    ret = CAIPJniSetContext();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPJniSetContext failed");
-        return ret;
-    }
-
-    ret = CACreateIPJNIInterfaceObject(g_context);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create caipinterface instance");
-        return ret;
-    }
-
-    ret = CAInitializeNetworkMonitorMutexes();
-
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
-        return CA_STATUS_FAILED;
-    }
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext = (CAIPNetworkMonitorContext *) OICCalloc(
-            1, sizeof(*g_networkMonitorContext));
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc  failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    g_networkMonitorContext->threadPool = threadPool;
-
-    g_networkMonitorContext->netInterfaceList = u_arraylist_create();
-    if (!g_networkMonitorContext->netInterfaceList)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
-        OICFree(g_networkMonitorContext);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    CAIPUpdateInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
-    if (u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_UP;
-    }
-    else
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    g_networkMonitorContext->threadPool = NULL;
-
-    CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
-
-    g_networkMonitorContext->netInterfaceList = NULL;
-    g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    g_networkMonitorContext->networkChangeCb = NULL;
-    g_networkMonitorContext->threadPool = NULL;
-
-    OICFree(g_networkMonitorContext);
-    g_networkMonitorContext = NULL;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitor = true;
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    CADestroyNetworkMonitorMutexes();
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitor = false;
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStopNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    if (!g_stopNetworkMonitor)
-    {
-        g_stopNetworkMonitor = true;
-    }
-    else
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStopNetworkMonitor, already stopped!");
-    }
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
-            list_length);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
-                  info->ipAddress);
-        CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-        if (!newNetinfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        memcpy(newNetinfo, info, sizeof(*info));
-
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) newNetinfo);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
-    VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
-        {
-            OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
-                      "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
-            *subnetMask = OICStrdup(info->subnetMask);
-            break;
-        }
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-bool CAIPIsConnected()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        return false;
-    }
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return true;
-}
-
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
-        return;
-    }
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext->networkChangeCb = callback;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-
-    if (g_stopNetworkMonitor)
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Stop Network Monitor Thread is called");
-        ca_mutex_unlock(g_stopNetworkMonitorMutex);
-        return;
-    }
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if(!g_networkMonitorContext)
-    {
-       OIC_LOG(DEBUG, IP_MONITOR_TAG, "g_networkChangeCb is NULL");
-       ca_mutex_unlock(g_networkMonitorContextMutex);
-       return;
-    }
-    if (!g_networkMonitorContext->networkChangeCb)
-    {    
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkChangeCb->networkChangeCb is NULL");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-  
-    u_arraylist_t *netInterfaceList = u_arraylist_create();
-
-    VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG,
-                         "memory allocation failed for netInterfaceList");
-
-    // if network status is changed
-    CAResult_t ret = CAIPUpdateInterfaceInformation(&netInterfaceList);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "could not update interface information");
-    }
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG,
-                "u_arraylist_create failed. Network Monitor thread stopped");
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
-    }
-
-    uint32_t listLength = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (uint32_t listIndex = 0; listIndex < listLength;)
-    {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, listIndex);
-        if (!info)
-        {
-            listIndex++;
-            continue;
-        }
-
-        bool ret = CACheckIsAnyInterfaceDown(netInterfaceList, info);
-        if (ret)
-        {
-            OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-            if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, listIndex))
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "u_arraylist_remove success");
-                if (g_networkMonitorContext->networkChangeCb)
-                {
-                    g_networkMonitorContext->networkChangeCb(info->ipAddress, CA_INTERFACE_DOWN);
-                }
-                OICFree(info);
-                listLength--;
-            }
-            else
-            {
-                OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                break;
-            }
-        }
-        else
-        {
-            listIndex++;
-        }
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    listLength = u_arraylist_length(netInterfaceList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
-        if (!info)
-        {
-            continue;
-        }
-        bool ret = CACheckIsInterfaceInfoChanged(info);
-        if (ret)
-        {
-            OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
-        }
-    }
-
-    CAClearNetInterfaceInfoList(netInterfaceList);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-JNIEXPORT void JNICALL Java_org_iotivity_ca_CaIpInterface_stateEnabled
-  (JNIEnv *env, jclass clazz)
-{
-    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_UP;
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStateEnabled");
-
-    CAIPSendNetworkChangeCallback(currNetworkStatus);
-}
-
-JNIEXPORT void JNICALL Java_org_iotivity_ca_CaIpInterface_stateDisabled
-  (JNIEnv *env, jclass clazz)
-{
-    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_DOWN;
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStateDisabled");
+    return iflist;
 
-    CAIPSendNetworkChangeCallback(currNetworkStatus);
+exit:
+    u_arraylist_destroy(iflist);
+    return NULL;
 }
 
index 1d66553..dbd2edf 100644 (file)
@@ -1,27 +1,47 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */\r
+/******************************************************************\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
 #include <jni.h>\r
 /* Header for class org_iotivity_ca_CaIpInterface */\r
 \r
 #ifndef _Included_org_iotivity_ca_CaIpInterface\r
 #define _Included_org_iotivity_ca_CaIpInterface\r
 #ifdef __cplusplus\r
-extern "C" {\r
+extern "C"\r
+{\r
 #endif\r
 /*\r
- * Class:     org_iotivity_ca_CaIpInterface\r
- * Method:    stateEnabled\r
+ * Class:     org_iotivity_ca_caIpInterface\r
+ * Method:    CaIpStateEnabled\r
  * Signature: ()V\r
  */\r
-JNIEXPORT void JNICALL Java_org_iotivity_ca_CaIpInterface_stateEnabled\r
-  (JNIEnv *, jclass);\r
+JNIEXPORT void JNICALL\r
+Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *, jclass);\r
 \r
 /*\r
- * Class:     org_iotivity_ca_CaIpInterface\r
- * Method:    stateDisabled\r
+ * Class:     org_iotivity_ca_caIpInterface\r
+ * Method:    CaIpStateDisabled\r
  * Signature: ()V\r
  */\r
-JNIEXPORT void JNICALL Java_org_iotivity_ca_CaIpInterface_stateDisabled\r
-  (JNIEnv *, jclass);\r
+JNIEXPORT void JNICALL\r
+Java_org_iotivity_ca_CaIpInterface_caIpStateDisabled(JNIEnv *, jclass);\r
 \r
 #ifdef __cplusplus\r
 }\r
diff --git a/resource/csdk/connectivity/src/ip_adapter/arduino/SConscript b/resource/csdk/connectivity/src/ip_adapter/arduino/SConscript
new file mode 100644 (file)
index 0000000..6e33f93
--- /dev/null
@@ -0,0 +1,20 @@
+#######################################################
+#       Build IP adapter for Ardunino
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.AppendUnique(CPPPATH = [ os.path.join(src_dir, 'arduino') ])
+
+if env.get('SHIELD') == 'WIFI':
+    src_files = [ 'caipclient_wifi.cpp',
+                   'caipserver_wifi.cpp',
+                   'caipnwmonitor_wifi.cpp' ]
+else:
+    src_files = [ 'caipadapterutils_eth.cpp',
+                   'caipclient_eth.cpp',
+                   'caipserver_eth.cpp',
+                   'caipnwmonitor_eth.cpp' ]
+
+Return('src_files')
index 534d3a4..60317e5 100644 (file)
@@ -29,7 +29,6 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
 #include "caadapterutils.h"
 
 #define TAG "IPU"
index c6b8213..668cfca 100644 (file)
@@ -36,7 +36,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
+#include "caipadapter.h"
 #include "caadapterutils.h"
 
 #ifdef __cplusplus
index 95b9334..3e234df 100644 (file)
@@ -17,7 +17,7 @@
 * limitations under the License.
 *
 ******************************************************************/
-#include "caipinterface_singlethread.h"
+#include "caipinterface.h"
 
 #include <Arduino.h>
 #include <Ethernet.h>
@@ -29,7 +29,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
+#include "caipadapter.h"
 #include "caipadapterutils_eth.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
@@ -68,26 +68,26 @@ void CAIPSetUnicastPort(uint16_t port)
     return;
 }
 
-uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
-                      const char *buf, uint32_t bufLen, bool isMulticast)
+void CAIPSendData(CAEndpoint_t *endpoint, const void *buf,
+                  uint32_t bufLen, bool isMulticast)
 {
     if (!isMulticast && 0 == g_unicastPort)
     {
         OIC_LOG(ERROR, TAG, "port 0");
-        return 0;
+        return;
     }
 
-    VERIFY_NON_NULL(buf, TAG, "buf");
-    VERIFY_NON_NULL(remoteAddress, TAG, "address");
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
 
     int socketID = 0;
+    uint16_t port = endpoint->port;
     if (isMulticast)
     {
-        if (CAArduinoInitMulticastUdpSocket(remoteAddress, port, g_unicastPort, &socketID)
-            != CA_STATUS_OK)
+        if (CAArduinoInitMulticastUdpSocket(endpoint->addr, port,
+                                            g_unicastPort, &socketID) != CA_STATUS_OK)
         {
             OIC_LOG(ERROR, TAG, "init mcast err");
-            return 0;
+            return;
         }
         OIC_LOG_V(DEBUG, TAG, "MPORT:%d", port);
         OIC_LOG_V(DEBUG, TAG, "LPORT:%d", g_unicastPort);
@@ -100,7 +100,7 @@ uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
             if (CAArduinoInitUdpSocket(&port, &socketID) != CA_STATUS_OK)
             {
                 OIC_LOG(ERROR, TAG, "init ucast err");
-                return 0;
+                return;
             }
         }
         else
@@ -112,27 +112,30 @@ uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
     uint32_t ret;
     uint8_t ipAddr[4] = { 0 };
     uint16_t parsedPort = 0;
-    if (CAParseIPv4AddressInternal(remoteAddress, ipAddr, sizeof(ipAddr),
+    if (CAParseIPv4AddressInternal(endpoint->addr, ipAddr, sizeof(ipAddr),
                                    &parsedPort) != CA_STATUS_OK)
     {
         OIC_LOG(ERROR, TAG, "parse fail");
-        return 0;
+        return;
     }
 
     if (bufLen > 65535) // Max value for uint16_t
     {
         // This will never happen as max buffer size we are dealing with is COAP_MAX_PDU_SIZE
         OIC_LOG(ERROR, TAG, "Size exceeded");
-        return 0;
+        return;
     }
 
     ret = sendto(socketID, (const uint8_t *)buf, (uint16_t)bufLen, ipAddr, port);
+    if (ret <= 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "SendData failed: %d", ret);
+    }
     if (g_sockID != socketID)
     {
         close(socketID);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
-    return ret;
 }
 
index 38acd84..9dda5aa 100644 (file)
@@ -17,7 +17,7 @@
 * limitations under the License.
 *
 ******************************************************************/
-#include "caipinterface_singlethread.h"
+#include "caipinterface.h"
 
 #include <Arduino.h>
 #include <WiFi.h>
@@ -30,7 +30,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
+#include "caipadapter.h"
 #include "caadapterutils.h"
 
 /// This is the max buffer size between Arduino and WiFi Shield
@@ -49,32 +49,32 @@ void CAIPSetUnicastPort(uint16_t port)
 
 }
 
-uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
-                      const char *data, uint32_t dataLength, bool isMulticast)
+void CAIPSendData(CAEndpoint_t *endpoint,
+                  const void *data, uint32_t dataLength, bool isMulticast)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_RET(data, TAG, "data", 0);
-    VERIFY_NON_NULL_RET(remoteAddress, TAG, "address", 0);
+    VERIFY_NON_NULL_VOID(data, TAG, "data");
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
 
-    OIC_LOG_V(DEBUG, TAG, "remoteip: %s", remoteAddress);
-    OIC_LOG_V(DEBUG, TAG, "port: %d", port);
+    OIC_LOG_V(DEBUG, TAG, "remoteip: %s", endpoint->addr);
+    OIC_LOG_V(DEBUG, TAG, "port: %d", endpoint->port);
 
     uint8_t ip[4] = {0};
     uint16_t parsedPort = 0;
-    CAResult_t res = CAParseIPv4AddressInternal(remoteAddress, ip, sizeof(ip),
+    CAResult_t res = CAParseIPv4AddressInternal(endpoint->addr, ip, sizeof(ip),
                                                 &parsedPort);
     if (res != CA_STATUS_OK)
     {
         OIC_LOG_V(ERROR, TAG, "Remote adrs parse fail %d", res);
-        return 0;
+        return;
     }
 
     IPAddress remoteIp(ip);
-    Udp.beginPacket(remoteIp, (uint16_t)port);
+    Udp.beginPacket(remoteIp, endpoint->port);
 
     uint32_t bytesWritten = 0;
-    while(bytesWritten < dataLength)
+    while (bytesWritten < dataLength)
     {
         // get remaining bytes
         size_t writeCount = dataLength - bytesWritten;
@@ -94,9 +94,9 @@ uint32_t CAIPSendData(const char *remoteAddress, uint16_t port,
     if (Udp.endPacket() == 0)
     {
         OIC_LOG(ERROR, TAG, "Failed to send");
-        return 0;
+        return;
     }
     OIC_LOG(DEBUG, TAG, "OUT");
-    return bytesWritten;
+    return;
 }
 
diff --git a/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor.cpp b/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor.cpp
deleted file mode 100644 (file)
index a64142a..0000000
+++ /dev/null
@@ -1,63 +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 caipnwmonitor.cpp
- * @brief This file is to keep design in sync with other platforms.  Right now there is no
- *        api for network monitioring in arduino.
- */
-
-#include "caipinterface_singlethread.h"
-
-#define TAG "IPNW"
-
-CAResult_t CAIPInitializeNetworkMonitor(void)
-{
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStartNetworkMonitor(void)
-{
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceInfo(char **ipAddress, char **interfaceName)
-{
-    return CA_STATUS_OK;
-}
-
-bool CAIPIsConnected(void)
-{
-    return true;
-}
-
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    return;
-}
-
-CAResult_t CAIPStopNetworkMonitor(void)
-{
-    return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor(void)
-{
-    return;
-}
diff --git a/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_eth.cpp b/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_eth.cpp
new file mode 100644 (file)
index 0000000..afedf68
--- /dev/null
@@ -0,0 +1,105 @@
+/******************************************************************
+*
+* 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 caipnwmonitor.cpp
+ * @brief This file is to keep design in sync with other platforms.  Right now there is no
+ *        api for network monitoring in arduino.
+ */
+
+#include "caipinterface.h"
+
+#include <Arduino.h>
+#include <Ethernet.h>
+#include <socket.h>
+#include <w5100.h>
+#include <EthernetUdp.h>
+#include <IPAddress.h>
+
+#include "logger.h"
+#include "cacommon.h"
+#include "caipadapter.h"
+#include "caadapterutils.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#define TAG "IPNW"
+
+// Since the CA abstraction expects a value for "family", AF_INET will be
+// defined & used (as-is defined in the linux socket headers).
+#define AF_INET (2)
+
+/// Retrieves the IP address assigned to Arduino Ethernet shield
+void CAArduinoGetInterfaceAddress(uint32_t *address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_VOID(address, TAG, "address");
+
+    //TODO : Fix this for scenarios when this API is invoked when device is not connected
+    uint8_t rawIPAddr[4];
+    W5100.getIPAddress(rawIPAddr);
+    *address = (uint32_t) rawIPAddr;
+
+    OIC_LOG_V(DEBUG, TAG, "address:%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1],
+              rawIPAddr[2], rawIPAddr[3]);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return;
+}
+
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
+{
+    CAResult_t result;
+
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to create iflist");
+        return NULL;
+    }
+
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
+    if (!ifitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        goto exit;
+    }
+
+    // Since Arduino currently only supports one interface, the next 4 lines are sufficient.
+    OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, "ETH");
+    ifitem->index = 1;
+    ifitem->family = AF_INET;
+    ifitem->flags = 0;
+    CAArduinoGetInterfaceAddress(&ifitem->ipv4addr);
+
+    result = u_arraylist_add(iflist, ifitem);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+        goto exit;
+    }
+
+    OIC_LOG_V(ERROR, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
+
+    return iflist;
+
+exit:
+    u_arraylist_destroy(iflist);
+    return NULL;
+}
+
diff --git a/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_wifi.cpp b/resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_wifi.cpp
new file mode 100644 (file)
index 0000000..e137f15
--- /dev/null
@@ -0,0 +1,109 @@
+/******************************************************************
+*
+* 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 caipnwmonitor.cpp
+ * @brief This file is to keep design in sync with other platforms.  Right now there is no
+ *        api for network monitoring in arduino.
+ */
+
+#include "caipinterface.h"
+
+#include <Arduino.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#include <SPI.h>
+#include <utility/server_drv.h>
+#include <utility/wifi_drv.h>
+#include <IPAddress.h>
+
+#include "logger.h"
+#include "cacommon.h"
+#include "caipadapter.h"
+#include "caadapterutils.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#define TAG "IPNW"
+
+// Since the CA abstraction expects a value for "family", AF_INET will be
+// defined & used (as-is defined in the linux socket headers).
+#define AF_INET (2)
+
+/// Retrieves the IP address assigned to Arduino WiFi shield
+void CAArduinoGetInterfaceAddress(uint32_t *address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (WiFi.status() != WL_CONNECTED)
+    {
+        OIC_LOG(DEBUG, TAG, "No WIFI");
+        return;
+    }
+
+    VERIFY_NON_NULL_VOID(address, TAG, "Invalid address");
+
+    IPAddress ip = WiFi.localIP();
+    *address = (uint32_t) ip;
+
+    OIC_LOG_V(DEBUG, TAG, "Wifi shield address is: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return;
+}
+
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
+{
+    CAResult_t result = CA_STATUS_OK;
+
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to create iflist");
+        return NULL;
+    }
+
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
+    if (!ifitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        goto exit;
+    }
+
+    // Since Arduino currently only supports one interface, the next 4 lines are sufficient.
+    OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, "WIFI");
+    ifitem->index = 1;
+    ifitem->family = AF_INET;
+    ifitem->flags = 0;
+    CAArduinoGetInterfaceAddress(&ifitem->ipv4addr);
+
+    result = u_arraylist_add(iflist, ifitem);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+        goto exit;
+    }
+
+    OIC_LOG_V(ERROR, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
+
+    return iflist;
+
+exit:
+    u_arraylist_destroy(iflist);
+    return NULL;
+}
+
index 0b7f3df..09098dc 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "caipinterface_singlethread.h"
+#include "caipinterface.h"
 
 #include <Arduino.h>
 #include <Ethernet.h>
 #include "cacommon.h"
 #include "cainterface.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
+#include "caipadapter.h"
 #include "caipadapterutils_eth.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 
 #define TAG "IPS"
 
@@ -44,7 +45,6 @@
 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
                                         const bool forceStart, int32_t *serverFD);
 static CAResult_t CAArduinoRecvData(int32_t sockFd);
-static CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
 static void CAArduinoCheckData();
 static void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
                               const void *data, const uint32_t dataLength);
@@ -54,12 +54,18 @@ static int g_unicastSocket = 0;
 static int g_multicastSocket = 0;
 
 /**
+ * @var g_isMulticastServerStarted
+ * @brief Flag to check if multicast server is started
+ */
+static bool g_isMulticastServerStarted = false;
+
+/**
  * @var g_unicastPort
  * @brief Unicast Port
  */
 static uint16_t g_unicastPort = 0;
 
-CAResult_t CAIPInitializeServer(void)
+CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
 {
     return CA_STATUS_OK;
 }
@@ -69,14 +75,13 @@ void CAIPTerminateServer(void)
     return;
 }
 
-CAResult_t CAIPGetUnicastServerInfo(char **ipAddress, uint16_t *port,
-                                          int *serverID)
+uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
 {
-    return CA_STATUS_OK;
+    return g_unicastPort;
 }
 
 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
-                                        const bool forceStart, int *serverFD)
+                                  bool secured)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL(port, TAG, "port");
@@ -86,15 +91,17 @@ CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
     W5100.getIPAddress(rawIPAddr);
     sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
     OIC_LOG_V(DEBUG, TAG, "address:%s", address);
-
-    if (CAArduinoInitUdpSocket(port, serverFD) != CA_STATUS_OK)
+    int serverFD = 1;
+    if (CAArduinoInitUdpSocket(port, &serverFD) != CA_STATUS_OK)
     {
         OIC_LOG(DEBUG, TAG, "failed");
         return CA_STATUS_FAILED;
     }
 
     g_unicastPort = *port;
-    g_unicastSocket = *serverFD;
+    g_unicastSocket = serverFD;
+    CAIPSetUnicastSocket(g_unicastSocket);
+    CAIPSetUnicastPort(g_unicastPort);
     OIC_LOG_V(DEBUG, TAG, "g_unicastPort: %d", g_unicastPort);
     OIC_LOG_V(DEBUG, TAG, "g_unicastSocket: %d", g_unicastSocket);
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -102,23 +109,47 @@ CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
 }
 
 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
-                                    uint16_t multicastPort, int *serverFD)
+                                    uint16_t multicastPort)
 {
     OIC_LOG(DEBUG, TAG, "IN");
+    if (g_isMulticastServerStarted == true)
+    {
+        OIC_LOG(ERROR, TAG, "Already Started!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+    int serverFD = 1;
     if (CAArduinoInitMulticastUdpSocket(multicastAddress, multicastPort, multicastPort,
-                                        serverFD) != CA_STATUS_OK)
+                                        &serverFD) != CA_STATUS_OK)
     {
         OIC_LOG(DEBUG, TAG, "failed");
         return CA_STATUS_FAILED;
     }
 
-    g_multicastSocket = *serverFD;
+    g_multicastSocket = serverFD;
+    g_isMulticastServerStarted = true;
     OIC_LOG_V(DEBUG, TAG, "gMulticastPort: %d", multicastPort);
     OIC_LOG_V(DEBUG, TAG, "g_multicastSocket: %d", g_multicastSocket);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
+CAResult_t CAIPStartServer()
+{
+    uint16_t unicastPort = 55555;
+
+    CAResult_t ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Start unicast serv failed[%d]", ret);
+    }
+    ret = CAIPStartMulticastServer("0.0.0.0", "224.0.1.187", 5683);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
+    }
+    return ret;
+}
+
 CAResult_t CAIPStopUnicastServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -137,13 +168,38 @@ CAResult_t CAIPStopMulticastServer()
     return CA_STATUS_OK;
 }
 
+void CAIPStopServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t result = CAIPStopUnicastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
+        return;
+    }
+    CAIPSetUnicastSocket(-1);
+    CAIPSetUnicastPort(0);
+
+    result = CAIPStopMulticastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
 void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
                               const void *data, const uint32_t dataLength)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     if (g_packetReceivedCallback)
     {
-        g_packetReceivedCallback(ipAddress, port, data, dataLength);
+        CAEndpoint_t ep;
+        strncpy(ep.addr, ipAddress, MAX_ADDR_STR_SIZE_CA);
+        ep.port = port;
+        ep.flags = CA_IPV4;
+        ep.adapter = CA_ADAPTER_IP;
+        g_packetReceivedCallback(&ep, data, dataLength);
     }
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -235,30 +291,58 @@ void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
     // TODO
 }
 
+void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
 void CAIPPullData()
 {
     CAArduinoCheckData();
 }
 
-/// Retrieves the IP address assigned to Arduino Ethernet shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
+CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(address, TAG, "address");
 
-    //TODO : Fix this for scenarios when this API is invoked when device is not connected
-    uint8_t rawIPAddr[4];
-    if (addrLen < IPNAMESIZE)
+    VERIFY_NON_NULL(info, TAG, "info is NULL");
+    VERIFY_NON_NULL(size, TAG, "size is NULL");
+
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
     {
-        OIC_LOG(ERROR, TAG, "Invalid addrLen");
+        OIC_LOG(ERROR, TAG, "get interface info failed");
         return CA_STATUS_FAILED;
     }
 
-    W5100.getIPAddress(rawIPAddr);
-    snprintf(address, sizeof(address), "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2],
-             rawIPAddr[3]);
+    uint32_t len = u_arraylist_length(iflist);
+
+    CAEndpoint_t *eps = (CAEndpoint_t *)OICCalloc(len, sizeof (CAEndpoint_t));
+    if (!eps)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc Failed");
+        u_arraylist_destroy(iflist);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    for (uint32_t i = 0, j = 0; i < len; i++)
+    {
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+
+        OICStrcpy(eps[j].addr, CA_INTERFACE_NAME_SIZE, ifitem->name);
+        eps[j].flags = CA_IPV4;
+        eps[j].adapter = CA_ADAPTER_IP;
+        eps[j].interface = 0;
+        eps[j].port = 0;
+        j++;
+    }
+
+    *info = eps;
+    *size = len;
+
+    u_arraylist_destroy(iflist);
 
-    OIC_LOG_V(DEBUG, TAG, "address:%s", address);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
index 97dd582..153dc52 100644 (file)
@@ -18,7 +18,7 @@
 *
 ******************************************************************/
 
-#include "caipinterface_singlethread.h"
+#include "caipinterface.h"
 
 #include <Arduino.h>
 #include <WiFi.h>
 #include "cacommon.h"
 #include "cainterface.h"
 #include "caadapterinterface.h"
-#include "caipadapter_singlethread.h"
+#include "caipadapter.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 
 #define TAG "IPS"
 
@@ -49,7 +50,6 @@
 #define IP_RECBUF_PORT_SIZE      (IP_RECBUF_PORT_OFFSET - 0)
 #define IP_RECBUF_FOOTER_SIZE    (IP_RECBUF_IPADDR_SIZE + IP_RECBUF_PORT_SIZE)
 
-static CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
 static void CAArduinoCheckData();
 static void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
                                      const void *data, const uint32_t dataLength);
@@ -58,8 +58,13 @@ static CAIPPacketReceivedCallback gPacketReceivedCallback = NULL;
 static int32_t gUnicastSocket = 0;
 static bool gServerRunning = false;
 static WiFiUDP Udp;
+/**
+ * @var g_unicastPort
+ * @brief Unicast Port
+ */
+static uint16_t g_unicastPort = 0;
 
-CAResult_t CAIPInitializeServer(void)
+CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
 {
     /**
      * This API is to keep design in sync with other platforms.
@@ -76,17 +81,13 @@ void CAIPTerminateServer(void)
      */
 }
 
-CAResult_t CAIPGetUnicastServerInfo(char **ipAddress, uint16_t *port, int *serverID)
+uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
 {
-    /*
-     * This API is to keep design in sync with other platforms.
-     * Will be implemented as and when CA layer wants this info.
-     */
-    return CA_STATUS_OK;
+    return g_unicastPort;
 }
 
 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
-                                  bool forceStart, int *serverFD)
+                                  bool secured)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL(port, TAG, "port");
@@ -104,21 +105,17 @@ CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
         return CA_STATUS_FAILED;
     }
 
-    char localIpAddress[CA_IPADDR_SIZE];
-    int32_t localIpAddressLen = sizeof(localIpAddress);
-    CAArduinoGetInterfaceAddress(localIpAddress, localIpAddressLen);
-    OIC_LOG_V(DEBUG, TAG, "address: %s", localIpAddress);
     OIC_LOG_V(DEBUG, TAG, "port: %d", *port);
 
     Udp.begin((uint16_t ) *port);
     gServerRunning = true;
-
+    g_unicastPort = *port;
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
-                                      uint16_t multicastPort, int *serverFD)
+                                      uint16_t multicastPort)
 {
     // wifi shield does not support multicast
     OIC_LOG(DEBUG, TAG, "IN");
@@ -126,6 +123,23 @@ CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multic
     return CA_NOT_SUPPORTED;
 }
 
+CAResult_t CAIPStartServer()
+{
+    uint16_t unicastPort = 55555;
+
+    CAResult_t ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Start unicast serv failed[%d]", ret);
+    }
+    ret = CAIPStartMulticastServer("0.0.0.0", "224.0.1.187", 5683);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Start multicast failed[%d]", ret);
+    }
+    return ret;
+}
+
 CAResult_t CAIPStopUnicastServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -141,13 +155,38 @@ CAResult_t CAIPStopMulticastServer()
     return CAIPStopUnicastServer();
 }
 
+void CAIPStopServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t result = CAIPStopUnicastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
+        return;
+    }
+    CAIPSetUnicastSocket(-1);
+    CAIPSetUnicastPort(0);
+
+    result = CAIPStopMulticastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
 void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
                               const void *data, const uint32_t dataLength)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     if (gPacketReceivedCallback)
     {
-        gPacketReceivedCallback(ipAddress, port, data, dataLength);
+        CAEndpoint_t ep;
+        strncpy(ep.addr, ipAddress, MAX_ADDR_STR_SIZE_CA);
+        ep.port = port;
+        ep.flags = CA_IPV4;
+        ep.adapter = CA_ADAPTER_IP;
+        gPacketReceivedCallback(&ep, data, dataLength);
         OIC_LOG(DEBUG, TAG, "Notified network packet");
     }
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -196,35 +235,59 @@ void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
     // TODO
 }
 
+void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
 void CAIPPullData()
 {
     CAArduinoCheckData();
 }
 
-/// Retrieves the IP address assigned to Arduino WiFi shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
+CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    if (WiFi.status() != WL_CONNECTED)
+
+    VERIFY_NON_NULL(info, TAG, "info is NULL");
+    VERIFY_NON_NULL(size, TAG, "size is NULL");
+
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
     {
-        OIC_LOG(DEBUG, TAG, "No WIFI");
+        OIC_LOG(ERROR, TAG, "get interface info failed");
         return CA_STATUS_FAILED;
     }
 
-    VERIFY_NON_NULL(address, TAG, "Invalid address");
-    if (addrLen < IPNAMESIZE)
+    uint32_t len = u_arraylist_length(iflist);
+
+    CAEndpoint_t *eps = (CAEndpoint_t *)OICCalloc(len, sizeof (CAEndpoint_t));
+    if (!eps)
     {
-        OIC_LOG_V(ERROR, TAG, "AddrLen MUST be atleast %d", IPNAMESIZE);
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, TAG, "Malloc Failed");
+        u_arraylist_destroy(iflist);
+        return CA_MEMORY_ALLOC_FAILED;
     }
 
-    IPAddress ip = WiFi.localIP();
-    sprintf((char *)address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    for (uint32_t i = 0, j = 0; i < len; i++)
+    {
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+
+        OICStrcpy(eps[j].addr, CA_INTERFACE_NAME_SIZE, ifitem->name);
+        eps[j].flags = CA_IPV4;
+        eps[j].adapter = CA_ADAPTER_IP;
+        eps[j].interface = 0;
+        eps[j].port = 0;
+        j++;
+    }
+
+    *info = eps;
+    *size = len;
+
+    u_arraylist_destroy(iflist);
 
-    OIC_LOG_V(DEBUG, TAG, "Wifi shield address is: %s", address);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-
-
index bd9af23..3a320bd 100644 (file)
 #endif
 #include "camutex.h"
 #include "uarraylist.h"
+#include "caremotehandler.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 
 /**
- * @def IP_ADAPTER_TAG
+ * @def TAG
  * @brief Logging tag for module name
  */
-#define IP_ADAPTER_TAG "IP_ADAP"
-
-/**
- * @def CA_PORT
- * @brief Port to listen for incoming data
- */
-#define CA_PORT   6298
-
-/**
- * @def CA_SECURE_PORT
- * @brief Secured (unicast) port number as defined in COAP Specification, RFC-7252.
- */
-#define CA_SECURE_PORT   5684
-
-/**
- * @def CA_MCAST_PORT
- * @brief Multicast port number as defined in COAP Specification, RFC-7252.
- */
-#define CA_MCAST_PORT   5683
-
-/**
- * @def CA_MULTICAST_IP
- * @brief Multicast IP Address as defined in COAP Specification, RFC-7252.
- */
-#define CA_MULTICAST_IP "224.0.1.187"
+#define TAG "IP_ADAP"
 
+#ifndef SINGLE_THREAD
 /**
  * @var CAIPData
  * @brief Holds inter thread ip data information.
  */
 typedef struct
 {
-    CARemoteEndpoint_t *remoteEndpoint;
+    CAEndpoint_t *remoteEndpoint;
     void *data;
     uint32_t dataLen;
+    bool isMulticast;
 } CAIPData;
 
 /**
+ * @var g_sendQueueHandle
+ * @brief Queue handle for Send Data
+ */
+static CAQueueingThread_t *g_sendQueueHandle = NULL;
+#endif
+
+/**
  * @var g_networkPacketCallback
  * @brief Network Packet Received Callback to CA
  */
@@ -89,51 +76,41 @@ static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
 static CANetworkChangeCallback g_networkChangeCallback = NULL;
 
 /**
- * @var g_sendQueueHandle
- * @brief Queue handle for Send Data
+ * @var g_errorCallback
+ * @brief error Callback to CA adapter
  */
-static CAQueueingThread_t *g_sendQueueHandle = NULL;
+static CAErrorHandleCallback g_errorCallback = NULL;
 
-/**
- * @var g_threadPool
- * @brief ThreadPool for storing ca_thread_pool_t handle passed from CA
- */
-static ca_thread_pool_t g_threadPool = NULL;
+static void CAIPPacketReceivedCB(const CAEndpoint_t *endpoint,
+                                 const void *data, uint32_t dataLength);
+#ifdef __WITH_DTLS__
+static void CAIPPacketSendCB(CAEndpoint_t *endpoint,
+                             const void *data, uint32_t dataLength);
+#endif
+
+#ifndef SINGLE_THREAD
 
 static CAResult_t CAIPInitializeQueueHandles();
 
 static void CAIPDeinitializeQueueHandles();
 
-static void CAIPNotifyNetworkChange(const char *address, uint16_t port,
-                                          CANetworkStatus_t status);
-
-static void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status);
-
-static void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port, const void *data,
-                                       uint32_t dataLength, bool isSecured);
-#ifdef __WITH_DTLS__
-static uint32_t CAIPPacketSendCB(const char *ipAddress, uint16_t port,
-                                       const void *data, uint32_t dataLength);
-#endif
-
-static CAResult_t CAIPStopServers();
-
 static void CAIPSendDataThread(void *threadData);
 
-static CAIPData *CACreateIPData(const CARemoteEndpoint_t *remoteEndpoint,
-                                            const void *data, uint32_t dataLength);
+static CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint,
+                                const void *data, uint32_t dataLength,
+                                bool isMulticast);
 void CAFreeIPData(CAIPData *ipData);
 
 static void CADataDestroyer(void *data, uint32_t size);
 
 CAResult_t CAIPInitializeQueueHandles()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     // Check if the message queue is already initialized
     if (g_sendQueueHandle)
     {
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "send queue handle is already initialized!");
+        OIC_LOG(DEBUG, TAG, "send queue handle is already initialized!");
         return CA_STATUS_OK;
     }
 
@@ -141,218 +118,170 @@ CAResult_t CAIPInitializeQueueHandles()
     g_sendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
     if (!g_sendQueueHandle)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
+        OIC_LOG(ERROR, TAG, "Memory allocation failed!");
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_threadPool,
-                                                   CAIPSendDataThread, CADataDestroyer))
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle,
+                                (const ca_thread_pool_t)caglobals.ip.threadpool,
+                                CAIPSendDataThread, CADataDestroyer))
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize send queue thread");
+        OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
         OICFree(g_sendQueueHandle);
         g_sendQueueHandle = NULL;
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CAIPDeinitializeQueueHandles()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     CAQueueingThreadDestroy(g_sendQueueHandle);
     OICFree(g_sendQueueHandle);
     g_sendQueueHandle = NULL;
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CAIPNotifyNetworkChange(const char *address, uint16_t port, CANetworkStatus_t status)
-{
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    VERIFY_NON_NULL_VOID(address, IP_ADAPTER_TAG, "address is NULL");
+#endif // SINGLE_THREAD
 
-    CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, address);
-    if (!localEndpoint)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "localEndpoint creation failed!");
-        return;
-    }
+void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+}
 
-    localEndpoint->addressInfo.IP.port = port;
+#ifdef __WITH_DTLS__
+static void CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    if (g_networkChangeCallback)
-    {
-        g_networkChangeCallback(localEndpoint, status);
-    }
-    else
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "g_networkChangeCallback is NULL");
-    }
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
 
-    CAAdapterFreeLocalEndpoint(localEndpoint);
+    CAIPSendData(endpoint, data, dataLength, false);
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
+#endif
 
-void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
+void CAIPPacketReceivedCB(const CAEndpoint_t *endpoint, const void *data,
+                          uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_VOID(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL");
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "ipAddress is NULL");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
 
-    if (CA_INTERFACE_UP == status)
-    {
-        uint16_t port = CA_PORT;
-        CAResult_t ret = CAIPStartUnicastServer(ipAddress, &port, false, false);
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port", port);
-        }
-        else
-        {
-            OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Unicast server port[%d]", ret);
-        }
+    OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", endpoint->addr, endpoint->port);
 
-#ifdef __WITH_DTLS__
-        port = CA_SECURE_PORT;
-        ret = CAIPStartUnicastServer(ipAddress, &port, false, true);
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Secure Unicast server started on %d", port);
-        }
-        else
-        {
-            OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start secure Unicast server [%d]",
-                      ret);
-        }
-#endif
-        ret = CAIPStartMulticastServer(ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT);
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Multicast server started on port[%d]",
-                      CA_MCAST_PORT);
-        }
-        else
-        {
-            OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Multicast server port[%d]",
-                      ret);
-        }
+    void *buf = OICCalloc(dataLength + 1, sizeof (char));
+    if (!buf)
+    {
+        OIC_LOG(ERROR, TAG, "Memory Allocation failed!");
+        return;
+    }
+    memcpy(buf, data, dataLength);
 
-        // Notify network change to CA
-        CAIPNotifyNetworkChange(ipAddress, port, status);
+    if (g_networkPacketCallback)
+    {
+        g_networkPacketCallback(endpoint, buf, dataLength);
     }
     else
     {
-        CAIPNotifyNetworkChange(ipAddress, 0, status);
-
-        // Stop Unicast, Secured unicast and Multicast servers
-        CAIPStopServer(ipAddress);
+        OICFree(buf);
     }
-
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-}
-
-#ifdef __WITH_DTLS__
-uint32_t CAIPPacketSendCB(const char *ipAddress, uint16_t port,
-        const void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    VERIFY_NON_NULL_RET(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL", 0);
-
-    VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data is NULL", 0);
-
-    uint32_t sentLength = CAIPSendData(ipAddress, port, data, dataLength, false, true);
-
-    OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Successfully sent %d of encrypted data!", sentLength);
-
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-
-    return sentLength;
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
-#endif
 
-void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port, const void *data,
-                                uint32_t dataLength, bool isSecured)
+void CAIPErrorHandler (const CAEndpoint_t *endpoint, const void *data,
+                       uint32_t dataLength, CAResult_t result)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    VERIFY_NON_NULL_VOID(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_VOID(data, IP_ADAPTER_TAG, "data is NULL");
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
 
-    OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Address: %s, port:%d", ipAddress, port);
-
-    // CA is freeing this memory
-    CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_IPV4, ipAddress, NULL );
-    if (!endPoint)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "EndPoint creation failed!");
-        return;
-    }
-    endPoint->addressInfo.IP.port = port;
-    endPoint->isSecured = isSecured;
+    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
 
-    void *buf = OICCalloc(dataLength + 1, sizeof(char));
+    void *buf = (void*)OICMalloc(sizeof(char) * dataLength);
     if (!buf)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory Allocation failed!");
-        CAAdapterFreeRemoteEndpoint(endPoint);
+        OIC_LOG(ERROR, TAG, "Memory Allocation failed!");
         return;
     }
     memcpy(buf, data, dataLength);
-    if (g_networkPacketCallback)
+    if (g_errorCallback)
     {
-        g_networkPacketCallback(endPoint, buf, dataLength);
+        g_errorCallback(endpoint, buf, dataLength, result);
     }
     else
     {
         OICFree(buf);
-        CAAdapterFreeRemoteEndpoint(endPoint);
     }
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static void CAInitializeIPGlobals()
+{
+    caglobals.ip.u6.fd  = -1;
+    caglobals.ip.u6s.fd = -1;
+    caglobals.ip.u4.fd  = -1;
+    caglobals.ip.u4s.fd = -1;
+    caglobals.ip.m6.fd  = -1;
+    caglobals.ip.m6s.fd = -1;
+    caglobals.ip.m4.fd  = -1;
+    caglobals.ip.m4s.fd = -1;
+    caglobals.ip.u6.port  = 0;
+    caglobals.ip.u6s.port = 0;
+    caglobals.ip.u4.port  = 0;
+    caglobals.ip.u4s.port = 0;
+    caglobals.ip.m6.port  = CA_COAP;
+    caglobals.ip.m6s.port = CA_SECURE_COAP;
+    caglobals.ip.m4.port  = CA_COAP;
+    caglobals.ip.m4s.port = CA_SECURE_COAP;
+
+    CATransportFlags_t flags = 0;
+    if (caglobals.client)
+    {
+        flags |= caglobals.clientFlags;
+    }
+    if (caglobals.server)
+    {
+        flags |= caglobals.serverFlags;
+    }
+    caglobals.ip.ipv6enabled = flags & CA_IPV6;
+    caglobals.ip.ipv4enabled = flags & CA_IPV4;
 }
 
 CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback networkPacketCallback,
-                                CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
+                          CANetworkPacketReceivedCallback networkPacketCallback,
+                          CANetworkChangeCallback netCallback,
+                          CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-    VERIFY_NON_NULL(registerCallback, IP_ADAPTER_TAG, "registerCallback");
-    VERIFY_NON_NULL(networkPacketCallback, IP_ADAPTER_TAG, "networkPacketCallback");
-    VERIFY_NON_NULL(netCallback, IP_ADAPTER_TAG, "netCallback");
-    VERIFY_NON_NULL(handle, IP_ADAPTER_TAG, "thread pool handle");
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
+    VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback");
+    VERIFY_NON_NULL(netCallback, TAG, "netCallback");
+#ifndef SINGLE_THREAD
+    VERIFY_NON_NULL(handle, TAG, "thread pool handle");
+#endif
 
-    g_threadPool = handle;
     g_networkChangeCallback = netCallback;
     g_networkPacketCallback = networkPacketCallback;
+    g_errorCallback = errorCallback;
 
-    CAResult_t ret = CAIPInitializeNetworkMonitor(g_threadPool);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
-        return ret;
-    }
-    CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
-
-    ret = CAIPInitializeServer(g_threadPool);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
-        CATerminateIP();
-        return ret;
-    }
+    CAInitializeIPGlobals();
+    caglobals.ip.threadpool = handle;
 
     CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
 #ifdef __WITH_DTLS__
     CAAdapterNetDtlsInit();
 
-    CADTLSSetAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, DTLS_IP);
+    CADTLSSetAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, 0);
 #endif
 
     CAConnectivityHandler_t ipHandler;
@@ -365,435 +294,234 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
     ipHandler.readData = CAReadIPData;
     ipHandler.stopAdapter = CAStopIP;
     ipHandler.terminate = CATerminateIP;
-    registerCallback(ipHandler, CA_IPV4);
-
-    if (CA_STATUS_OK != CAIPInitializeQueueHandles())
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize Queue Handle");
-        CATerminateIP();
-        return CA_STATUS_FAILED;
-    }
+    registerCallback(ipHandler, CA_ADAPTER_IP);
 
-    OIC_LOG(INFO, IP_ADAPTER_TAG, "OUT IntializeIP is Success");
+    OIC_LOG(INFO, TAG, "OUT IntializeIP is Success");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAStartIP()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    // Start monitoring IP network
-    CAResult_t ret = CAIPStartNetworkMonitor();
+#ifdef SINGLE_THREAD
+    uint16_t unicastPort = 55555;
+    // Address is hardcoded as we are using Single Interface
+    CAResult_t ret = CAIPStartServer();
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start n/w monitor");
+        OIC_LOG_V(DEBUG, TAG, "CAIPStartServer failed[%d]", ret);
         return ret;
     }
-
-    // Start send queue thread
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
+#else
+    if (CA_STATUS_OK != CAIPInitializeQueueHandles())
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start Send Data Thread");
+        OIC_LOG(ERROR, TAG, "Failed to Initialize Queue Handle");
+        CATerminateIP();
         return CA_STATUS_FAILED;
     }
 
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
+    // Start send queue thread
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
     {
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IP is not Connected");
-        return CA_STATUS_OK;
+        OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
+        return CA_STATUS_FAILED;
     }
 
-    u_arraylist_t *netInterfaceList = u_arraylist_create();
-
-    VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
-
-    ret = CAIPGetInterfaceInfo(&netInterfaceList);
+    CAResult_t ret = CAIPStartServer((const ca_thread_pool_t)caglobals.ip.threadpool);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret);
-        CAClearNetInterfaceInfoList(netInterfaceList);
+        OIC_LOG_V(ERROR, TAG, "Failed to start server![%d]", ret);
         return ret;
     }
 
-    uint32_t listIndex = 0;
-    uint32_t listLength = u_arraylist_length(netInterfaceList);
-    for (listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
-        if (!netInfo)
-        {
-            continue;
-        }
-        uint16_t unicastPort = CA_PORT;
-        ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, false, false);
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port",
-                      unicastPort);
-        }
-
-#ifdef __WITH_DTLS__
-        unicastPort = CA_SECURE_PORT;
-        ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, false, true);
-
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG,
-                      "Secure Unicast server started on %d port", unicastPort);
-        }
 #endif
-    }
-    CAClearNetInterfaceInfoList(netInterfaceList);
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-    return ret;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
 CAResult_t CAStartIPListeningServer()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
-    {
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG,
-                  "IP not Connected. Couldn't start multicast server");
-        return CA_STATUS_OK;
-    }
-
-    u_arraylist_t *netInterfaceList = u_arraylist_create();
-
-    VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
-
-    CAResult_t ret = CAIPGetInterfaceInfo(&netInterfaceList);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret);
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        return ret;
-    }
-
-    uint32_t listIndex = 0;
-    uint32_t listLength = u_arraylist_length(netInterfaceList);
-    for (listIndex = 0; listIndex < listLength; listIndex++)
-    {
-
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
-        if (!netInfo)
-        {
-            continue;
-        }
-
-        OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Ip address for multicast interface %s",
-                  netInfo->ipAddress);
-        ret = CAIPStartMulticastServer(netInfo->ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT);
-        if (CA_STATUS_OK == ret)
-        {
-            OIC_LOG(INFO, IP_ADAPTER_TAG, "Multicast Server is Started Successfully");
-        }
-    }
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    CAClearNetInterfaceInfoList(netInterfaceList);
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-    return ret;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
 CAResult_t CAStartIPDiscoveryServer()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
     return CAStartIPListeningServer();
 }
 
-int32_t CASendIPUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                                  uint32_t dataLength)
+static int32_t CAQueueIPData(bool isMulticast, const CAEndpoint_t *endpoint,
+                            const void *data, uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_RET(remoteEndpoint, IP_ADAPTER_TAG, "remoteEndpoint", -1);
-    VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1);
-    VERIFY_NON_NULL_RET(g_sendQueueHandle, IP_ADAPTER_TAG, "sendQueueHandle", -1);
+    VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1);
+    VERIFY_NON_NULL_RET(data, TAG, "data", -1);
 
     if (0 == dataLength)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length");
-        return -1;
-    }
-
-    // Create IPData to add to queue
-    CAIPData *ipData = CACreateIPData(remoteEndpoint, data, dataLength);
-    if (!ipData)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to create ipData!");
+        OIC_LOG(ERROR, TAG, "Invalid Data Length");
         return -1;
     }
-    else
-    {
-        // Add message to send queue
-        CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
-
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-        return dataLength;
-    }
-}
 
-int32_t CASendIPMulticastData(const void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+#ifdef SINGLE_THREAD
 
-    VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1);
-    VERIFY_NON_NULL_RET(g_sendQueueHandle, IP_ADAPTER_TAG, "sendQueueHandle", -1);
+    CAIPSendData(endpoint, data, dataLength, isMulticast);
 
-    if (0 == dataLength)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length");
-        return -1;
-    }
+#else
 
+    VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1);
     // Create IPData to add to queue
-    CAIPData *ipData = CACreateIPData(NULL, data, dataLength);
+    CAIPData *ipData = CACreateIPData(endpoint, data, dataLength, isMulticast);
     if (!ipData)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to create ipData!");
+        OIC_LOG(ERROR, TAG, "Failed to create ipData!");
         return -1;
     }
-    else
-    {
-        // Add message to send queue
-        CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
+    // Add message to send queue
+    CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
 
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-        return dataLength;
-    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return dataLength;
+
+#endif // SINGLE_THREAD
 }
 
-CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint,
+                            const void *data, uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    VERIFY_NON_NULL(info, IP_ADAPTER_TAG, "info is NULL");
-    VERIFY_NON_NULL(size, IP_ADAPTER_TAG, "size is NULL");
-
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG,
-                "Failed to get interface address, IP not Connected");
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    u_arraylist_t *netInterfaceList = u_arraylist_create();
-
-    VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
-
-    CAResult_t ret = CAIPGetInterfaceInfo(&netInterfaceList);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "CAIPGetInterfaceInfo failed:%d", ret);
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        return ret;
-    }
-
-    uint32_t listLength = u_arraylist_length(netInterfaceList);
-    uint32_t netInfoSize = listLength;
-
-#ifdef __WITH_DTLS__
-    if (listLength)
-    {
-        netInfoSize = listLength * 2;
-    }
-#endif
-
-    CALocalConnectivity_t *conInfo = (CALocalConnectivity_t *) OICCalloc(
-                                      netInfoSize, sizeof(CALocalConnectivity_t));
-    if (!conInfo)
-    {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Malloc Failed");
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    uint32_t listIndex = 0;
-    uint32_t count = 0;
-    for (listIndex = 0; listIndex < listLength; listIndex++)
-    {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
-        if (!netInfo)
-        {
-            continue;
-        }
-
-        conInfo[count].type = CA_IPV4;
-        conInfo[count].isSecured = false;
-        conInfo[count].addressInfo.IP.port = CAGetServerPortNum(netInfo->ipAddress, false);
-        strncpy(conInfo[count].addressInfo.IP.ipAddress, netInfo->ipAddress,
-                strlen(netInfo->ipAddress));
-
-#ifdef __WITH_DTLS__
-        // copy secure unicast server information
-        {
-            count ++;
-            conInfo[count].type = CA_IPV4;
-            conInfo[count].isSecured = true;
-            conInfo[count].addressInfo.IP.port = CAGetServerPortNum(netInfo->ipAddress, true);
-            strncpy(conInfo[count].addressInfo.IP.ipAddress, netInfo->ipAddress,
-                    strlen(netInfo->ipAddress));
-        }
-#endif
-        count ++;
-    }
-    *size = count;
-    *info = conInfo;
-    CAClearNetInterfaceInfoList(netInterfaceList);
-
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "IN");
+    return CAQueueIPData(false, endpoint, data, dataLength);
 }
 
-CAResult_t CAReadIPData()
+int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "IN");
+    return CAQueueIPData(true, endpoint, data, dataLength);
 }
 
-CAResult_t CAIPStopServers()
+CAResult_t CAReadIPData()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    // Stop all unicast and multicast servers.
-    if (CA_STATUS_OK == CAIPStopAllServers())
-    {
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAIPStopAllServers success");
-    }
-
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "IN");
+    CAIPPullData();
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAStopIP()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
 #ifdef __WITH_DTLS__
     CAAdapterNetDtlsDeInit();
 #endif
 
-    // Stop IP network monitor
-    CAIPStopNetworkMonitor();
-
-    // Stop send queue thread
-    if (g_sendQueueHandle)
+#ifndef SINGLE_THREAD
+    if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
     {
         CAQueueingThreadStop(g_sendQueueHandle);
     }
 
-    // Stop Unicast, Secured unicast and Multicast servers running
-    CAIPStopServers();
+    CAIPDeinitializeQueueHandles();
+#endif
+
+    CAIPStopServer();
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CATerminateIP()
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
-
-    // Stop IP adapter
-    CAStopIP();
+    OIC_LOG(DEBUG, TAG, "IN");
 
 #ifdef __WITH_DTLS__
-    CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_IP);
+    CADTLSSetAdapterCallbacks(NULL, NULL, 0);
 #endif
 
     CAIPSetPacketReceiveCallback(NULL);
 
-    // Terminate IP server
-    CAIPTerminateServer();
-
-    // Terminate network monitor
-    CAIPSetConnectionStateChangeCallback(NULL);
-    CAIPTerminateNetworkMonitor();
-
-    // Terminate message queue handler
+#ifndef SINGLE_THREAD
     CAIPDeinitializeQueueHandles();
+#endif
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+#ifndef SINGLE_THREAD
+
 void CAIPSendDataThread(void *threadData)
 {
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
     CAIPData *ipData = (CAIPData *) threadData;
     if (!ipData)
     {
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Invalid ip data!");
+        OIC_LOG(DEBUG, TAG, "Invalid ip data!");
         return;
     }
 
-    //If remoteEndpoint is NULL, its Multicast, else its Unicast.
-    if (ipData->remoteEndpoint)
+    if (ipData->isMulticast)
+    {
+        //Processing for sending multicast
+        OIC_LOG(DEBUG, TAG, "Send Multicast Data is called");
+        CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, true);
+    }
+    else
     {
         //Processing for sending unicast
-        char *address = ipData->remoteEndpoint->addressInfo.IP.ipAddress;
-        uint16_t port = ipData->remoteEndpoint->addressInfo.IP.port;
-
 #ifdef __WITH_DTLS__
-        if (!ipData->remoteEndpoint->isSecured)
+        if (ipData->remoteEndpoint->flags & CA_SECURE)
         {
-            OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Unicast Data is called");
-            CAIPSendData(address, port, ipData->data, ipData->dataLen, false,
-                               ipData->remoteEndpoint->isSecured);
-        }
-        else
-        {
-            OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
-            uint8_t cacheFlag = 0;
-            CAResult_t result = CAAdapterNetDtlsEncrypt(address, port, ipData->data,
-                                                        ipData->dataLen, &cacheFlag,
-                                                        DTLS_IP);
-
+            OIC_LOG(DEBUG, TAG, "CAAdapterNetDtlsEncrypt called!");
+            CAResult_t result = CAAdapterNetDtlsEncrypt(ipData->remoteEndpoint,
+                                               ipData->data, ipData->dataLen);
             if (CA_STATUS_OK != result)
             {
-                OIC_LOG(ERROR, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
+                OIC_LOG(ERROR, TAG, "CAAdapterNetDtlsEncrypt failed!");
             }
-            OIC_LOG_V(DEBUG, IP_ADAPTER_TAG,
-                      "CAAdapterNetDtlsEncrypt returned with cache[%d]", cacheFlag);
+            OIC_LOG_V(DEBUG, TAG,
+                      "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
+        }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "Send Unicast Data is called");
+            CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false);
         }
 #else
-        CAIPSendData(address, port, ipData->data, ipData->dataLen, false,
-                           ipData->remoteEndpoint->isSecured);
+        CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false);
 #endif
     }
-    else
-    {
-        //Processing for sending multicast
-        OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Multicast Data is called");
-        CAIPSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ipData->data,
-                           ipData->dataLen, true, false);
-    }
 
-    OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAIPData *CACreateIPData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                                     uint32_t dataLength)
+#endif
+
+#ifndef SINGLE_THREAD
+
+CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data,
+                                     uint32_t dataLength, bool isMulticast)
 {
-    VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "IPData is NULL", NULL);
+    VERIFY_NON_NULL_RET(data, TAG, "IPData is NULL", NULL);
 
     CAIPData *ipData = (CAIPData *) OICMalloc(sizeof(CAIPData));
     if (!ipData)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
+        OIC_LOG(ERROR, TAG, "Memory allocation failed!");
         return NULL;
     }
 
-    ipData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+    ipData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
     ipData->data = (void *) OICMalloc(dataLength);
     if (!ipData->data)
     {
-        OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
+        OIC_LOG(ERROR, TAG, "Memory allocation failed!");
         CAFreeIPData(ipData);
         return NULL;
     }
@@ -801,14 +529,16 @@ CAIPData *CACreateIPData(const CARemoteEndpoint_t *remoteEndpoint, const void *d
     memcpy(ipData->data, data, dataLength);
     ipData->dataLen = dataLength;
 
+    ipData->isMulticast = isMulticast;
+
     return ipData;
 }
 
 void CAFreeIPData(CAIPData *ipData)
 {
-    VERIFY_NON_NULL_VOID(ipData, IP_ADAPTER_TAG, "ipData is NULL");
+    VERIFY_NON_NULL_VOID(ipData, TAG, "ipData is NULL");
 
-    CAAdapterFreeRemoteEndpoint(ipData->remoteEndpoint);
+    CAFreeEndpoint(ipData->remoteEndpoint);
     OICFree(ipData->data);
     OICFree(ipData);
 }
@@ -820,3 +550,5 @@ void CADataDestroyer(void *data, uint32_t size)
     CAFreeIPData(etdata);
 }
 
+#endif // SINGLE_THREAD
+
diff --git a/resource/csdk/connectivity/src/ip_adapter/caipadapter_singlethread.c b/resource/csdk/connectivity/src/ip_adapter/caipadapter_singlethread.c
deleted file mode 100644 (file)
index 9a36455..0000000
+++ /dev/null
@@ -1,487 +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.
- *
- ******************************************************************/
-
-#include "caipadapter_singlethread.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include "caadapterutils.h"
-#include "logger.h"
-#include "oic_malloc.h"
-#include "caipinterface_singlethread.h"
-
-/**
- * @def TAG
- * @brief Logging tag for module name
- */
-#define TAG "IPAD"
-
-/**
- * @def CA_PORT
- * @brief Unicast port number (to listen for incoming data on unicast server).
- * Note :- Actual port number may differ based on result of bind() operation.
- */
-#define CA_PORT   6298
-
-/**
- * @def CA_SECURE_PORT
- * @brief Secured (unicast) port number as defined in COAP Specification, RFC-7252.
- */
-#define CA_SECURE_PORT   5684
-
-/**
- * @def CA_MCAST_PORT
- * @brief Multicast port number as defined in COAP Specification, RFC-7252.
- */
-#define CA_MCAST_PORT   5683
-
-/**
- * @def CA_MULTICAST_IP
- * @brief Multicast IP Address
- */
-#define CA_MULTICAST_IP "224.0.1.187"
-
-/* Skip Queue */
-/**
- * @var g_networkPacketCallback
- * @brief Network Packet Received Callback to CA
- */
-static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
-
-/**
- * @var g_networkChangeCallback
- * @brief Network Changed Callback to CA
- */
-
-static CANetworkChangeCallback g_networkChangeCallback = NULL;
-
-/**
- * @var g_isMulticastServerStarted
- * @brief Flag to check if multicast server is started
- */
-static bool g_isMulticastServerStarted = false;
-
-/**
- * @var g_startUnicastServerRequested
- * @brief Flag to check if server start requested by CA.
- */
-static bool g_startUnicastServerRequested = false;
-
-/**
- * @var g_unicastServerport
- * @brief port number on which unicast server is running.
- */
-static uint16_t g_unicastServerport = 0;
-
-/**
- * @var g_startMulticastServerRequested
- * @brief Flag to check if server start requested by CA.
- */
-static bool g_startMulticastServerRequested = false;
-
-
-static void CAIPNotifyNetworkChange(const char *address, uint16_t port,
-                                          CANetworkStatus_t status);
-static void CAIPConnectionStateCB(const char *ipAddress,
-                                        CANetworkStatus_t status);
-static void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port,
-                                       const void *data, uint32_t dataLength);
-static CAResult_t CAIPStopServers();
-
-void CAIPNotifyNetworkChange(const char *address, uint16_t port, CANetworkStatus_t status)
-{
-    CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, address);
-    if (!localEndpoint)
-    {
-        OIC_LOG(ERROR, TAG, "Out of memory!");
-        return;
-    }
-    localEndpoint->addressInfo.IP.port = port;
-
-    if (NULL != g_networkChangeCallback)
-    {
-        g_networkChangeCallback(localEndpoint, status);
-    }
-
-    CAAdapterFreeLocalEndpoint(localEndpoint);
-}
-
-void CAIPConnectionStateCB(const char *ipAddr,
-                                 CANetworkStatus_t status)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAResult_t ret = CA_STATUS_FAILED;
-    /* If IP is connected, then get the latest IP from the IP Interface
-      * and start unicast and multicast servers if requested earlier */
-    if (CA_INTERFACE_UP == status)
-    {
-        uint16_t port = CA_PORT;
-        int32_t serverFd = -1;
-        /* Start Unicast server if requested earlier */
-        if (g_startUnicastServerRequested)
-        {
-            ret = CAIPStartUnicastServer("0.0.0.0", &port, false, &serverFd);
-            if (CA_STATUS_OK == ret)
-            {
-                OIC_LOG_V(DEBUG, TAG, "unicast started:%d", port);
-                CAIPSetUnicastSocket(serverFd);
-                CAIPSetUnicastPort(port);
-                g_unicastServerport = port;
-            }
-            else
-            {
-                OIC_LOG_V(ERROR, TAG, "FAILED:%d", ret);
-            }
-        }
-
-        /* Start Multicast server if requested earlier */
-        if (g_startMulticastServerRequested)
-        {
-            uint16_t multicastPort = CA_MCAST_PORT;
-            ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFd);
-            if (CA_STATUS_OK == ret)
-            {
-                OIC_LOG_V(DEBUG, TAG, "multicast started:%d", multicastPort);
-                g_isMulticastServerStarted = true;
-            }
-            else
-            {
-                OIC_LOG_V(ERROR, TAG, "strt mcast srv fail:%d", ret);
-            }
-        }
-
-        char *ipAddress = NULL;
-        char *ifcName = NULL;
-        CAResult_t ret = CAIPGetInterfaceInfo(&ifcName, &ipAddress);
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG_V(ERROR, TAG, "get interface info fail:%d", ret);
-            OICFree(ipAddress);
-            OICFree(ifcName);
-            return;
-        }
-        /* Notify network change to CA */
-        CAIPNotifyNetworkChange(ipAddress, port, status);
-        OICFree(ipAddress);
-        OICFree(ifcName);
-    }
-    else
-    {
-        CAIPNotifyNetworkChange("", 0, status);
-        /* Stop both Unicast and Multicast servers */
-        ret = CAIPStopServers();
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG_V(ERROR, TAG, "stop srv fail:%d", ret);
-            return;
-        }
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port,
-                                const void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    OIC_LOG_V(DEBUG, TAG, "sddress:%s", ipAddress);
-    OIC_LOG_V(DEBUG, TAG, "port:%d", port);
-    OIC_LOG_V(DEBUG, TAG, "data:%s", data);
-
-    /* CA is freeing this memory */
-    CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_IPV4, ipAddress, NULL);
-    if (NULL == endPoint)
-    {
-        OIC_LOG(ERROR, TAG, "Out of memory!");
-        return;
-    }
-    endPoint->addressInfo.IP.port = port;
-
-    if (g_networkPacketCallback)
-    {
-        g_networkPacketCallback(endPoint, data, dataLength);
-    }
-    CAAdapterFreeRemoteEndpoint(endPoint);
-    OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback networkPacketCallback,
-                                CANetworkChangeCallback netCallback)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
-    VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback");
-    VERIFY_NON_NULL(netCallback, TAG, "netCallback");
-
-    g_networkChangeCallback = netCallback;
-    g_networkPacketCallback = networkPacketCallback;
-
-    CAResult_t ret = CAIPInitializeNetworkMonitor();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, TAG, "init n/w fail:%d", ret);
-        return ret;
-    }
-    CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
-
-    ret = CAIPInitializeServer();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, TAG, "init fail:%d", ret);
-        CATerminateIP();
-        return ret;
-    }
-    CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
-
-    CAConnectivityHandler_t IPHandler;
-    IPHandler.startAdapter = CAStartIP;
-    IPHandler.startListenServer = CAStartIPListeningServer;
-    IPHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
-    IPHandler.sendData = CASendIPUnicastData;
-    IPHandler.sendDataToAll = CASendIPMulticastData;
-    IPHandler.GetnetInfo = CAGetIPInterfaceInformation;
-    IPHandler.readData = CAReadIPData;
-    IPHandler.stopAdapter = CAStopIP;
-    IPHandler.terminate = CATerminateIP;
-    registerCallback(IPHandler, CA_IPV4);
-
-    OIC_LOG(INFO, TAG, "success");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartIP()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    /* Start monitoring IP network */
-    CAResult_t ret = CAIPStartNetworkMonitor();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, TAG, "strt n/w monitor fail");
-    }
-
-    g_startUnicastServerRequested = true;
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
-    {
-        OIC_LOG(ERROR, TAG, "not connected");
-        return ret;
-    }
-
-    uint16_t unicastPort = CA_PORT;
-    int32_t serverFd = 0;
-    // Address is hardcoded as we are using Single Interface
-    ret = CAIPStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
-    if (CA_STATUS_OK == ret)
-    {
-        OIC_LOG_V(DEBUG, TAG, "unicast started:%d", unicastPort);
-        CAIPSetUnicastSocket(serverFd);
-        CAIPSetUnicastPort(unicastPort);
-        g_unicastServerport = unicastPort;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return ret;
-}
-
-CAResult_t CAStartIPListeningServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAResult_t ret = CA_STATUS_OK;
-    uint16_t multicastPort = CA_MCAST_PORT;
-    int32_t serverFD = 1;
-    if (g_isMulticastServerStarted == true)
-    {
-        OIC_LOG(ERROR, TAG, "Already Started!");
-        return CA_SERVER_STARTED_ALREADY;
-    }
-
-    g_startMulticastServerRequested = true;
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
-    {
-        OIC_LOG(ERROR, TAG,"Not connected");
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    ret = CAIPStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFD);
-    if (CA_STATUS_OK == ret)
-    {
-        OIC_LOG(INFO, TAG, "multicast success");
-        g_isMulticastServerStarted = true;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return ret;
-}
-
-CAResult_t CAStartIPDiscoveryServer()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    /* Both listening and discovery server are same */
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CAStartIPListeningServer();
-}
-
-int32_t CASendIPUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
-                                  uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "remoteEndpoint", -1);
-    VERIFY_NON_NULL_RET(data, TAG, "data", -1);
-    if (dataLength == 0)
-    {
-        OIC_LOG(ERROR, TAG, "Invalid length");
-        return -1;
-    }
-
-    CAIPSendData(remoteEndpoint->addressInfo.IP.ipAddress,
-                       remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return dataLength;
-}
-
-int32_t CASendIPMulticastData(const void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    VERIFY_NON_NULL_RET(data, TAG, "data", -1);
-    if (dataLength == 0)
-    {
-        OIC_LOG(ERROR, TAG, "Invalid length");
-        return -1;
-    }
-
-    CAIPSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return dataLength;
-}
-
-CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL(info, TAG, "info");
-    VERIFY_NON_NULL(size, TAG, "size");
-
-    bool retVal = CAIPIsConnected();
-    if (false == retVal)
-    {
-        OIC_LOG(ERROR, TAG, "Not connected");
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    char *ipAddress = NULL;
-    char *ifcName = NULL;
-    CAResult_t ret = CAIPGetInterfaceInfo(&ipAddress, &ifcName);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, TAG, "get interface info fail:%d", ret);
-        OICFree(ipAddress);
-        OICFree(ifcName);
-        return ret;
-    }
-
-    // Create local endpoint using util function
-    (*info) = CAAdapterCreateLocalEndpoint(CA_IPV4, ipAddress);
-    if (NULL == (*info))
-    {
-        OIC_LOG(ERROR, TAG, "malloc fail");
-        OICFree(ipAddress);
-        OICFree(ifcName);
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    (*info)->addressInfo.IP.port = g_unicastServerport;
-    (*size) = 1;
-
-    OICFree(ipAddress);
-    OICFree(ifcName);
-
-    OIC_LOG(INFO, TAG, "success");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadIPData()
-{
-    CAIPPullData();
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStopServers()
-{
-    CAResult_t result = CAIPStopUnicastServer();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TAG, "stop ucast srv fail:%d", result);
-        return result;
-    }
-    CAIPSetUnicastSocket(-1);
-    CAIPSetUnicastPort(0);
-    g_unicastServerport = 0;
-
-    result = CAIPStopMulticastServer();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TAG, "stop mcast srv fail:%d", result);
-        return result;
-    }
-    g_isMulticastServerStarted = false;
-
-    return result;
-}
-
-CAResult_t CAStopIP()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    g_startUnicastServerRequested = false;
-    g_startMulticastServerRequested = false;
-    CAIPStopNetworkMonitor();
-    CAResult_t result = CAIPStopServers();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TAG, "stop srv fail:%d", result);
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return result;
-}
-
-void CATerminateIP()
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAIPSetConnectionStateChangeCallback(NULL);
-    CAIPTerminateNetworkMonitor();
-    CAIPSetPacketReceiveCallback(NULL);
-    OIC_LOG(INFO, TAG, "Terminated Ethernet");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return;
-}
-
-
diff --git a/resource/csdk/connectivity/src/ip_adapter/caipclient.c b/resource/csdk/connectivity/src/ip_adapter/caipclient.c
deleted file mode 100644 (file)
index 2f9cfd0..0000000
+++ /dev/null
@@ -1,147 +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.
- *
- ******************************************************************/
-#include "caipinterface.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-#include "caadapterutils.h"
-
-/**
- * @def IP_CLIENT_TAG
- * @brief Logging tag for module name
- */
-#define IP_CLIENT_TAG "IP_CLIENT"
-#define OC_MULTICAST_IP "224.0.1.187"
-
-static uint32_t CASendData(const char *remoteAddress, uint16_t port, const void *data,
-                           uint32_t dataLength, int sockfd)
-{
-    OIC_LOG(DEBUG, IP_CLIENT_TAG, "IN");
-
-    VERIFY_NON_NULL_RET(remoteAddress, IP_CLIENT_TAG, "IP address is NULL", 0);
-    VERIFY_NON_NULL_RET(data, IP_CLIENT_TAG, "data is NULL", 0);
-
-    if (0 == dataLength)
-    {
-        OIC_LOG(ERROR, IP_CLIENT_TAG, "Data length is 0!");
-        return 0;
-    }
-
-    if (0 > sockfd)
-    {
-        OIC_LOG(ERROR, IP_CLIENT_TAG, "Unicast Server is not running!");
-        return 0;
-    }
-
-    struct sockaddr_in destAddr = { 0 };
-    destAddr.sin_family = AF_INET;
-    destAddr.sin_port = htons(port);
-
-    int ret = inet_pton(AF_INET, remoteAddress, &(destAddr.sin_addr));
-    if (1 != ret)
-    {
-        OIC_LOG(ERROR, IP_CLIENT_TAG, "inet_pton failed!");
-        return 0;
-    }
-
-    ssize_t sendDataLength = sendto(sockfd, data, dataLength, 0, (struct sockaddr *) &destAddr,
-                                    sizeof(destAddr));
-    if (-1 == sendDataLength)
-    {
-        OIC_LOG_V(ERROR, IP_CLIENT_TAG, "sendto failed, Error code: %s",
-                  strerror(errno));
-        return 0;
-    }
-
-    OIC_LOG_V(INFO, IP_CLIENT_TAG, "Sending data is successful, sent bytes[%d] to ip[%s:%d]",
-              sendDataLength, remoteAddress, port);
-    OIC_LOG(DEBUG, IP_CLIENT_TAG, "OUT");
-    return sendDataLength;
-}
-
-uint32_t CAIPSendData(const char *remoteAddress, uint16_t remotePort, const void *data,
-                            uint32_t dataLength, bool isMulticast, bool isSecured)
-{
-    u_arraylist_t *tempServerInfoList = u_arraylist_create();
-    if (!tempServerInfoList)
-    {
-        OIC_LOG(ERROR, IP_CLIENT_TAG, "u_arraylist_create failed");
-        return 0;
-    }
-
-    CAResult_t res = CAGetIPServerInfoList(&tempServerInfoList);
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, IP_CLIENT_TAG, "CAGetIPServerInfoList failed");
-        CAClearServerInfoList(tempServerInfoList);
-        return 0;
-    }
-
-    uint32_t len = 0;
-    if (isMulticast || strcmp(remoteAddress, OC_MULTICAST_IP) == 0)
-    {
-        uint32_t listIndex = 0;
-        uint32_t listLength = u_arraylist_length(tempServerInfoList);
-        for (listIndex = 0; listIndex < listLength; listIndex++)
-        {
-            CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
-                                                                      listIndex);
-            if (!info || info->isMulticastServer || info->isSecured)
-            {
-                continue;
-            }
-
-            if (info->socketFd < 0)
-            {
-                OIC_LOG(ERROR, IP_CLIENT_TAG, "Invalid Socket Fd");
-                continue;
-            }
-
-            OIC_LOG_V(DEBUG, IP_CLIENT_TAG,
-                      "CA IP Multicast SendData with src ip %s port %d sockFd %d",
-                      info->ipAddress, info->port, info->socketFd);
-            len = CASendData(remoteAddress, remotePort, data, dataLength, info->socketFd);
-        }
-    }
-    else
-    {
-        int sockFd = CAGetSocketFdForUnicastServer(tempServerInfoList, remoteAddress, isSecured,
-                                                   isMulticast, CA_IPV4);
-
-        if (sockFd < 0)
-        {
-            OIC_LOG(ERROR, IP_CLIENT_TAG, "Invalid Socket Fd");
-            CAClearServerInfoList(tempServerInfoList);
-            return len;
-        }
-
-        OIC_LOG_V(DEBUG, IP_CLIENT_TAG, "IP unicast SendData sockFd %d", sockFd);
-
-        len = CASendData(remoteAddress, remotePort, data, dataLength, sockFd);
-
-    }
-    CAClearServerInfoList(tempServerInfoList);
-    return len;
-}
-
index 38f164c..2818bc0 100644 (file)
@@ -1,4 +1,4 @@
-/******************************************************************
+/*****************************************************************j
  *
  * Copyright 2014 Samsung Electronics All Rights Reserved.
  *
 
 #include "caipinterface.h"
 
+#ifndef __APPLE__
+#include <asm/types.h>
+#else
+    #ifndef IPV6_ADD_MEMBERSHIP
+        #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+    #endif
+#endif
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <stdio.h>
 #include <unistd.h>
+#include <sys/types.h>
 #include <fcntl.h>
 #include <sys/select.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
+#include <net/if.h>
 #include <errno.h>
+#ifdef __linux__
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#endif
 
 #include "pdu.h"
 #include "caadapterutils.h"
 #endif
 #include "camutex.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 
 /**
- * @def IP_SERVER_TAG
+ * @def TAG
  * @brief Logging tag for module name
  */
-#define IP_SERVER_TAG "IP_SERVER"
-
-/**
- * @def CA_UDP_BIND_RETRY_COUNT
- * @brief Retry count in case of socket bind failure.
- */
-#define CA_UDP_BIND_RETRY_COUNT 10
-
-/**
- * @def IPNAMESIZE
- * @brief Max length for ip address.
- */
-#define IPNAMESIZE 16
-
-/**
- * @def SOCKETOPTION
- * @brief Socket option.
- */
-#define SOCKETOPTION 1
-
-/**
- * @var g_packetHandlerStopFlag
- * @brief Flag for stopping packet handler thread.
- */
-static bool g_packetHandlerStopFlag = false;
+#define TAG "IP_SERVER"
+
+#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 IPv6_MULTICAST_INT "ff01::fd"
+static struct in6_addr IPv6MulticastAddressInt;
+#define IPv6_MULTICAST_LNK "ff02::fd"
+static struct in6_addr IPv6MulticastAddressLnk;
+#define IPv6_MULTICAST_RLM "ff03::fd"
+static struct in6_addr IPv6MulticastAddressRlm;
+#define IPv6_MULTICAST_ADM "ff04::fd"
+static struct in6_addr IPv6MulticastAddressAdm;
+#define IPv6_MULTICAST_SIT "ff05::fd"
+static struct in6_addr IPv6MulticastAddressSit;
+#define IPv6_MULTICAST_ORG "ff08::fd"
+static struct in6_addr IPv6MulticastAddressOrg;
+#define IPv6_MULTICAST_GLB "ff0e::fd"
+static struct in6_addr IPv6MulticastAddressGlb;
+
+static char *ipv6mcnames[IPv6_DOMAINS] = {
+    NULL,
+    IPv6_MULTICAST_INT,
+    IPv6_MULTICAST_LNK,
+    IPv6_MULTICAST_RLM,
+    IPv6_MULTICAST_ADM,
+    IPv6_MULTICAST_SIT,
+    NULL,
+    NULL,
+    IPv6_MULTICAST_ORG,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    IPv6_MULTICAST_GLB,
+    NULL
+};
+
+static CAIPExceptionCallback g_exceptionCallback;
+
+static CAIPPacketReceivedCallback g_packetReceivedCallback;
+
+static void CAHandleNetlink();
+static void CAApplyInterfaces();
+static void CAFindReadyMessage();
+static void CASelectReturned(fd_set *readFds, int ret);
+static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags);
+
+#define SET(TYPE, FDS) \
+    if (caglobals.ip.TYPE.fd != -1) \
+    { \
+        FD_SET(caglobals.ip.TYPE.fd, FDS); \
+    }
+
+#define ISSET(TYPE, FDS, FLAGS) \
+    if (caglobals.ip.TYPE.fd != -1 && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \
+    { \
+        fd = caglobals.ip.TYPE.fd; \
+        flags = FLAGS; \
+    }
 
-/**
- * @var CAAdapterIPServerContext_t
- * @brief Thread context information for callbacks and threadpool.
- */
-typedef struct
+static void CAReceiveHandler(void *data)
 {
-    ca_thread_pool_t threadPool;
-    CAIPPacketReceivedCallback packetReceivedCallback;
-    CAIPExceptionCallback exceptionCallback;
-} CAAdapterIPServerContext_t;
+    OIC_LOG(DEBUG, TAG, "IN");
 
-/**
- * @var g_serverInfoList
- * @brief Mutex to synchronize ethenet adapter context.
- */
-static u_arraylist_t *g_serverInfoList = NULL;
-
-/**
- * @var g_mutexServerInfoList
- * @brief Mutex to synchronize Server Information.
- */
-static ca_mutex g_mutexServerInfoList = NULL;
-
-/**
- * @var g_adapterEthServerContext
- * @brief Mutex to synchronize ethenet adapter context.
- */
-static CAAdapterIPServerContext_t *g_adapterEthServerContext = NULL;
+    while (!caglobals.ip.terminate)
+    {
+        CAFindReadyMessage();
+    }
 
-/**
- * @var g_mutexAdapterServerContext
- * @brief Mutex to synchronize unicast server
- */
-static ca_mutex g_mutexAdapterServerContext = NULL;
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
 
-static void CAReceiveHandler(void *data)
+static void CAFindReadyMessage()
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
     fd_set readFds;
-    int maxSd = 0;
     struct timeval timeout;
-    char recvBuffer[COAP_MAX_PDU_SIZE] = { 0 };
 
-    while (true != g_packetHandlerStopFlag)
-    {
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-        FD_ZERO(&readFds);
+    timeout.tv_sec = caglobals.ip.selectTimeout;
+    timeout.tv_usec = 0;
+    struct timeval *tv = caglobals.ip.selectTimeout == -1 ? NULL : &timeout;
 
-        ca_mutex_lock(g_mutexServerInfoList);
-        uint32_t listIndex = 0;
-        uint32_t listLength = u_arraylist_length(g_serverInfoList);
+    FD_ZERO(&readFds);
+    SET(u6,  &readFds)
+    SET(u6s, &readFds)
+    SET(u4,  &readFds)
+    SET(u4s, &readFds)
+    SET(m6,  &readFds)
+    SET(m6s, &readFds)
+    SET(m4,  &readFds)
+    SET(m4s, &readFds)
+    if (caglobals.ip.shutdownFds[0] != -1)
+    {
+        FD_SET(caglobals.ip.shutdownFds[0], &readFds);
+    }
+    if (caglobals.ip.netlinkFd != -1)
+    {
+        FD_SET(caglobals.ip.netlinkFd, &readFds);
+    }
 
-        u_arraylist_t *tempServerInfoList = u_arraylist_create();
-        if (!tempServerInfoList)
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return;
-        }
+    int ret = select(caglobals.ip.maxfd + 1, &readFds, NULL, NULL, tv);
 
-        for (listIndex = 0; listIndex < listLength; listIndex++)
+    if (caglobals.ip.terminate)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Packet receiver Stop request received.");
+        return;
+    }
+    if (ret <= 0)
+    {
+        if (ret < 0)
         {
-            CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
-            if (!info)
-            {
-                listIndex++;
-                continue;
-            }
-
-            int sd = info->socketFd;
-            //if valid socket descriptor then add to read list
-            if (sd > 0)
-            {
-                FD_SET(sd, &readFds);
-            }
-
-            //highest file descriptor number, need it for the select function
-            if (sd > maxSd)
-            {
-                maxSd = sd;
-            }
-
-            CAServerInfo_t *newInfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
-            if (!newInfo)
-            {
-                OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
-                CAClearServerInfoList(tempServerInfoList);
-                ca_mutex_unlock(g_mutexServerInfoList);
-                return;
-            }
-
-            memcpy(newInfo, info, sizeof(CAServerInfo_t));
-
-            CAResult_t result = u_arraylist_add(tempServerInfoList, (void *) newInfo);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!Thread exit");
-                CAClearServerInfoList(tempServerInfoList);
-                ca_mutex_unlock(g_mutexServerInfoList);
-                return;
-            }
+            OIC_LOG_V(FATAL, TAG, "select error %s", strerror(errno));
         }
+        return;
+    }
 
-        ca_mutex_unlock(g_mutexServerInfoList);
+    CASelectReturned(&readFds, ret);
+}
 
-        int ret = select(maxSd + 1, &readFds, NULL, NULL, &timeout);
-        if (g_packetHandlerStopFlag)
+static void CASelectReturned(fd_set *readFds, int ret)
+{
+    int fd = -1;
+    CATransportFlags_t flags = CA_DEFAULT_FLAGS;
+
+    while (!caglobals.ip.terminate)
+    {
+        ISSET(u6,  readFds, CA_IPV6)
+        else ISSET(u6s, readFds, CA_IPV6 | CA_SECURE)
+        else ISSET(u4,  readFds, CA_IPV4)
+        else ISSET(u4s, readFds, CA_IPV4 | CA_SECURE)
+        else ISSET(m6,  readFds, CA_MULTICAST | CA_IPV6)
+        else ISSET(m6s, readFds, CA_MULTICAST | CA_IPV6 | CA_SECURE)
+        else ISSET(m4,  readFds, CA_MULTICAST | CA_IPV4)
+        else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
+        else if (FD_ISSET(caglobals.ip.netlinkFd, readFds))
         {
-            OIC_LOG_V(DEBUG, IP_SERVER_TAG,
-                      "Packet receiver handler Stop request received. Thread exited");
-            CAClearServerInfoList(tempServerInfoList);
+            CAHandleNetlink();
             break;
         }
-        if (ret < 0)
+        else
         {
-            OIC_LOG_V(FATAL, IP_SERVER_TAG, "select returned error %s", strerror(errno));
-            CAClearServerInfoList(tempServerInfoList);
-            continue;
+            break;
         }
 
-        listLength = u_arraylist_length(tempServerInfoList);
-        for (listIndex = 0; listIndex < listLength; listIndex++)
-        {
-            CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
-                                                                      listIndex);
-            if (!info)
-            {
-                continue;
-            }
-
-            int sd = info->socketFd;
-            if (FD_ISSET(sd , &readFds))
-            {
-                OIC_LOG_V(ERROR, IP_SERVER_TAG,
-                          "data Received server information ip %s, port %d socket %d",
-                          info->ipAddress, info->port, sd);
-                memset(recvBuffer, 0, sizeof(recvBuffer));
-
-                struct sockaddr_in srcSockAddress = { 0 };
-                socklen_t srcAddressLen = sizeof(srcSockAddress);
-
-                //Reading from socket
-                ssize_t recvLen = recvfrom(sd, recvBuffer, sizeof(recvBuffer), 0,
-                                           (struct sockaddr *) &srcSockAddress, &srcAddressLen);
-                if (-1 == recvLen)
-                {
-                    OIC_LOG_V(ERROR, IP_SERVER_TAG, "Recvfrom failed %s", strerror(errno));
-                    continue;
-                }
-                else if (0 == recvLen)
-                {
-                    OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
-                    ca_mutex_lock(g_mutexAdapterServerContext);
-                    // Notify upper layer this exception
-                    if (g_adapterEthServerContext->exceptionCallback)
-                    {
-                        // need to make proper exception callback.
-                        //g_adapterEthServerContext->exceptionCallback(ctx->type);
-                    }
-                    ca_mutex_unlock(g_mutexAdapterServerContext);
-                }
-
-                char srcIPAddress[CA_IPADDR_SIZE] = { 0 };
-                if (!inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress,
-                               sizeof(srcIPAddress)))
-                {
-
-                    OIC_LOG(ERROR, IP_SERVER_TAG, "inet_ntop is failed!");
-                    continue;
-                }
-
-                uint16_t srcPort = ntohs(srcSockAddress.sin_port);
-
-                OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Received packet from %s:%d len %d",
-                          srcIPAddress, srcPort, recvLen);
-
-                char *netMask = NULL;
-                if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(info->ifAddr, &netMask))
-                {
-                    OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
-                    continue;
-                }
-
-                if (!CAAdapterIsSameSubnet(info->ifAddr, srcIPAddress, netMask))
-                {
-                    OIC_LOG(DEBUG, IP_SERVER_TAG,
-                            "Packet received from different subnet, Ignore!");
-                    OICFree(netMask);
-                    continue;
-                }
-                OICFree(netMask);
-
-                if (info->isSecured)
-                {
-#ifdef __WITH_DTLS__
-                    CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress, srcPort,
-                                                             (uint8_t *)recvBuffer, recvLen,
-                                                             DTLS_IP);
-                    OIC_LOG_V(DEBUG, IP_SERVER_TAG,
-                              "CAAdapterNetDtlsDecrypt returns [%d]", ret);
-#endif
-                }
-                else //both multicast and unicast
-                {
-                    ca_mutex_lock(g_mutexAdapterServerContext);
-
-                    if (g_adapterEthServerContext->packetReceivedCallback)
-                    {
-                        g_adapterEthServerContext->packetReceivedCallback(srcIPAddress, srcPort,
-                                                                          recvBuffer, recvLen,
-                                                                          false);
-                    }
-
-                    ca_mutex_unlock(g_mutexAdapterServerContext);
-                }
-            }
-        }
-        CAClearServerInfoList(tempServerInfoList);
+        (void)CAReceiveMessage(fd, flags);
+        FD_CLR(fd, readFds);
     }
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
 }
 
-static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port,
-                                 bool forceBindStart)
+static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
 {
-    VERIFY_NON_NULL(socketFD, IP_SERVER_TAG, "socketFD is NULL");
-    VERIFY_NON_NULL(localIp, IP_SERVER_TAG, "localIp is NULL");
-    VERIFY_NON_NULL(port, IP_SERVER_TAG, "port is NULL");
-    // Create a UDP socket
-    int sock = -1;
-
-#ifdef SOCK_CLOEXEC
-    sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
-#endif
+    char recvBuffer[COAP_MAX_PDU_SIZE];
 
-    if (-1 == sock)
-    {
-        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-    }
+    struct sockaddr_storage srcAddr;
+    socklen_t srcAddrLen = sizeof (srcAddr);
 
-    if (-1 == sock)
+    ssize_t recvLen = recvfrom(fd,
+                               recvBuffer,
+                               sizeof (recvBuffer),
+                               0,
+                               (struct sockaddr *)&srcAddr,
+                               &srcAddrLen);
+    if (-1 == recvLen)
     {
-        OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to create Socket, Error code: %s",
-                  strerror(errno));
+        OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
         return CA_STATUS_FAILED;
     }
 
-    // Make the socket non-blocking
-    if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
-    {
-        OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
-                  strerror(errno));
+    CAEndpoint_t ep = { CA_ADAPTER_IP, flags };
 
-        close(sock);
-        return CA_STATUS_FAILED;
+    if (flags & CA_IPV6)
+    {
+        ep.interface = ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id;
+        ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id = 0;
     }
+    CAConvertAddrToName(&srcAddr, ep.addr, &ep.port);
 
-    if (true == forceBindStart)
+    if (flags & CA_SECURE)
+    {
+#ifdef __WITH_DTLS__
+        int ret = CAAdapterNetDtlsDecrypt(&ep, (uint8_t *)recvBuffer, recvLen);
+        OIC_LOG_V(DEBUG, TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
+#else
+        OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS");
+#endif
+    }
+    else
     {
-        int setOptionOn = SOCKETOPTION;
-        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &setOptionOn,
-                             sizeof(setOptionOn)))
+        if (g_packetReceivedCallback)
         {
-            OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
-                      strerror(errno));
-            close(sock);
-            return CA_STATUS_FAILED;
+            g_packetReceivedCallback(&ep, recvBuffer, recvLen);
         }
     }
 
-    struct sockaddr_in sockAddr = { 0 };
-    uint16_t serverPort = *port;
-    sockAddr.sin_family = AF_INET;
-    sockAddr.sin_port = htons(serverPort);
-    if (localIp)
+    return CA_STATUS_OK;
+}
+
+void CAIPPullData()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static int CACreateSocket(int family, uint16_t *port)
+{
+    int socktype = SOCK_DGRAM;
+    #ifdef SOCK_CLOEXEC
+    socktype |= SOCK_CLOEXEC;
+    #endif
+    int fd = socket(family, socktype, IPPROTO_UDP);
+    if (-1 == fd)
     {
-        sockAddr.sin_addr.s_addr = inet_addr(localIp);
+        OIC_LOG_V(ERROR, TAG, "create socket failed: %s", strerror(errno));
+        return -1;
     }
 
-    int16_t i = 0;
-    bool isBound = false;
-    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    #ifndef SOCK_CLOEXEC
+    int fl = fcntl(fd, F_GETFD);
+    if (-1 == fl || -1 == fcntl(fd, F_SETFD, fl|FD_CLOEXEC))
     {
-        if (-1 == bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
+        OIC_LOG_V(ERROR, TAG, "set FD_CLOEXEC failed: %s", strerror(errno));
+        close(fd);
+        return -1;
+    }
+    #endif
+
+    struct sockaddr_storage sa = { family };
+    if (family == AF_INET6)
+    {
+        int on = 1;
+        if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
         {
-            if (false == forceBindStart)
-            {
-                OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
-                          strerror(errno));
+            OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno));
+        }
+        ((struct sockaddr_in6 *)&sa)->sin6_port = htons(*port);
+    }
+    else
+    {
+        ((struct sockaddr_in *)&sa)->sin_port = htons(*port);
+    }
 
-                //Set the port to next one
-                serverPort += 1;
-                sockAddr.sin_port = htons(serverPort);
-                continue;
-            }
-            else
-            {
-                OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
-                          strerror(errno));
-                break;
-            }
+    if (*port)  // use the given port
+    {
+        int on = 1;
+        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)))
+        {
+            OIC_LOG_V(ERROR, TAG, "SO_REUSEADDR failed: %s", strerror(errno));
+            close(fd);
+            return -1;
         }
+    }
 
-        isBound = true;
-        break;
+    if (-1 == bind(fd, (struct sockaddr *)&sa, sizeof(sa)))
+    {
+        OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", strerror(errno));
+        close(fd);
+        return -1;
     }
 
-    if (false == isBound)
+    if (!*port)  // return the assigned port
     {
-        close(sock);
-        return CA_STATUS_FAILED;
+        struct sockaddr_storage sa;
+        socklen_t socklen = sizeof (sa);
+        if (-1 == getsockname(fd, (struct sockaddr *)&sa, &socklen))
+        {
+            OIC_LOG_V(ERROR, TAG, "getsockname failed: %s", strerror(errno));
+            close(fd);
+            return -1;
+        }
+        *port = ntohs(family == AF_INET6 ?
+                      ((struct sockaddr_in6 *)&sa)->sin6_port :
+                      ((struct sockaddr_in *)&sa)->sin_port);
     }
 
-    *port = serverPort;
-    *socketFD = sock;
-    return CA_STATUS_OK;
+    return fd;
 }
 
-static void CACloseSocket(int socketFD)
+#define CHECKFD(FD) \
+    if (FD > caglobals.ip.maxfd) \
+        caglobals.ip.maxfd = FD;
+#define NEWSOCKET(FAMILY, NAME) \
+    caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port); \
+    CHECKFD(caglobals.ip.NAME.fd)
+
+static void CAInitializeNetlink()
 {
-    if (-1 == socketFD)
+#ifdef __linux__
+    // create NETLINK fd for interface change notifications
+    struct sockaddr_nl sa = { AF_NETLINK, 0, 0, RTMGRP_LINK };
+
+    caglobals.ip.netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
+    if (caglobals.ip.netlinkFd == -1)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid Socket Fd");
-        return;
+        OIC_LOG_V(ERROR, TAG, "netlink socket failed: %s", strerror(errno));
     }
-
-    // close the socket
-    if (-1 == close(socketFD))
+    else
     {
-        OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
-                  strerror(errno));
+        int r = bind(caglobals.ip.netlinkFd, (struct sockaddr *)&sa, sizeof (sa));
+        if (r)
+        {
+            OIC_LOG_V(ERROR, TAG, "netlink bind failed: %s", strerror(errno));
+            close(caglobals.ip.netlinkFd);
+            caglobals.ip.netlinkFd = -1;
+        }
+        else
+        {
+            CHECKFD(caglobals.ip.netlinkFd);
+        }
     }
+#endif
 }
 
-static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
-                                       bool forceBindStart, bool isSecured, int *serverFD)
+static void CAInitializePipe()
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    VERIFY_NON_NULL(serverFD, IP_SERVER_TAG, "serverFD");
-    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
-    VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
-
-    CAResult_t ret = CACreateSocket(serverFD, localAddress, port, forceBindStart);
-    if (CA_STATUS_OK != ret)
+    caglobals.ip.selectTimeout = -1;
+#ifdef HAVE_PIPE2
+    int ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC);
+#else
+    int ret = pipe(caglobals.ip.shutdownFds);
+    if (-1 != ret)
+    {
+        ret = fcntl(caglobals.ip.shutdownFds[0], F_GETFD);
+        if (-1 != ret)
+        {
+            ret = fcntl(caglobals.ip.shutdownFds[0], F_SETFD, ret|FD_CLOEXEC);
+        }
+        if (-1 != ret)
+        {
+            ret = fcntl(caglobals.ip.shutdownFds[1], F_GETFD);
+        }
+        if (-1 != ret)
+        {
+            ret = fcntl(caglobals.ip.shutdownFds[1], F_SETFD, ret|FD_CLOEXEC);
+        }
+        if (-1 == ret)
+        {
+            close(caglobals.ip.shutdownFds[1]);
+            close(caglobals.ip.shutdownFds[0]);
+            caglobals.ip.shutdownFds[0] = -1;
+            caglobals.ip.shutdownFds[1] = -1;
+        }
+    }
+#endif
+    if (-1 == ret)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
+        OIC_LOG_V(ERROR, TAG, "pipe failed: %s", strerror(errno));
+        caglobals.ip.selectTimeout = SELECT_TIMEOUT; //poll needed for shutdown
     }
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return ret;
 }
 
-static CAResult_t CAIPStartPacketReceiverHandler()
+CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    ca_mutex_lock(g_mutexServerInfoList);
+    CAResult_t res = CA_STATUS_OK;
 
-    uint32_t listLength = u_arraylist_length(g_serverInfoList);
-
-    ca_mutex_unlock(g_mutexServerInfoList);
+    if (caglobals.ip.started)
+    {
+        return res;
+    }
 
-    ca_mutex_lock(g_mutexAdapterServerContext);
+    if (!IPv4MulticastAddress.s_addr)
+    {
+        (void)inet_aton(IPv4_MULTICAST, &IPv4MulticastAddress);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_INT, &IPv6MulticastAddressInt);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_LNK, &IPv6MulticastAddressLnk);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_RLM, &IPv6MulticastAddressRlm);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_ADM, &IPv6MulticastAddressAdm);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_SIT, &IPv6MulticastAddressSit);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_ORG, &IPv6MulticastAddressOrg);
+        (void)inet_pton(AF_INET6, IPv6_MULTICAST_GLB, &IPv6MulticastAddressGlb);
+    }
 
-    if (!g_adapterEthServerContext)
+    if (!caglobals.ip.ipv6enabled && !caglobals.ip.ipv4enabled)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return CA_STATUS_FAILED;
+        caglobals.ip.ipv4enabled = true;  // only needed to run CA tests
     }
 
-    if (1 == listLength) //Its first time.
+    if (caglobals.ip.ipv6enabled)
     {
-        g_packetHandlerStopFlag = false;
-        if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterEthServerContext->threadPool,
-                                                   CAReceiveHandler, NULL ))
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
-            ca_mutex_unlock(g_mutexAdapterServerContext);
-            return CA_STATUS_FAILED;
-        }
-        OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
+        NEWSOCKET(AF_INET6, u6)
+        NEWSOCKET(AF_INET6, u6s)
+        NEWSOCKET(AF_INET6, m6)
+        NEWSOCKET(AF_INET6, m6s)
+        OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
     }
-    else
+    if (caglobals.ip.ipv4enabled)
     {
-        OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
+        NEWSOCKET(AF_INET, u4)
+        NEWSOCKET(AF_INET, u4s)
+        NEWSOCKET(AF_INET, m4)
+        NEWSOCKET(AF_INET, m4s)
+        OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
     }
-    ca_mutex_unlock(g_mutexAdapterServerContext);
 
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, 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);
 
-    return CA_STATUS_OK;
-}
+    // create pipe for fast shutdown
+    CAInitializePipe();
+    CHECKFD(caglobals.ip.shutdownFds[0]);
+    CHECKFD(caglobals.ip.shutdownFds[1]);
 
-static void CAIPServerDestroyMutex(void)
-{
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
+    // create source of network interface change notifications
+    CAInitializeNetlink();
 
-    if (g_mutexServerInfoList)
-    {
-        ca_mutex_free(g_mutexServerInfoList);
-        g_mutexServerInfoList = NULL;
-    }
+    CAApplyInterfaces();
 
-    if (g_mutexAdapterServerContext)
+    caglobals.ip.terminate = false;
+    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL);
+    if (CA_STATUS_OK != res)
     {
-        ca_mutex_free(g_mutexAdapterServerContext);
-        g_mutexAdapterServerContext = NULL;
+        OIC_LOG(ERROR, TAG, "thread_pool_add_task failed");
+        return res;
     }
+    OIC_LOG(DEBUG, TAG, "CAReceiveHandler thread started successfully.");
 
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
+    caglobals.ip.started = true;
+    return CA_STATUS_OK;
 }
 
-static CAResult_t CAIPServerCreateMutex(void)
+void CAIPStopServer()
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    caglobals.ip.terminate = true;
 
-    g_mutexServerInfoList = ca_mutex_new();
-    if (!g_mutexServerInfoList)
+    if (caglobals.ip.shutdownFds[1] != -1)
     {
-        OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-        return CA_MEMORY_ALLOC_FAILED;
+        close(caglobals.ip.shutdownFds[1]);
+        // receive thread will stop immediately
     }
-
-    g_mutexAdapterServerContext = ca_mutex_new();
-    if (!g_mutexAdapterServerContext)
+    else
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to created mutex!");
-        ca_mutex_free(g_mutexServerInfoList);
-        g_mutexServerInfoList = NULL;
-        return CA_MEMORY_ALLOC_FAILED;
+        // receive thread will stop in SELECT_TIMEOUT seconds.
     }
 
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
+static void applyMulticastToInterface4(struct in_addr inaddr)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    // Input validation
-    VERIFY_NON_NULL(threadPool, IP_SERVER_TAG, "Thread pool handle is NULL");
-
-    // Initialize mutex
-    if (CA_STATUS_OK != CAIPServerCreateMutex())
+    if (!caglobals.ip.ipv4enabled)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create mutex!");
-        return CA_STATUS_FAILED;
+        return;
     }
 
-    ca_mutex_lock(g_mutexAdapterServerContext);
-    g_adapterEthServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
-                                 sizeof(CAAdapterIPServerContext_t));
-
-    if (!g_adapterEthServerContext)
+    struct ip_mreq mreq = { IPv4MulticastAddress };
+    mreq.imr_interface = inaddr;
+    if (setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)))
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return CA_MEMORY_ALLOC_FAILED;
+        if (EADDRINUSE != errno)
+        {
+            OIC_LOG_V(ERROR, TAG, "IPv4 IP_ADD_MEMBERSHIP failed: %s", strerror(errno));
+        }
     }
+    if (setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)))
+    {
+        if (EADDRINUSE != errno)
+        {
+            OIC_LOG_V(ERROR, TAG, "secure IPv4 IP_ADD_MEMBERSHIP failed: %s", strerror(errno));
+        }
+    }
+}
 
-    g_adapterEthServerContext->threadPool = threadPool;
-
-    ca_mutex_unlock(g_mutexAdapterServerContext);
-
-    ca_mutex_lock(g_mutexServerInfoList);
-
-    g_serverInfoList = u_arraylist_create();
-    if (!g_serverInfoList)
+static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t interface)
+{
+    struct ipv6_mreq mreq;
+    mreq.ipv6mr_multiaddr = *addr;
+    mreq.ipv6mr_interface = interface;
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof (mreq)))
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
-        ca_mutex_unlock(g_mutexServerInfoList);
-        return CA_MEMORY_ALLOC_FAILED;
+        if (EADDRINUSE != errno)
+        {
+            OIC_LOG_V(ERROR, TAG, "IPv6 IP_ADD_MEMBERSHIP failed: %s", strerror(errno));
+        }
     }
-    ca_mutex_unlock(g_mutexServerInfoList);
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-void CAIPTerminateServer()
+static void applyMulticastToInterface6(uint32_t interface)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-    ca_mutex_lock(g_mutexAdapterServerContext);
-    if (!g_adapterEthServerContext)
+    if (!caglobals.ip.ipv6enabled)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
         return;
     }
-
-    OICFree(g_adapterEthServerContext);
-    g_adapterEthServerContext = NULL;
-
-    ca_mutex_unlock(g_mutexAdapterServerContext);
-
-    ca_mutex_lock(g_mutexServerInfoList);
-
-    CAClearServerInfoList(g_serverInfoList);
-    g_serverInfoList = NULL;
-
-    ca_mutex_unlock(g_mutexServerInfoList);
-    // Destroy mutex
-    CAIPServerDestroyMutex();
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressInt, interface);
+    applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressLnk, interface);
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressRlm, interface);
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressAdm, interface);
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, interface);
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressOrg, interface);
+    //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressGlb, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressInt, interface);
+    applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressLnk, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressAdm, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressSit, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressOrg, interface);
+    //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressGlb, interface);
 }
 
-CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
-                                        bool forceBindStart, bool isSecured)
+static void CAApplyInterfaces()
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    // Input validation
-    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
-    VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
-
-    if (0 >= *port)
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!");
-        return CA_STATUS_INVALID_PARAM;
+        OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+        return;
     }
 
-    ca_mutex_lock(g_mutexServerInfoList);
-    bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
-    if (!isUnicastServerStarted)
-    {
-        int unicastServerFd = -1;
-        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceBindStart, isSecured,
-                                                 &unicastServerFd))
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_STATUS_FAILED;
-        }
+    uint32_t len = u_arraylist_length(iflist);
+    OIC_LOG_V(DEBUG, TAG, "IP network interfaces found: %d", len);
 
-        CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
-        if (!info)
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
-            close(unicastServerFd);
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
+    for (uint32_t i = 0; i < len; i++)
+    {
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
 
-        char *netMask = NULL;
-        if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
-        }
-        if (netMask)
+        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
         {
-            strncpy(info->subNetMask, netMask, sizeof(info->subNetMask) - 1);
-            info->subNetMask[sizeof(info->subNetMask)-1] = '\0';
-            OICFree(netMask);
+            continue;
         }
-        strncpy(info->ipAddress, localAddress, sizeof(info->ipAddress) - 1);
-        info->ipAddress[sizeof(info->ipAddress) - 1] = '\0';
-        info->port = *port;
-        info->socketFd = unicastServerFd;
-        info->isSecured = isSecured;
-        info->isServerStarted = true;
-        info->isMulticastServer = false;
-        strncpy(info->ifAddr, localAddress, sizeof(info->ifAddr) - 1);
-        info->ifAddr[sizeof(info->ifAddr) - 1] = '\0';
-
-        CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
-        if (CA_STATUS_OK != res)
+        if (ifitem->family == AF_INET)
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
-            close(unicastServerFd);
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return res;
+            struct in_addr inaddr;
+            inaddr.s_addr = ifitem->ipv4addr;
+            applyMulticastToInterface4(inaddr);
+            OIC_LOG_V(DEBUG, TAG, "IPv4 network interface: %s", ifitem->name);
         }
-        ca_mutex_unlock(g_mutexServerInfoList);
-
-        res = CAIPStartPacketReceiverHandler();
-        if (CA_STATUS_OK != res)
+        if (ifitem->family == AF_INET6)
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
-            close(unicastServerFd);
-            return res;
+            applyMulticastToInterface6(ifitem->index);
+            OIC_LOG_V(DEBUG, TAG, "IPv6 network interface: %s", ifitem->name);
         }
     }
-    else
-    {
-        OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
-                  localAddress, *port);
-        ca_mutex_unlock(g_mutexServerInfoList);
-    }
 
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
+    u_arraylist_destroy(iflist);
 }
 
-CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
-                                          uint16_t multicastPort)
+static void CAHandleNetlink()
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    // Input validation
-    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
-    VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");
-
-    uint16_t port = multicastPort;
-    if (0 >= port)
-    {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    ca_mutex_lock(g_mutexServerInfoList);
-    bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
-                                                               multicastAddress, port);
-    if (!isMulticastServerStarted)
+#ifdef __linux__
+char buf[4096];
+struct nlmsghdr *nh;
+struct sockaddr_nl sa;
+struct iovec iov = { buf, sizeof(buf) };
+struct msghdr msg = { (void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
+
+int len = recvmsg(caglobals.ip.netlinkFd, &msg, 0);
+for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len))
+{
+    if (nh->nlmsg_type == RTM_NEWLINK)
     {
-        int mulicastServerFd = -1;
-        CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, true);
-        if (ret != CA_STATUS_OK)
+        struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
+        if ((ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING))
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return ret;
+            continue;
         }
 
-        struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
-        inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);
+        int newIndex = ifi->ifi_index;
 
-        if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                             (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
+        u_arraylist_t *iflist = CAIPGetInterfaceInformation(newIndex);
+        if (!iflist)
         {
-            OIC_LOG_V(ERROR, IP_SERVER_TAG,
-                      "Failed to add to multicast group, Error code: %s\n", strerror(errno));
-            close(mulicastServerFd);
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_STATUS_FAILED;
+            OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+            return;
         }
 
-        CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
-        if (!info)
+        uint32_t len = u_arraylist_length(iflist);
+        for (uint32_t i = 0; i < len; i++)
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
-            close(mulicastServerFd);
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
+            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+            if (ifitem->index != newIndex)
+            {
+                continue;
+            }
 
-        char *netMask = NULL;
-        if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
-        }
-        if (netMask)
-        {
-            strncpy(info->subNetMask, netMask, sizeof(info->subNetMask) - 1);
-            info->subNetMask[sizeof(info->subNetMask) -1] = '\0';
-            OICFree(netMask);
+            applyMulticastToInterface6(newIndex);
+            struct in_addr inaddr;
+            inaddr.s_addr = ifitem->ipv4addr;
+            applyMulticastToInterface4(inaddr);
+            break;  // we found the one we were looking for
         }
+        u_arraylist_destroy(iflist);
+    }
+}
+#endif // __linux__
+}
 
-        strncpy(info->ipAddress, multicastAddress, sizeof(info->ipAddress) - 1);
-        info->ipAddress[sizeof(info->ipAddress) -1] = '\0';
-        info->port = multicastPort;
-        info->socketFd = mulicastServerFd;
-        info->isSecured = false;
-        info->isServerStarted = true;
-        info->isMulticastServer = true;
-        strncpy(info->ifAddr, localAddress, sizeof(info->ifAddr)-1);
-        info->ifAddr[sizeof(info->ifAddr) -1] = '\0';
+void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
+{
+OIC_LOG(DEBUG, TAG, "IN");
 
-        ret = CAAddServerInfo(g_serverInfoList, info);
+g_packetReceivedCallback = callback;
 
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
-            close(mulicastServerFd);
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return ret;
-        }
-        ca_mutex_unlock(g_mutexServerInfoList);
+OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
+{
+OIC_LOG(DEBUG, TAG, "IN");
+
+    g_exceptionCallback = callback;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static void sendData(int fd, const CAEndpoint_t *endpoint,
+                     const void *data, uint32_t dlen,
+                     const char *cast, const char *fam)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    char *secure = (endpoint->flags & CA_SECURE) ? "secure " : "";
+    (void)secure;   // eliminates release warning
+    struct sockaddr_storage sock;
+    CAConvertNameToAddr(endpoint->addr, endpoint->port, &sock);
 
-        ret = CAIPStartPacketReceiverHandler();
-        if (CA_STATUS_OK != ret)
+    if (sock.ss_family == AF_INET6)
+    {
+        struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)&sock;
+        if (!sock6->sin6_scope_id)
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
-            close(mulicastServerFd);
-            return ret;
+            sock6->sin6_scope_id = endpoint->interface;
         }
     }
+
+    ssize_t len = sendto(fd, data, dlen, 0, (struct sockaddr *)&sock, sizeof (sock));
+    if (-1 == len)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %s", secure, cast, fam, strerror(errno));
+    }
     else
     {
-        OIC_LOG_V(DEBUG, IP_SERVER_TAG,
-                  "Multicast Server is already started on interface addr[%s]", localAddress);
-        ca_mutex_unlock(g_mutexServerInfoList);
+        OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %d bytes", secure, cast, fam, len);
     }
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-CAResult_t CAIPStopServer(const char *interfaceAddress)
+static void sendMulticastData6(const u_arraylist_t *iflist,
+                               CAEndpoint_t *endpoint,
+                               const void *data, uint32_t datalen)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    VERIFY_NON_NULL(interfaceAddress, IP_SERVER_TAG, "interfaceAddress is NULL");
-
-    ca_mutex_lock(g_mutexServerInfoList);
-    uint32_t listIndex = 0;
-    uint32_t listLength = u_arraylist_length(g_serverInfoList);
+    int scope = endpoint->flags & CA_SCOPE_MASK;
+    char *ipv6mcname = ipv6mcnames[scope];
+    if (!ipv6mcname)
+    {
+        OIC_LOG_V(INFO, TAG, "IPv6 multicast scope invalid: %d", scope);
+        return;
+    }
+    strncpy(endpoint->addr, ipv6mcname, MAX_ADDR_STR_SIZE_CA);
+    int fd = caglobals.ip.u6.fd;
 
-    for (listIndex = 0; listIndex < listLength;)
+    uint32_t len = u_arraylist_length(iflist);
+    for (uint32_t i = 0; i < len; i++)
     {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
-        if (!info)
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
         {
-            listIndex++;
             continue;
         }
-
-        if (info->isMulticastServer && strncmp(interfaceAddress, info->ifAddr, strlen(info->ifAddr))
-                == 0)
-        {
-            if (u_arraylist_remove(g_serverInfoList, listIndex))
-            {
-                struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
-
-                multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
-                inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
-                if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-                                     (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
-                {
-                    OIC_LOG_V(ERROR, IP_SERVER_TAG,
-                              "Failed to leave multicast group, Error code: %s", strerror(errno));
-                }
-                CACloseSocket(info->socketFd);
-                OICFree(info);
-                OIC_LOG(DEBUG, IP_SERVER_TAG, "Multicast server is stopped successfully.");
-                // Reduce list length by 1 as we removed one element.
-                listLength--;
-            }
-            else
-            {
-                OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
-                ca_mutex_unlock(g_mutexServerInfoList);
-                return CA_STATUS_FAILED;
-            }
-        }
-        else if (strncmp(interfaceAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
+        if (ifitem->family != AF_INET6)
         {
-            if (u_arraylist_remove(g_serverInfoList, listIndex))
-            {
-                CACloseSocket(info->socketFd);
-                OICFree(info);
-                OIC_LOG(DEBUG, IP_SERVER_TAG, "Unicast server is stopped successfully.");
-                // Reduce list length by 1 as we removed one element.
-                listLength--;
-            }
-            else
-            {
-                OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
-                ca_mutex_unlock(g_mutexServerInfoList);
-                return CA_STATUS_FAILED;
-            }
+            continue;
         }
-        else
+
+        int index = ifitem->index;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, sizeof (index)))
         {
-            listIndex++;
+            OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", strerror(errno));
+            return;
         }
+        sendData(fd, endpoint, data, datalen, "multicast", "ipv6");
     }
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    ca_mutex_unlock(g_mutexServerInfoList);
-    return CA_STATUS_OK;
 }
 
-CAResult_t CAIPStopAllServers()
+static void sendMulticastData4(const u_arraylist_t *iflist,
+                               CAEndpoint_t *endpoint,
+                               const void *data, uint32_t datalen)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-
-    g_packetHandlerStopFlag = true;
+    struct ip_mreq mreq = { IPv4MulticastAddress };
+    strncpy(endpoint->addr, IPv4_MULTICAST, MAX_ADDR_STR_SIZE_CA);
+    int fd = caglobals.ip.u4.fd;
 
-    ca_mutex_lock(g_mutexServerInfoList);
-
-    uint32_t listIndex = 0;
-    uint32_t listLength = u_arraylist_length(g_serverInfoList);
-    for (listIndex = 0; listIndex < listLength;)
+    uint32_t len = u_arraylist_length(iflist);
+    for (uint32_t i = 0; i < len; i++)
     {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
-        if (!info)
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+        if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
         {
-            listIndex++;
             continue;
         }
-        if (u_arraylist_remove(g_serverInfoList, listIndex))
+        if (ifitem->family != AF_INET)
         {
-            if (info->isMulticastServer)
-            {
-                struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
-
-                multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
-                inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
-                if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-                                     (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
-                {
-                    OIC_LOG_V(ERROR, IP_SERVER_TAG,
-                              "Failed to leave multicast group, Error code: %s", strerror(errno));
-                }
-            }
-            CACloseSocket(info->socketFd);
-            //Freeing server info.
-            OICFree(info);
-            // Reduce list length by 1 as we removed one element.
-            listLength--;
+            continue;
         }
-        else
+
+        struct in_addr inaddr;
+        inaddr.s_addr = ifitem->ipv4addr;
+        mreq.imr_interface = inaddr;
+        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq)))
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_STATUS_FAILED;
+            OIC_LOG_V(ERROR, TAG, "send IP_MULTICAST_IF failed: %s (using defualt)", strerror(errno));
         }
+        sendData(fd, endpoint, data, datalen, "multicast", "ipv4");
     }
-
-    ca_mutex_unlock(g_mutexServerInfoList);
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "All Server stopped successfully. OUT");
-    return CA_STATUS_OK;
 }
 
-uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
+void CAIPSendData(CAEndpoint_t *endpoint, const void *data, uint32_t datalen,
+                                                            bool isMulticast)
 {
-    ca_mutex_lock(g_mutexServerInfoList);
+    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
 
-    uint16_t port = CAGetServerPort(g_serverInfoList, ipAddress, isSecured);
+    bool isSecure = (endpoint->flags & CA_SECURE) != 0;
 
-    ca_mutex_unlock(g_mutexServerInfoList);
+    if (isMulticast)
+    {
+        endpoint->port = isSecure ? CA_SECURE_COAP : CA_COAP;
 
-    return port;
-}
+        u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+        if (!iflist)
+        {
+            OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+            return;
+        }
 
-CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList)
-{
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-    ca_mutex_lock(g_mutexServerInfoList);
+        if ((endpoint->flags & CA_IPV6) && caglobals.ip.ipv6enabled)
+        {
+            sendMulticastData6(iflist, endpoint, data, datalen);
+        }
+        if ((endpoint->flags & CA_IPV4) && caglobals.ip.ipv4enabled)
+        {
+            sendMulticastData4(iflist, endpoint, data, datalen);
+        }
 
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_serverInfoList);
-    for (list_index = 0; list_index < list_length; list_index++)
+        u_arraylist_destroy(iflist);
+    }
+    else
     {
-        CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, list_index);
-        if (!info)
+        if (!endpoint->port)    // unicast discovery
         {
-            continue;
+            endpoint->port = isSecure ? CA_SECURE_COAP : CA_COAP;
         }
 
-        CAServerInfo_t *newNetinfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
-        if (!newNetinfo)
+        int fd;
+        if (caglobals.ip.ipv6enabled && (endpoint->flags & CA_IPV6))
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_MEMORY_ALLOC_FAILED;
+            fd = isSecure ? caglobals.ip.u6s.fd : caglobals.ip.u6.fd;
+            #ifndef __WITH_DTLS__
+            fd = caglobals.ip.u6.fd;
+            #endif
+            sendData(fd, endpoint, data, datalen, "unicast", "ipv6");
         }
-
-        memcpy(newNetinfo, info, sizeof(*info));
-
-        CAResult_t result = u_arraylist_add(*serverInfoList, (void *) newNetinfo);
-        if (CA_STATUS_OK != result)
+        if (caglobals.ip.ipv4enabled && (endpoint->flags & CA_IPV4))
         {
-            OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_mutexServerInfoList);
-            return CA_STATUS_FAILED;
+            fd = isSecure ? caglobals.ip.u4s.fd : caglobals.ip.u4.fd;
+            #ifndef __WITH_DTLS__
+            fd = caglobals.ip.u4.fd;
+            #endif
+            sendData(fd, endpoint, data, datalen, "unicast", "ipv4");
         }
     }
-    ca_mutex_unlock(g_mutexServerInfoList);
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-    return CA_STATUS_OK;
 }
 
-void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
+CAResult_t CAGetIPInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_mutexAdapterServerContext);
+    VERIFY_NON_NULL(info, TAG, "info is NULL");
+    VERIFY_NON_NULL(size, TAG, "size is NULL");
 
-    if (!g_adapterEthServerContext)
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return;
+        OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+        return CA_STATUS_FAILED;
     }
-    g_adapterEthServerContext->packetReceivedCallback = callback;
 
-    ca_mutex_unlock(g_mutexAdapterServerContext);
-
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
-}
+    uint32_t len = u_arraylist_length(iflist);
 
-void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
-{
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
-    ca_mutex_lock(g_mutexAdapterServerContext);
+    CAEndpoint_t *eps = (CAEndpoint_t *)OICCalloc(len, sizeof (CAEndpoint_t));
+    if (!eps)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc Failed");
+        u_arraylist_destroy(iflist);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
-    if (!g_adapterEthServerContext)
+    for (uint32_t i = 0, j = 0; i < len; i++)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return;
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+
+        OICStrcpy(eps[j].addr, CA_INTERFACE_NAME_SIZE, ifitem->name);
+        eps[j].flags = ifitem->family == AF_INET6 ? CA_IPV6 : CA_IPV4;
+        eps[j].adapter = CA_ADAPTER_IP;
+        eps[j].interface = 0;
+        eps[j].port = 0;
+        j++;
     }
-    g_adapterEthServerContext->exceptionCallback = callback;
 
-    ca_mutex_unlock(g_mutexAdapterServerContext);
+    *info = eps;
+    *size = len;
 
-    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
+    u_arraylist_destroy(iflist);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
index c077580..a04b1c7 100644 (file)
 #include <unistd.h>
 
 #include "caadapterutils.h"
-#include "camutex.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
-#define IP_MONITOR_TAG "IP_MONITOR"
+#define TAG "IP_MONITOR"
 
-/**
- * @var g_networkMonitorContextMutex
- * @brief  Mutex for synchronizing access to cached interface and IP address information.
- */
-static ca_mutex g_networkMonitorContextMutex = NULL;
-
-/**
- * @var g_stopNetworkMonitor
- * @brief  Used to stop the network monitor thread.
- */
-static bool g_stopNetworkMonitor = false;
-
-/**
- * @var g_stopNetworkMonitorMutex
- * @brief  Mutex for synchronizing access to g_stopNetworkMonitor flag.
- */
-static ca_mutex g_stopNetworkMonitorMutex = NULL;
-
-/**
- * @struct CAIPNwMonitorContext
- * @brief  Used for storing network monitor context information.
- */
-typedef struct
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
 {
-    u_arraylist_t  *netInterfaceList;
-    ca_thread_pool_t threadPool;
-    CANetworkStatus_t nwConnectivityStatus;
-    CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
-
-/**
- * @var g_networkMonitorContext
- * @brief  network monitor context.
- */
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
-
-static void CAIPGetInterfaceInformation(u_arraylist_t **netInterfaceList)
-{
-
-    VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is 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, IP_MONITOR_TAG, "Failed to get interface list!, Error code: %s",
-                  strerror(errno));
-        return;
+        OIC_LOG_V(ERROR, TAG, "Failed to get ifaddrs: %s", strerror(errno));
+        u_arraylist_destroy(iflist);
+        return NULL;
     }
+    OIC_LOG(DEBUG, TAG, "Got ifaddrs");
 
     struct ifaddrs *ifa = NULL;
     for (ifa = ifp; ifa; ifa = ifa->ifa_next)
     {
-        char interfaceAddress[CA_IPADDR_SIZE] = {0};
-        char interfaceSubnetMask[CA_IPADDR_SIZE] = {0};
-        socklen_t len = sizeof(struct sockaddr_in);
-
-        if (!ifa->ifa_addr)
-        {
-            continue;
-        }
-
-        int type = ifa->ifa_addr->sa_family;
-        if (ifa->ifa_flags & IFF_LOOPBACK
-            || !((ifa->ifa_flags & IFF_UP) && (ifa->ifa_flags & IFF_RUNNING)))
+        int family = ifa->ifa_addr->sa_family;
+        if ((ifa->ifa_flags & IFF_LOOPBACK) || (AF_INET != family && AF_INET6 != family))
         {
             continue;
         }
 
-        if (AF_INET != type)
+        int ifindex = if_nametoindex(ifa->ifa_name);
+        if (desiredIndex && (ifindex != desiredIndex))
         {
             continue;
         }
 
-        // get the interface ip address
-        if (0 != getnameinfo(ifa->ifa_addr, len, interfaceAddress,
-                             sizeof(interfaceAddress), NULL, 0, NI_NUMERICHOST))
-        {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
-                      strerror(errno));
-            continue;
-        }
-
-        // get the interface subnet mask
-        if (0 != getnameinfo(ifa->ifa_netmask, len, interfaceSubnetMask,
-                             sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
-        {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
-                      strerror(errno));
-            continue;
-        }
-
-        CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
-        if (!netInfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
-            freeifaddrs(ifp);
-            return;
-        }
-        // set interface name
-        strncpy(netInfo->interfaceName, ifa->ifa_name, sizeof(netInfo->interfaceName) - 1);
-        netInfo->interfaceName[sizeof(netInfo->interfaceName)-1] = '\0';
-
-        // set local ip address
-        strncpy(netInfo->ipAddress, interfaceAddress, strlen(interfaceAddress));
-
-        // set subnet mask
-        strncpy(netInfo->subnetMask, interfaceSubnetMask, strlen(interfaceSubnetMask));
-
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)netInfo);
-        if (CA_STATUS_OK != result)
+        int length = u_arraylist_length(iflist);
+        int already = false;
+        for (int i = length-1; i >= 0; i--)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!Thread exiting.");
-            freeifaddrs(ifp);
-            return;
-        }
-    }
-
-    freeifaddrs(ifp);
-}
-
-static bool CACheckIsAnyInterfaceDown(const u_arraylist_t *netInterfaceList,
-                                      const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null", false);
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
-
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(netInterfaceList);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(netInterfaceList,
-                               list_index);
-        if (!netInfo)
-        {
-            continue;
-        }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
-        {
-            return false;
-        }
-    }
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-    return true;
-}
-
-static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
-                               g_networkMonitorContext->netInterfaceList, list_index);
-        if (!netInfo)
-        {
-            continue;
-        }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
-        {
-            if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
+            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+            if (ifitem->index == ifindex && ifitem->family == family)
             {
-                ca_mutex_unlock(g_networkMonitorContextMutex);
-                return false;
-            }
-            else
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
-                if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
-                {
-                    if (g_networkMonitorContext->networkChangeCb)
-                    {
-                        g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
-                                                                 CA_INTERFACE_DOWN);
-                    }
-                    OICFree(netInfo);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                }
+                already = true;
                 break;
             }
         }
-    }
-
-    CANetInfo_t *newNetInfo = (CANetInfo_t *)OICMalloc(sizeof(CANetInfo_t));
-    if (!newNetInfo)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    memcpy(newNetInfo, info, sizeof(*newNetInfo));
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
-
-    CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
-                                        (void *)newNetInfo);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-        OICFree(newNetInfo);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    /*Callback will be unset only at the time of termination. By that time, all the threads will be
-      stopped gracefully. This callback is properly protected*/
-    if (g_networkMonitorContext->networkChangeCb)
-    {
-        g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
-    }
-
-    return true;
-}
-
-static void CANetworkMonitorThread(void *threadData)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    while (!g_stopNetworkMonitor)
-    {
-        u_arraylist_t  *netInterfaceList = u_arraylist_create();
-
-        VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
-        CAIPGetInterfaceInformation(&netInterfaceList);
-
-        ca_mutex_lock(g_networkMonitorContextMutex);
-        if (!g_networkMonitorContext->netInterfaceList)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG,
-                    "u_arraylist_create failed. Network Monitor thread stopped");
-            CAClearNetInterfaceInfoList(netInterfaceList);
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return;
-        }
-
-        uint32_t listIndex = 0;
-        uint32_t listLength = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-        for (listIndex = 0; listIndex < listLength;)
-        {
-            CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
-                                    g_networkMonitorContext->netInterfaceList, listIndex);
-            if (!info)
-            {
-                listIndex++;
-                continue;
-            }
-
-            bool ret = CACheckIsAnyInterfaceDown(netInterfaceList, info);
-            if (ret)
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-                if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, listIndex))
-                {
-                    OIC_LOG(DEBUG, IP_MONITOR_TAG, "u_arraylist_remove success");
-                    if (g_networkMonitorContext->networkChangeCb)
-                    {
-                        g_networkMonitorContext->networkChangeCb(info->ipAddress,
-                                                                 CA_INTERFACE_DOWN);
-                    }
-                    OICFree(info);
-                    listLength--;
-                }
-                else
-                {
-                    OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                    break;
-                }
-            }
-            else
-            {
-                listIndex++;
-            }
-        }
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-
-        listLength = u_arraylist_length(netInterfaceList);
-        for (listIndex = 0; listIndex < listLength; listIndex++)
-        {
-            CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(netInterfaceList, listIndex);
-            if (!info)
-            {
-                continue;
-            }
-            bool ret = CACheckIsInterfaceInfoChanged(info);
-            if (ret)
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
-            }
-        }
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        sleep(2); // To avoid maximum cpu usage.
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-static CAResult_t CAInitializeNetworkMonitorMutexes()
-{
-    if (!g_networkMonitorContextMutex)
-    {
-        g_networkMonitorContextMutex = ca_mutex_new();
-        if (!g_networkMonitorContextMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc  failed");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-
-    if (!g_stopNetworkMonitorMutex)
-    {
-        g_stopNetworkMonitorMutex = ca_mutex_new();
-        if (!g_stopNetworkMonitorMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_stopNetworkMonitorMutex Malloc  failed");
-            ca_mutex_free(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-    return CA_STATUS_OK;
-}
-static void CADestroyNetworkMonitorMutexes()
-{
-    ca_mutex_free(g_networkMonitorContextMutex);
-    g_networkMonitorContextMutex = NULL;
-
-    ca_mutex_free(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitorMutex = NULL;
-}
-
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
-    CAResult_t ret = CAInitializeNetworkMonitorMutexes();
-
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
-        return CA_STATUS_FAILED;
-    }
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext = (CAIPNetworkMonitorContext *)OICCalloc(1,
-                              sizeof(*g_networkMonitorContext));
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc  failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    g_networkMonitorContext->threadPool = threadPool;
-
-    g_networkMonitorContext->netInterfaceList = u_arraylist_create();
-    if (!g_networkMonitorContext->netInterfaceList)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
-        OICFree(g_networkMonitorContext);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    CAIPGetInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
-
-    if (u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_UP;
-    }
-    else
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    g_networkMonitorContext->threadPool = NULL;
-
-    CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
-
-    g_networkMonitorContext->netInterfaceList = NULL;
-    g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    g_networkMonitorContext->networkChangeCb = NULL;
-    g_networkMonitorContext->threadPool = NULL;
-
-    OICFree(g_networkMonitorContext);
-    g_networkMonitorContext = NULL;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitor = true;
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    CADestroyNetworkMonitorMutexes();
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-
-    g_stopNetworkMonitor = false;
-
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_networkMonitorContext->threadPool,
-            CANetworkMonitorThread, NULL))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "[ThreadPool] thread_pool_add_task failed!");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_STATUS_FAILED;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStopNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    if (!g_stopNetworkMonitor)
-    {
-        g_stopNetworkMonitor = true;
-    }
-    else
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStopNetworkMonitor, already stopped!");
-    }
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
-                    "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
-              list_length);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
-                            g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
+        if (already)
         {
             continue;
         }
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
-                  info->ipAddress);
-        CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-        if (!newNetinfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        memcpy(newNetinfo, info, sizeof(*info));
 
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)newNetinfo);
-        if (CA_STATUS_OK != result)
+        CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
+        if (!ifitem)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_STATUS_FAILED;
+            OIC_LOG(ERROR, TAG, "Malloc failed");
+            goto exit;
         }
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
 
-    VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
-    VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
-                    "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
+        OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, ifa->ifa_name);
+        ifitem->index = ifindex;
+        ifitem->family = family;
+        ifitem->ipv4addr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr;
+        ifitem->flags = ifa->ifa_flags;
 
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
-                            g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
+        CAResult_t result = u_arraylist_add(iflist, ifitem);
+        if (CA_STATUS_OK != result)
         {
-            OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
-                      "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
-            *subnetMask = OICStrdup(info->subnetMask);
-            break;
+            OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+            goto exit;
         }
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
 
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-bool CAIPIsConnected()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        return false;
+        OIC_LOG_V(ERROR, TAG, "Added interface: %s (%d)", ifitem->name, family);
     }
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return true;
-}
-
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
-        return;
-    }
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext->networkChangeCb = callback;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    freeifaddrs(ifp);
+    return iflist;
 
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+exit:
+    freeifaddrs(ifp);
+    u_arraylist_destroy(iflist);
+    return NULL;
 }
-
diff --git a/resource/csdk/connectivity/src/ip_adapter/tizen/SConscript b/resource/csdk/connectivity/src/ip_adapter/tizen/SConscript
new file mode 100644 (file)
index 0000000..249d73c
--- /dev/null
@@ -0,0 +1,12 @@
+#######################################################
+#       Build IP adapter for Tizen
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+env.ParseConfig("pkg-config --cflags --libs capi-network-wifi")
+
+src_files = [ 'caipnwmonitor.c' ]
+
+Return('src_files')
index 1a46cd8..90e200f 100644 (file)
 
 #include "caipinterface.h"
 
-#include <wifi.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
 
 #include "caadapterutils.h"
-#include "camutex.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
-#define IP_MONITOR_TAG "IP_MONITOR"
+#define TAG "IP_MONITOR"
 
-/**
- * @var g_networkMonitorContextMutex
- * @brief  Mutex for synchronizing access to cached interface and IP address information.
- */
-static ca_mutex g_networkMonitorContextMutex = NULL;
-
-/**
- * @struct CAIPNwMonitorContext
- * @brief  Used for storing network monitor context information.
- */
-typedef struct
-{
-    u_arraylist_t  *netInterfaceList;
-    ca_thread_pool_t threadPool;
-    CANetworkStatus_t nwConnectivityStatus;
-    CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
-
-/**
- * @var g_networkMonitorContext
- * @brief  network monitor context.
- */
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
-
-static void CARemoveInterfaceInfo()
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
 {
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList)
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG,
-                "netInterfaceList is empty");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
+        OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+        return NULL;
     }
 
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (list_index = 0; list_index < list_length; list_index++)
+    struct ifaddrs *ifp = NULL;
+    if (-1 == getifaddrs(&ifp))
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
-                               g_networkMonitorContext->netInterfaceList, list_index);
-        if (!netInfo)
-        {
-            continue;
-        }
-
-        if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
-        {
-            if (g_networkMonitorContext->networkChangeCb)
-            {
-                g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
-                                                         CA_INTERFACE_DOWN);
-            }
-        }
-        else
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-        }
-
-        OICFree(netInfo);
+        OIC_LOG_V(ERROR, TAG, "Failed to get ifaddrs: %s", strerror(errno));
+        u_arraylist_destroy(iflist);
+        return NULL;
     }
 
-    u_arraylist_free(&g_networkMonitorContext->netInterfaceList);
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-}
-
-static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (list_index = 0; list_index < list_length; list_index++)
+    struct ifaddrs *ifa = NULL;
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next)
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
-                               g_networkMonitorContext->netInterfaceList, list_index);
-        if (!netInfo)
+        int family = ifa->ifa_addr->sa_family;
+        if ((ifa->ifa_flags & IFF_LOOPBACK) || (AF_INET != family && AF_INET6 != family))
         {
             continue;
         }
 
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
+        int ifindex = if_nametoindex(ifa->ifa_name);
+        int length = u_arraylist_length(iflist);
+        int already = false;
+        for (int i = length-1; i >= 0; i--)
         {
-            if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
+            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+            if (ifitem->index == ifindex && ifitem->family == family)
             {
-                ca_mutex_unlock(g_networkMonitorContextMutex);
-                return false;
-            }
-            else
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
-                if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
-                {
-                    if (g_networkMonitorContext->networkChangeCb)
-                    {
-                        g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
-                                                                 CA_INTERFACE_DOWN);
-                    }
-                    OICFree(netInfo);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                }
+                already = true;
                 break;
             }
         }
-    }
-
-    CANetInfo_t *newNetInfo = (CANetInfo_t *)OICMalloc(sizeof(CANetInfo_t));
-    if (!newNetInfo)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    memcpy(newNetInfo, info, sizeof(*newNetInfo));
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
-
-    CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
-                                        (void *)newNetInfo);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-        OICFree(newNetInfo);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    /*Callback will be unset only at the time of termination. By that time, all the threads will be
-      stopped gracefully. This callback is properly protected*/
-    if (g_networkMonitorContext->networkChangeCb)
-    {
-        g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
-    }
-
-    return true;
-}
-
-void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    int ret = WIFI_ERROR_NONE;
-
-    if (!interfaceName || !ipAddress || !subnetMask)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
-        return;
-    }
-
-    // Get wifi interface name
-    if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
-    {
-        OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
-        return;
-    }
-
-    // Get wifi connected IP address
-    wifi_ap_h accessPoint = NULL;
-    if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
-    {
-        OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get access point! error num [%d]",
-                  ret);
-
-        OICFree(*interfaceName);
-        *interfaceName = NULL;
-        return;
-    }
-
-    if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
-                                  ipAddress)))
-    {
-        OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
-                  ret);
-        OICFree(*interfaceName);
-        *interfaceName = NULL;
-        return;
-    }
-
-    if (WIFI_ERROR_NONE != (ret = wifi_ap_get_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
-                                  subnetMask)))
-    {
-        OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
-                  ret);
-        OICFree(*ipAddress);
-        OICFree(*interfaceName);
-        *ipAddress = NULL;
-        *interfaceName = NULL;
-        return;
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-static void CAIPGetInterfaceInformation(u_arraylist_t **netInterfaceList)
-{
-    VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
-    // Get wifi network information
-    char *interfaceName = NULL;
-    char *ipAddress = NULL;
-    char *subnetMask = NULL;
-    ///TODO: currently we are filling single interface. Once found the proper tizen apis for
-    // getting multiple interfaces, then this function will be updated.
-    CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
-
-    if (!interfaceName || !ipAddress || !subnetMask)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "interface/ipaddress/subnetmask is NULL!");
-        return;
-    }
-
-    CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
-    if (!netInfo)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
-        OICFree(interfaceName);
-        OICFree(ipAddress);
-        OICFree(subnetMask);
-        return;
-    }
-
-    // set interface name
-    strncpy(netInfo->interfaceName, interfaceName, strlen(interfaceName));
-
-    // set local ip address
-    strncpy(netInfo->ipAddress, ipAddress, strlen(ipAddress));
-
-    // set subnet mask
-    strncpy(netInfo->subnetMask, subnetMask, strlen(subnetMask));
-
-    CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)netInfo);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-    }
-    OICFree(interfaceName);
-    OICFree(ipAddress);
-    OICFree(subnetMask);
-}
-
-
-void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
-                                    void *userData)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    if (WIFI_CONNECTION_STATE_ASSOCIATION == state
-        || WIFI_CONNECTION_STATE_CONFIGURATION == state)
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Connection is in Association State");
-        return;
-    }
-
-    // If Wifi is connected, then get the latest IP from the WIFI Interface
-    if (WIFI_CONNECTION_STATE_CONNECTED == state)
-    {
-        // Get network information
-        char *interfaceName = NULL;
-        char *ipAddress = NULL;
-        char *subnetMask = NULL;
-        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
-
-        CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
-        if (!netInfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
-            OICFree(interfaceName);
-            OICFree(ipAddress);
-            OICFree(subnetMask);
-            return;
-        }
-
-        // set interface name
-        strncpy(netInfo->interfaceName, interfaceName, strlen(interfaceName));
-
-        // set local ip address
-        strncpy(netInfo->ipAddress, ipAddress, strlen(ipAddress));
-
-        // set subnet mask
-        strncpy(netInfo->subnetMask, subnetMask, strlen(subnetMask));
-
-        bool ret = CACheckIsInterfaceInfoChanged(netInfo);
-        if (ret)
-        {
-            OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
-        }
-
-        OICFree(interfaceName);
-        OICFree(ipAddress);
-        OICFree(subnetMask);
-    }
-    else
-    {
-        CARemoveInterfaceInfo();
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    if (WIFI_DEVICE_STATE_ACTIVATED == state)
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Activated State");
-    }
-    else
-    {
-        CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Deactivated State");
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-static CAResult_t CAInitializeNetworkMonitorMutexes()
-{
-    if (!g_networkMonitorContextMutex)
-    {
-        g_networkMonitorContextMutex = ca_mutex_new();
-        if (!g_networkMonitorContextMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc  failed");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-
-    return CA_STATUS_OK;
-}
-
-static void CADestroyNetworkMonitorMutexes()
-{
-    ca_mutex_free(g_networkMonitorContextMutex);
-    g_networkMonitorContextMutex = NULL;
-}
-
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
-    CAResult_t ret = CAInitializeNetworkMonitorMutexes();
-
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
-        return CA_STATUS_FAILED;
-    }
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-     // Initialize Wifi service
-    wifi_error_e retValue = wifi_initialize();
-    if (WIFI_ERROR_NONE != retValue)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_initialize failed");
-        return CA_STATUS_FAILED;
-    }
-
-    g_networkMonitorContext = (CAIPNetworkMonitorContext *)OICCalloc(1,
-                              sizeof(*g_networkMonitorContext));
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc  failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    g_networkMonitorContext->netInterfaceList = u_arraylist_create();
-    if (!g_networkMonitorContext->netInterfaceList)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
-        OICFree(g_networkMonitorContext);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    CAIPGetInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-     // Deinitialize Wifi service
-    wifi_error_e ret = wifi_deinitialize();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_deinitialize failed");
-    }
-
-    CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
-
-    g_networkMonitorContext->netInterfaceList = NULL;
-    g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    g_networkMonitorContext->networkChangeCb = NULL;
-
-    OICFree(g_networkMonitorContext);
-    g_networkMonitorContext = NULL;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    CADestroyNetworkMonitorMutexes();
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-     // Set callback for receiving state changes
-    wifi_error_e ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
-        return CA_STATUS_FAILED;
-    }
-
-    // Set callback for receiving connection state changes
-    ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStopNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-     // Reset callback for receiving state changes
-    wifi_error_e ret = wifi_unset_device_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
-    }
-
-    // Reset callback for receiving connection state changes
-    ret = wifi_unset_connection_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
-                    "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
-              list_length);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
-                            g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
+        if (already)
         {
             continue;
         }
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
-                  info->ipAddress);
-        CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-        if (!newNetinfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        memcpy(newNetinfo, info, sizeof(*info));
 
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)newNetinfo);
-        if (CA_STATUS_OK != result)
+        CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
+        if (!ifitem)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_STATUS_FAILED;
+            OIC_LOG(ERROR, TAG, "Malloc failed");
+            goto exit;
         }
-    }
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
 
-    VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
-    VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
-                    "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
+        OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, ifa->ifa_name);
+        ifitem->index = ifindex;
+        ifitem->family = family;
+        ifitem->ipv4addr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr;
+        ifitem->flags = ifa->ifa_flags;
 
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    uint32_t list_index = 0;
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
-    for (list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
-                            g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
+        CAResult_t result = u_arraylist_add(iflist, ifitem);
+        if (CA_STATUS_OK != result)
         {
-            OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
-                      "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
-            *subnetMask = OICStrdup(info->subnetMask);
-            break;
+            OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+            goto exit;
         }
     }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-bool CAIPIsConnected()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    wifi_connection_state_e connection_state;
-    wifi_error_e ret = wifi_get_connection_state(&connection_state);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get the Connection State");
-        return false;
-    }
-
-    if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "WIFI is not Connected");
-        return false;
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return true;
-}
-
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
-        return;
-    }
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext->networkChangeCb = callback;
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    freeifaddrs(ifp);
+    return iflist;
 
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+exit:
+    freeifaddrs(ifp);
+    u_arraylist_destroy(iflist);
+    return NULL;
 }
diff --git a/resource/csdk/connectivity/src/ra_adapter/SConscript b/resource/csdk/connectivity/src/ra_adapter/SConscript
new file mode 100644 (file)
index 0000000..2b077bb
--- /dev/null
@@ -0,0 +1,31 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+import os
+
+print "Reading RA adapter script"
+
+target_os = env.get('TARGET_OS')
+inc_files = env.get('CPPPATH')
+src_dir = './ra_adapter'
+
+#Source files to build in Linux platform
+env.AppendUnique(CA_SRC=[os.path.join(src_dir, 'caraadapter.c')])
diff --git a/resource/csdk/connectivity/src/ra_adapter/caraadapter.c b/resource/csdk/connectivity/src/ra_adapter/caraadapter.c
new file mode 100644 (file)
index 0000000..7413035
--- /dev/null
@@ -0,0 +1,427 @@
+/******************************************************************
+//
+// 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 "caraadapter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "caadapterutils.h"
+#include "camutex.h"
+#include "uarraylist.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ra_xmpp.h"
+#include "caremotehandler.h"
+#include "cacommon.h"
+
+/**
+ * @def RA_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define RA_ADAPTER_TAG "RA_ADAP"
+
+/**
+ * @var g_networkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
+
+/**
+ * @var g_networkChangeCallback
+ * @brief Network Changed Callback to CA
+ */
+static CANetworkChangeCallback g_networkChangeCallback = NULL;
+
+/**
+ * @var CARAXmppData
+ * @brief Holds XMPP data information.
+ */
+typedef struct
+{
+    xmpp_context_t context;
+    xmpp_handle_t handle;
+    xmpp_connection_callback_t connection_callback;
+    xmpp_connection_handle_t connection_handle;
+    xmpp_message_context_t message_context;
+    xmpp_message_callback_t message_callback;
+    CANetworkStatus_t connection_status;
+    xmpp_host_t     g_host;
+    xmpp_identity_t g_identity;
+    char jabberID[CA_RAJABBERID_SIZE];
+} CARAXmppData_t;
+
+static ca_mutex g_raadapterMutex = NULL;
+
+static CARAXmppData_t g_xmppData = {};
+
+static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
+
+static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
+        const char *const bound_jid,
+        xmpp_connection_handle_t connection);
+
+static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
+        xmpp_connection_handle_t connection);
+
+static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
+        const void *const recipient, const void *const msg, size_t messageOctets);
+
+static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
+        const void *const sender, const void *const msg, size_t messageOctets);
+
+void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
+
+    CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                CA_ADAPTER_REMOTE_ACCESS,
+                                address, 0);
+    if (!localEndpoint)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
+        return;
+    }
+    CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
+    if (networkChangeCallback)
+    {
+        networkChangeCallback(localEndpoint, status);
+    }
+    else
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
+    }
+
+    CAFreeEndpoint(localEndpoint);
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
+}
+
+void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
+        const char *const bound_jid,
+        xmpp_connection_handle_t connection)
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
+    CANetworkStatus_t connection_status;
+    if (XMPP_ERR_OK == result)
+    {
+        printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
+
+        ca_mutex_lock (g_raadapterMutex);
+        OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
+
+        g_xmppData.connection_status = CA_INTERFACE_UP;
+        connection_status = CA_INTERFACE_UP;
+        g_xmppData.connection_handle = connection;
+        g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
+        g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
+        g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
+                g_xmppData.message_callback);
+    }
+    else
+    {
+        g_xmppData.connection_status = CA_INTERFACE_DOWN;
+        connection_status = CA_INTERFACE_DOWN;
+        OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
+    }
+
+    ca_mutex_unlock (g_raadapterMutex);
+    // Notify network change to CA
+    CARANotifyNetworkChange(bound_jid, connection_status);
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
+}
+
+void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
+        xmpp_connection_handle_t connection)
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
+    char jabberID[CA_RAJABBERID_SIZE];
+    ca_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);
+
+    // Notify network change to CA
+    CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
+}
+
+void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
+        const void *const recipient, const void *const msg, size_t messageOctets)
+{
+    OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
+        recipient, result);
+}
+
+void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
+        const void *const sender, const void *const msg, size_t messageOctets)
+{
+    if (g_networkPacketCallback)
+    {
+        VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
+        VERIFY_NON_NULL_VOID(msg,    RA_ADAPTER_TAG, "message is NULL");
+
+        OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
+        OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
+
+        CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                        CA_ADAPTER_REMOTE_ACCESS, sender, 0);
+        if (!endPoint)
+        {
+            OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
+            return;
+        }
+
+        void *buf = OICMalloc(messageOctets);
+        if (!buf)
+        {
+            OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
+            CAFreeEndpoint(endPoint);
+            return;
+        }
+        memcpy(buf, msg, messageOctets);
+        CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
+        if (networkPacketCallback)
+        {
+            g_networkPacketCallback(endPoint, buf, messageOctets);
+        }
+
+        CAFreeEndpoint (endPoint);
+    }
+    else
+    {
+        OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA  received message found");
+    }
+}
+
+CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
+                                CANetworkPacketReceivedCallback networkPacketCallback,
+                                CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
+    if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    g_networkChangeCallback = netCallback;
+    g_networkPacketCallback = networkPacketCallback;
+
+    CAConnectivityHandler_t raHandler = {};
+    raHandler.startAdapter = CAStartRA;
+    raHandler.startListenServer = CAStartRAListeningServer;
+    raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
+    raHandler.sendData = CASendRAUnicastData;
+    raHandler.sendDataToAll = CASendRAMulticastData;
+    raHandler.GetnetInfo = CAGetRAInterfaceInformation;
+    raHandler.readData = CAReadRAData;
+    raHandler.stopAdapter = CAStopRA;
+    raHandler.terminate = CATerminateRA;
+    registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
+{
+    if (!caraInfo)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+    xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
+            caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
+    xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
+            caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
+    return CA_STATUS_OK;
+}
+
+void CATerminateRA()
+{
+    CAStopRA();
+}
+
+CAResult_t CAStartRA()
+{
+    if (g_xmppData.handle.abstract_handle)
+    {
+        OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
+        return CA_STATUS_OK;
+    }
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
+
+    g_raadapterMutex = ca_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);
+
+    xmpp_context_init(&g_xmppData.context);
+    g_xmppData.handle = xmpp_startup(&g_xmppData.context);
+
+    // Wire up connection callbacks and call API to connect to XMPP server
+    g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
+    g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
+
+    xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
+            &g_xmppData.g_identity, g_xmppData.connection_callback);
+
+    // Destroy host and identity structures as they are only
+    // required to establish initial connection
+    xmpp_identity_destroy(&g_xmppData.g_identity);
+    xmpp_host_destroy(&g_xmppData.g_host);
+
+    ca_mutex_unlock (g_raadapterMutex);
+
+    if (XMPP_ERR_OK != ret)
+    {
+        OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
+            ret);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopRA()
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
+
+    xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
+    if (XMPP_ERR_OK != ret)
+    {
+        OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
+            ret);
+        return CA_STATUS_FAILED;
+    }
+
+    xmpp_shutdown_xmpp(g_xmppData.handle);
+    xmpp_context_destroy(&g_xmppData.context);
+    ca_mutex_free (g_raadapterMutex);
+    g_raadapterMutex = NULL;
+
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
+    return CA_STATUS_OK;
+}
+
+int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
+                                  uint32_t dataLength)
+{
+    if (!remoteEndpoint || !data)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+        return -1;
+    }
+
+    if (0 == dataLength)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
+        return 0;
+    }
+
+    OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
+    ca_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);
+        return -1;
+    }
+
+    xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
+            remoteEndpoint->addr, data, dataLength,
+            XMPP_MESSAGE_TRANSMIT_DEFAULT);
+    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);
+        return -1;
+    }
+    ca_mutex_unlock (g_raadapterMutex);
+
+    OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
+            dataLength, remoteEndpoint->addr);
+
+    return dataLength;
+}
+
+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);
+
+    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);
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    ca_mutex_unlock (g_raadapterMutex);
+
+    CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                                 CA_ADAPTER_REMOTE_ACCESS,
+                                 g_xmppData.jabberID, 0);
+
+    *size = 1;
+    *info = localEndpoint;
+
+    return CA_STATUS_OK;
+}
+
+int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
+                    const void *data, uint32_t dataLength)
+{
+    OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
+    return 0;
+}
+
+CAResult_t CAStartRAListeningServer()
+{
+    OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
+    return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CAStartRADiscoveryServer()
+{
+    OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
+    return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CAReadRAData()
+{
+    OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
+    return CA_NOT_SUPPORTED;
+}
index 7189319..b66a223 100644 (file)
@@ -32,7 +32,6 @@ catest_env.PrependUnique(CPPPATH = [
                 '../../ocsocket/include',
                 '../../logger/include',
                 '../../stack/include',
-                '../../ocmalloc/include',
                 '../../extlibs/cjson',
                 '../../../oc_logger/include',
                 '../../../../extlibs/gtest/gtest-1.7.0/include'
@@ -74,7 +73,8 @@ if env.get('LOGGING'):
 catests = catest_env.Program('catests', ['catests.cpp',
                                          'caprotocolmessagetest.cpp',
                                                'ca_api_unittest.cpp',
-                                               'camutex_tests.cpp'])
+                                               'camutex_tests.cpp'
+                                               ])
 
 Alias("test", [catests])
 
@@ -82,12 +82,7 @@ env.AppendTarget('test')
 if env.get('TEST') == '1':
         target_os = env.get('TARGET_OS')
         if target_os == 'linux':
-                out_dir = env.get('BUILD_DIR')
-                result_dir = env.get('BUILD_DIR') + '/test_out/'
-                if not os.path.isdir(result_dir):
-                        os.makedirs(result_dir)
-                catest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
-                catest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
-                catest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
-                ut = catest_env.Command ('ut', None, 'valgrind -q --leak-check=full --xml=yes --xml-file=resource_csdk_connectivity_test.memcheck ' + out_dir + 'resource/csdk/connectivity/test/catests')
-                AlwaysBuild ('ut')
+                from tools.scons.RunTest import *
+                run_test(catest_env,
+                         'resource_csdk_connectivity_test.memcheck',
+                         'resource/csdk/connectivity/test/catests')
index e684abd..486f28a 100644 (file)
@@ -35,40 +35,47 @@ class CATests : public testing::Test {
     }
 };
 
-void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo);
-void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo);
+void request_handler(CAEndpoint_t* object, CARequestInfo_t* requestInfo);
+void response_handler(CAEndpoint_t* object, CAResponseInfo_t* responseInfo);
+void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
 CAResult_t checkGetNetworkInfo();
 CAResult_t checkSelectNetwork();
 
+void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
+{
 
+}
 
-void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
+void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
 
 }
 
-void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
+void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo)
 {
+    if(!object || !errorInfo)
+    {
+        return;
+    }
 
+    //error handling shall be added
+    return;
 }
 
-static char* uri = NULL;
-static CARemoteEndpoint_t* tempRep = NULL;
+static char* addr = NULL;
+static CAEndpoint_t* tempRep = NULL;
 static CARequestInfo_t requestInfo;
 static CAInfo_t requestData;
 static CAInfo_t responseData;
 static CAResponseInfo_t responseInfo;
 static CAToken_t tempToken = NULL;
 static uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-static const char URI[] = "coap://10.11.12.13:4545/a/light";
-static const char RESOURCE_URI[] = "/a/light";
+static const char ADDRESS[] = "10.11.12.13";
+static const uint16_t PORT = 4545;
 
-static const char SECURE_INFO_DATA[] =
-                                    "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
-                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
 static const char NORMAL_INFO_DATA[] =
                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
-                                     "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
+                                     "\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
 
 #ifdef __WITH_DTLS__
 
@@ -161,7 +168,7 @@ TEST_F(CATests, TerminateTest)
 // check return value
 TEST(StartListeningServerTest, DISABLED_TC_03_Positive_01)
 {
-    CASelectNetwork(CA_IPV4);
+    CASelectNetwork(CA_ADAPTER_IP);
     EXPECT_EQ(CA_STATUS_OK, CAStartListeningServer());
 }
 
@@ -176,7 +183,7 @@ TEST(StartDiscoveryServerTest, DISABLED_TC_04_Positive_01)
 // check return value
 TEST_F(CATests, RegisterHandlerTest)
 {
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
     char* check = (char *) "registerHandler success";
     EXPECT_STREQ(check, "registerHandler success");
 }
@@ -185,13 +192,14 @@ TEST_F(CATests, RegisterHandlerTest)
 // check return value
 TEST_F(CATests, CreateRemoteEndpointTestGood)
 {
-    uri = (char *) URI;
+    addr = (char *) ADDRESS;
 
-    EXPECT_EQ(CA_STATUS_OK, CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep));
+    EXPECT_EQ(CA_STATUS_OK, CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr,
+                                             PORT, &tempRep));
 
     if (tempRep != NULL)
     {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
 }
@@ -199,71 +207,19 @@ TEST_F(CATests, CreateRemoteEndpointTestGood)
 // check remoteEndpoint and values of remoteEndpoint
 TEST_F(CATests, CreateRemoteEndpointTestValues)
 {
-    uri = (char *) URI;
+    addr = (char *) ADDRESS;
 
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     EXPECT_TRUE(tempRep != NULL);
 
     if (tempRep != NULL)
     {
-        EXPECT_STRNE(NULL, tempRep->resourceUri);
-    }
-
-    if (tempRep != NULL)
-    {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
 }
 
-// check return value when uri is NULL
-TEST_F(CATests, CreateRemoteEndpointTestBad)
-{
-    uri = NULL;
-
-    EXPECT_EQ(CA_STATUS_FAILED, CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep));
-
-    if (tempRep != NULL)
-    {
-        CADestroyRemoteEndpoint(tempRep);
-        tempRep = NULL;
-    }
-}
-
-// check values of remoteEndpoint when uri is NULL
-TEST_F(CATests, CreateRemoteEndpointTestWithNullUri)
-{
-    uri = NULL;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
-
-    if (tempRep != NULL)
-    {
-        EXPECT_STREQ(NULL, tempRep->resourceUri);
-
-    }
-
-    if (tempRep != NULL)
-    {
-        CADestroyRemoteEndpoint(tempRep);
-        tempRep = NULL;
-    }
-}
-
-// CADestroyRemoteEndpoint TC
-// check destroyed remoteEndpoint
-TEST_F(CATests, DestroyRemoteEndpointTest)
-{
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
-
-    CADestroyRemoteEndpoint(tempRep);
-    tempRep = NULL;
-
-    char * check = (char *) "destroy success";
-    EXPECT_STREQ(check, "destroy success");
-}
-
 // CAGerateToken TC
 // check return value
 TEST_F(CATests, GenerateTokenTestGood)
@@ -290,32 +246,12 @@ TEST_F(CATests, DestroyTokenTest)
     EXPECT_STREQ(check, "destroy success");
 }
 
-// CAFindResource TC
-// check return value
-TEST(FindResourceTest, DISABLED_TC_14_Positive_01)
-{
-    uri = (char *) RESOURCE_URI;
-
-    CAGenerateToken(&tempToken, tokenLength);
-    EXPECT_EQ(CA_STATUS_OK, CAFindResource(uri, tempToken, tokenLength));
-    CADestroyToken(tempToken);
-}
-
-// check return value when uri is NULL
-TEST_F(CATests, FindResourceTest)
-{
-    uri = NULL;
-    CAGenerateToken(&tempToken, tokenLength);
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CAFindResource(uri, tempToken, tokenLength));
-    CADestroyToken(tempToken);
-}
-
 // CASendRequest TC
 // check return value
 TEST(SendRequestTest, DISABLED_TC_16_Positive_01)
 {
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = (char *) ADDRESS;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     memset(&requestData, 0, sizeof(CAInfo_t));
     CAGenerateToken(&tempToken, tokenLength);
@@ -324,14 +260,13 @@ TEST(SendRequestTest, DISABLED_TC_16_Positive_01)
 
     int length = strlen(NORMAL_INFO_DATA) + strlen("a/light");
     requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
-
     if(!requestData.payload)
     {
         CADestroyToken(tempToken);
         FAIL() << "requestData.payload allocation failed";
     }
-
-    snprintf(requestData.payload, length, NORMAL_INFO_DATA, "a/light");
+    snprintf((char*)requestData.payload, length, NORMAL_INFO_DATA, "a/light");
+    requestData.payloadSize = length + 1;
     requestData.type = CA_MSG_NONCONFIRM;
 
     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
@@ -344,62 +279,22 @@ TEST(SendRequestTest, DISABLED_TC_16_Positive_01)
 
     free(requestData.payload);
 
-    CADestroyRemoteEndpoint(tempRep);
+    CADestroyEndpoint(tempRep);
     tempRep = NULL;
 
 }
 
-// check return value when uri is NULL
-TEST_F(CATests, SendRequestTestWithNullURI)
-{
-    uri = NULL;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
-
-    memset(&requestData, 0, sizeof(CAInfo_t));
-    CAGenerateToken(&tempToken, tokenLength);
-    requestData.token = tempToken;
-    requestData.tokenLength = tokenLength;
-
-    int length = strlen(NORMAL_INFO_DATA) + strlen("a/light");
-    requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
-
-    if(!requestData.payload)
-    {
-        CADestroyToken(tempToken);
-        FAIL() << "requestData.payload allocation failed";
-    }
-
-    snprintf(requestData.payload, length, NORMAL_INFO_DATA, "a/light");
-    requestData.type = CA_MSG_NONCONFIRM;
-
-    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
-    requestInfo.method = CA_GET;
-    requestInfo.info = requestData;
-
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendRequest(tempRep, &requestInfo));
-
-    CADestroyToken(tempToken);
-
-    free(requestData.payload);
-
-    if (tempRep != NULL)
-    {
-        CADestroyRemoteEndpoint(tempRep);
-        tempRep = NULL;
-    }
-}
-
 // check return value when a NULL is passed instead of a valid CARequestInfo_t address
 TEST_F(CATests, SendRequestTestWithNullAddr)
 {
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = (char *) ADDRESS;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendRequest(tempRep, NULL));
 
     if (tempRep != NULL)
     {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
 }
@@ -408,69 +303,75 @@ TEST_F(CATests, SendRequestTestWithNullAddr)
 // check return value
 TEST(SendResponseTest, DISABLED_TC_19_Positive_01)
 {
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = (char *) ADDRESS;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
     responseData.messageId = 1;
-    responseData.payload = (char *) "response payload";
+    responseData.payload = (CAPayload_t)malloc(sizeof("response payload"));
+    memcpy(responseData.payload, "response payload", sizeof("response payload"));
+    responseData.payloadSize = sizeof("response payload");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
     requestData.tokenLength = tokenLength;
 
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = responseData;
 
     EXPECT_EQ(CA_STATUS_OK, CASendResponse(tempRep, &responseInfo));
 
     CADestroyToken(tempToken);
-    CADestroyRemoteEndpoint(tempRep);
+    CADestroyEndpoint(tempRep);
+    free(responseData.payload);
     tempRep = NULL;
 }
 
-// check return value when uri is NULL
+// check return value when address is NULL as multicast
 TEST(SendResponseTest, DISABLED_TC_20_Negative_01)
 {
-    uri = NULL;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = NULL;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, 0, &tempRep);
 
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
     responseData.messageId = 1;
-    responseData.payload = (char *) "response payload";
+    responseData.payload = (CAPayload_t)malloc(sizeof("response payload"));
+    memcpy(responseData.payload, "response payload", sizeof("response payload"));
+    responseData.payloadSize = sizeof("response payload");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
     requestData.tokenLength = tokenLength;
 
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = responseData;
 
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendResponse(tempRep, &responseInfo));
+    EXPECT_EQ(CA_STATUS_OK, CASendResponse(tempRep, &responseInfo));
 
     CADestroyToken(tempToken);
     if (tempRep != NULL)
     {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
+    free (responseData.payload);
 }
 
 // check return value NULL is passed instead of a valid CAResponseInfo_t address
 TEST_F(CATests, SendResponseTest)
 {
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = (char *) ADDRESS;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendResponse(tempRep, NULL));
 
     if (tempRep != NULL)
     {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
 }
@@ -479,19 +380,21 @@ TEST_F(CATests, SendResponseTest)
 // check return value
 TEST(SendNotificationTest, DISABLED_TC_22_Positive_01)
 {
-    uri = (char *) URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
+    addr = (char *) ADDRESS;
+    CACreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_IP, addr, PORT, &tempRep);
 
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
-    responseData.payload = (char *) "Temp Notification Data";
+    responseData.payload = (CAPayload_t)malloc(sizeof("Temp Notification Data"));
+    memcpy(responseData.payload, "Temp Notification Data", sizeof("Temp Notification Data"));
+    responseData.payloadSize = sizeof("Temp Notification Data");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
     requestData.tokenLength = tokenLength;
 
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_SUCCESS;
+    responseInfo.result = CA_CONTENT;
     responseInfo.info = responseData;
 
     EXPECT_EQ(CA_STATUS_OK, CASendNotification(tempRep, &responseInfo));
@@ -499,114 +402,10 @@ TEST(SendNotificationTest, DISABLED_TC_22_Positive_01)
     CADestroyToken(tempToken);
     if (tempRep != NULL)
     {
-        CADestroyRemoteEndpoint(tempRep);
-        tempRep = NULL;
-    }
-}
-
-// check return value when uri is NULL
-TEST_F(CATests, SendNotificationTest)
-{
-    uri = NULL;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
-
-    memset(&responseData, 0, sizeof(CAInfo_t));
-    responseData.type = CA_MSG_NONCONFIRM;
-    responseData.payload = (char *) "Temp Notification Data";
-
-    CAGenerateToken(&tempToken, tokenLength);
-    requestData.token = tempToken;
-    requestData.tokenLength = tokenLength;
-
-    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_SUCCESS;
-    responseInfo.info = responseData;
-
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendNotification(tempRep, &responseInfo));
-
-    CADestroyToken(tempToken);
-    if (tempRep != NULL)
-    {
-        CADestroyRemoteEndpoint(tempRep);
+        CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
-}
-
-// CAAdvertiseResource TC
-// check return value
-TEST(AdvertiseResourceTest, DISABLED_TC_24_Positive_01)
-{
-    uri = (char *) RESOURCE_URI;
-    int optionNum = 2;
-
-    CAHeaderOption_t* headerOpt;
-    headerOpt = (CAHeaderOption_t *) calloc(1, optionNum * sizeof(CAHeaderOption_t));
-
-    if(!headerOpt)
-    {
-        FAIL() <<"Allocation for headerOpt failed";
-    }
-
-    char* tmpOptionData1 = (char *) "Hello";
-    size_t tmpOptionDataLen = (strlen(tmpOptionData1) < CA_MAX_HEADER_OPTION_DATA_LENGTH) ?
-            strlen(tmpOptionData1) : CA_MAX_HEADER_OPTION_DATA_LENGTH - 1;
-    headerOpt[0].optionID = 3000;
-    memcpy(headerOpt[0].optionData, tmpOptionData1, tmpOptionDataLen);
-    headerOpt[0].optionLength = (uint16_t) tmpOptionDataLen;
-
-    char* tmpOptionData2 = (char *) "World";
-    tmpOptionDataLen = (strlen(tmpOptionData2) < CA_MAX_HEADER_OPTION_DATA_LENGTH) ?
-                strlen(tmpOptionData2) : CA_MAX_HEADER_OPTION_DATA_LENGTH - 1;
-    headerOpt[1].optionID = 3001;
-    memcpy(headerOpt[1].optionData, tmpOptionData2, tmpOptionDataLen);
-    headerOpt[1].optionLength = (uint16_t) tmpOptionDataLen;
-
-    CAGenerateToken(&tempToken, tokenLength);
-
-    EXPECT_EQ(CA_STATUS_OK, CAAdvertiseResource(uri, tempToken, tokenLength,
-                                                headerOpt, (uint8_t )optionNum));
-
-    CADestroyToken(tempToken);
-
-    free(headerOpt);
-}
-
-// check return value when uri is NULL
-TEST_F(CATests, AdvertiseResourceTest)
-{
-    uri = NULL;
-    int optionNum = 2;
-
-    CAHeaderOption_t* headerOpt;
-    headerOpt = (CAHeaderOption_t *) calloc(1, optionNum * sizeof(CAHeaderOption_t));
-
-    if(!headerOpt)
-    {
-        FAIL() << "Allocation for headerOpt failed";
-    }
-
-    char* tmpOptionData1 = (char *) "Hello";
-    size_t tmpOptionDataLen = (strlen(tmpOptionData1) < CA_MAX_HEADER_OPTION_DATA_LENGTH) ?
-            strlen(tmpOptionData1) : CA_MAX_HEADER_OPTION_DATA_LENGTH - 1;
-    headerOpt[0].optionID = 3000;
-    memcpy(headerOpt[0].optionData, tmpOptionData1, tmpOptionDataLen);
-    headerOpt[0].optionLength = (uint16_t) tmpOptionDataLen;
-
-    char* tmpOptionData2 = (char *) "World";
-    tmpOptionDataLen = (strlen(tmpOptionData2) < CA_MAX_HEADER_OPTION_DATA_LENGTH) ?
-                strlen(tmpOptionData2) : CA_MAX_HEADER_OPTION_DATA_LENGTH - 1;
-    headerOpt[1].optionID = 3001;
-    memcpy(headerOpt[1].optionData, tmpOptionData2, tmpOptionDataLen);
-    headerOpt[1].optionLength = (uint16_t) tmpOptionDataLen;
-
-    CAGenerateToken(&tempToken, tokenLength);
-
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CAAdvertiseResource(uri, tempToken, tokenLength,
-                                                           headerOpt, (uint8_t )optionNum));
-
-    CADestroyToken(tempToken);
-
-    free(headerOpt);
+    free(responseData.payload);
 }
 
 // CASelectNewwork TC
@@ -619,16 +418,16 @@ TEST_F(CATests, SelectNetworkTestGood)
 
 CAResult_t checkSelectNetwork()
 {
-    CAResult_t res = CASelectNetwork(CA_IPV4);
+    CAResult_t res = CASelectNetwork(CA_ADAPTER_IP);
 
     if (CA_STATUS_OK == res)
     {
-        EXPECT_EQ(CA_STATUS_OK, CAUnSelectNetwork(CA_IPV4));
+        EXPECT_EQ(CA_STATUS_OK, CAUnSelectNetwork(CA_ADAPTER_IP));
         return CA_STATUS_OK;
     }
     if (CA_NOT_SUPPORTED == res)
     {
-        EXPECT_EQ(CA_STATUS_FAILED, CAUnSelectNetwork(CA_IPV4));
+        EXPECT_EQ(CA_STATUS_FAILED, CAUnSelectNetwork(CA_ADAPTER_IP));
         return CA_STATUS_OK;
     }
 
@@ -639,14 +438,14 @@ CAResult_t checkSelectNetwork()
 TEST_F(CATests, SelectNetworkTestBad)
 {
     //Select disable network
-    EXPECT_EQ(CA_NOT_SUPPORTED, CASelectNetwork(1000));
+    EXPECT_EQ(CA_NOT_SUPPORTED, CASelectNetwork((CATransportAdapter_t)1000));
 }
 
 // check return value when selected network is disable
 TEST_F(CATests, UnSelectNetworkTest)
 {
     //UnSelect disable network
-    EXPECT_EQ(CA_STATUS_FAILED, CAUnSelectNetwork(1000));
+    EXPECT_EQ(CA_STATUS_FAILED, CAUnSelectNetwork((CATransportAdapter_t)1000));
 }
 
 // CAHandlerRequestResponse TC
@@ -656,67 +455,6 @@ TEST_F(CATests, HandlerRequestResponseTest)
     EXPECT_EQ(CA_STATUS_OK, CAHandleRequestResponse());
 }
 
-// CASendRequestToAll TC
-// check return value
-TEST(SendRequestToAllTest, DISABLED_TC_31_Positive_01)
-{
-    CASelectNetwork(CA_IPV4);
-
-    uri = (char *) RESOURCE_URI;
-    CACreateRemoteEndpoint(uri, CA_IPV4, &tempRep);
-    CAGroupEndpoint_t *group = NULL;
-    group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t));
-    if(!group)
-    {
-        FAIL() << "Allocation for group failed";
-    }
-
-    group->transportType = tempRep->transportType;
-    group->resourceUri = tempRep->resourceUri;
-
-    memset(&requestData, 0, sizeof(CAInfo_t));
-    CAGenerateToken(&tempToken, tokenLength);
-    requestData.token = tempToken;
-    requestData.tokenLength = tokenLength;
-
-    requestData.payload = (char *) "Temp Json Payload";
-    requestData.type = CA_MSG_NONCONFIRM;
-    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
-    requestInfo.method = CA_GET;
-    requestInfo.info = requestData;
-
-    EXPECT_EQ(CA_STATUS_OK, CASendRequestToAll(group, &requestInfo));
-
-    CADestroyToken(tempToken);
-
-    CADestroyRemoteEndpoint(tempRep);
-    tempRep = NULL;
-
-    free(group);
-}
-
-// check return value when group->resourceUri is NULL
-TEST(SendRequestToAllTest, DISABLED_TC_32_Negative_01)
-{
-    uri = (char *) RESOURCE_URI;
-    CAGroupEndpoint_t *group = NULL;
-
-    memset(&requestData, 0, sizeof(CAInfo_t));
-    CAGenerateToken(&tempToken, tokenLength);
-    requestData.token = tempToken;
-    requestData.tokenLength = tokenLength;
-
-    requestData.payload = (char *) "Temp Json Payload";
-    requestData.type = CA_MSG_NONCONFIRM;
-    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
-    requestInfo.method = CA_GET;
-    requestInfo.info = requestData;
-
-    EXPECT_EQ(CA_STATUS_INVALID_PARAM, CASendRequestToAll(group, &requestInfo));
-
-    CADestroyToken(tempToken);
-}
-
 // CAGetNetworkInformation TC
 // check return value
 TEST_F (CATests, GetNetworkInformationTestGood)
@@ -738,7 +476,7 @@ TEST_F(CATests, RegisterDTLSCredentialsHandlerTest)
 
 CAResult_t checkGetNetworkInfo()
 {
-    CALocalConnectivity_t *tempInfo = NULL;
+    CAEndpoint_t *tempInfo = NULL;
     uint32_t tempSize = 0;
 
     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
index 12d6701..4791ce0 100644 (file)
@@ -26,8 +26,6 @@
 
 namespace {
 
-static const char COAP_HEADER[] = "coap://[::]/";
-
 class CoAPOptionCase
 {
 public:
@@ -79,11 +77,10 @@ void verifyParsedOptions(CoAPOptionCase const *cases,
 
 TEST(CAProtocolMessage, CAParseURIBase)
 {
-    char sampleURI[] = "coap://[::]/oc/core?rt=core.sensor&if=core.mi.ll";
-
+    char sampleURI[] = "coap://[::]/oic/res?rt=core.sensor;if=core.mi.ll";
     CoAPOptionCase cases[] = {
-        {COAP_OPTION_URI_PATH, 2, "oc"},
-        {COAP_OPTION_URI_PATH, 4, "core"},
+        {COAP_OPTION_URI_PATH, 3, "oic"},
+        {COAP_OPTION_URI_PATH, 3, "res"},
         {COAP_OPTION_URI_QUERY, 14, "rt=core.sensor"},
         {COAP_OPTION_URI_QUERY, 13, "if=core.mi.ll"},
     };
@@ -95,6 +92,7 @@ TEST(CAProtocolMessage, CAParseURIBase)
 
 
     verifyParsedOptions(cases, numCases, optlist);
+    coap_delete_list(optlist);
 }
 
 // Try for multiple URI path components that still total less than 128
@@ -102,7 +100,7 @@ TEST(CAProtocolMessage, CAParseURIManyPath)
 {
     char sampleURI[] = "coap://[::]"
         "/medium/a/b/c/d/e/f/g/h/i/j/"
-        "?rt=core.sensor&if=core.mi.ll";
+        "?rt=core.sensor;if=core.mi.ll";
 
     CoAPOptionCase cases[] = {
         {COAP_OPTION_URI_PATH, 6, "medium"},
@@ -127,17 +125,18 @@ TEST(CAProtocolMessage, CAParseURIManyPath)
 
 
     verifyParsedOptions(cases, numCases, optlist);
+    coap_delete_list(optlist);
 }
 
 // Try for multiple URI parameters that still total less than 128
 TEST(CAProtocolMessage, CAParseURIManyParams)
 {
-    char sampleURI[] = "coap://[::]/oc/core/"
-        "?rt=core.sensor&a=0&b=1&c=2&d=3&e=4&f=5&g=6&h=7&i=8&j=9";
+    char sampleURI[] = "coap://[::]/oic/res/"
+        "?rt=core.sensor;a=0;b=1;c=2;d=3;e=4;f=5;g=6;h=7;i=8;j=9";
 
     CoAPOptionCase cases[] = {
-        {COAP_OPTION_URI_PATH, 2, "oc"},
-        {COAP_OPTION_URI_PATH, 4, "core"},
+        {COAP_OPTION_URI_PATH, 3, "oic"},
+        {COAP_OPTION_URI_PATH, 3, "res"},
         {COAP_OPTION_URI_QUERY, 14, "rt=core.sensor"},
         {COAP_OPTION_URI_QUERY, 3, "a=0"},
         {COAP_OPTION_URI_QUERY, 3, "b=1"},
@@ -158,21 +157,22 @@ TEST(CAProtocolMessage, CAParseURIManyParams)
 
 
     verifyParsedOptions(cases, numCases, optlist);
+    coap_delete_list(optlist);
 }
 
 // Test that an initial long path component won't hide latter ones.
 TEST(CAProtocolMessage, CAParseURILongPath)
 {
-    char sampleURI[] = "coap://[::]/oc"
+    char sampleURI[] = "coap://[::]/oic"
         "123456789012345678901234567890123456789012345678901234567890"
         "12345678901234567890123456789012345678901234567890"
-        "/core?rt=core.sensor&if=core.mi.ll";
+        "/res?rt=core.sensor;if=core.mi.ll";
 
     CoAPOptionCase cases[] = {
-        {COAP_OPTION_URI_PATH, 112, "oc"
+        {COAP_OPTION_URI_PATH, 113, "oic"
         "123456789012345678901234567890123456789012345678901234567890"
         "12345678901234567890123456789012345678901234567890"},
-        {COAP_OPTION_URI_PATH, 4, "core"},
+        {COAP_OPTION_URI_PATH, 3, "res"},
         {COAP_OPTION_URI_QUERY, 14, "rt=core.sensor"},
         {COAP_OPTION_URI_QUERY, 13, "if=core.mi.ll"},
     };
@@ -184,4 +184,5 @@ TEST(CAProtocolMessage, CAParseURILongPath)
 
 
     verifyParsedOptions(cases, numCases, optlist);
+    coap_delete_list(optlist);
 }
index ca2ba59..a95101f 100644 (file)
@@ -32,7 +32,7 @@ PROJECT_NAME           = "IoTivity C SDK"
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 
+PROJECT_NUMBER         =
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer
@@ -662,7 +662,6 @@ WARN_LOGFILE           =
 INPUT                  = . \
                                                 ../stack/include \
                                                 ../ocsocket/include \
-                                                ../ocmalloc/include \
                                                 ../ocrandom/include \
                                                 ../occoap/include \
 
index b642464..4b090a5 100644 (file)
@@ -117,8 +117,7 @@ void OCLogv(LogLevel level, const char * tag, const char * format, ...) {
     if (!format || !tag) {
         return;
     }
-    char buffer[MAX_LOG_V_BUFFER_SIZE];
-    memset(buffer, 0, sizeof buffer);
+    char buffer[MAX_LOG_V_BUFFER_SIZE] = {};
     va_list args;
     va_start(args, format);
     vsnprintf(buffer, sizeof buffer - 1, format, args);
@@ -200,6 +199,8 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
         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[LINE_BUFFER_SIZE];
     memset(lineBuffer, 0, sizeof lineBuffer);
     int lineIndex = 0;
diff --git a/resource/csdk/ocmalloc/include/ocmalloc.h b/resource/csdk/ocmalloc/include/ocmalloc.h
deleted file mode 100644 (file)
index 7019982..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#ifndef OCMALLOC_H_
-#define OCMALLOC_H_
-
-// The purpose of this module is to allow custom dynamic memory allocation
-// code to easily be added to the TB Stack by redefining the OCMalloc and
-// OCFree functions.  Examples of when this might be needed are on TB
-// platforms that do not support dynamic allocation or if a memory pool
-// needs to be added.
-//
-// Note that these functions are intended to be used ONLY within the TB
-// stack and NOT by the application code.  The application should be
-// responsible for its own dynamic allocation.
-
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-//-----------------------------------------------------------------------------
-// Defines
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Typedefs
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Function prototypes
-//-----------------------------------------------------------------------------
-
-/**
- * Allocates a block of size bytes, returning a pointer to the beginning of
- * the allocated block.
- *
- * @param size - Size of the memory block in bytes, where size > 0
- *
- * @return
- *     on success, a pointer to the allocated memory block
- *     on failure, a null pointer is returned
- */
-void *OCMalloc(size_t size);
-
-/**
- * Allocates a block of memory for an array of num elements, each of them
- * size bytes long and initializes all its bits to zero.
- *
- * @param num - The number of elements
- * @param size - Size of the element type in bytes, where size > 0
- *
- * @return
- *     on success, a pointer to the allocated memory block
- *     on failure, a null pointer is returned
- */
-void *OCCalloc(size_t num, size_t size);
-
-/**
- * Deallocate a block of memory previously allocated by a call to OCMalloc
- *
- * @param ptr - Pointer to block of memory previously allocated by OCMalloc.
- *              If ptr is a null pointer, the function does nothing.
- */
-void OCFree(void *ptr);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif /* OCMALLOC_H_ */
diff --git a/resource/csdk/ocmalloc/src/ocmalloc.c b/resource/csdk/ocmalloc/src/ocmalloc.c
deleted file mode 100644 (file)
index fe62c15..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
-#include <stdlib.h>
-#include "ocmalloc.h"
-
-// Enable extra debug logging for malloc.  Comment out to disable
-//#define ENABLE_MALLOC_DEBUG  (1)
-
-#ifdef ENABLE_MALLOC_DEBUG
-    #include "logger.h"
-    #define TAG PCF("OCMalloc")
-#endif
-
-//-----------------------------------------------------------------------------
-// Typedefs
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// Private variables
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// Macros
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// Internal API function
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Private internal function prototypes
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Public APIs
-//-----------------------------------------------------------------------------
-
-void *OCMalloc(size_t size)
-{
-    if (0 == size)
-    {
-        return NULL;
-    }
-
-#ifdef ENABLE_MALLOC_DEBUG
-    void *ptr = 0;
-
-    ptr = malloc(size);
-    OC_LOG_V(INFO, TAG, "malloc: ptr=%p, size=%u", ptr, size);
-    return ptr;
-#else
-    return malloc(size);
-#endif
-}
-
-void *OCCalloc(size_t num, size_t size)
-{
-    if(0 == size || 0 == num)
-    {
-        return NULL;
-    }
-
-#ifdef ENABLE_MALLOC_DEBUG
-    void *ptr = 0;
-
-    ptr = calloc(num, size);
-    OC_LOG_V(INFO, TAG, "calloc: ptr=%p, num=%u, size=%u", ptr, num, size);
-    return ptr;
-#else
-    return calloc(num, size);
-#endif
-}
-
-void OCFree(void *ptr)
-{
-#ifdef ENABLE_MALLOC_DEBUG
-    OC_LOG_V(INFO, TAG, "free: ptr=%p", ptr);
-#endif
-
-    free(ptr);
-}
-
diff --git a/resource/csdk/ocmalloc/test/linux/README b/resource/csdk/ocmalloc/test/linux/README
deleted file mode 100644 (file)
index 72e3c1c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
--------------------------------------------------------------------------------
-  NOTICE - Transition to SCONS
--------------------------------------------------------------------------------
-
-The IoTivity build system is transitioning to SCONS. Although the 
-makefiles are still available (until v1.0) and some developers are 
-still using them, they are currently no longer supported. To learn more 
-about building using SCONS see Readme.scons.txt in the repository root 
-directory. The build steps used in continuous integration can be found
-in auto_build.sh which is also in the the repository root directory.
-
--------------------------------------------------------------------------------
-
-# To build the ocmalloc google unit test for Linux:
-
-# First
-cd <root>/csdk
-make deepclean
-
-make BUILD=release
-# or
-make BUILD=debug
-
-# Next
-cd <root>/csdk/ocmalloc/test/linux
-
-make BUILD=release
-# or
-make BUILD=debug
-
-# Run the test test
-
-<root>/csdk/ocmalloc/test/linux/release/unittest
-# or
-<root>/csdk/ocmalloc/test/linux/debug/unittest
index c4d219e..e096fc5 100644 (file)
@@ -19,8 +19,8 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 
-#ifndef _RANDOM_H
-#define _RANDOM_H
+#ifndef OC_RANDOM_H
+#define OC_RANDOM_H
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -128,4 +128,4 @@ OCRandomUuidResult OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
 }
 #endif
 
-#endif //_RANDOM_H
+#endif // OC_RANDOM_H
index ab221cd..2e7bc52 100644 (file)
@@ -31,7 +31,6 @@ src_dir = randomtest_env.get('SRC_DIR')
 randomtest_env.PrependUnique(CPPPATH = [
         '../include',
                '../../logger/include',
-               '../../ocmalloc/include',
                '../../../oc_logger/include',
                '../../../../extlibs/gtest/gtest-1.7.0/include'
                ])
@@ -61,12 +60,7 @@ env.AppendTarget('test')
 if env.get('TEST') == '1':
        target_os = env.get('TARGET_OS')
        if target_os == 'linux':
-               out_dir = env.get('BUILD_DIR')
-               result_dir = env.get('BUILD_DIR') + '/test_out/'
-               if not os.path.isdir(result_dir):
-                       os.makedirs(result_dir)
-               randomtest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
-               randomtest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
-               randomtest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
-               ut = randomtest_env.Command ('ut', None, 'valgrind -q --leak-check=full --xml=yes --xml-file=resource_csdk_random_test.memcheck ' + out_dir + 'resource/csdk/ocrandom/test/randomtests')
-               AlwaysBuild ('ut')
+                from tools.scons.RunTest import *
+                run_test(randomtest_env,
+                         'resource_csdk_random_test.memcheck',
+                         'resource/csdk/ocrandom/test/randomtests')
index 9f22173..07028e2 100644 (file)
@@ -50,8 +50,7 @@ TEST(RandomGeneration,OCGetRandom) {
 
 TEST(RandomGeneration,OCFillRandomMem) {
     uint16_t ARR_SIZE = 20;
-    uint8_t array[ARR_SIZE];
-    memset(array, 0, ARR_SIZE);
+    uint8_t array[ARR_SIZE]={};
     OCFillRandomMem(array + 1, ARR_SIZE - 2);
 
     for (int i = 1; i < ARR_SIZE - 2; i++) {
index 904b73c..d9faf0d 100644 (file)
@@ -52,8 +52,7 @@ void setup() {
     }
 
     Serial.print("Testing OCFillRandomMem ... ");
-    uint8_t array[ARR_SIZE];
-    memset(array, 0, ARR_SIZE);
+    uint8_t array[ARR_SIZE] = {};
     OCFillRandomMem(array + 1, ARR_SIZE - 2);
     uint8_t overall = 0;
     uint8_t value82 = 0;
index 98a1d5c..d8654fa 100644 (file)
@@ -35,7 +35,7 @@ int main(int argc, char* argv[]) {
 }
 
 TEST(RandomGeneration,OCSeedRandom) {
-    EXPECT_EQ((uint32_t )0, OCSeedRandom());
+    EXPECT_EQ(0, OCSeedRandom());
 }
 
 TEST(RandomGeneration,OCGetRandomByte) {
@@ -51,8 +51,7 @@ TEST(RandomGeneration,OCGetRandom) {
 }
 
 TEST(RandomGeneration,OCFillRandomMem) {
-    uint8_t array[ARR_SIZE];
-    memset(array, 0, ARR_SIZE);
+    uint8_t array[ARR_SIZE] = {};
     OCFillRandomMem(array + 1, ARR_SIZE - 2);
 
     for (int i = 1; i <= ARR_SIZE - 2; i++) {
diff --git a/resource/csdk/security/README-building-and-running-secure-IoTivity-stack.txt b/resource/csdk/security/README-building-and-running-secure-IoTivity-stack.txt
new file mode 100644 (file)
index 0000000..9def457
--- /dev/null
@@ -0,0 +1,17 @@
+LAST UPDATED 5/27/2015
+
+To build the IoTivity stack with the security features enabled:
+
+1) Build IoTivity with security enabled:
+       $ cd <iotivity-base>
+       $ scons resource SECURED=1
+
+2) Verify functionality using secure sample apps:
+       $ cd <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure
+       $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release
+       $ ./ocserverbasicops &
+       $ ./occlientbasicops -t 1
+        Message "INFO: occlientbasicops: Secure -- YES" indicates success!
+       $ ./occlientbasicops -t 2
+        Completion of 'GET' and 'PUT' query successfully indicates success!
+
diff --git a/resource/csdk/security/SConscript b/resource/csdk/security/SConscript
new file mode 100644 (file)
index 0000000..379aec5
--- /dev/null
@@ -0,0 +1,106 @@
+# //******************************************************************
+# //
+# // 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.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# libocsrm (share library) build script
+##
+
+Import('env')
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env')
+
+libocsrm_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+# As in the source code, it includes arduino Time library (C++)
+# It requires compile the .c with g++
+if target_os == 'arduino':
+       libocsrm_env.Replace(CC = env.get('CXX'))
+       libocsrm_env.Replace(CFLAGS = env.get('CXXFLAGS'))
+
+######################################################################
+# Build flags
+######################################################################
+libocsrm_env.PrependUnique(CPPPATH = [
+               '../../../extlibs/cjson/',
+#              '../../../extlibs/tinydtls/',
+               '../logger/include',
+               '../ocrandom/include',
+               '../stack/include',
+               '../stack/include/internal',
+               '../../oc_logger/include',
+               '../connectivity/lib/libcoap-4.1.1',
+               '../connectivity/external/inc',
+               '../connectivity/inc',
+               '../connectivity/api',
+               '../security/include',
+               '../security/include/internal',
+               ])
+
+if target_os not in ['arduino', 'windows', 'winrt']:
+       libocsrm_env.AppendUnique(CPPDEFINES  = ['WITH_POSIX'])
+       libocsrm_env.AppendUnique(CFLAGS = ['-std=c99'])
+       libocsrm_env.AppendUnique(CPPDEFINES = ['HAVE_STRINGS_H'])
+
+if target_os not in ['windows', 'winrt']:
+       libocsrm_env.AppendUnique(CFLAGS = ['-Wall'])
+
+libocsrm_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+libocsrm_env.AppendUnique(LIBS = ['coap', 'm'])
+
+if target_os == 'arduino':
+       libocsrm_env.AppendUnique(CPPDEFINES = ['NDEBUG', 'WITH_ARDUINO'])
+else:
+       libocsrm_env.AppendUnique(CFLAGS = ['-fPIC'])
+
+if target_os in ['darwin', 'ios']:
+       libocsrm_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
+       libocsrm_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+       libocsrm_env.AppendUnique(LIBS = ['coap'])
+
+if not env.get('RELEASE'):
+       libocsrm_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+OCSRM_SRC = 'src/'
+libocsrm_src = [
+       OCSRM_SRC + 'secureresourcemanager.c',
+       OCSRM_SRC + 'resourcemanager.c',
+       OCSRM_SRC + 'aclresource.c',
+       OCSRM_SRC + 'pstatresource.c',
+       OCSRM_SRC + 'doxmresource.c',
+       OCSRM_SRC + 'credresource.c',
+       OCSRM_SRC + 'policyengine.c',
+       OCSRM_SRC + 'psinterface.c',
+       OCSRM_SRC + 'srmresourcestrings.c',
+       OCSRM_SRC + 'srmutility.c',
+       OCSRM_SRC + 'base64.c'
+       ]
+
+libocsrm = libocsrm_env.StaticLibrary('libocsrm', libocsrm_src)
+
+libocsrm_env.InstallTarget(libocsrm, 'libocsrm')
+libocsrm_env.UserInstallTargetLib(libocsrm, 'libocsrm')
+
+if env.get('SECURED') == '1':
+        SConscript('provisioning/SConscript')
+
diff --git a/resource/csdk/security/include/base64.h b/resource/csdk/security/include/base64.h
new file mode 100644 (file)
index 0000000..4d5837d
--- /dev/null
@@ -0,0 +1,88 @@
+ /******************************************************************
+  *
+  * 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.
+  *
+  ******************************************************************/
+
+#ifndef _IOTVT_B64_H_
+#define _IOTVT_B64_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Macro to calculate the size of 'output' buffer required for
+ * a 'input' buffer of length x during Base64 encoding operation.
+ */
+#define B64ENCODE_OUT_SAFESIZE(x) ((((x) + 3 - 1)/3) * 4 + 1)
+
+/**
+ * Macro to calculate the size of 'output' buffer required for
+ * a 'input' buffer of length x during Base64 decoding operation.
+ */
+#define B64DECODE_OUT_SAFESIZE(x) (((x)*3)/4)
+
+/**
+ * Result code of base64 functions
+ */
+typedef enum {
+    B64_OK = 0,
+    B64_INVALID_PARAM,
+    B64_OUTPUT_BUFFER_TOO_SMALL,
+    B64_ERROR
+}B64Result;
+
+/**
+ * Encode the plain message in base64.
+ *
+ * @param[in] in  Plain message
+ * @param[in] inLen  Byte length of 'in'
+ * @param[in,out] outBuf Output buffer
+ *                Base64 encoded message will be written into 'outBuf'
+ *                NOTE : This method adds a NULL to the string configuration
+ * @param[in] outBufSize Size of output buffer
+ * @param[out] outLen  Byte length of encoded message
+ *
+ * @return  B64_OK for Success, otherwise some error value
+ */
+B64Result b64Encode(const uint8_t* in, const size_t inLen,
+               char* outBuf, const size_t outBufSize, uint32_t *outLen);
+
+/**
+ * Decode the encoded message in base64.
+ *
+ * @param[in] in  Base64 encoded message
+ * @param[in] inLen  Byte lenth of 'in'
+ * @param[in, out] outBuf  Output buffer
+ *                 Base64 decoded message will be written into 'outBuf'
+ * @param[in] outBufSize Size of output buffer
+ * @param[out] outLen  Byte length of decoded message
+ *
+ * @return  B64_OK for Success, otherwise some error value
+ */
+B64Result b64Decode(const char* in, const size_t inLen,
+               uint8_t* outBuf, size_t outBufSize, uint32_t *outLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //IOTVT_B64_H
diff --git a/resource/csdk/security/include/internal/aclresource.h b/resource/csdk/security/include/internal/aclresource.h
new file mode 100755 (executable)
index 0000000..ce9fa60
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// 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_ACLR_H
+#define IOTVT_SRM_ACLR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize ACL resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitACLResource();
+
+/**
+ * Perform cleanup for ACL resources.
+ *
+ * @retval  none
+ */
+void DeInitACLResource();
+
+/**
+ * This method is used by PolicyEngine to retrieve ACL for a Subject.
+ *
+ * @param subjectId ID of the subject for which ACL is required.
+ * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
+ *                successive calls for same subjectId.
+ *
+ * @retval  reference to @ref OicSecAcl_t if ACL is found, else NULL
+ *
+ * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
+ */
+const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr);
+
+/**
+ * This function converts ACL data into JSON format.
+ * Caller needs to invoke 'free' when done using
+ * returned string.
+ * @param acl  instance of OicSecAcl_t structure.
+ *
+ * @retval  pointer to ACL in json format.
+ */
+char* BinToAclJSON(const OicSecAcl_t * acl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_ACLR_H
+
+
diff --git a/resource/csdk/security/include/internal/credresource.h b/resource/csdk/security/include/internal/credresource.h
new file mode 100644 (file)
index 0000000..9ae31bd
--- /dev/null
@@ -0,0 +1,133 @@
+//******************************************************************
+//
+// 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_CREDR_H
+#define IOTVT_SRM_CREDR_H
+
+#include "ocsecurityconfig.h"
+#include "cainterface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize credential resource by loading data from persistent storage.
+ *
+ * @retval
+ *     OC_STACK_OK    - no errors
+ *     OC_STACK_ERROR - stack process error
+ */
+OCStackResult InitCredResource();
+
+/**
+ * Perform cleanup for credential resources.
+ *
+ * @retval
+ *     OC_STACK_OK              - no errors
+ *     OC_STACK_ERROR           - stack process error
+ *     OC_STACK_NO_RESOURCE     - resource not found
+ *     OC_STACK_INVALID_PARAM   - invalid param
+ */
+OCStackResult DeInitCredResource();
+
+/**
+ * This method is used by tinydtls/SRM to retrieve credential for given Subject.
+ *
+ * @param subject - subject for which credential is required.
+ *
+ * @retval
+ *     reference to OicSecCred_t - if credential is found
+ *     NULL                      - if credential not found
+ */
+const OicSecCred_t* GetCredResourceData(const OicUuid_t* subjectId);
+
+/**
+ * This function converts credential data into JSON format.
+ * Caller needs to invoke 'free' when done using
+ * returned string.
+ * @param cred  pointer to instance of OicSecCred_t structure.
+ *
+ * @retval
+ *      pointer to JSON credential representation - if credential for subjectId found
+ *      NULL                                      - if credential for subjectId not found
+ */
+char* BinToCredJSON(const OicSecCred_t* cred);
+
+/**
+ * This function generates the bin credential data.
+ *
+ * @param subject pointer to subject of this credential.
+ * @param credType credential type.
+ * @param publicData public data such as public key.
+ * @param privateData private data such as private key.
+ * @param ownersLen length of owners array
+ * @param owners array of owners.
+ *
+ * @retval
+ *      pointer to instance of OicSecCred_t  - success
+ *      NULL                                 - error
+ */
+OicSecCred_t * GenerateCredential(const OicUuid_t* subject, OicSecCredType_t credType,
+                     const char * publicData, const char * privateData, size_t ownersLen,
+                     const OicUuid_t * owners);
+
+/**
+ * This function adds the new cred to the credential list.
+ *
+ * @param cred pointer to new credential.
+ *
+ * @retval
+ *      OC_STACK_OK     - cred not NULL and persistent storage gets updated
+ *      OC_STACK_ERROR  - cred is NULL or fails to update persistent storage
+ */
+OCStackResult AddCredential(OicSecCred_t * cred);
+
+#if defined(__WITH_DTLS__)
+/**
+ * This internal callback is used by lower stack (i.e. CA layer) to
+ * retrieve PSK credentials from RI security layer.
+ *
+ * Note: When finished, caller should initialize memory to zeroes and
+ * invoke OCFree to delete @p credInfo.
+ *
+ * @param credInfo
+ *     binary blob containing PSK credentials
+ *
+ * @retval none
+ */
+void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
+#endif /* __WITH_DTLS__ */
+
+/**
+ * Function to deallocate allocated memory to OicSecCred_t
+ *
+ * @param cred pointer to cred type
+ *
+ */
+void DeleteCredList(OicSecCred_t* cred);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_CREDR_H
+
+
diff --git a/resource/csdk/security/include/internal/doxmresource.h b/resource/csdk/security/include/internal/doxmresource.h
new file mode 100644 (file)
index 0000000..cd8477e
--- /dev/null
@@ -0,0 +1,102 @@
+//******************************************************************
+//
+// 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_DOXM_H
+#define IOTVT_SRM_DOXM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize DOXM resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitDoxmResource();
+
+/**
+ * Perform cleanup for DOXM resources.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult DeInitDoxmResource();
+
+/**
+ * This method is used by SRM to retrieve DOXM resource data..
+ *
+ * @retval  reference to @ref OicSecDoxm_t, binary format of Doxm resource data
+ */
+const OicSecDoxm_t* GetDoxmResourceData();
+
+/**
+ * This method converts JSON DOXM into binary DOXM.
+ * The JSON DOXM can be from persistent database or
+ * or received as PUT/POST request.
+ *
+ * @param[in] jsonStr  doxm data in json string.
+ * @return pointer to OicSecDoxm_t.
+ *
+ * @note Caller needs to invoke OCFree after done
+ *       using the return pointer
+ */
+OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr);
+
+/**
+ * This method converts DOXM data into JSON format.
+ * Caller needs to invoke 'free' when finished done using
+ * return string
+ *
+ * @param[in] doxm  Pointer to OicSecDoxm_t.
+ * @return pointer to json string.
+ *
+ * @note Caller needs to invoke OCFree after done
+ *       using the return pointer
+ */
+char * BinToDoxmJSON(const OicSecDoxm_t * doxm);
+
+/**
+ * This method returns the SRM device ID for this device.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID);
+
+/**
+ * @brief Gets the OicUuid_t value for the owner of this device.
+ *
+ * @return OC_STACK_OK if devOwner is a valid UUID, otherwise OC_STACK_ERROR.
+ */
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner);
+
+/** This function deallocates the memory for OicSecDoxm_t .
+ *
+ * @param[in] doxm  Pointer to OicSecDoxm_t.
+ */
+void DeleteDoxmBinData(OicSecDoxm_t* doxm);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_DOXMR_H
+
+
diff --git a/resource/csdk/security/include/internal/policyengine.h b/resource/csdk/security/include/internal/policyengine.h
new file mode 100644 (file)
index 0000000..a792bfa
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// 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_PE_H
+#define IOTVT_SRM_PE_H
+
+#include "ocstack.h"
+#include "logger.h"
+#include "securevirtualresourcetypes.h"
+#include "cainterface.h"
+#include <stdlib.h>
+#include <stdint.h>
+
+
+typedef enum PEState
+{
+    STOPPED = 0,
+    AWAITING_REQUEST,
+    BUSY
+} PEState_t;
+
+typedef struct PEContext
+{
+    PEState_t   state;
+    OicUuid_t   *subject;
+    char        *resource;
+    uint16_t    permission;
+    bool        matchingAclFound;
+    SRMAccessResponse_t retVal;
+} PEContext_t;
+
+/**
+ * Check whether a request should be allowed.
+ *
+ * @param   context     Pointer to Policy Engine context to use.
+ * @param   subjectId   Pointer to Id of the requesting entity.
+ * @param   resource    Pointer to URI of Resource being requested.
+ * @param   permission  Requested permission.
+ *
+ * @return  ACCESS_GRANTED if request should go through,
+ *          otherwise some flavor of ACCESS_DENIED
+ */
+SRMAccessResponse_t CheckPermission(
+    PEContext_t     *context,
+    const OicUuid_t *subjectId,
+    const char      *resource,
+    const uint16_t  requestedPermission);
+
+/**
+ * Initialize the Policy Engine. Call this before calling CheckPermission().
+ * TODO Eventually this and DeInit() need to be called from a new
+ *      "SRMInit(SRMContext_t *)" function, TBD after BeachHead.
+ * @param   context     Pointer to Policy Engine context to initialize.
+ * @return  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitPolicyEngine(PEContext_t *context);
+
+/**
+ * De-Initialize the Policy Engine. Call this before exiting to allow Policy
+ * Engine to do cleanup on context.
+ * @param   context     Pointer to Policy Engine context to de-initialize.
+ * @return  none
+ */
+void DeInitPolicyEngine(PEContext_t *context);
+
+/**
+ * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t.
+ */
+uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method);
+
+#endif //IOTVT_SRM_PE_H
@@ -1,6 +1,6 @@
 //******************************************************************
 //
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 //
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#ifndef OC_SECURITY_INTERNAL_H
-#define OC_SECURITY_INTERNAL_H
-
-#include "ocsecurityconfig.h"
+#ifndef IOTVT_SRM_PSI_H
+#define IOTVT_SRM_PSI_H
 
 /**
- * This callback is used by lower stack (i.e. CA layer) to retrieve PSK
- * credentials from RI security layer.
- *
- * Note: When finished, caller should initialize memory to zeroes and
- * invoke OCFree to delete @p credInfo.
+ * Reads the Secure Virtual Database from PS into dynamically allocated
+ * memory buffer.
  *
- * @param credInfo
- *     binary blob containing PSK credentials
+ * @note Caller of this method MUST use OCFree() method to release memory
+ *       referenced by return value.
  *
- * @retval none
+ * @retval  reference to memory buffer containing SVR database.
  */
-#ifdef __WITH_DTLS__
-void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
-#endif //__WITH_DTLS__
-
+char * GetSVRDatabase();
 
 /**
- * This internal API removes/clears the global variable holding the security
- * config data. This needs to be invoked when OIC stack is shutting down.
+ * This method is used by a entity handlers of SVR's to update
+ * SVR database.
  *
- * @retval none
+ * @param rsrcName string denoting the SVR name ("acl", "cred", "pstat" etc).
+ * @param jsonObj JSON object containing the SVR contents.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
  */
-void DeinitOCSecurityInfo();
-
-#endif //OC_SECURITY_INTERNAL_H
+OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj);
 
+#endif //IOTVT_SRM_PSI_H
diff --git a/resource/csdk/security/include/internal/pstatresource.h b/resource/csdk/security/include/internal/pstatresource.h
new file mode 100644 (file)
index 0000000..40c41ab
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// 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_PSTATR_H
+#define IOTVT_SRM_PSTATR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize Pstat resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitPstatResource();
+
+/**
+ * Perform cleanup for Pstat resources.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult DeInitPstatResource();
+
+/**
+ * This method converts JSON PSTAT into binary PSTAT.
+ *
+ * @param[in] jsonStr  pstat data in json string.
+ * @return pointer to OicSecPstat_t.
+ */
+OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
+
+/**
+ * This method converts pstat data into JSON format.
+ *
+ * @param[in] pstat  pstat data in binary format.
+ * @return pointer to pstat json string.
+ */
+char * BinToPstatJSON(const OicSecPstat_t * pstat);
+
+/** This function deallocates the memory for OicSecPstat_t.
+ *
+ * @param[in] pstat  Pointer to OicSecPstat_t.
+ */
+void DeletePstatBinData(OicSecPstat_t* pstat);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_PSTATR_H
+
+
diff --git a/resource/csdk/security/include/internal/resourcemanager.h b/resource/csdk/security/include/internal/resourcemanager.h
new file mode 100644 (file)
index 0000000..3e946f5
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************
+//
+// 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_RM_H
+#define IOTVT_SRM_RM_H
+
+#include <stdlib.h>
+#include "ocstack.h"
+#include "securevirtualresourcetypes.h"
+
+/**
+ * Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitSecureResources();
+
+/**
+ * Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult DestroySecureResources();
+
+/**
+ * This method is used by all secure resource modules to send responses to REST queries.
+ *
+ * @param ehRequest pointer to entity handler request data structure.
+ * @param ehRet result code from entity handler.
+ * @param rspPayload response payload in JSON.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SendSRMResponse(const OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResult ehRet, const char *rspPayload);
+
+#endif //IOTVT_SRM_RM_H
+
+
diff --git a/resource/csdk/security/include/internal/secureresourcemanager.h b/resource/csdk/security/include/internal/secureresourcemanager.h
new file mode 100644 (file)
index 0000000..6fc5b42
--- /dev/null
@@ -0,0 +1,101 @@
+//******************************************************************
+//
+// 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 SECURITYRESOURCEMANAGER_H_
+#define SECURITYRESOURCEMANAGER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Register Persistent storage callback.
+ * @param   persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - Invalid parameter
+ */
+OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler);
+
+/**
+ * @brief   Get Persistent storage handler pointer.
+ * @return
+ *     The pointer to Persistent Storage callback handler
+ */
+OCPersistentStorage* SRMGetPersistentStorageHandler();
+
+/**
+ * @brief   Register request and response callbacks.
+ *          Requests and responses are delivered in these callbacks.
+ * @param   reqHandler   [IN] Request handler callback ( for GET,PUT ..etc)
+ * @param   respHandler  [IN] Response handler callback.
+ * @param   errHandler   [IN] Error handler callback.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - Invalid parameter
+ */
+OCStackResult SRMRegisterHandler(CARequestCallback reqHandler,
+                                 CAResponseCallback respHandler,
+                                 CAErrorCallback errHandler);
+
+/**
+ * @brief   Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ * @return  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SRMInitSecureResources();
+
+/**
+ * @brief   Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ * @return  none
+ */
+void SRMDeInitSecureResources();
+
+/**
+ * @brief   Initialize Policy Engine context.
+ * @return  OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult SRMInitPolicyEngine();
+
+/**
+ * @brief   Cleanup Policy Engine context.
+ * @return  none
+ */
+void SRMDeInitPolicyEngine();
+
+/**
+ * @brief   Provisioning API response callback.
+ * @param object[IN]       endpoint instance.
+ * @param responseInfo[IN] instance of CAResponseInfo_t structure.
+ * @return true if received response is for provisioning API false otherwise.
+ */
+typedef bool (*SPResponseCallback) (const CAEndpoint_t *object,
+                                    const CAResponseInfo_t *responseInfo);
+
+/**
+ * @brief function to register provisoning API's response callback.
+ * @param respHandler response handler callback.
+ */
+void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SECURITYRESOURCEMANAGER_H_ */
diff --git a/resource/csdk/security/include/internal/srmresourcestrings.h b/resource/csdk/security/include/internal/srmresourcestrings.h
new file mode 100644 (file)
index 0000000..017eb79
--- /dev/null
@@ -0,0 +1,92 @@
+//******************************************************************
+//
+// 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_RSRC_STRINGS_H
+#define IOTVT_SRM_RSRC_STRINGS_H
+
+#include "securevirtualresourcetypes.h"
+
+extern const char * SVR_DB_FILE_NAME;
+extern const char * OIC_MI_DEF;
+
+//ACL
+extern const char * OIC_RSRC_TYPE_SEC_ACL;
+extern const char * OIC_RSRC_ACL_URI;
+extern const char * OIC_JSON_ACL_NAME;
+
+//PSTAT
+extern const char * OIC_RSRC_TYPE_SEC_PSTAT;
+extern const char * OIC_RSRC_PSTAT_URI;
+extern const char * OIC_JSON_PSTAT_NAME;
+
+
+//DOXM
+extern const char * OIC_RSRC_TYPE_SEC_DOXM;
+extern const char * OIC_RSRC_DOXM_URI;
+extern const char * OIC_JSON_DOXM_NAME;
+
+//cred
+extern const char * OIC_RSRC_TYPE_SEC_CRED;
+extern const char * OIC_RSRC_CRED_URI;
+extern const char * OIC_JSON_CRED_NAME;
+
+extern const char * OIC_JSON_SUBJECT_NAME;
+extern const char * OIC_JSON_RESOURCES_NAME;
+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_OWNED_NAME;
+extern const char * OIC_JSON_OXM_NAME;
+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;
+extern const char * OIC_JSON_CREDID_NAME;
+extern const char * OIC_JSON_ROLEIDS_NAME;
+extern const char * OIC_JSON_CREDTYPE_NAME;
+extern const char * OIC_JSON_PUBLICDATA_NAME;
+extern const char * OIC_JSON_PRIVATEDATA_NAME;
+extern const char * OIC_JSON_PERIOD_NAME;
+extern const char * OIC_JSON_ISOP_NAME;
+extern const char * OIC_JSON_COMMIT_HASH_NAME;
+extern const char * OIC_JSON_DEVICE_ID_NAME;
+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 OicUuid_t WILDCARD_SUBJECT_ID;
+extern size_t WILDCARD_SUBJECT_ID_LEN;
+extern const char * WILDCARD_RESOURCE_URI;
+
+//Ownership Transfer Methods
+extern const char * OXM_JUST_WORKS;
+extern const char * OXM_MODE_SWITCH;
+extern const char * RANDOM_DEVICE_PIN;
+extern const char * PRE_PROVISIONED_DEVICE_PIN;
+extern const char * PRE_PROVISIONED_STRONG_CREDENTIAL;
+
+extern const char * OIC_SEC_TRUE;
+extern const char * OIC_SEC_FALSE;
+
+extern const char * OIC_SEC_REST_QUERY_SEPARATOR;
+extern char OIC_SEC_REST_QUERY_DELIMETER;
+
+#endif //IOTVT_SRM_RSRC_STRINGS_H
+
diff --git a/resource/csdk/security/include/ocsecurityconfig.h b/resource/csdk/security/include/ocsecurityconfig.h
deleted file mode 100644 (file)
index fa5d164..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#ifndef OC_SECURITY_CONFIG_H
-#define OC_SECURITY_CONFIG_H
-
-#include <stdint.h>
-
-#define DTLS_PSK_ID_LEN 16
-#define DTLS_PSK_PSK_LEN 16
-
-#define OCSecConfigVer_1 1 /**< Initial version supporting PSK Credentials */
-#define OCSecConfigVer_CurrentVersion OCSecConfigVer_1
-
-typedef enum{
-    OC_BLOB_TYPE_PSK = 1,   /**< Security blob holding PSK data */
-} OCBlobType;
-
-
-/**
- * Credentials of a peer device. Includes identity and the associated PSK.
- */
-typedef struct
-{
-    unsigned char id[DTLS_PSK_ID_LEN];      /**< identity of the peer device */
-    unsigned char psk[DTLS_PSK_PSK_LEN];    /**< psk of the peer device */
-} OCDtlsPskCreds;
-
-
-/**
- * Binary blob containing device identity and the credentials for all devices
- * trusted by this device.
- */
-typedef struct
-{
-    unsigned char identity[DTLS_PSK_ID_LEN]; /**< identity of self */
-    uint32_t num;                            /**< number of credentials in this blob */
-    OCDtlsPskCreds creds[1];                 /**< list of credentials. Size of this
-                                                 array is determined by 'num' variable. */
-} OCDtlsPskCredsBlob;
-
-
-/**
- * Generic definition of a security blob. A security blob can contain
- * info of various types, such as : PSK info, certificates,
- * access control lists(ACL) etc.
- */
-typedef struct
-{
-    uint16_t  type;     /**< Type of blob */
-    uint16_t  len;   /**< length of blob data */
-    uint8_t   val[1];   /**< A variable size array holding blob data */
-} OCSecBlob;
-
-
-/**
- * This structure defines the security related configuration data for
- * Iotivity applications.
- */
-typedef struct
-{
-   uint16_t    version;  /**< version of the config data */
-   uint16_t    numBlob;  /**< number of security blobs in this config data */
-   uint8_t     blob[1];  /**< A variable size array holding a blob */
-} OCSecConfigData;
-
-/**
- * Interprets @p blob as pointer to a OCSecBlob and advances to
- * the next blob in the OCSecConfigData
- */
-#define config_data_next_blob(blob) \
-            ((OCSecBlob*)((blob)->val + (blob)->len));
-
-/**
- * Configuration data for security will be stored in below fashion in a
- * flat file on persistent storage.
- *
- *  --------------------------------------------------------------
- *  | OCSecConfigData| OCSecBlob #1 | OCSecBlob #2 | OCSecBlob #3|
- *  --------------------------------------------------------------
- */
-
-#endif //OC_SECURITY_CONFIG_H
-
-
-
diff --git a/resource/csdk/security/include/securevirtualresourcetypes.h b/resource/csdk/security/include/securevirtualresourcetypes.h
new file mode 100644 (file)
index 0000000..6df713b
--- /dev/null
@@ -0,0 +1,418 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * Data type definitions for all oic.sec.* types defined in the
+ * OIC Security Specification.
+ *
+ * Note that throughout, ptrs are used rather than arrays.  There
+ * are two primary reasons for this:
+ * 1) The Spec defines many structures with optional fields, so pre-
+ *    allocating these would be wasteful.
+ * 2) There are in many cases arrays of Strings or arrays of Structs,
+ *    which could not be defined as variable length arrays (e.g. array[])
+ *    without breaking from the structure order and definition in the Spec.
+ *
+ * The primary drawback to this decision is that marshalling functions
+ * will have to be written by hand to marshal these structures (e.g. to/from
+ * Persistent Storage, or across memory boundaries).
+ *
+ * TODO reconcile against latest OIC Security Spec to ensure all fields correct.
+ * (Last checked against v0.95)
+ */
+
+#ifndef OC_SECURITY_RESOURCE_TYPES_H
+#define OC_SECURITY_RESOURCE_TYPES_H
+
+#include <stdint.h> // for uint8_t typedef
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Values used to create bit-maskable enums for single-value
+ *          response with embedded code.
+ */
+#define ACCESS_GRANTED_DEF            (1 << 0)
+#define ACCESS_DENIED_DEF             (1 << 1)
+#define INSUFFICIENT_PERMISSION_DEF   (1 << 2)
+#define SUBJECT_NOT_FOUND_DEF         (1 << 3)
+#define RESOURCE_NOT_FOUND_DEF        (1 << 4)
+#define POLICY_ENGINE_ERROR_DEF       (1 << 5)
+#define REASON_MASK_DEF               (INSUFFICIENT_PERMISSION_DEF | \
+                                       SUBJECT_NOT_FOUND_DEF | \
+                                       RESOURCE_NOT_FOUND_DEF | \
+                                       POLICY_ENGINE_ERROR_DEF)
+
+
+/**
+ * Access policy in least significant bits (from Spec):
+ * 1st lsb:  C (Create)
+ * 2nd lsb:  R (Read, Observe, Discover)
+ * 3rd lsb:  U (Write, Update)
+ * 4th lsb:  D (Delete)
+ * 5th lsb:  N (Notify)
+ */
+#define PERMISSION_CREATE       (1 << 0)
+#define PERMISSION_READ         (1 << 1)
+#define PERMISSION_WRITE        (1 << 2)
+#define PERMISSION_DELETE       (1 << 3)
+#define PERMISSION_NOTIFY       (1 << 4)
+#define PERMISSION_FULL_CONTROL (PERMISSION_CREATE | \
+                                 PERMISSION_READ | \
+                                 PERMISSION_WRITE | \
+                                 PERMISSION_DELETE | \
+                                 PERMISSION_NOTIFY)
+
+/**
+ * @brief   Response type for all Action requests from CA layer;
+ *          may include a reason code.
+ *
+ * To extract codes use GetReasonCode function on SRMAccessResponse:
+ *
+ * SRMAccessResponse_t response = SRMRequestHandler(obj, info);
+ * if(SRM_TRUE == IsAccessGranted(response)) {
+ *     SRMAccessResponseReasonCode_t reason = GetReasonCode(response);
+ *     switch(reason) {
+ *         case INSUFFICIENT_PERMISSION:
+ *         ...etc.
+ *     }
+ * }
+ */
+typedef enum
+{
+    ACCESS_GRANTED = ACCESS_GRANTED_DEF,
+    ACCESS_DENIED = ACCESS_DENIED_DEF,
+    ACCESS_DENIED_INSUFFICIENT_PERMISSION = ACCESS_DENIED_DEF
+        | INSUFFICIENT_PERMISSION_DEF,
+    ACCESS_DENIED_SUBJECT_NOT_FOUND = ACCESS_DENIED_DEF
+        | SUBJECT_NOT_FOUND_DEF,
+    ACCESS_DENIED_RESOURCE_NOT_FOUND = ACCESS_DENIED_DEF
+        | RESOURCE_NOT_FOUND_DEF,
+    ACCESS_DENIED_POLICY_ENGINE_ERROR = ACCESS_DENIED_DEF
+        | POLICY_ENGINE_ERROR_DEF,
+} SRMAccessResponse_t;
+
+/**
+ * Reason code for SRMAccessResponse.
+ */
+typedef enum
+{
+    NO_REASON_GIVEN = 0,
+    INSUFFICIENT_PERMISSION = INSUFFICIENT_PERMISSION_DEF,
+    SUBJECT_NOT_FOUND = SUBJECT_NOT_FOUND_DEF,
+    RESOURCE_NOT_FOUND = RESOURCE_NOT_FOUND_DEF,
+} SRMAccessResponseReasonCode_t;
+
+/**
+ * Extract Reason Code from Access Response.
+ */
+static inline SRMAccessResponseReasonCode_t GetReasonCode(
+    SRMAccessResponse_t response)
+{
+    SRMAccessResponseReasonCode_t reason =
+        (SRMAccessResponseReasonCode_t)(response & REASON_MASK_DEF);
+    return reason;
+}
+
+/**
+ * Returns 'true' iff request should be passed on to RI layer.
+ */
+static inline bool IsAccessGranted(SRMAccessResponse_t response)
+{
+    if(ACCESS_GRANTED == (response & ACCESS_GRANTED))
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+typedef struct OicSecAcl OicSecAcl_t;
+
+typedef struct OicSecAmacl OicSecAmacl_t;
+
+typedef struct OicSecCred OicSecCred_t;
+
+/**
+ * @brief   /oic/sec/credtype (Credential Type) data type.
+ *          Derived from OIC Security Spec /oic/sec/cred; see Spec for details.
+ *              0:  no security mode
+ *              1:  symmetric pair-wise key
+ *              2:  symmetric group key
+ *              4:  asymmetric key
+ *              8:  signed asymmetric key (aka certificate)
+ *              16: PIN /password
+ */
+typedef uint16_t OicSecCredType_t;
+
+/**
+ * Aid for assigning/testing vals with OicSecCredType_t.
+ * Example:
+ *  OicSecCredType_t ct = PIN_PASSWORD | ASYMMETRIC_KEY;
+ *  if((ct & PIN_PASSWORD) == PIN_PASSWORD)
+ *  {
+ *      // ct contains PIN_PASSWORD flag.
+ *  }
+ */
+typedef enum OSCTBitmask
+{
+    NO_SECURITY_MODE                = 0x0,
+    SYMMETRIC_PAIR_WISE_KEY         = (0x1 << 0),
+    SYMMETRIC_GROUP_KEY             = (0x1 << 1),
+    ASYMMETRIC_KEY                  = (0x1 << 2),
+    SIGNED_ASYMMETRIC_KEY           = (0x1 << 3),
+    PIN_PASSWORD                    = (0x1 << 4),
+} OSCTBitmask_t;
+
+typedef struct OicSecDoxm OicSecDoxm_t;
+
+typedef enum OicSecDpm
+{
+    NORMAL                          = 0x0,
+    RESET                           = (0x1 << 0),
+    TAKE_OWNER                      = (0x1 << 1),
+    BOOTSTRAP_SERVICE               = (0x1 << 2),
+    SECURITY_MANAGEMENT_SERVICES    = (0x1 << 3),
+    PROVISION_CREDENTIALS           = (0x1 << 4),
+    PROVISION_ACLS                  = (0x1 << 5),
+    // << 6 THROUGH 15 RESERVED
+} OicSecDpm_t;
+
+typedef enum OicSecDpom
+{
+    MULTIPLE_SERVICE_SERVER_DRIVEN  = 0x0,
+    SINGLE_SERVICE_SERVER_DRIVEN    = 0x1,
+    MULTIPLE_SERVICE_CLIENT_DRIVEN  = 0x2,
+    SINGLE_SERVICE_CLIENT_DRIVEN    = 0x3,
+} OicSecDpom_t;
+
+//TODO: Need more clarification on deviceIDFormat field type.
+#if 0
+typedef enum
+{
+    URN = 0x0
+}OicSecDvcIdFrmt_t;
+#endif
+
+typedef enum
+{
+    OIC_JUST_WORKS                          = 0x0,
+    OIC_MODE_SWITCH                         = 0x1,
+    OIC_RANDOM_DEVICE_PIN                   = 0x2,
+    OIC_PRE_PROVISIONED_DEVICE_PIN          = 0x3,
+    OIC_PRE_PROVISION_STRONG_CREDENTIAL     = 0x4
+}OicSecOxm_t;
+
+typedef struct OicSecJwk OicSecJwk_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?
+
+
+/**
+ * @brief   /oic/uuid (Universal Unique Identifier) data type.
+ */
+#define UUID_LENGTH 128/8 // 128-bit GUID length
+//TODO: Confirm the length and type of ROLEID.
+#define ROLEID_LENGTH 128/8 // 128-bit ROLEID length
+#define OWNER_PSK_LENGTH_128 128/8 //byte size of 128-bit key size
+#define OWNER_PSK_LENGTH_256 256/8 //byte size of 256-bit key size
+
+struct OicUuid
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    //TODO fill in unless this is defined elsewhere?
+    uint8_t             id[UUID_LENGTH];
+};
+
+/**
+ * @brief   /oic/sec/jwk (JSON Web Key) data type.
+ *          See JSON Web Key (JWK)  draft-ietf-jose-json-web-key-41
+ */
+#define JWK_LENGTH 256/8 // 256 bit key length
+struct OicSecJwk
+{
+    char                *data;
+};
+
+/**
+ * @brief   /oic/sec/acl (Access Control List) data type.
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecAcl
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    OicUuid_t           subject;        // 0:R:S:Y:uuid TODO: this deviates
+                                        // from spec and needs to be updated
+                                        // in spec (where it's a String).
+    size_t              resourcesLen;   // the number of elts in Resources
+    char                **resources;    // 1:R:M:Y:String
+    uint16_t            permission;     // 2:R:S:Y:UINT16
+    size_t              periodsLen;     // the number of elts in Periods
+    char                **periods;      // 3:R:M*:N:String (<--M*; see Spec)
+    char                *recurrences;   // 5:R:M:N:String
+    size_t              ownersLen;      // the number of elts in Owners
+    OicUuid_t           *owners;        // 8:R:M:Y:oic.uuid
+    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
+    // SRM version only; this will change to Svc type for full implementation.
+    //TODO change Owners type to oic.sec.svc
+    //OicSecSvc_t         *Owners;        // 6:R:M:Y:oic.sec.svc
+    OicSecAcl_t         *next;
+};
+
+/**
+ * @brief   /oic/sec/amacl (Access Manager Service Accesss Control List)
+ *          data type.
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecAmacl
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    size_t              resourcesLen;   // the number of elts in Resources
+    char                **resources;    // 0:R:M:Y:String
+    size_t              amssLen;        // the number of elts in Amss
+    OicSecSvc_t         *amss;          // 1:R:M:Y:acl
+    size_t              ownersLen;      // the number of elts in Owners
+    OicUuid_t           *owners;        // 2:R:M:Y:oic.uuid
+    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
+    // SRM version only; this will change to Svc type for full implementation.
+    //TODO change Owners type to oic.sec.svc
+    //OicSecSvc_t         *Owners;        // 2:R:M:Y:oic.sec.svc
+};
+
+/**
+ * @brief   /oic/sec/cred (Credential) data type.
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecCred
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    uint16_t            credId;         // 0:R:S:Y:UINT16
+    OicUuid_t           subject;        // 1:R:S:Y:oic.uuid
+    //Note: Need further clarification on roleID data type
+    //NOTE: Need further clarification on roleId datatype.
+    //size_t              roleIdsLen;     // the number of elts in RoleIds
+    //OicSecRole_t        *roleIds;       // 2:R:M:N:oic.sec.role
+    OicSecCredType_t    credType;       // 3:R:S:Y:oic.sec.credtype
+    OicSecJwk_t         publicData;     // 5:R:S:N:oic.sec.jwk
+    OicSecJwk_t         privateData;    // 6:R:S:N:oic.sec.jwk
+    char                *period;        // 7:R:S:N:String
+    size_t              ownersLen;      // the number of elts in Owners
+    OicUuid_t           *owners;        // 8:R:M:Y:oic.uuid
+    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
+    // SRM version only; this will change to Svc type for full implementation.
+    //OicSecSvc_t         *Owners;        // 8:R:M:Y:oic.sec.svc
+    //TODO change Owners type to oic.sec.svc
+    OicSecCred_t        *next;
+};
+
+/**
+ * @brief   /oic/sec/doxm (Device Owner Transfer Methods) data type
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecDoxm
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    OicUrn_t            *oxmType;       // 0:R:M:N:URN
+    size_t              oxmTypeLen;     // the number of elts in OxmType
+    OicSecOxm_t         *oxm;           // 1:R:M:N:UINT16
+    size_t              oxmLen;         // the number of elts in Oxm
+    OicSecOxm_t         oxmSel;         // 2:R/W:S:Y:UINT16
+    bool                owned;          // 3:R:S:Y:Boolean
+    //TODO: Need more clarification on deviceIDFormat field type.
+    //OicSecDvcIdFrmt_t   deviceIDFormat; // 4:R:S:Y:UINT8
+    OicUuid_t           deviceID;       // 5:R:S:Y:oic.uuid
+    OicUuid_t           owner;         // 6:R:S:Y:oic.uuid
+    // NOTE: we are using UUID for Owner instead of Svc type for mid-April
+    // SRM version only; this will change to Svc type for full implementation.
+    //OicSecSvc_t       Owner;        // 5:R:S:Y:oic.sec.svc
+    //TODO change Owner type to oic.sec.svc
+};
+
+/**
+ * @brief   /oic/sec/pstat (Provisioning Status) data type.
+ * NOTE: this struct is ahead of Spec v0.95 in definition to include Sm.
+ * TODO: change comment when reconciled to Spec v0.96.
+ */
+struct OicSecPstat
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    bool                isOp;           // 0:R:S:Y:Boolean
+    OicSecDpm_t         cm;             // 1:R:S:Y:oic.sec.dpm
+    OicSecDpm_t         tm;             // 2:RW:S:Y:oic.sec.dpm
+    OicUuid_t           deviceID;       // 3:R:S:Y:oic.uuid
+    OicSecDpom_t        om;             // 4:RW:M:Y:oic.sec.dpom
+    size_t              smLen;          // the number of elts in Sm
+    OicSecDpom_t        *sm;            // 5:R:M:Y:oic.sec.dpom
+    uint16_t            commitHash;     // 6:R:S:Y:oic.sec.sha256
+    //TODO: this is supposed to be a 256-bit uint; temporarily use uint16_t
+    //TODO: need to decide which 256 bit and 128 bit types to use... boost?
+};
+
+/**
+ * @brief   /oic/sec/role (Role) data type.
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecRole
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    //TODO fill in with Role definition
+    uint8_t             id[ROLEID_LENGTH];
+};
+
+/**
+ * @brief   /oic/sec/sacl (Signed Access Control List) data type.
+ *          Derived from OIC Security Spec; see Spec for details.
+ */
+struct OicSecSacl
+{
+    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+    //TODO fill in from OIC Security Spec
+};
+
+/**
+ * @brief   /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>
+    //TODO fill in from OIC Security Spec
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //OC_SECURITY_RESOURCE_TYPES_H
diff --git a/resource/csdk/security/include/srmutility.h b/resource/csdk/security/include/srmutility.h
new file mode 100644 (file)
index 0000000..d811e25
--- /dev/null
@@ -0,0 +1,104 @@
+//******************************************************************
+//
+// 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_UTILITY_H
+#define IOTVT_SRM_UTILITY_H
+
+#include "ocstack.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "uri.h"
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+
+typedef struct OicParseQueryIter OicParseQueryIter_t;
+
+/**
+ * @brief   OicRestQueryIter data structure is used for book-keeping
+ *          sub-REST query's attribute's and value's, starting location &
+ *          length between calls to GetNextQuery(). This struct needs
+ *          to be first initialized with ParseQueryIterInit().
+ *
+ */
+struct OicParseQueryIter
+{
+    unsigned char * attrPos;    /**<stating location of attribute */
+    size_t attrLen;             /**<length of the attribute */
+    unsigned char * valPos;     /**<starting location of value*/
+    size_t valLen;              /**<length of the value*/
+    coap_parse_iterator_t pi;   /**<coap struct for tokenizing the query*/
+};
+
+/**
+ * @def VERIFY_SUCCESS
+ * @brief Macro to verify success of operation.
+ * eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR);
+ * @note Invoking function must define "exit:" label for goto functionality to work correctly.
+ *
+ */
+#define VERIFY_SUCCESS(tag, op, logLevel) { if (!(op)) \
+            {OC_LOG((logLevel), tag, PCF(#op " failed!!")); goto exit;} }
+
+/**
+ * @def VERIFY_NON_NULL
+ * @brief Macro to verify argument is not equal to NULL.
+ * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR);
+ * @note Invoking function must define "exit:" label for goto functionality to work correctly.
+ *
+ */
+#define VERIFY_NON_NULL(tag, arg, logLevel) { if (NULL == (arg)) \
+            { OC_LOG((logLevel), tag, PCF(#arg " is NULL")); goto exit; } }
+
+/**
+ * This method initializes the OicParseQueryIter_t struct
+ *
+ *@param query     - REST query, to be parsed
+ *@param parseIter - OicParseQueryIter_t struct, to be initialized
+ *
+ */
+void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter);
+
+
+/**
+ * This method fills the OicParseQueryIter_t struct with next REST query's
+ * attribute's and value's information
+ *
+ *@param parseIter - OicParseQueryIter_t struct, has next query's attribute's & value's info
+ *
+ * @retval
+ *     OicParseQueryIter_t *  - has parsed query info
+ *     NULL                   - has no query to parse
+ */
+OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif //IOTVT_SRM_UTILITY_H
diff --git a/resource/csdk/security/provisioning/SConscript b/resource/csdk/security/provisioning/SConscript
new file mode 100644 (file)
index 0000000..d5cc915
--- /dev/null
@@ -0,0 +1,91 @@
+# //******************************************************************
+# //
+# // 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')
+
+provisioning_env = env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+provisioning_env.AppendUnique(CPPPATH = [
+               '../../stack/include',
+               '../../stack/include/internal',
+               '../../ocrandom/include',
+               '../../logger/include',
+               '../../../oc_logger/include',
+               '../../ocmalloc/include',
+               'include',
+               'include/internal',
+               '../../resource/csdk/security/include',
+               '../../../../extlibs/cjson/',
+               '../../../../../extlibs/tinydtlsra/',
+               '../../connectivity/inc',
+               '../../connectivity/external/inc',
+               '../../connectivity/common/inc',
+               '../../connectivity/api',
+               '../include',
+               '../include/internal'
+               ])
+target_os = env.get('TARGET_OS')
+provisioning_env.AppendUnique(CFLAGS = ['-D__WITH_DTLS__'])
+provisioning_env.AppendUnique(CFLAGS = ['-std=c99'])
+if target_os not in ['windows', 'winrt']:
+       provisioning_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread', '-D__WITH_DTLS__'])
+
+       # Note: 'pthread' is in libc for android. On other platform, if use
+       # new gcc(>4.9?) it isn't required, otherwise, it's required
+       if target_os != 'android':
+               provisioning_env.AppendUnique(LIBS = ['-lpthread'])
+
+
+provisioning_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+provisioning_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap'])
+
+provisioning_env.AppendUnique(LIBS = ['tinydtls'])
+
+provisioning_env.ParseConfig('pkg-config --libs glib-2.0');
+
+if target_os == 'android':
+       provisioning_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+       provisioning_env.AppendUnique(LIBS = ['gnustl_static'])
+
+       if not env.get('RELEASE'):
+               provisioning_env.AppendUnique(LIBS = ['log'])
+
+if target_os in ['darwin', 'ios']:
+       provisioning_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+provisioning_src = [
+       'src/provisioningmanager.c',
+    'src/credentialgenerator.c'
+       ]
+provisioningserver = provisioning_env.StaticLibrary('ocspapi', provisioning_src)
+
+provisioning_env.InstallTarget(provisioningserver, 'libocspapi')
+provisioning_env.UserInstallTargetLib(provisioningserver, 'libocspapi')
+
+if target_os in ['linux']:
+       SConscript('sample/SConscript')
+
diff --git a/resource/csdk/security/provisioning/include/internal/credentialgenerator.h b/resource/csdk/security/provisioning/include/internal/credentialgenerator.h
new file mode 100644 (file)
index 0000000..259a608
--- /dev/null
@@ -0,0 +1,48 @@
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+
+#ifndef SP_CREDENTIAL_GENERATOR_H
+#define SP_CREDENTIAL_GENERATOR_H
+
+#include "ocstack.h"
+#include "securevirtualresourcetypes.h"
+#include "provisioningmanager.h"
+
+/**
+ * Function to generate credentials according to the type.
+ *
+ * @param[in]  type           Type of credential.
+ * @param[in]  ptDeviceId     Device ID of provisioning tool.
+ * @param[in]  firstDeviceId  DeviceID of the first device.
+ * @param[in]  secondDeviceId DeviceID of the second device.
+ * @param[out] firstCred      Generated credential for first device.
+ * @param[out] secondCred     Generated credential for second device.
+ * @return  SP_SUCCESS on success
+ */
+SPResult SPGeneratePairWiseCredentials(OicSecCredType_t type, const OicUuid_t *ptDeviceId,
+                                       const OicUuid_t *firstDeviceId,
+                                       const OicUuid_t *secondDeviceId,
+                                       OicSecCred_t **firstCred,
+                                       OicSecCred_t **secondCred);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //SP_CREDENTIAL_GENERATOR_H
diff --git a/resource/csdk/security/provisioning/include/provisioningmanager.h b/resource/csdk/security/provisioning/include/provisioningmanager.h
new file mode 100644 (file)
index 0000000..cf23b88
--- /dev/null
@@ -0,0 +1,159 @@
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+
+#ifndef SP_PROVISION_API_H
+#define SP_PROVISION_API_H
+
+#include "ocstack.h"
+#include "securevirtualresourcetypes.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Error Code.
+ */
+typedef enum
+{
+    SP_RESULT_SUCCESS = 0,
+    SP_RESULT_INVALID_PARAM,
+    SP_RESULT_MEM_ALLOCATION_FAIL,
+    SP_RESULT_INTERNAL_ERROR,
+    SP_RESULT_TIMEOUT,
+    SP_RESULT_CONN_INVALID_PARAM,
+    SP_RESULT_CONN_ADAPTER_NOT_ENABLED,
+    SP_RESULT_CONN_SERVER_STARTED_ALREADY,
+    SP_RESULT_CONN_SERVER_NOT_STARTED,
+    SP_RESULT_CONN_DESTINATION_NOT_REACHABLE,
+    SP_RESULT_CONN_SOCKET_OPERATION_FAILED,
+    SP_RESULT_CONN_SEND_FAILED,
+    SP_RESULT_CONN_RECEIVE_FAILED,
+    SP_RESULT_CONN_MEMORY_ALLOC_FAILED,
+    SP_RESULT_CONN_REQUEST_TIMEOUT,
+    SP_RESULT_CONN_DESTINATION_DISCONNECTED,
+    SP_RESULT_CONN_STATUS_FAILED,
+    SP_RESULT_CONN_NOT_SUPPORTED
+
+} SPResult;
+
+typedef struct SPTargetDeviceInfo SPTargetDeviceInfo_t;
+typedef struct SPDevInfo SPDevInfo_t;
+
+/**
+ * Device Info structure.
+ */
+struct SPTargetDeviceInfo
+{
+    OCDevAddr endpoint;             /**< target address **/
+    OicSecPstat_t *pstat;           /**< Pointer to target's pstat resource. **/
+    OicSecDoxm_t *doxm;             /**< Pointer to target's doxm resource. **/
+    uint16_t securePort;            /**< Secure port **/
+    SPTargetDeviceInfo_t *next;     /**< Next pointer. **/
+};
+
+/**
+ * Owned target device info
+ */
+struct SPDevInfo
+{
+    OCDevAddr endpoint;             /**< target address **/
+    OicUuid_t deviceId;             /**< Device ID. **/
+    SPDevInfo_t *next;              /**< Next pointer. **/
+};
+
+/**
+ * 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.
+ *
+ * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
+ *                    client before returning the list of devices.
+ * @param[out] list List of provision candidate devices.
+ * @return SP_SUCCESS in case of success and other value otherwise.
+ */
+SPResult SPProvisioningDiscovery(unsigned short timeout,
+                                 SPTargetDeviceInfo_t **list);
+
+/**
+ * The function is reponsible for following activities:
+ * - Send post to /oic/sec/doxm resource with selected ownership transfer method
+ * - Get pstat resource of target device to enumerate supported operation modes.
+ * - Select and let the target device know the selected methods.
+ * - Initiate anon handshake and save owner PSK
+ * - Update doxm resource of target device with ownership info.
+ *
+ * @param[in] timeout  Timeout value in secs till which call REST request will wait before
+ *                     returning error in case of 0 function will wait till success.
+ * @param[in] selectedDeviceInfo Device information.
+ * @return SP_SUCCESS in case of success and other value otherwise.
+ */
+SPResult SPInitProvisionContext(unsigned short timeout,
+                                SPTargetDeviceInfo_t *selectedDeviceInfo);
+
+/**
+ * Function to send ACL information to resource.
+ *
+ * @param[in] timeout Timeout value in secs till which call to REST request will wait before
+ *                     returning error in case of 0 function will wait till success.
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] acl ACL to provision
+ * @return  SP_SUCCESS in case of success and other value otherwise.
+ */
+SPResult SPProvisionACL(unsigned short timeout, const SPTargetDeviceInfo_t *selectedDeviceInfo,
+                        OicSecAcl_t *acl);
+
+/**
+ * Function to send credential information to list of resources.
+ *
+ * @param[in] timeout Timeout value in secs till which call to REST request will wait before
+ *                    returning error in case of 0 function will wait till success.
+ * @param[in] type Type of credentials to be provisioned to the device.
+ * @param[in] pDevList List of devices to be provisioned with the specified credential.
+ *
+ * @return  SP_SUCCESS in case of success and other value otherwise.
+ */
+SPResult SPProvisionCredentials(unsigned short timeout, OicSecCredType_t type,
+                                const SPDevInfo_t *pDevList);
+
+/**
+ * Function to confirm the ACL post request to check  whether its updated at
+ * resource server end properly or not.
+ *
+ * @param[in] timeout Timeout value in seconds till which call REST request will wait
+ *                     before returning error in case of 0 function will wait till success.
+ * @param[in] context Provisioning context
+ * @return  SP_SUCCESS on success
+ */
+SPResult SPFinalizeProvisioning(unsigned short timeout,
+                                SPTargetDeviceInfo_t *selectedDeviceInfo);
+
+/**
+ * Function to end Provisioning session.
+ *
+ * @return  SP_SUCCESS on success
+ */
+SPResult SPTerminateProvisioning();
+
+#ifdef __cplusplus
+}
+#endif
+#endif //SP_PROVISION_API_H
diff --git a/resource/csdk/security/provisioning/sample/README-Provisioning-Tool.txt b/resource/csdk/security/provisioning/sample/README-Provisioning-Tool.txt
new file mode 100644 (file)
index 0000000..45d750f
--- /dev/null
@@ -0,0 +1,23 @@
+LAST UPDATED 7/16/2015
+
+To execute Provisioning Tool sample:
+
+1) Build IoTivity with security enabled:
+       $ cd <iotivity-base>
+       $ scons resource SECURED=1
+
+2) Verify Provisioning Tool functionality using secure sample apps:
+
+    On Resource Server Device which needs to be 'provisioned':
+       $ cd <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure
+       $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release
+       $ cp ../../../../security/provisioning/sample/oic_svr_db_unowned_server.json oic_svr_db_server.json
+       $ ./ocserverbasicops
+
+
+    On Provisioning Tool Device:
+       $ cd <iotivity-base>/out/<...>/release/resource/csdk/security/provisioning/sample
+       $ ./provisioningclient
+
+    Follow the prompts on Provisioning Tool device and provisioning should be completed
+    successfully. You should see a message 'Provisioning Success~!!'.
diff --git a/resource/csdk/security/provisioning/sample/SConscript b/resource/csdk/security/provisioning/sample/SConscript
new file mode 100755 (executable)
index 0000000..1947307
--- /dev/null
@@ -0,0 +1,77 @@
+# //******************************************************************
+# //
+# // 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')
+
+provisioning_env = env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+provisioning_env.AppendUnique(CPPPATH = [
+               '../../../stack/include',
+               '../../../ocrandom/include',
+               '../../../logger/include',
+               '../../../stack/include',
+               '../../../security/include',
+               '../../../../oc_logger/include',
+               '../include',
+               '../../include',
+               '../../../../../extlibs/tinydtls',
+               '../../../../../extlibs/cjson',
+               '../../../../../extlibs/base64',
+               '../../../connectivity/inc',
+               '../../../connectivity/common/inc',
+               '../../../connectivity/lib/libcoap-4.1.1',
+               '../../../connectivity/api'
+               ])
+
+provisioning_env.AppendUnique(CFLAGS = ['-D__WITH_DTLS__','-std=c99'])
+provisioning_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread', '-fpermissive'])
+provisioning_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+provisioning_env.AppendUnique(LIBS = ['-lpthread'])
+provisioning_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+provisioning_env.PrependUnique(LIBS = ['ocspapi','oc', 'oc_logger', 'ocsrm','m', 'octbstack', 'connectivity_abstraction', 'coap'])
+
+if env.get('SECURED') == '1':
+    provisioning_env.AppendUnique(LIBS = ['tinydtls'])
+provisioning_env.ParseConfig('pkg-config --libs glib-2.0');
+
+provisioning_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+
+provisioningclient = provisioning_env.Program('provisioningclient', 'provisioningclient.c')
+
+Alias("sample", [provisioningclient])
+
+provisioning_env.AppendTarget('samples')
+
+src_dir = provisioning_env.get('SRC_DIR')
+sec_provisioning_src_dir = src_dir + '/resource/csdk/security/provisioning/sample/'
+sec_provisioning_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/provisioning/sample/'
+
+provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
+    sec_provisioning_src_dir + 'oic_svr_db_prov_tool.json'))
+provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
+    sec_provisioning_src_dir + 'oic_svr_db_unowned_server.json'))
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_prov_tool.json b/resource/csdk/security/provisioning/sample/oic_svr_db_prov_tool.json
new file mode 100755 (executable)
index 0000000..96befc0
--- /dev/null
@@ -0,0 +1,43 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat",
+                "/oic/sec/acl",
+                "/oic/sec/cred"
+             ],
+             "perms": 7,
+             "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "YWRtaW5EZXZpY2VVVUlE",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "YWRtaW5EZXZpY2VVVUlE",
+               "ownr": "YWRtaW5EZXZpY2VVVUlE"
+       }
+}
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_unowned_server.json b/resource/csdk/security/provisioning/sample/oic_svr_db_unowned_server.json
new file mode 100644 (file)
index 0000000..8b18b67
--- /dev/null
@@ -0,0 +1,43 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl",
+                "/oic/sec/svc",
+                "/oic/sec/amacl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 6,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        }
+    ],
+       "pstat":        {
+               "isop": false,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": false,
+               "deviceid":     "MTExMTExMTExMTExMTExMQ=="
+       }
+}
diff --git a/resource/csdk/security/provisioning/sample/provisioningclient.c b/resource/csdk/security/provisioning/sample/provisioningclient.c
new file mode 100755 (executable)
index 0000000..b342959
--- /dev/null
@@ -0,0 +1,326 @@
+/******************************************************************
+*
+* 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "logger.h"
+#include "oic_malloc.h"
+#include "utlist.h"
+#include "securevirtualresourcetypes.h"
+#include "provisioningmanager.h"
+
+#define MAX_URI_LENGTH (64)
+#define MAX_PERMISSION_LENGTH (5)
+#define MAX_INPUT_ID_LENGTH (16)
+#define PREDEFINED_TIMEOUT (10)
+#define CREATE (1)
+#define READ (2)
+#define UPDATE (4)
+#define DELETE (8)
+#define NOTIFY (16)
+#define DASH '-'
+#define TAG  "provisioningclient"
+
+static OicSecAcl_t        *gAcl = NULL;
+static char PROV_TOOL_DB_FILE[] = "oic_svr_db_prov_tool.json";
+
+/**
+ * Perform cleanup for ACL list
+ *
+ * @param[in]    ACL list
+ */
+static void DeleteACLList(OicSecAcl_t *acl)
+{
+    if (acl)
+    {
+        OicSecAcl_t *aclTmp1 = NULL;
+        OicSecAcl_t *aclTmp2 = NULL;
+        LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
+        {
+            LL_DELETE(acl, aclTmp1);
+
+            /* Clean Resources */
+            for (int i = 0; i < aclTmp1->resourcesLen; i++)
+            {
+                OICFree(aclTmp1->resources[i]);
+            }
+            OICFree(aclTmp1->resources);
+
+            /* Clean Owners */
+            OICFree(aclTmp1->owners);
+
+            /* Clean ACL node itself */
+            OICFree(aclTmp1);
+        }
+        acl = NULL;
+    }
+}
+
+/**
+ * Calculate ACL permission from string to bit
+ *
+ * @param[in] temp_psm    Input data of ACL permission string
+ * @param[in,out] pms    The pointer of ACL permission value
+ * @return  0 on success otherwise a positive error value
+ * @retval  SP_RESULT_SUCCESS    Successful
+ * @retval  SP_RESULT_INVALID_PARAM    Invaild input arguments
+ */
+static SPResult CalculateAclPermission(const char *temp_pms, uint16_t *pms)
+{
+    int i = 0;
+
+    if (NULL == temp_pms || NULL == pms)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    *pms = 0;
+    while (temp_pms[i] != '\0')
+    {
+        switch (temp_pms[i])
+        {
+            case 'C':
+                {
+                    *pms += CREATE;
+                    i++;
+                    break;
+                }
+            case 'R':
+                {
+                    *pms += READ;
+                    i++;
+                    break;
+                }
+            case 'U':
+                {
+                    *pms += UPDATE;
+                    i++;
+                    break;
+                }
+            case 'D':
+                {
+                    *pms += DELETE;
+                    i++;
+                    break;
+                }
+            case 'N':
+                {
+                    *pms += NOTIFY;
+                    i++;
+                    break;
+                }
+            case '_':
+                {
+                    i++;
+                    break;
+                }
+            default:
+                {
+                    return SP_RESULT_INVALID_PARAM;
+                }
+        }
+    }
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * Get the ACL property from user
+ *
+ * @param[in]    ACL Datastructure to save user inputs
+ * @return  0 on success otherwise a positive error value
+ * @retval  SP_RESULT_SUCCESS    Successful
+ * @retval  SP_RESULT_MEM_ALLOCATION_FAIL    Memmory allocation failure
+ */
+static SPResult InputACL(OicSecAcl_t *acl)
+{
+    int unused __attribute__((unused));
+    char temp_id [MAX_INPUT_ID_LENGTH + 4] = {0,};
+    char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
+    char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
+    printf("******************************************************************************\n");
+    printf("-Set ACL policy for target device\n");
+    printf("******************************************************************************\n");
+    //Set Subject.
+    printf("-URN identifying the subject\n");
+    printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
+    printf("Subject : ");
+    unused = scanf("%19s", temp_id);
+    int j = 0;
+    for (int i = 0; temp_id[i] != '\0'; i++)
+    {
+        if (DASH != temp_id[i])
+            acl->subject.id[j++] = temp_id[i];
+    }
+
+    //Set Resource.
+    printf("Num. of Resource : ");
+    unused = scanf("%zu", &acl->resourcesLen);
+    printf("-URI of resource\n");
+    printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
+    acl->resources = (char **)OICMalloc(acl->resourcesLen * sizeof(char *));
+    if (NULL == acl->resources)
+    {
+        OC_LOG(ERROR, TAG, "Error while memory allocation");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+    for (int i = 0; i < acl->resourcesLen; i++)
+    {
+        printf("[%d]Resource : ", i + 1);
+        unused = scanf("%64s", temp_rsc);
+        acl->resources[i] = (char *)OICMalloc((strlen(temp_rsc) + 1) * sizeof(char));
+        if (NULL == acl->resources[i])
+        {
+            OC_LOG(ERROR, TAG, "Error while memory allocation");
+            return SP_RESULT_MEM_ALLOCATION_FAIL;
+        }
+        strncpy(acl->resources[i], temp_rsc, strlen(temp_rsc));
+        acl->resources[i][strlen(temp_rsc)] = '\0';
+    }
+    // Set Permission
+    do
+    {
+        printf("-Set the permission(C,R,U,D,N)\n");
+        printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
+        printf("Permission : ");
+        unused = scanf("%5s", temp_pms);
+    }
+    while (SP_RESULT_SUCCESS != CalculateAclPermission(temp_pms, &(acl->permission)) );
+    // Set Rowner
+    printf("Num. of Rowner : ");
+    unused = scanf("%zu", &acl->ownersLen);
+    printf("-URN identifying the rowner\n");
+    printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
+    acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
+    if (NULL == acl->owners)
+    {
+        OC_LOG(ERROR, TAG, "Error while memory allocation");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+    for (int i = 0; i < acl->ownersLen; i++)
+    {
+        printf("[%d]Rowner : ", i + 1);
+        unused = scanf("%19s", temp_id);
+        j = 0;
+        for (int k = 0; temp_id[k] != '\0'; k++)
+        {
+            if (DASH != temp_id[k])
+            {
+                acl->owners[i].id[j++] = temp_id[k];
+            }
+        }
+    }
+    return SP_RESULT_SUCCESS;
+}
+
+FILE* client_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(PROV_TOOL_DB_FILE, mode);
+}
+
+/**
+ * Provisioning client sample using ProvisioningAPI on provisioningmanager.c
+ * To change network type use command line option -w for Wifi and -e for Ethernet
+ */
+int main(int argc, char **argv)
+{
+    SPResult res = SP_RESULT_SUCCESS;
+    SPTargetDeviceInfo_t *pDeviceList = NULL;
+    gAcl = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
+
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {};
+    ps.open = client_fopen;
+    ps.read = fread;
+    ps.write = fwrite;
+    ps.close = fclose;
+    ps.unlink = unlink;
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack init error");
+        return 0;
+    }
+
+    if (NULL == gAcl)
+    {
+        OC_LOG(ERROR, TAG, "Error while memory allocation");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+
+    res = SPProvisioningDiscovery(PREDEFINED_TIMEOUT, &pDeviceList);
+    if (SP_RESULT_SUCCESS == res)
+    {
+        while (pDeviceList != NULL)
+        {
+            printf("-Provisioning device ID : ");
+            for (int i = 0; i < MAX_INPUT_ID_LENGTH; i++)
+            {
+                if (pDeviceList->doxm->deviceID.id[i] == '\0')
+                {
+                     break;
+                }
+                printf("%c", pDeviceList->doxm->deviceID.id[i]);
+            }
+            printf("\n");
+            res = SPInitProvisionContext(PREDEFINED_TIMEOUT, pDeviceList);
+            if (SP_RESULT_SUCCESS != res)
+            {
+                OC_LOG(ERROR, TAG, "Error while init provisioning Context");
+                goto error;
+            }
+            res = InputACL(gAcl);
+            if (SP_RESULT_SUCCESS != res)
+            {
+                OC_LOG(ERROR, TAG, "Error while user ACL input ");
+                goto error;
+            }
+            res = SPProvisionACL(PREDEFINED_TIMEOUT, pDeviceList, gAcl);
+            if (SP_RESULT_SUCCESS != res)
+            {
+                OC_LOG(ERROR, TAG, "Error while provisioning ACL");
+                goto error;
+            }
+            res = SPFinalizeProvisioning(PREDEFINED_TIMEOUT, pDeviceList);
+            if (SP_RESULT_SUCCESS == res)
+            {
+                printf("Provisioning Success~!!\n");
+            }
+            else if (SP_RESULT_SUCCESS != res)
+            {
+                OC_LOG(ERROR, TAG, "Error while Finalize Provisioning");
+                goto error;
+            }
+            pDeviceList = pDeviceList->next;
+        }
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "Error while Provisioning Discovery");
+        goto error;
+    }
+
+error:
+    DeleteACLList(gAcl);
+    SPTerminateProvisioning();
+    return 0;
+}
diff --git a/resource/csdk/security/provisioning/src/credentialgenerator.c b/resource/csdk/security/provisioning/src/credentialgenerator.c
new file mode 100644 (file)
index 0000000..8e96518
--- /dev/null
@@ -0,0 +1,76 @@
+/* *****************************************************************
+ *
+ * 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 <string.h>
+
+#include "provisioningmanager.h"
+#include "credentialgenerator.h"
+#include "oic_malloc.h"
+#include "logger.h"
+#include "credresource.h"
+#include "ocrandom.h"
+#include "base64.h"
+#define TAG "SPProvisionAPI"
+#define KEY_LENGTH 16
+
+SPResult SPGeneratePairWiseCredentials(OicSecCredType_t type, const OicUuid_t *ptDeviceId,
+                                       const OicUuid_t *firstDeviceId,
+                                       const OicUuid_t *secondDeviceId,
+                                       OicSecCred_t **firstCred,
+                                       OicSecCred_t **secondCred)
+{
+
+    if (NULL == ptDeviceId || NULL == firstDeviceId || NULL == secondDeviceId)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    uint8_t privData[KEY_LENGTH] = {0,};
+    OCFillRandomMem(privData, KEY_LENGTH);
+
+    uint32_t outLen = 0;
+    char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(privData)) + 1] = {};
+    B64Result b64Ret = b64Encode(privData, sizeof(privData), base64Buff,
+                                sizeof(base64Buff), &outLen);
+    if (B64_OK != b64Ret)
+    {
+        OC_LOG(ERROR, TAG, "Error while encoding key");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    // TODO currently owner array is 1. only provisioning tool's id.
+    OicSecCred_t *tempFirstCred =  GenerateCredential(secondDeviceId, type, NULL, base64Buff, 1,
+                                   ptDeviceId);
+    if (NULL == tempFirstCred)
+    {
+        OC_LOG(ERROR, TAG, "Error while generating credential.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    // TODO currently owner array is 1. only provisioning tool's id.
+    OicSecCred_t *tempSecondCred =  GenerateCredential(firstDeviceId, type, NULL, base64Buff, 1,
+                                    ptDeviceId);
+    if (NULL == tempSecondCred)
+    {
+        DeleteCredList(tempFirstCred);
+        OC_LOG(ERROR, TAG, "Error while generating credential.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    *firstCred = tempFirstCred;
+    *secondCred = tempSecondCred;
+    return SP_RESULT_SUCCESS;
+}
diff --git a/resource/csdk/security/provisioning/src/provisioningmanager.c b/resource/csdk/security/provisioning/src/provisioningmanager.c
new file mode 100644 (file)
index 0000000..bcd5e4d
--- /dev/null
@@ -0,0 +1,1669 @@
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+
+// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1b, Real-time extensions
+// (IEEE Std 1003.1b-1993) specification
+//
+// For this specific file, see use of clock_gettime,
+// Refer to http://pubs.opengroup.org/stage7tc1/functions/clock_gettime.html
+// and to http://man7.org/linux/man-pages/man2/clock_gettime.2.html
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <stdbool.h>
+
+#include "cJSON.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "oic_malloc.h"
+#include "logger.h"
+#include "cacommon.h"
+#include "cainterface.h"
+#include "provisioningmanager.h"
+#include "credentialgenerator.h"
+#include "global.h"
+#include "base64.h"
+#include "aclresource.h"
+#include "doxmresource.h"
+#include "pstatresource.h"
+#include "srmresourcestrings.h"
+#include "credresource.h"
+#include "oic_string.h"
+#include "secureresourcemanager.h"
+
+typedef enum
+{
+    SP_NO_MASK                = (0       ),
+    SP_DISCOVERY_STARTED      = (0x1 << 1),
+    SP_DISCOVERY_ERROR        = (0x1 << 2),
+    SP_DISCOVERY_DONE         = (0x1 << 3),
+    SP_SEC_RES_INFO_STARTED   = (0x1 << 4),
+    SP_SEC_RES_INFO_ERROR     = (0x1 << 5),
+    SP_SEC_RES_INFO_DONE      = (0x1 << 6),
+    SP_UP_OWN_TR_METH_STARTED = (0x1 << 7),
+    SP_UP_OWN_TR_METH_ERROR   = (0x1 << 8),
+    SP_UP_OWN_TR_METH_DONE    = (0x1 << 9),
+    SP_LIST_METHODS_STARTED   = (0x1 << 10),
+    SP_LIST_METHODS_ERROR     = (0x1 << 11),
+    SP_LIST_METHODS_DONE      = (0x1 << 12),
+    SP_UPDATE_OP_MODE_STARTED = (0x1 << 13),
+    SP_UPDATE_OP_MODE_ERROR   = (0x1 << 14),
+    SP_UPDATE_OP_MODE_DONE    = (0x1 << 15),
+    SP_UPDATE_OWNER_STARTED   = (0x1 << 16),
+    SP_UPDATE_OWNER_ERROR     = (0x1 << 17),
+    SP_UPDATE_OWNER_DONE      = (0x1 << 18),
+    SP_PROV_ACL_STARTED       = (0x1 << 19),
+    SP_PROV_ACL_ERROR         = (0x1 << 20),
+    SP_PROV_ACL_DONE          = (0x1 << 21),
+    SP_UP_HASH_STARTED        = (0x1 << 22),
+    SP_UP_HASH_ERROR          = (0x1 << 23),
+    SP_UP_HASH_DONE           = (0x1 << 24),
+    SP_PROV_CRED_STARTED      = (0x1 << 25),
+    SP_PROV_CRED_ERROR        = (0x1 << 26),
+    SP_PROV_CRED_DONE         = (0x1 << 27)
+} SPProvisioningStates;
+
+#define SP_MAX_BUF_LEN 1024
+#define TAG "SPProvisionAPI"
+#define COAP_QUERY "coap://%s:%d%s"
+#define COAPS_QUERY "coaps://%s:%d%s"
+
+bool (*handler)(const CAEndpoint_t *, const CAResponseInfo_t *);
+
+/**
+ * CA token to keep track of response.
+ */
+static CAToken_t gToken = NULL;
+
+/**
+ * start pointer for discovered device linked list.
+ */
+static SPTargetDeviceInfo_t *gStartOfDiscoveredDevices = NULL;
+
+/**
+ * current pointer of device linked list.
+ */
+static SPTargetDeviceInfo_t *gCurrent = NULL;
+
+/**
+ * Variable to keep track of various request.
+ */
+static uint32_t gStateManager = 0;
+
+/**
+ * Variable for storing provisioning tool's provisioning capabilities
+ * Must be in decreasing order of preference. More prefered method should
+ * have lower array index.
+ */
+static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIVEN };
+
+/**
+ * Number of supported provisioning methods
+ * current version supports only one.
+ */
+static int gNumOfProvisioningMethodsPT = 1;
+
+/**
+ * Global variable to save pstat.
+ */
+static OicSecPstat_t *gPstat = NULL;
+
+/**
+ * Secure String copy function
+ * @param[in] destination  Pointer to destination string.
+ * @param[in] source       Pointer to source string.
+ * @return pointer to destination string, NULL in case of error.
+ */
+static inline char *SPStringCopy(char *destination, const char *source, size_t num)
+{
+    if (strncpy(destination, source, num))
+    {
+        destination[num - 1] = '\0';
+        return destination;
+    }
+    return NULL;
+}
+
+/**
+ * Function to convert CA result code to SP result code.
+ *
+ * @return result code of SP corresponding to that of CA.
+ */
+static SPResult convertCAResultToSPResult(CAResult_t caResult)
+{
+    switch (caResult)
+    {
+        case CA_STATUS_OK:
+            {
+                return SP_RESULT_SUCCESS;
+            }
+        case CA_STATUS_INVALID_PARAM:
+            {
+                return SP_RESULT_CONN_INVALID_PARAM;
+            }
+        case CA_ADAPTER_NOT_ENABLED:
+            {
+                return SP_RESULT_CONN_SERVER_STARTED_ALREADY;
+            }
+        case CA_SERVER_STARTED_ALREADY:
+            {
+                return SP_RESULT_CONN_SERVER_STARTED_ALREADY;
+            }
+        case CA_SERVER_NOT_STARTED:
+            {
+                return SP_RESULT_CONN_SERVER_NOT_STARTED;
+            }
+        case CA_DESTINATION_NOT_REACHABLE:
+            {
+                return SP_RESULT_CONN_DESTINATION_NOT_REACHABLE;
+            }
+        case CA_SOCKET_OPERATION_FAILED:
+            {
+                return SP_RESULT_CONN_SOCKET_OPERATION_FAILED;
+            }
+        case CA_SEND_FAILED:
+            {
+                return SP_RESULT_CONN_SEND_FAILED;
+            }
+        case CA_RECEIVE_FAILED:
+            {
+                return SP_RESULT_CONN_RECEIVE_FAILED;
+            }
+        case CA_MEMORY_ALLOC_FAILED:
+            {
+                return SP_RESULT_CONN_MEMORY_ALLOC_FAILED;
+            }
+        case CA_REQUEST_TIMEOUT:
+            {
+                return SP_RESULT_CONN_REQUEST_TIMEOUT;
+            }
+        case CA_DESTINATION_DISCONNECTED:
+            {
+                return SP_RESULT_CONN_DESTINATION_DISCONNECTED;
+            }
+        case CA_STATUS_FAILED:
+            {
+                return SP_RESULT_CONN_STATUS_FAILED;
+            }
+        case CA_NOT_SUPPORTED:
+            {
+                return SP_RESULT_CONN_NOT_SUPPORTED;
+            }
+        default:
+            {
+                return SP_RESULT_INTERNAL_ERROR;
+            }
+    }
+}
+
+/**
+ * Function to delete memory allocated to linked list.
+ *
+ */
+static void deleteList()
+{
+    SPTargetDeviceInfo_t *current = gStartOfDiscoveredDevices;
+
+    while (current)
+    {
+        SPTargetDeviceInfo_t *next = current->next;
+        DeleteDoxmBinData(current->doxm);
+        DeletePstatBinData(current->pstat);
+        OICFree(current);
+        current = next;
+    }
+    gStartOfDiscoveredDevices = NULL;
+}
+
+/**
+ * Timeout implementation.
+ * @param[in]  timeout  Timeout in seconds. with 0 it will wait forever for success.
+ * @param[in]  mask     Mask of operation and 0 for no mask.
+ * @return SP_RESULT_SUCCESS on success otherwise error.
+ */
+static SPResult SPTimeout(unsigned short timeout, uint32_t mask)
+{
+    struct timespec startTime = {};
+    struct timespec currTime  = {};
+
+    CAResult_t res = SP_RESULT_SUCCESS;
+#ifdef _POSIX_MONOTONIC_CLOCK
+    int clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime);
+#else
+    int clock_res = clock_gettime(CLOCK_REALTIME, &startTime);
+#endif
+    if (0 != clock_res)
+    {
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    while (CA_STATUS_OK == res)
+    {
+        res = CAHandleRequestResponse();
+#ifdef _POSIX_MONOTONIC_CLOCK
+        clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime);
+#else
+        clock_res = clock_gettime(CLOCK_REALTIME, &currTime);
+#endif
+        if (0 != clock_res)
+        {
+            return SP_RESULT_INTERNAL_ERROR;
+        }
+        long elapsed = (currTime.tv_sec - startTime.tv_sec);
+        if (SP_NO_MASK == mask)
+        {
+            if (elapsed > timeout)
+            {
+                return SP_RESULT_SUCCESS;
+            }
+        }
+        else
+        {
+            if (gStateManager & mask)
+            {
+                return SP_RESULT_SUCCESS;
+            }
+            if ((elapsed > timeout) && timeout)
+            {
+                return SP_RESULT_INTERNAL_ERROR;
+            }
+        }
+    }
+    return convertCAResultToSPResult(res);
+}
+
+/**
+ * Function to send request to resource server.
+ * @param[in] method          method to be used for sending rquest.
+ * @param[in] endpoint        endpoint address
+ * @param[in] secure          use secure connection
+ * @param[in] resourceUri     resourceUri token.
+ * @param[in] payload         Payload to be sent with data. NULL is case message
+ *                            doesn't have payload.
+ * @param[in] payloadLen      Size of data to be sent.
+ * @return  CA_STATUS_OK on success, otherwise error code.
+ */
+static CAResult_t sendCARequest(CAMethod_t method,
+                                const OCDevAddr *devAddr,
+                                OCTransportFlags secure,
+                                const char *resourceUri,
+                                char *payload, int payloadLen)
+{
+    if (payload && '\0' != (*(payload + payloadLen)))
+    {
+        OC_LOG(ERROR, TAG, "Payload not properly terminated.");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (CA_STATUS_OK != CAGenerateToken(&gToken, CA_MAX_TOKEN_LEN))
+    {
+        OC_LOG(ERROR, TAG, "Error while generating token");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    CAEndpoint_t *endpoint = NULL;
+    if (CA_STATUS_OK != CACreateEndpoint(devAddr->flags | (CATransportFlags_t)secure,
+                                         devAddr->adapter, devAddr->addr,
+                                         devAddr->port, &endpoint))
+    {
+        OC_LOG(ERROR, TAG, "Failed to create remote endpoint");
+        CADestroyEndpoint(endpoint);
+        return CA_STATUS_FAILED;
+    }
+
+    OCSecurityPayload secPayload = {};
+    secPayload.securityData = payload;
+    secPayload.base.type = PAYLOAD_TYPE_SECURITY;
+
+    CARequestInfo_t requestInfo = {};
+    requestInfo.method = method;
+    requestInfo.isMulticast = false;
+    OCConvertPayload((OCPayload*)(&secPayload), &requestInfo.info.payload,
+            &requestInfo.info.payloadSize);
+
+    requestInfo.info.type = CA_MSG_CONFIRM;
+    requestInfo.info.token = gToken;
+    requestInfo.info.tokenLength  = CA_MAX_TOKEN_LEN;
+    requestInfo.info.resourceUri  = (CAURI_t)resourceUri;
+
+    CAResult_t caResult = CA_STATUS_OK;
+    caResult = CASendRequest(endpoint, &requestInfo);
+    if (CA_STATUS_OK != caResult)
+    {
+        OC_LOG(ERROR, TAG, "Send Request Error !!");
+    }
+    CADestroyEndpoint(endpoint);
+    return caResult;
+}
+
+/**
+ * addDevice to list.
+ *
+ * @param[in] endpoint   Endpoint information
+ * @param[in] doxm   pointer to doxm instance.
+ * @return SP_RESULT_SUCCESS for success and errorcode otherwise.
+ */
+static SPResult addDevice(const CAEndpoint_t *endpoint, OicSecDoxm_t* doxm)
+{
+    if (NULL == endpoint)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    SPTargetDeviceInfo_t *ptr = (SPTargetDeviceInfo_t *)OICCalloc(1, sizeof (SPTargetDeviceInfo_t));
+    if (NULL == ptr)
+    {
+        OC_LOG(ERROR, TAG, "Error while allocating memory for linkedlist node !!");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+
+    memcpy(&(ptr->endpoint), endpoint, sizeof(CAEndpoint_t));
+    ptr->doxm = doxm;
+
+    ptr->next = NULL;
+
+    if (NULL == gStartOfDiscoveredDevices)
+    {
+        gStartOfDiscoveredDevices = ptr;
+        gCurrent = ptr;
+    }
+    else
+    {
+        gCurrent->next = ptr;
+        gCurrent = ptr;
+    }
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * updateDevice to update resource info for the endpoint.
+ *
+ * @param[in] endpoint   Endpoint information
+ * @param[in] port   secure port.
+ * @return SP_RESULT_SUCCESS for success and errorcode otherwise.
+ */
+
+static SPResult updateDevice(const CAEndpoint_t *endpoint, uint16_t port)
+{
+    if (NULL == endpoint)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    SPTargetDeviceInfo_t *ptr = gStartOfDiscoveredDevices;
+    while(ptr)
+    {
+        if(0 == strcmp(ptr->endpoint.addr, endpoint->addr) &&
+                ptr->endpoint.port == endpoint->port)
+        {
+            ptr->securePort = port;
+            return SP_RESULT_SUCCESS;
+        }
+        ptr = ptr->next;
+    }
+    return SP_RESULT_INTERNAL_ERROR;
+}
+
+/**
+ * Function to provide timeframe in which response can be received.
+ *
+ * @param[in]  timeout   Timeout in seconds.
+ * @return  SP_RESULT_SUCCESS on success , otherwise error code.
+ */
+static SPResult SPWaitForResponse(unsigned short timeout)
+{
+    return SPTimeout(timeout, SP_NO_MASK);
+}
+
+/**
+ * Function to select appropriate  provisioning method.
+ *
+ * @param[in]   supportedMethodsList   List of supported methods
+ * @param[out]  selectedMethod         Selected methods
+ * @return  SP_SUCCESS on success
+ */
+static SPResult selectProvisioningMethod(OicSecOxm_t *supportedMethods, size_t numberOfMethods,
+        OicSecOxm_t *selectedMethod)
+{
+    /*
+     TODO Logic to find appropiate method and assign it to out param
+     for beachhead release method at index 0 will be returned.
+     */
+    *selectedMethod = supportedMethods[0];
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * Response handler for discovery.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool ProvisionDiscoveryHandler(const CAEndpoint_t *object,
+                                      const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_DISCOVERY_STARTED) && gToken)
+    {
+        // Response handler for discovery.
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            OC_LOG(INFO, TAG, "Inside ProvisionDiscoveryHandler.");
+            if (NULL == responseInfo->info.payload)
+            {
+                OC_LOG(INFO, TAG, "Skiping Null payload");
+            }
+            else
+            {
+                OCPayload* payload = NULL;
+                OCStackResult result = OCParsePayload(&payload, responseInfo->info.payload,
+                        responseInfo->info.payloadSize);
+
+                OicSecDoxm_t *ptrDoxm = NULL;
+
+                if(result == OC_STACK_OK && payload->type == PAYLOAD_TYPE_SECURITY)
+                {
+                    ptrDoxm = JSONToDoxmBin(((OCSecurityPayload*)payload)->securityData);
+                }
+
+                OCPayloadDestroy(payload);
+
+                if (NULL == ptrDoxm)
+                {
+                    OC_LOG(INFO, TAG, "Ignoring malformed JSON");
+                }
+                else
+                {
+                    OC_LOG(DEBUG, TAG, "Successfully converted doxm json to bin.");
+
+                    SPResult res = addDevice(object, ptrDoxm);
+                    if (SP_RESULT_SUCCESS != res)
+                    {
+                        OC_LOG(ERROR, TAG, "Error while adding data to linkedlist.");
+                        gStateManager = gStateManager | SP_DISCOVERY_ERROR;
+                        DeleteDoxmBinData(ptrDoxm);
+                        return true;
+                    }
+                    OC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
+                    gStateManager |= SP_DISCOVERY_DONE;
+                }
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for discovery.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+
+static bool ProvisionSecureResourceInfoHandler(const CAEndpoint_t *object,
+                                      const CAResponseInfo_t *responseInfo)
+{
+    if (!object || !responseInfo)
+    {
+        return false;
+    }
+
+    if ((gStateManager & SP_SEC_RES_INFO_STARTED) && gToken)
+    {
+        // Response handler for discovery.
+        if (0 == memcmp(gToken, responseInfo->info.token, CA_MAX_TOKEN_LEN))
+        {
+            OC_LOG(INFO, TAG, "Inside ProvisionSecureResourceInfoHandler.");
+            if (NULL == responseInfo->info.payload)
+            {
+                OC_LOG(ERROR, TAG, "Exiting ProvisionSecureResourceInfoHandler.");
+                gStateManager |= SP_SEC_RES_INFO_ERROR;
+            }
+            else
+            {
+                OCPayload* payload = NULL;
+                OCStackResult result = OCParsePayload(&payload, responseInfo->info.payload,
+                        responseInfo->info.payloadSize);
+
+                OCDiscoveryPayload* discover = (OCDiscoveryPayload*) payload;
+                // Discovered secure resource payload contains secure port; update the device
+                // with the secure port using endpoint.
+                if (result == OC_STACK_OK && discover)
+                {
+                    if (updateDevice(object, discover->resources->port) == SP_RESULT_SUCCESS)
+                    {
+                        gStateManager |= SP_SEC_RES_INFO_DONE;
+                    }
+                    else
+                    {
+                        gStateManager |= SP_SEC_RES_INFO_ERROR;
+                    }
+                    OC_LOG(INFO, TAG, "Exiting ProvisionSecureResourceInfoHandler.");
+                }
+
+                OCPayloadDestroy(payload);
+            }
+            return true;
+        }
+        else
+        {
+            OC_LOG(ERROR, TAG, "Error in ProvisionSecureResourceInfoHandler.");
+            gStateManager |= SP_SEC_RES_INFO_ERROR;
+            return false;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler ownership transfer.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool OwnerShipTransferModeHandler(const CAEndpoint_t *object,
+        const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_UP_OWN_TR_METH_STARTED) && gToken)
+    {
+        // response handler for ownership tranfer
+        OC_LOG(INFO, TAG, "Inside OwnerShipTransferModeHandler.");
+        if (memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength) == 0)
+        {
+            OC_LOG_V(DEBUG, TAG, "Response result for OwnerShipTransferMode: %d", responseInfo->result);
+            if (CA_SUCCESS == responseInfo->result)
+            {
+                gStateManager |= SP_UP_OWN_TR_METH_DONE;
+                OC_LOG(INFO, TAG, "Exiting OwnerShipTransferModeHandler.");
+            }
+            else
+            {
+                gStateManager |= SP_UP_OWN_TR_METH_ERROR;
+                OC_LOG(ERROR, TAG, "Error in OwnerShipTransferModeHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler list methods.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool ListMethodsHandler(const CAEndpoint_t *object,
+                               const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_LIST_METHODS_STARTED) && gToken)
+    {
+        OC_LOG(INFO, TAG, "Inside ListMethodsHandler.");
+        if (memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength) == 0)
+        {
+            OC_LOG_V(DEBUG, TAG, "Response result for ListMethodsHandler: %d", responseInfo->result);
+            if (CA_SUCCESS == responseInfo->result)
+            {
+                OC_LOG_V (DEBUG, TAG, "Response Payload: %s", responseInfo->info.payload);
+                // Temp logic to trim oc attribute from json
+                // JSONToPstatBin should handle OC in JSON.
+                if (NULL == responseInfo->info.payload)
+                {
+                    OC_LOG(ERROR, TAG, "response payload is null.");
+                    gStateManager |= SP_LIST_METHODS_ERROR;
+                    return true;
+                }
+
+                OCPayload* payload = NULL;
+                OCStackResult result = OCParsePayload(&payload, responseInfo->info.payload,
+                        responseInfo->info.payloadSize);
+
+                OicSecPstat_t *pstat = NULL;
+
+                if(result == OC_STACK_OK && payload->type == PAYLOAD_TYPE_SECURITY)
+                {
+                    pstat =  JSONToPstatBin(((OCSecurityPayload*)payload)->securityData);
+                }
+
+                OCPayloadDestroy(payload);
+
+                if (NULL == pstat)
+                {
+                    OC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
+                    gStateManager |= SP_LIST_METHODS_ERROR;
+                    return true;
+                }
+                DeletePstatBinData(gPstat);
+
+                gPstat = pstat;
+                gStateManager |= SP_LIST_METHODS_DONE;
+
+                OC_LOG(INFO, TAG, "Exiting ListMethodsHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for update operation mode.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool OperationModeUpdateHandler(const CAEndpoint_t *object,
+                                       const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_UPDATE_OP_MODE_STARTED) && gToken)
+    {
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            OC_LOG(INFO, TAG, "Inside OperationModeUpdateHandler.");
+            OC_LOG_V(DEBUG, TAG, "Response result for OperationModeUpdateHandler: %d", responseInfo->result);
+            if (CA_SUCCESS == responseInfo->result)
+            {
+                gStateManager |= SP_UPDATE_OP_MODE_DONE;
+                OC_LOG(INFO, TAG, "Exiting OperationModeUpdateHandler.");
+            }
+            else
+            {
+                gStateManager |= SP_UPDATE_OP_MODE_ERROR;
+                OC_LOG(ERROR, TAG, "Error in OperationModeUpdateHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for ownership transfer.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool OwnerShipUpdateHandler(const CAEndpoint_t *object,
+                                   const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_UPDATE_OWNER_STARTED) && gToken)
+    {
+        // response handler for ownership tranfer
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            OC_LOG(INFO, TAG, "Inside OwnerShipUpdateHandler.");
+            OC_LOG_V(DEBUG, TAG, "Response result for OwnerShipUpdateHandler: %d", responseInfo->result);
+            if (CA_SUCCESS == responseInfo->result)
+            {
+                gStateManager |= SP_UPDATE_OWNER_DONE;
+                OC_LOG(INFO, TAG, "Exiting OwnerShipUpdateHandler.");
+            }
+            else
+            {
+                gStateManager |= SP_UPDATE_OWNER_ERROR;
+                OC_LOG(ERROR, TAG, "Error in OwnerShipUpdateHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for ACL provisioning.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool ACLProvisioningHandler(const CAEndpoint_t *object,
+                                   const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_PROV_ACL_STARTED) && gToken)
+    {
+
+        // response handler for ACL provisioning.
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            OC_LOG(INFO, TAG, "Inside ACLProvisioningHandler.");
+            OC_LOG_V(DEBUG, TAG, "Response result for ACLProvisioningHandler: %d", responseInfo->result);
+            if (CA_CREATED == responseInfo->result)
+            {
+                OC_LOG(INFO, TAG, "Exiting ACLProvisioningHandler.");
+                gStateManager |= SP_PROV_ACL_DONE;
+            }
+            else
+            {
+                OC_LOG(ERROR, TAG, "Error in ACLProvisioningHandler.");
+                gStateManager |= SP_PROV_ACL_ERROR;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for provisioning finalization.
+ *
+ * @param[in] object       Remote endpoint object
+ * @param[in] requestInfo  Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool FinalizeProvisioningHandler(const CAEndpoint_t *object,
+                                        const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_UP_HASH_STARTED) && gToken)
+    {
+        // response handler for finalize provisioning.
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            OC_LOG(INFO, TAG, "Inside FinalizeProvisioningHandler.");
+            OC_LOG_V(DEBUG, TAG, "Response result for FinalizeProvisioningHandler: %d", responseInfo->result);
+            if (CA_SUCCESS == responseInfo->result)
+            {
+                gStateManager |= SP_UP_HASH_DONE;
+                OC_LOG(INFO, TAG, "Exiting FinalizeProvisioningHandler.");
+            }
+            else
+            {
+                gStateManager |= SP_UP_HASH_ERROR;
+                OC_LOG(ERROR, TAG, "Error in FinalizeProvisioningHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response handler for Credential provisioning.
+ *
+ * @param[in] object        Remote endpoint object
+ * @param[in] requestInfo   Datastructure containing request information.
+ * @return true is CA token matches request token, false otherwise.
+ */
+static bool CredProvisioningHandler(const CAEndpoint_t *object,
+                                    const CAResponseInfo_t *responseInfo)
+{
+    if ((gStateManager & SP_PROV_CRED_STARTED) && gToken)
+    {
+        // response handler for CRED provisioning.
+        OC_LOG(INFO, TAG, "Inside CredProvisioningHandler.");
+        OC_LOG_V(DEBUG, TAG, "Response result for CredProvisioningHandler: %d", responseInfo->result);
+        if (0 == memcmp(gToken, responseInfo->info.token, responseInfo->info.tokenLength))
+        {
+            if (CA_CREATED == responseInfo->result)
+            {
+                gStateManager |= SP_PROV_CRED_DONE;
+                OC_LOG(INFO, TAG, "Exiting CredProvisioningHandler.");
+            }
+            else
+            {
+                gStateManager |= SP_PROV_CRED_ERROR;
+                OC_LOG(ERROR, TAG, "Error in CredProvisioningHandler.");
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Response Handler
+ *
+ * @param[in] object        Remote endpoint object
+ * @param[in] responseInfo  Datastructure containing response information.
+ * @return true if received response is for provisioning API false otherwise.
+ */
+static bool SPResponseHandler(const CAEndpoint_t *object,
+                              const CAResponseInfo_t *responseInfo)
+{
+    bool isProvResponse = false;
+    if ((NULL != responseInfo) && (NULL != responseInfo->info.token))
+    {
+        isProvResponse = handler(object, responseInfo);
+    }
+    return isProvResponse;
+}
+
+/**
+ * Function to find the resources using multicast discovery.
+ *
+ * @param[in]   timeout     timeout in secs
+ * @return  SP_RESULT_SUCCESS normally otherwise error code.
+ */
+static SPResult findResource(unsigned short timeout)
+{
+    static char DOXM_OWNED_FALSE_MULTICAST_QUERY[] = "/oic/sec/doxm?Owned=FALSE";
+    CAResult_t res = CAGenerateToken(&gToken, CA_MAX_TOKEN_LEN);
+    if (CA_STATUS_OK != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while generating token.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    CAEndpoint_t endpoint = {};
+
+    // Only IP is supported currently for provisioning and ownership transfer
+    endpoint.adapter = CA_ADAPTER_IP;
+    endpoint.flags   = CA_IPV4 | CA_IPV6 | CA_SCOPE_LINK;
+
+    CAMessageType_t msgType = CA_MSG_NONCONFIRM;
+    CAInfo_t requestData = { 0 };
+    requestData.token = gToken;
+    requestData.tokenLength  = CA_MAX_TOKEN_LEN;
+    requestData.payload = NULL;
+    requestData.payloadSize = 0;
+    requestData.type = msgType;
+    requestData.resourceUri = DOXM_OWNED_FALSE_MULTICAST_QUERY;
+    CARequestInfo_t requestInfo = { 0 };
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+    requestInfo.isMulticast = true;
+    res = CASendRequest(&endpoint, &requestInfo);
+
+    handler = &ProvisionDiscoveryHandler;
+    gStateManager |= SP_DISCOVERY_STARTED;
+    if (CA_STATUS_OK != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while finding resource.");
+        return convertCAResultToSPResult(res);
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Discovery Request sent successfully");
+    }
+    return SPWaitForResponse(timeout);
+}
+
+/**
+ * Function to get the secure resource info.
+ *
+ * @param[in]   devAddr     Device address for the destination
+ * @param[in]   timeout     timeout in secs
+ * @return  SP_RESULT_SUCCESS normally otherwise error code.
+ */
+static SPResult getSecureResourceInfo(OCDevAddr *devAddr, unsigned short timeout)
+{
+    char OIC_UNICAST_SEC_QUERY[] = "/oic/res?rt=oic.sec.doxm";
+    CAResult_t res = CAGenerateToken(&gToken, CA_MAX_TOKEN_LEN);
+    if (CA_STATUS_OK != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while generating token.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    CAInfo_t requestData = {};
+    requestData.token = gToken;
+    requestData.tokenLength  = CA_MAX_TOKEN_LEN;
+    requestData.payload = NULL;
+    requestData.payloadSize = 0;
+    requestData.type = CA_MSG_NONCONFIRM;
+    requestData.resourceUri = OIC_UNICAST_SEC_QUERY;
+    CARequestInfo_t requestInfo = { 0 };
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
+    handler = &ProvisionSecureResourceInfoHandler;
+    res = CASendRequest((CAEndpoint_t*)devAddr, &requestInfo);
+
+    gStateManager |= SP_SEC_RES_INFO_STARTED;
+    if (CA_STATUS_OK != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while finding secure resource.");
+        return convertCAResultToSPResult(res);
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Secure resource info request sent successfully");
+    }
+    return SPWaitForResponse(timeout);
+}
+
+/**
+ * Function to update the operation mode. As per the spec. Operation mode in client driven
+ * single service provisioning it will be updated to 0x3
+ *
+ * @param[in]  timeout     timeout for operation.
+ * @param[in]  deviceInfo  Device Info.
+ * @return  SP_SUCCESS on success
+ */
+static SPResult updateOwnerTransferModeToResource(unsigned short timeout,
+        SPTargetDeviceInfo_t *deviceInfo, OicSecOxm_t selectedMethod)
+{
+    SPResult res = SP_RESULT_INTERNAL_ERROR;
+
+    deviceInfo->doxm->oxmSel = selectedMethod;
+    char *payload = BinToDoxmJSON(deviceInfo->doxm);
+    if (NULL == payload)
+    {
+        OC_LOG(ERROR, TAG, "Error while converting bin to json");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    OC_LOG_V(DEBUG, TAG, "Payload: %s", payload);
+    int payloadLen = strlen(payload);
+
+    handler = &OwnerShipTransferModeHandler;
+    gStateManager |= SP_UP_OWN_TR_METH_STARTED;
+
+    CAResult_t result = sendCARequest(CA_PUT,
+                                      &deviceInfo->endpoint,
+                                      OC_DEFAULT_FLAGS,
+                                      OIC_RSRC_DOXM_URI,
+                                      payload, payloadLen);
+    OICFree(payload);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Error while sending request.");
+        CADestroyToken(gToken);
+        return convertCAResultToSPResult(result);
+    }
+    res = SPTimeout(timeout, SP_UP_OWN_TR_METH_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        return SP_RESULT_TIMEOUT;
+    }
+    CADestroyToken(gToken);
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * Function to send request to resource to get its pstat resource information.
+ *
+ * @param[in]  timeout     timeout for operation.
+ * @param[in]  deviceInfo  Device Info.
+ * @return  SP_SUCCESS on success
+ */
+static SPResult getProvisioningStatusResource(unsigned short timeout,
+                                              SPTargetDeviceInfo_t *deviceInfo)
+{
+    handler = &ListMethodsHandler;
+    gStateManager |= SP_LIST_METHODS_STARTED;
+
+    CAResult_t result = sendCARequest(CA_GET,
+                                      &deviceInfo->endpoint,
+                                      OC_DEFAULT_FLAGS,
+                                      OIC_RSRC_PSTAT_URI,
+                                      NULL, 0);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Failure while sending request.");
+        CADestroyToken(gToken);
+        return convertCAResultToSPResult(result);
+    }
+    SPResult res = SPTimeout(timeout, SP_LIST_METHODS_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Timeout while getting method list.");
+        CADestroyToken(gToken);
+        return SP_RESULT_TIMEOUT;
+    }
+    if (gStateManager && SP_LIST_METHODS_DONE)
+    {
+        deviceInfo->pstat = gPstat;
+        CADestroyToken(gToken);
+        OC_LOG(DEBUG, TAG, "getProvisioningStatusResource completed.");
+        return SP_RESULT_SUCCESS;
+    }
+    CADestroyToken(gToken);
+    return SP_RESULT_INTERNAL_ERROR;
+}
+
+/**
+ * Function to update the operation mode. As per the spec. Operation mode in client driven
+ * single service provisioning it will be updated to 0x3
+ *
+ * @param[in]  timeout     timeout for operation.
+ * @param[in]  deviceInfo  Device Info.
+ * @return  SP_SUCCESS on success
+ */
+static SPResult updateOperationMode(unsigned short timeout,
+                                    SPTargetDeviceInfo_t *deviceInfo,
+                                    OicSecDpom_t selectedOperationMode)
+{
+
+    SPResult res = SP_RESULT_INTERNAL_ERROR;
+
+    deviceInfo->pstat->om = selectedOperationMode;
+
+    char *payloadBuffer = BinToPstatJSON(deviceInfo->pstat);
+    if (NULL == payloadBuffer)
+    {
+        OC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    size_t payloadLen = strlen(payloadBuffer);
+    handler = &OperationModeUpdateHandler;
+    gStateManager |= SP_UPDATE_OP_MODE_STARTED;
+
+    CAResult_t result = sendCARequest(CA_PUT,
+                                      &deviceInfo->endpoint,
+                                      OC_DEFAULT_FLAGS,
+                                      OIC_RSRC_PSTAT_URI,
+                                      payloadBuffer, payloadLen);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Error while sending request.");
+        CADestroyToken(gToken);
+        OICFree(payloadBuffer);
+        return convertCAResultToSPResult(result);
+    }
+    res = SPTimeout(timeout, SP_UPDATE_OP_MODE_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        OICFree(payloadBuffer);
+        return SP_RESULT_TIMEOUT;
+    }
+    CADestroyToken(gToken);
+    OICFree(payloadBuffer);
+
+    if (gStateManager & SP_UPDATE_OP_MODE_DONE)
+    {
+        return SP_RESULT_SUCCESS;
+    }
+    return SP_RESULT_INTERNAL_ERROR;
+}
+
+/**
+ * Function to initiate DTLS handshake.
+ *
+ * @param[in]  deviceInfo  Provisioning context
+ * @return SP_SUCCESS on success
+ */
+static SPResult initiateDtlsHandshake(const CAEndpoint_t *endpoint)
+{
+    CAResult_t caresult = CAEnableAnonECDHCipherSuite(true);
+    if (CA_STATUS_OK != caresult)
+    {
+        OC_LOG_V(ERROR, TAG, "Unable to enable anon cipher suite");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    OC_LOG(INFO, TAG, "Anonymous cipher suite Enabled.");
+
+    caresult = CAInitiateHandshake(endpoint);
+    if (CA_STATUS_OK != caresult)
+    {
+        OC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
+    }
+
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * Function to send ownerShip info. This function would update Owned as true and
+ * owner as UUID for provisioning tool
+ *
+ * @param[in]  timeout     timeout value for the operation.
+ * @param[in]  deviceInfo  provisioning context.
+ * @return  SP_SUCCESS on success
+ */
+static SPResult sendOwnershipInfo(unsigned short timeout,
+                                  SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    OicUuid_t provTooldeviceID = {};
+
+    if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
+    {
+        OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    memcpy(selectedDeviceInfo->doxm->owner.id, provTooldeviceID.id , UUID_LENGTH);
+
+    selectedDeviceInfo->doxm->owned = true;
+
+    char *payloadBuffer =  BinToDoxmJSON(selectedDeviceInfo->doxm);
+    if (NULL == payloadBuffer)
+    {
+        OC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    int payloadLen = strlen(payloadBuffer);
+
+    handler = &OwnerShipUpdateHandler;
+    gStateManager |= SP_UPDATE_OWNER_STARTED;
+
+    CAResult_t result = sendCARequest(CA_PUT,
+                                      &selectedDeviceInfo->endpoint,
+                                      OC_FLAG_SECURE,
+                                      OIC_RSRC_DOXM_URI,
+                                      payloadBuffer, payloadLen);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Error while sending request.");
+        CADestroyToken(gToken);
+        OICFree(payloadBuffer);
+        return convertCAResultToSPResult(result);
+    }
+    SPResult res = SPTimeout(timeout, SP_UPDATE_OWNER_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        OICFree(payloadBuffer);
+        return SP_RESULT_TIMEOUT;
+    }
+    CADestroyToken(gToken);
+    OICFree(payloadBuffer);
+    return SP_RESULT_SUCCESS;
+}
+
+/**
+ * Function to save ownerPSK at provisioning tool end.
+ *
+ * @return  SP_SUCCESS on success
+ */
+static SPResult saveOwnerPSK(SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    SPResult result = SP_RESULT_INTERNAL_ERROR;
+
+    CAEndpoint_t endpoint = {};
+    OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
+    endpoint.port = selectedDeviceInfo->securePort;
+
+    OicUuid_t provTooldeviceID = {};
+    if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
+    {
+        OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+        return result;
+    }
+
+    uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
+
+    //Generating OwnerPSK
+    CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
+            (uint8_t *)OXM_JUST_WORKS, strlen(OXM_JUST_WORKS), provTooldeviceID.id,
+            sizeof(provTooldeviceID.id), selectedDeviceInfo->doxm->deviceID.id,
+            sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK,
+            OWNER_PSK_LENGTH_128);
+
+    if (CA_STATUS_OK == pskRet)
+    {
+        OC_LOG(INFO, TAG,"ownerPSK dump:\n");
+        OC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
+        //Generating new credential for provisioning tool
+        size_t ownLen = 1;
+        uint32_t outLen = 0;
+
+        char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
+        B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
+                &outLen);
+        if (B64_OK == b64Ret)
+        {
+            OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
+                    SYMMETRIC_PAIR_WISE_KEY, NULL,
+                    base64Buff, ownLen, &provTooldeviceID);
+            if (cred)
+            {
+                //Update the SVR database.
+                if (OC_STACK_OK == AddCredential(cred))
+                {
+                    result = SP_RESULT_SUCCESS;
+                }
+                else
+                {
+                    OC_LOG(ERROR, TAG, "AddCredential failed");
+                }
+            }
+            else
+            {
+                OC_LOG(ERROR, TAG, "GenerateCredential failed");
+            }
+        }
+        else
+        {
+            OC_LOG(ERROR, TAG, "b64Encode failed");
+        }
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
+    }
+    return result;
+}
+
+/**
+ * Function to select operation mode.This function will return most secure common operation mode.
+ *
+ * @param[out]   selectedMode   selected operation mode
+ * @return  SP_SUCCESS on success
+ */
+static void selectOperationMode(const SPTargetDeviceInfo_t *selectedDeviceInfo,
+                                OicSecDpom_t **selectedMode)
+{
+    int i = 0;
+    int j = 0;
+    while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
+    {
+        if (gProvisioningToolCapability[i] < selectedDeviceInfo->pstat->sm[j])
+        {
+            i++;
+        }
+        else if (selectedDeviceInfo->pstat->sm[j] < gProvisioningToolCapability[i])
+        {
+            j++;
+        }
+        else /* if gProvisioningToolCapability[i] == deviceSupportedMethods[j] */
+        {
+            *selectedMode = &(gProvisioningToolCapability[j]);
+            break;
+        }
+    }
+}
+
+/**
+ * Function to perform onwership tranfer based to ownership transfer mode.
+ *
+ * @param[in]  timeout            timeout in secs to perform operation. 0 timeout means
+                                  function will wait forever.
+ * @param[in]  selectedDeviceInfo instance of SPTargetDeviceInfo_t structure.
+ * @return  SP_SUCCESS on success
+ */
+static SPResult doOwnerShipTransfer(unsigned short timeout,
+                                    SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    OicSecDpom_t *selectedOperationMode = NULL;
+    selectOperationMode(selectedDeviceInfo, &selectedOperationMode);
+
+    SPResult res = updateOperationMode(timeout, selectedDeviceInfo, *selectedOperationMode);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while updating operation mode.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    if (*selectedOperationMode == SINGLE_SERVICE_CLIENT_DRIVEN)
+    {
+        CAEndpoint_t endpoint = {0};
+        OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
+        endpoint.port = selectedDeviceInfo->securePort;
+
+        res = initiateDtlsHandshake(&endpoint);
+        if (SP_RESULT_SUCCESS == res)
+        {
+            selectedDeviceInfo->endpoint.port = selectedDeviceInfo->securePort;
+            res = sendOwnershipInfo(timeout, selectedDeviceInfo);
+            if (SP_RESULT_SUCCESS != res)
+            {
+                OC_LOG(ERROR, TAG, "Error while updating ownership information.");
+            }
+            res = saveOwnerPSK(selectedDeviceInfo);
+
+            //Close temporal DTLS session
+            if(CA_STATUS_OK != CACloseDtlsSession(&endpoint))
+            {
+                OC_LOG(WARNING, TAG, "doOwnerShipTransfer() : failed to close the dtls session");
+            }
+        }
+        else
+        {
+            OC_LOG(ERROR, TAG, "Error during initiating DTLS handshake.");
+        }
+
+        //Disable Anonymous ECDH cipher suite before leaving this method
+        if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
+        {
+            OC_LOG(WARNING, TAG, "doOwnerShipTransfer() : failed to disable Anon ECDH cipher suite");
+        }
+    }
+    return (res != SP_RESULT_SUCCESS) ? SP_RESULT_INTERNAL_ERROR : SP_RESULT_SUCCESS;
+
+}
+/**
+ * The function is responsible for discovering secure resources(such as, /oic/sec/doxm etc) with
+ * OC_EXPLICIT_DISCOVERABLE on a OIC device which needs to be provisioned.
+ *
+ * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
+ *                    client before returning the list of devices.
+ * @param[in] selectedDeviceInfo Device information.
+ * @return SP_SUCCESS in case of success and other value otherwise.
+ */
+static SPResult discoverSecureResource(unsigned short timeout,
+        SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    if (NULL == selectedDeviceInfo)
+    {
+        OC_LOG(ERROR, TAG, "List is not null can cause memory leak");
+        return SP_RESULT_INVALID_PARAM;
+    }
+    SPResult smResponse = SP_RESULT_SUCCESS;
+    smResponse = getSecureResourceInfo(&selectedDeviceInfo->endpoint, timeout);
+    if (SP_RESULT_SUCCESS != smResponse)
+    {
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    if (gStateManager & SP_SEC_RES_INFO_DONE)
+    {
+        if (gStateManager & SP_SEC_RES_INFO_ERROR)
+        {
+            return SP_RESULT_INTERNAL_ERROR;
+        }
+        return SP_RESULT_SUCCESS;
+    }
+    return SP_RESULT_INTERNAL_ERROR;
+}
+
+/**
+ * Function to provision credentials to specific device.
+ *
+ * @param[in] timeout     timeout in secs to perform operation. 0 timeout means function will
+                          wait till success.
+ * @param[in] cred        credential to be provisioned.
+ * @param[in] deviceInfo  Instance of SPDevInfo_t structure. Representing a selected device for
+                          provisioning.
+ * @return  SP_SUCCESS on success
+ */
+SPResult provisionCredentials(unsigned short timeout, const OicSecCred_t *cred,
+                              const SPDevInfo_t *deviceInfo)
+{
+    char *credJson = NULL;
+    credJson = BinToCredJSON(cred);
+    if (NULL == credJson)
+    {
+        OC_LOG(ERROR, TAG, "Memory allocation problem");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+
+    int payloadLen = strlen(credJson);
+    handler = &CredProvisioningHandler;
+    gStateManager |= SP_PROV_CRED_STARTED;
+
+    CAResult_t result = sendCARequest(CA_POST,
+                                      &deviceInfo->endpoint,
+                                      OC_FLAG_SECURE,
+                                      OIC_RSRC_CRED_URI,
+                                      credJson, payloadLen);
+    OICFree(credJson);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error while sending Credentials.");
+        CADestroyToken(gToken);
+        return convertCAResultToSPResult(result);
+    }
+
+    SPResult res = SPTimeout(timeout, SP_PROV_CRED_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        return SP_RESULT_TIMEOUT;
+    }
+    CADestroyToken(gToken);
+    gStateManager = 0;
+    return res;
+}
+
+SPResult SPProvisioningDiscovery(unsigned short timeout,
+                                 SPTargetDeviceInfo_t **list)
+{
+    if (NULL != *list)
+    {
+        OC_LOG(ERROR, TAG, "List is not null can cause memory leak");
+        return SP_RESULT_INVALID_PARAM;
+    }
+    SRMRegisterProvisioningResponseHandler(SPResponseHandler);
+    SPResult smResponse = SP_RESULT_SUCCESS;
+    smResponse = findResource(timeout);
+    if (SP_RESULT_SUCCESS != smResponse)
+    {
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    if (gStateManager & SP_DISCOVERY_DONE)
+    {
+        if (gStateManager & SP_DISCOVERY_ERROR)
+        {
+            return SP_RESULT_INTERNAL_ERROR;
+        }
+        *list = gStartOfDiscoveredDevices;
+        return SP_RESULT_SUCCESS;
+    }
+    return SP_RESULT_INTERNAL_ERROR;
+}
+
+SPResult SPInitProvisionContext(unsigned short timeout,
+                                SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    if (NULL == selectedDeviceInfo )
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    SPResult res = SP_RESULT_SUCCESS;
+
+    //Discover secure resource and update the device info.
+    res = discoverSecureResource(timeout, selectedDeviceInfo);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Error in discoverSecureResource");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    OicSecOxm_t selectedMethod = OIC_JUST_WORKS;
+
+    selectProvisioningMethod(selectedDeviceInfo->doxm->oxm, selectedDeviceInfo->doxm->oxmLen,
+                             &selectedMethod);
+    OC_LOG_V(DEBUG, TAG, "Selected method %d:", selectedMethod);
+    res = updateOwnerTransferModeToResource(timeout, selectedDeviceInfo, selectedMethod);
+
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while updating owner transfer mode.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+
+    res = getProvisioningStatusResource(timeout, selectedDeviceInfo);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Error while getting provisioning status.");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    OC_LOG(INFO, TAG, "Starting ownership transfer");
+    return doOwnerShipTransfer(timeout, selectedDeviceInfo);
+
+}
+
+SPResult SPProvisionACL(unsigned short timeout, const SPTargetDeviceInfo_t *selectedDeviceInfo,
+                        OicSecAcl_t *acl)
+{
+    if (NULL == selectedDeviceInfo || NULL == acl)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    char *aclString = NULL;
+    aclString = BinToAclJSON(acl);
+
+    if (NULL == aclString)
+    {
+        OC_LOG(ERROR, TAG, "Memory allocation problem");
+        return SP_RESULT_MEM_ALLOCATION_FAIL;
+    }
+
+    int payloadLen = strlen(aclString);
+    handler = &ACLProvisioningHandler;
+    gStateManager |= SP_PROV_ACL_STARTED;
+
+    CAResult_t result = sendCARequest(CA_POST,
+                                      &selectedDeviceInfo->endpoint,
+                                      OC_FLAG_SECURE,
+                                      OIC_RSRC_ACL_URI,
+                                      aclString, payloadLen);
+    OICFree(aclString);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error while sending ACL.");
+        CADestroyToken(gToken);
+        return convertCAResultToSPResult(result);
+    }
+
+    SPResult res = SPTimeout(timeout, SP_PROV_ACL_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        return SP_RESULT_TIMEOUT;
+    }
+    CADestroyToken(gToken);
+    return res;
+}
+
+SPResult SPProvisionCredentials(unsigned short timeout, OicSecCredType_t type,
+                                const SPDevInfo_t *pDevList)
+{
+    if (NULL == pDevList)
+    {
+        return SP_RESULT_INVALID_PARAM;
+    }
+    const SPDevInfo_t *curr = pDevList;
+    OicUuid_t provTooldeviceID = {};
+    if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
+    {
+        OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    //TODO Need to support other key types in future.
+    switch (type)
+    {
+        case SYMMETRIC_PAIR_WISE_KEY:
+            {
+                if (NULL == curr->next)
+                {
+                    return SP_RESULT_INVALID_PARAM;
+                }
+                // Devices if present after second node will not be considered.
+                // in scenario-2. 2 devices are provisioned with credentials.
+                const SPDevInfo_t *firstDevice = curr;
+                const SPDevInfo_t *secondDevice = curr->next;
+
+                OicSecCred_t *firstCred = NULL;
+                OicSecCred_t *secondCred = NULL;
+
+                SPResult res = SPGeneratePairWiseCredentials(type, &provTooldeviceID,
+                               &firstDevice->deviceId, &secondDevice->deviceId,
+                               &firstCred, &secondCred);
+                if (res != SP_RESULT_SUCCESS)
+                {
+                    OC_LOG(ERROR, TAG, "error while generating credentials");
+                    return SP_RESULT_INTERNAL_ERROR;
+                }
+                res = provisionCredentials(timeout, firstCred, firstDevice);
+                if (SP_RESULT_SUCCESS != res)
+                {
+                    OC_LOG_V(ERROR, TAG, "Credentials provisioning Error");
+                    DeleteCredList(firstCred);
+                    DeleteCredList(secondCred);
+                    return SP_RESULT_INTERNAL_ERROR;
+                }
+                res = provisionCredentials(timeout, secondCred, secondDevice);
+                if (SP_RESULT_SUCCESS != res)
+                {
+                    OC_LOG_V(ERROR, TAG, "Credentials provisioning Error");
+                    DeleteCredList(firstCred);
+                    DeleteCredList(secondCred);
+                    return SP_RESULT_INTERNAL_ERROR;
+                }
+                DeleteCredList(firstCred);
+                DeleteCredList(secondCred);
+                return SP_RESULT_SUCCESS;
+            }
+        default:
+            {
+                OC_LOG(ERROR, TAG, "Invalid option.");
+                return SP_RESULT_INVALID_PARAM;
+            }
+            return SP_RESULT_INTERNAL_ERROR;
+    }
+}
+
+SPResult SPFinalizeProvisioning(unsigned short timeout,
+                                SPTargetDeviceInfo_t *selectedDeviceInfo)
+{
+    // TODO
+    if (NULL == selectedDeviceInfo)
+    {
+        OC_LOG(ERROR, TAG, "Target device Info is NULL.");
+        return SP_RESULT_INVALID_PARAM;
+    }
+
+    uint16_t aclHash = 0; // value for beachhead version.
+    selectedDeviceInfo->pstat->commitHash = aclHash;
+    selectedDeviceInfo->pstat->tm = NORMAL;
+    char *payloadBuffer = BinToPstatJSON(selectedDeviceInfo->pstat);
+    if (NULL == payloadBuffer)
+    {
+        OC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
+        return SP_RESULT_INTERNAL_ERROR;
+    }
+    int payloadLen = strlen(payloadBuffer);
+
+    handler = &FinalizeProvisioningHandler;
+    gStateManager |= SP_UP_HASH_STARTED;
+
+    CAResult_t result = sendCARequest(CA_PUT,
+                                      &selectedDeviceInfo->endpoint,
+                                      OC_FLAG_SECURE,
+                                      OIC_RSRC_PSTAT_URI,
+                                      payloadBuffer, payloadLen);
+    OICFree(payloadBuffer);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        return convertCAResultToSPResult(result);
+    }
+
+    SPResult res = SPTimeout(timeout, SP_UP_HASH_DONE);
+    if (SP_RESULT_SUCCESS != res)
+    {
+        OC_LOG(ERROR, TAG, "Internal Error occured");
+        CADestroyToken(gToken);
+        return SP_RESULT_TIMEOUT;
+    }
+
+    result = CACloseDtlsSession((CAEndpoint_t*)&selectedDeviceInfo->endpoint);
+    if (CA_STATUS_OK != result)
+    {
+        OC_LOG(WARNING, TAG, "Failed to close the DTLS session.");
+    }
+
+    CADestroyToken(gToken);
+    gStateManager = 0;
+    gPstat = NULL;
+    return res;
+}
+
+SPResult SPTerminateProvisioning()
+{
+    deleteList();
+    return SP_RESULT_SUCCESS;;
+}
diff --git a/resource/csdk/security/provisioning/unittest/SConscript b/resource/csdk/security/provisioning/unittest/SConscript
new file mode 100644 (file)
index 0000000..e6b59ed
--- /dev/null
@@ -0,0 +1,83 @@
+# //******************************************************************
+# //
+# // 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
+import os.path
+sptest_env = env.Clone()
+
+src_dir = sptest_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+sptest_env.PrependUnique(CPPPATH = [
+               '../../../connectivity/inc',
+               '../../../connectivity/api',
+               '../../include',
+               '../../../../../extlibs/tinydtls',
+               '../include/internal',
+               '../../../logger/include',
+               '../../../stack/include',
+               '../../../../oc_logger/include',
+               '../../../../../extlibs/gtest/gtest-1.7.0/include',
+               '../include'
+               ])
+sptest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+sptest_env.AppendUnique(LIBS = ['-lpthread'])
+sptest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+sptest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
+sptest_env.PrependUnique(LIBS = [   'ocspapi',
+                                    'ocsrm',
+                                    'octbstack',
+                                    'oc_logger',
+                                    'connectivity_abstraction',
+                                    'coap',
+                                    'gtest',
+                                    'gtest_main'])
+
+if env.get('SECURED') == '1':
+    sptest_env.AppendUnique(LIBS = ['tinydtls'])
+
+if not env.get('RELEASE'):
+       sptest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+unittest = sptest_env.Program('unittest', ['provisioningmanager.cpp'])
+
+Alias("test", [unittest])
+
+env.AppendTarget('test')
+if env.get('TEST') == '1':
+       target_os = env.get('TARGET_OS')
+       if target_os == 'linux':
+               out_dir = env.get('BUILD_DIR')
+               result_dir = env.get('BUILD_DIR') + '/test_out/'
+               if not os.path.isdir(result_dir):
+                       os.makedirs(result_dir)
+               sptest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
+               sptest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
+               sptest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
+               ut = sptest_env.Command ('ut', None, out_dir + '/resource/csdk/security/unittest/unittest')
+               AlwaysBuild ('ut')
+
diff --git a/resource/csdk/security/provisioning/unittest/provisioningmanager.cpp b/resource/csdk/security/provisioning/unittest/provisioningmanager.cpp
new file mode 100644 (file)
index 0000000..11f7dc2
--- /dev/null
@@ -0,0 +1,58 @@
+/* *****************************************************************
+ *
+ * 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 "gtest/gtest.h"
+
+#include "provisioningmanager.h"
+
+
+static OicSecAcl_t acl;
+SPTargetDeviceInfo_t list;
+SPTargetDeviceInfo_t *ptr = &list;
+
+TEST(SPProvisioningDiscoveryTest, NotNullList)
+{
+    EXPECT_EQ(SP_RESULT_INVALID_PARAM, SPProvisioningDiscovery(0, &ptr));
+}
+
+TEST(SPInitProvisionContextTest, NullDeviceInfo)
+{
+    EXPECT_EQ(SP_RESULT_INVALID_PARAM, SPInitProvisionContext(0, NULL));
+}
+
+TEST(SPProvisionACLTest, NullDeviceInfo)
+{
+    EXPECT_EQ(SP_RESULT_INVALID_PARAM, SPProvisionACL(0, NULL, &acl));
+}
+
+TEST(SPFinalizeProvisioningTest, NullDeviceInfo)
+{
+    EXPECT_EQ(SP_RESULT_INVALID_PARAM, SPFinalizeProvisioning(0, NULL));
+}
+
+TEST(SPTerminateProvisioningTest, ValidCase)
+{
+    EXPECT_EQ(SP_RESULT_SUCCESS, SPTerminateProvisioning());
+}
+
+TEST(SPProvisionCredentialsTest, NullList)
+{
+    EXPECT_EQ(SP_RESULT_INVALID_PARAM, SPProvisionCredentials(0, 0, NULL));
+}
diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c
new file mode 100644 (file)
index 0000000..a1afef8
--- /dev/null
@@ -0,0 +1,599 @@
+//******************************************************************
+//
+// 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 "logger.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "resourcemanager.h"
+#include "aclresource.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "srmresourcestrings.h"
+#include "doxmresource.h"
+#include "srmutility.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define TAG  PCF("SRM-ACL")
+
+OicSecAcl_t        *gAcl = NULL;
+static OCResourceHandle    gAclHandle = NULL;
+
+void DeleteACLList(OicSecAcl_t* acl)
+{
+    if (acl)
+    {
+        OicSecAcl_t *aclTmp1 = NULL, *aclTmp2 = NULL;
+        LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
+        {
+            int i = 0;
+
+            LL_DELETE(acl, aclTmp1);
+
+            // Clean Resources
+            for (i = 0; i < aclTmp1->resourcesLen; i++)
+            {
+                OICFree(aclTmp1->resources[i]);
+            }
+            OICFree(aclTmp1->resources);
+
+            // Clean Owners
+            OICFree(aclTmp1->owners);
+
+            // Clean ACL node itself
+            OICFree(aclTmp1);
+        }
+    }
+}
+
+/*
+ * This internal method converts ACL data into JSON format.
+ *
+ * Note: Caller needs to invoke 'free' when finished done using
+ * return string.
+ */
+char * BinToAclJSON(const OicSecAcl_t * acl)
+{
+    cJSON *jsonRoot = NULL;
+    char *jsonStr = NULL;
+
+    if (acl)
+    {
+        jsonRoot = cJSON_CreateObject();
+        VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+        cJSON *jsonAclArray = NULL;
+        cJSON_AddItemToObject (jsonRoot, OIC_JSON_ACL_NAME, jsonAclArray = cJSON_CreateArray());
+        VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
+
+        while(acl)
+        {
+            char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+            uint32_t outLen = 0;
+            size_t inLen = 0;
+            B64Result b64Ret = B64_OK;
+
+            cJSON *jsonAcl = cJSON_CreateObject();
+
+            // Subject -- Mandatory
+            outLen = 0;
+            if (memcmp(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
+            {
+                inLen = WILDCARD_SUBJECT_ID_LEN;
+            }
+            else
+            {
+                inLen =  sizeof(OicUuid_t);
+            }
+            b64Ret = b64Encode(acl->subject.id, inLen, base64Buff,
+                sizeof(base64Buff), &outLen);
+            VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+            cJSON_AddStringToObject(jsonAcl, OIC_JSON_SUBJECT_NAME, base64Buff );
+
+            // Resources -- Mandatory
+            cJSON *jsonRsrcArray = NULL;
+            cJSON_AddItemToObject (jsonAcl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray = cJSON_CreateArray());
+            VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
+            for (int i = 0; i < acl->resourcesLen; i++)
+            {
+                cJSON_AddItemToArray (jsonRsrcArray, cJSON_CreateString(acl->resources[i]));
+            }
+
+            // Permissions -- Mandatory
+            cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, acl->permission);
+
+            // Owners -- Mandatory
+            cJSON *jsonOwnrArray = NULL;
+            cJSON_AddItemToObject (jsonAcl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
+            VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
+            for (int i = 0; i < acl->ownersLen; i++)
+            {
+                outLen = 0;
+
+                b64Ret = b64Encode(acl->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
+                    sizeof(base64Buff), &outLen);
+                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+                cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
+            }
+
+            // Attach current acl node to Acl Array
+            cJSON_AddItemToArray(jsonAclArray, jsonAcl);
+            acl = acl->next;
+        }
+
+        jsonStr = cJSON_PrintUnformatted(jsonRoot);
+    }
+
+exit:
+    if (jsonRoot)
+    {
+        cJSON_Delete(jsonRoot);
+    }
+    return jsonStr;
+}
+
+/*
+ * This internal method converts JSON ACL into binary ACL.
+ */
+OicSecAcl_t * JSONToAclBin(const char * jsonStr)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecAcl_t * headAcl = NULL;
+    OicSecAcl_t * prevAcl = NULL;
+    cJSON *jsonRoot = NULL;
+    cJSON *jsonAclArray = NULL;
+
+    VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+
+    jsonRoot = cJSON_Parse(jsonStr);
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    jsonAclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
+    VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
+
+    if (cJSON_Array == jsonAclArray->type)
+    {
+        int numAcl = cJSON_GetArraySize(jsonAclArray);
+        int idx = 0;
+
+        VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
+        do
+        {
+            cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
+            VERIFY_NON_NULL(TAG, jsonAcl, ERROR);
+
+            OicSecAcl_t *acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
+            VERIFY_NON_NULL(TAG, acl, ERROR);
+
+            headAcl = (headAcl) ? headAcl : acl;
+            if (prevAcl)
+            {
+                prevAcl->next = acl;
+            }
+
+            size_t jsonObjLen = 0;
+            cJSON *jsonObj = NULL;
+
+            unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+            uint32_t outLen = 0;
+            B64Result b64Ret = B64_OK;
+
+            // Subject -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECT_NAME);
+            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(acl->subject.id)), ERROR);
+            memcpy(acl->subject.id, base64Buff, outLen);
+
+            // Resources -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+
+            acl->resourcesLen = cJSON_GetArraySize(jsonObj);
+            VERIFY_SUCCESS(TAG, acl->resourcesLen > 0, ERROR);
+            acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
+            VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
+
+            int idxx = 0;
+            do
+            {
+                cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
+                VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
+
+                jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
+                acl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
+                VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR);
+                strncpy(acl->resources[idxx], jsonRsrc->valuestring, jsonObjLen);
+            } while ( ++idxx < acl->resourcesLen);
+
+            // Permissions -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_PERMISSION_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+            acl->permission = jsonObj->valueint;
+
+            // Owners -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_OWNERS_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+
+            acl->ownersLen = cJSON_GetArraySize(jsonObj);
+            VERIFY_SUCCESS(TAG, acl->ownersLen > 0, ERROR);
+            acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
+            VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
+
+            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(acl->owners[idxx].id)),
+                                    ERROR);
+                memcpy(acl->owners[idxx].id, base64Buff, outLen);
+            } while ( ++idxx < acl->ownersLen);
+
+            prevAcl = acl;
+        } while( ++idx < numAcl);
+    }
+
+    ret = OC_STACK_OK;
+
+exit:
+    cJSON_Delete(jsonRoot);
+    if (OC_STACK_OK != ret)
+    {
+        DeleteACLList(headAcl);
+        headAcl = NULL;
+    }
+    return headAcl;
+}
+
+static OCEntityHandlerResult HandleACLGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+    // Convert ACL data into JSON for transmission
+    char* jsonStr = BinToAclJSON(gAcl);
+
+    /*
+     * A device should 'always' have a default ACL. Therefore,
+     * jsonStr should never be NULL.
+     */
+    OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+
+    // Send response payload to request originator
+    SendSRMResponse(ehRequest, ehRet, jsonStr);
+
+    OICFree(jsonStr);
+
+    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
+    return ehRet;
+}
+
+static OCEntityHandlerResult HandleACLPostRequest (const OCEntityHandlerRequest * ehRequest)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+    // Convert JSON ACL data into binary. This will also validate the ACL data received.
+    OicSecAcl_t* newAcl = JSONToAclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
+
+    if (newAcl)
+    {
+        // Append the new ACL to existing ACL
+        LL_APPEND(gAcl, newAcl);
+
+        // Convert ACL data into JSON for update to persistent storage
+        char *jsonStr = BinToAclJSON(gAcl);
+        if (jsonStr)
+        {
+            cJSON *jsonAcl = cJSON_Parse(jsonStr);
+            OICFree(jsonStr);
+
+            if ((jsonAcl) &&
+                (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl)))
+            {
+                ehRet = OC_EH_RESOURCE_CREATED;
+            }
+            cJSON_Delete(jsonAcl);
+        }
+    }
+
+    // Send payload to request originator
+    SendSRMResponse(ehRequest, ehRet, NULL);
+
+    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
+    return ehRet;
+}
+
+/*
+ * This internal method is the entity handler for ACL resources and
+ * will handle REST request (GET/PUT/POST/DEL) for them.
+ */
+OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
+                                        OCEntityHandlerRequest * ehRequest,
+                                        void* callbackParameter)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+    if (!ehRequest)
+    {
+        return ehRet;
+    }
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        // TODO :  Handle PUT and DEL methods
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        switch (ehRequest->method)
+        {
+            case OC_REST_GET:
+                ehRet = HandleACLGetRequest(ehRequest);
+                break;
+
+            case OC_REST_POST:
+                ehRet = HandleACLPostRequest(ehRequest);
+                break;
+
+            default:
+                ehRet = OC_EH_ERROR;
+                SendSRMResponse(ehRequest, ehRet, NULL);
+        }
+    }
+
+    return ehRet;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/acl' resource.
+ */
+OCStackResult CreateACLResource()
+{
+    OCStackResult ret;
+
+    ret = OCCreateResource(&gAclHandle,
+                           OIC_RSRC_TYPE_SEC_ACL,
+                           OIC_MI_DEF,
+                           OIC_RSRC_ACL_URI,
+                           ACLEntityHandler,
+                           NULL,
+                           OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+
+    if (OC_STACK_OK != ret)
+    {
+        OC_LOG (FATAL, TAG, PCF("Unable to instantiate ACL resource"));
+        DeInitACLResource();
+    }
+    return ret;
+}
+
+/*
+ * This internal method is to retrieve the default ACL.
+ * If SVR database in persistent storage got corrupted or
+ * is not available for some reason, a default ACL is created
+ * which allows user to initiate ACL provisioning again.
+ */
+OCStackResult  GetDefaultACL(OicSecAcl_t** defaultAcl)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    OicUuid_t ownerId = {};
+
+    /*
+     * TODO In future, when new virtual resources will be added in OIC
+     * specification, Iotivity stack should be able to add them in
+     * existing SVR database. To support this, we need to add 'versioning'
+     * mechanism in SVR database.
+     */
+
+    const char *rsrcs[] = {
+        OC_RSRVD_WELL_KNOWN_URI,
+        OC_RSRVD_DEVICE_URI,
+        OC_RSRVD_PLATFORM_URI,
+        OC_RSRVD_RESOURCE_TYPES_URI,
+#ifdef WITH_PRESENCE
+        OC_RSRVD_PRESENCE_URI,
+#endif //WITH_PRESENCE
+        OIC_RSRC_ACL_URI,
+        OIC_RSRC_DOXM_URI,
+        OIC_RSRC_PSTAT_URI,
+    };
+
+    if (!defaultAcl)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OicSecAcl_t *acl = (OicSecAcl_t *)OICCalloc(1, sizeof(OicSecAcl_t));
+    VERIFY_NON_NULL(TAG, acl, ERROR);
+
+    // Subject -- Mandatory
+    memcpy(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(acl->subject));
+
+    // Resources -- Mandatory
+    acl->resourcesLen = sizeof(rsrcs)/sizeof(rsrcs[0]);
+
+    acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
+    VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
+
+    for (int i = 0; i <  acl->resourcesLen; i++)
+    {
+        size_t len = strlen(rsrcs[i]) + 1;
+        acl->resources[i] = (char*)OICMalloc(len * sizeof(char));
+        VERIFY_NON_NULL(TAG, (acl->resources[i]), ERROR);
+        strncpy(acl->resources[i], rsrcs[i], len);
+    }
+
+    acl->permission = PERMISSION_READ;
+    acl->periodsLen = 0;
+    acl->periods = NULL;
+    acl->recurrences = NULL;
+
+    // Device ID is the owner of this default ACL
+    ret = GetDoxmDeviceID( &ownerId);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
+
+    acl->ownersLen = 1;
+    acl->owners = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
+    VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
+    memcpy(acl->owners, &ownerId, sizeof(OicUuid_t));
+
+    acl->next = NULL;
+
+    *defaultAcl = acl;
+    ret = OC_STACK_OK;
+
+exit:
+
+    if (ret != OC_STACK_OK)
+    {
+        DeleteACLList(acl);
+        acl = NULL;
+    }
+
+    return ret;
+}
+
+/**
+ * Initialize ACL resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitACLResource()
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    // Read ACL resource from PS
+    char* jsonSVRDatabase = GetSVRDatabase();
+
+    if (jsonSVRDatabase)
+    {
+        // Convert JSON ACL into binary format
+        gAcl = JSONToAclBin(jsonSVRDatabase);
+        OICFree(jsonSVRDatabase);
+    }
+    /*
+     * If SVR database in persistent storage got corrupted or
+     * is not available for some reason, a default ACL is created
+     * which allows user to initiate ACL provisioning again.
+     */
+    if (!jsonSVRDatabase || !gAcl)
+    {
+        GetDefaultACL(&gAcl);
+        // TODO Needs to update persistent storage
+    }
+    VERIFY_NON_NULL(TAG, gAcl, FATAL);
+
+    // Instantiate 'oic.sec.acl'
+    ret = CreateACLResource();
+
+exit:
+    if (OC_STACK_OK != ret)
+    {
+        DeInitACLResource();
+    }
+    return ret;
+}
+
+/**
+ * Perform cleanup for ACL resources.
+ *
+ * @retval  none
+ */
+void DeInitACLResource()
+{
+    OCDeleteResource(gAclHandle);
+    gAclHandle = NULL;
+
+    DeleteACLList(gAcl);
+    gAcl = NULL;
+}
+
+/**
+ * This method is used by PolicyEngine to retrieve ACL for a Subject.
+ *
+ * @param subjectId ID of the subject for which ACL is required.
+ * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
+ *                successive calls for same subjectId.
+ *
+ * @retval  reference to @ref OicSecAcl_t if ACL is found, else NULL
+ *
+ * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
+ */
+const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr)
+{
+    OicSecAcl_t *acl = NULL;
+    OicSecAcl_t *begin = NULL;
+
+    if ( NULL == subjectId)
+    {
+        return NULL;
+    }
+
+    /*
+     * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
+     * subjectID.
+     */
+    if (NULL == *savePtr)
+    {
+        begin = gAcl;
+    }
+    else
+    {
+        /*
+         * If this is a 'successive' call, search for location pointed by
+         * savePtr and assign 'begin' to the next ACL after it in the linked
+         * list and start searching from there.
+         */
+        LL_FOREACH(gAcl, acl)
+        {
+            if (acl == *savePtr)
+            {
+                begin = acl->next;
+            }
+        }
+    }
+
+    // Find the next ACL corresponding to the 'subjectID' and return it.
+    LL_FOREACH(begin, acl)
+    {
+        if (memcmp(&(acl->subject), subjectId, sizeof(OicUuid_t)) == 0)
+        {
+            *savePtr = acl;
+            return acl;
+        }
+    }
+
+    // Cleanup in case no ACL is found
+    *savePtr = NULL;
+    return NULL;
+}
diff --git a/resource/csdk/security/src/base64.c b/resource/csdk/security/src/base64.c
new file mode 100644 (file)
index 0000000..3b20cf5
--- /dev/null
@@ -0,0 +1,255 @@
+/******************************************************************
+ *
+ * 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 "base64.h"
+
+/**< base character of Base64  */
+static const char g_b64TransTbl[] =
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"\
+                "ghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * base64 block encode function
+ *
+ * @param[in] in  octet stream, max 3 byte
+ * @param[out] out  base64 encoded stream, 4 byte
+ * @param[in] len  byte-length of in
+ *
+ * @return  B64_OK for Success, otherwise some error value
+ */
+static B64Result b64EncodeBlk(const uint8_t* in, char* out, uint32_t len)
+{
+    if (NULL == in || NULL ==  out || 0 == len )
+    {
+        return B64_INVALID_PARAM;
+    }
+
+    out[0] = g_b64TransTbl[in[0] >> 2];
+
+    if(1 == len)
+    {
+        out[1] = g_b64TransTbl[((in[0] & 0x03) << 4)];
+    }
+    else
+    {
+        out[1] = g_b64TransTbl[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
+    }
+
+    if(2 == len)
+    {
+        out[2] = g_b64TransTbl[((in[1] & 0x0f) << 2)];
+    }
+    else if (1 < len)
+    {
+        out[2] = g_b64TransTbl[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)];
+    }
+    else
+    {
+        out[2] = '=';
+    }
+
+    if (2 < len)
+    {
+        out[3] = g_b64TransTbl[in[2] & 0x3f];
+    }
+    else
+    {
+        out[3] = '=';
+    }
+
+    return B64_OK;
+}
+
+/**
+ * Encode the plain message in base64.
+ *
+ * @param[in] in  Plain message
+ * @param[in] inLen  Byte length of 'in'
+ * @param[in,out] outBuf Output buffer
+ *                Base64 encoded message will be written into 'out'
+ *                NOTE : This method adds a NULL to the string configuration
+ * @param[in] outBufSize Size of output buffer
+ * @param[out] outLen  Byte length of encoded message
+ *
+ * @return  B64_OK for Success, otherwise some error value
+*/
+B64Result b64Encode(const uint8_t* in, const size_t inLen,
+               char* outBuf, const size_t outBufSize, uint32_t* outLen)
+{
+    uint32_t i;
+    uint32_t minBufSize;
+
+    if (NULL == in || 0 == inLen || NULL ==  outBuf || NULL == outLen )
+    {
+        return B64_INVALID_PARAM;
+    }
+
+    *outLen = ((inLen / 3) * 3 == inLen) ?
+              ((inLen / 3) * 4) :
+              (((inLen / 3) + 1) * 4);
+    minBufSize = (*outLen + 1);
+    if(outBufSize < minBufSize)
+    {
+        return B64_OUTPUT_BUFFER_TOO_SMALL;
+    }
+
+    for (i = 0; i < inLen / 3; i++)
+    {
+        if(B64_OK != b64EncodeBlk(in + i * 3, outBuf + i * 4, 3))
+        {
+            return B64_INVALID_PARAM;
+        }
+    }
+
+    if (i * 3 != inLen)
+    {
+        if(B64_OK != b64EncodeBlk(in + i * 3, outBuf + i * 4, inLen - i * 3))
+        {
+            return B64_INVALID_PARAM;
+        }
+    }
+
+    outBuf[*outLen] = '\0';
+
+    return B64_OK;
+}
+
+/**
+ * Get decoded value
+ *
+ * @param[in] c  Base64 encoded charactor
+ *
+ * @return decoded value, 6-bit
+ */
+static uint32_t b64GetVal(char c)
+{
+    if (('A' <= c) && ('Z' >= c))
+    {
+        return c - 'A';
+    }
+    else if (('a' <= c) && ('z' >= c))
+    {
+        return c - 'a' + 26;
+    }
+    else if (('0' <= c) && ('9' >= c))
+    {
+        return c - '0' + 52;
+    }
+    else if ('+' == c)
+    {
+        return 62;
+    }
+    else if ('/' == c)
+    {
+        return 63;
+    }
+    else if ('=' == c)
+    {
+        return 0;
+    }
+
+    return 0;
+}
+
+/**
+ * base64 block decode function
+ *
+ * @param[in] in  Base64 encoded stream, 4 bytes
+ * @param[out] out  Octet stream, 3 bytes
+ *
+ * @return  B64_OK for Success, otherwise some error value
+ */
+static B64Result b64DecodeBlk(const char* in, uint8_t* out)
+{
+    uint32_t val;
+
+    if(NULL == in || NULL == out)
+    {
+        return B64_INVALID_PARAM;
+    }
+
+    val = (b64GetVal(in[0]) << 18) | (b64GetVal(in[1]) << 12) |
+          (b64GetVal(in[2]) << 6) | (b64GetVal(in[3]));
+
+    out[0] = (val >> 16) & 0xff;
+
+    if ('=' != in[2])
+    {
+        out[1] = (val >> 8) & 0xff;
+    }
+    if ('=' != in[3])
+    {
+        out[2] = val & 0xff;
+    }
+
+    return B64_OK;
+}
+
+/**
+ * Decode the encoded message in base64.
+ *
+ * @param[in] in  Base64 encoded message
+ * @param[in] inLen  Byte lenth of 'in'
+ * @param[in, out] outBuf  Output buffer
+ *                 Base64 decoded message will be written into 'out'
+ * @param[in] outBufSize Size of output buffer
+ * @param[out] outLen  Byte length of decoded message
+ *
+ * @return  B64_OK for Success, otherwise some error value
+ */
+B64Result b64Decode(const char* in, const size_t inLen,
+               uint8_t* outBuf, size_t outBufSize, uint32_t* outLen)
+{
+    uint32_t i;
+    uint32_t minBufSize;
+
+    if (NULL == in || 0 == inLen || 0 != (inLen & 0x03) || NULL == outBuf || NULL == outLen)
+    {
+        return B64_INVALID_PARAM;
+    }
+
+    *outLen = (inLen / 4) * 3;
+    minBufSize = (inLen / 4) * 3;
+    if('=' == in[inLen - 1])
+    {
+        minBufSize--;
+        (*outLen)--;
+    }
+    if('=' == in[inLen - 2])
+    {
+        minBufSize--;
+        (*outLen)--;
+    }
+    if(outBufSize < minBufSize)
+    {
+        return B64_OUTPUT_BUFFER_TOO_SMALL;
+    }
+
+    for (i = 0; i < inLen / 4; i++)
+    {
+        if(B64_OK != b64DecodeBlk(in + i * 4, outBuf + i * 3))
+        {
+            return B64_INVALID_PARAM;
+        }
+    }
+
+    return B64_OK;
+}
+
diff --git a/resource/csdk/security/src/credresource.c b/resource/csdk/security/src/credresource.c
new file mode 100755 (executable)
index 0000000..af21b26
--- /dev/null
@@ -0,0 +1,753 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#define __STDC_LIMIT_MACROS
+#include "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "resourcemanager.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "srmresourcestrings.h"
+#include "credresource.h"
+#include "ocrandom.h"
+#include "doxmresource.h"
+#include "base64.h"
+#include "srmutility.h"
+#include "cainterface.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+
+#define TAG  PCF("SRM-CREDL")
+
+static OicSecCred_t        *gCred = NULL;
+static OCResourceHandle    gCredHandle = NULL;
+
+void DeleteCredList(OicSecCred_t* cred)
+{
+    if (cred)
+    {
+        OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
+        LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
+        {
+            LL_DELETE(cred, credTmp1);
+
+            //Note: Need further clarification on roleID data type
+#if 0
+            //Clean roleIds
+            OICFree(credTmp1->roleIds);
+#endif
+
+            //Clean PublicData
+            OICFree(credTmp1->publicData.data);
+
+            //Clean PrivateData
+            OICFree(credTmp1->privateData.data);
+
+            //Clean Period
+            OICFree(credTmp1->period);
+
+            //Clean Owners
+            OICFree(credTmp1->owners);
+
+            //Clean Cred node itself
+            OICFree(credTmp1);
+        }
+    }
+}
+
+/**
+ * This function converts credential data into JSON format.
+ * Caller needs to invoke 'free' when done using
+ * returned string.
+ * @param cred  pointer to instance of OicSecCred_t structure.
+ *
+ * @retval
+ *      pointer to JSON credential representation - if credential for subjectId found
+ *      NULL                                      - if credential for subjectId not found
+ */
+char * BinToCredJSON(const OicSecCred_t * cred)
+{
+    cJSON *jsonRoot = NULL;
+    char *jsonStr = NULL;
+
+    if (cred)
+    {
+        char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+        uint32_t outLen = 0;
+        B64Result b64Ret = B64_OK;
+
+        jsonRoot = cJSON_CreateObject();
+        VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+        cJSON *jsonCredArray = NULL;
+        cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRED_NAME,
+                jsonCredArray = cJSON_CreateArray());
+        VERIFY_NON_NULL(TAG, jsonCredArray, ERROR);
+
+        while(cred)
+        {
+            cJSON *jsonCred = cJSON_CreateObject();
+            VERIFY_NON_NULL(TAG, jsonCred, ERROR);
+
+            //CredID -- Mandatory
+            cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDID_NAME, (int)cred->credId);
+
+            //Subject -- Mandatory
+            outLen = 0;
+            memset(base64Buff, 0, sizeof(base64Buff));
+            b64Ret = b64Encode(cred->subject.id, sizeof(cred->subject.id), base64Buff,
+                   sizeof(base64Buff), &outLen);
+            VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+            cJSON_AddStringToObject(jsonCred, OIC_JSON_SUBJECT_NAME, base64Buff);
+
+            //Note: Need further clarification on roleID data type
+#if 0
+            //RoleId -- Not Mandatory
+            if(cred->roleIdsLen > 0)
+            {
+                cJSON *jsonRoleIdsArray = NULL;
+                cJSON_AddItemToObject (jsonCred, OIC_JSON_ROLEIDS_NAME,
+                                         jsonRoleIdsArray = cJSON_CreateArray());
+                VERIFY_NON_NULL(TAG, jsonRoleIdsArray, ERROR);
+                for (size_t i = 0; i < cred->roleIdsLen; i++)
+                {
+                    cJSON_AddItemToArray (jsonRoleIdsArray,
+                            cJSON_CreateString((char *)cred->roleIds[i].id));
+                }
+            }
+#endif
+
+            //CredType -- Mandatory
+            cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDTYPE_NAME,(int)cred->credType);
+
+#if 0
+            //PublicData -- Not Mandatory
+            if(cred->publicData.data)
+            {
+                cJSON_AddStringToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, cred->publicData.data);
+            }
+#endif
+            //PrivateData -- Not Mandatory
+            if(cred->privateData.data)
+            {
+                cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
+            }
+
+            //Period -- Not Mandatory
+            if(cred->period)
+            {
+                cJSON_AddStringToObject(jsonCred, OIC_JSON_PERIOD_NAME,
+                                        cred->period);
+            }
+
+            //Owners -- Mandatory
+            cJSON *jsonOwnrArray = NULL;
+            cJSON_AddItemToObject (jsonCred, OIC_JSON_OWNERS_NAME,
+                                             jsonOwnrArray = cJSON_CreateArray());
+            VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
+            for (size_t i = 0; i < cred->ownersLen; i++)
+            {
+                outLen = 0;
+                memset(base64Buff, 0, sizeof(base64Buff));
+                b64Ret = b64Encode(cred->owners[i].id, sizeof(cred->owners[i].id),
+                        base64Buff, sizeof(base64Buff), &outLen);
+                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+                cJSON_AddItemToArray (jsonOwnrArray,
+                                       cJSON_CreateString((char *)(base64Buff)));
+            }
+
+            /* Attach current cred node to cred Array */
+            cJSON_AddItemToArray(jsonCredArray, jsonCred);
+            cred = cred->next;
+        }
+
+        jsonStr = cJSON_PrintUnformatted(jsonRoot);
+    }
+
+exit:
+    if (jsonRoot)
+    {
+        cJSON_Delete(jsonRoot);
+    }
+    return jsonStr;
+}
+
+/*
+ * This internal method converts JSON cred into binary cred.
+ */
+OicSecCred_t * JSONToCredBin(const char * jsonStr)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecCred_t * headCred = NULL;
+    OicSecCred_t * prevCred = NULL;
+    cJSON *jsonCredArray = NULL;
+
+    cJSON *jsonRoot = cJSON_Parse(jsonStr);
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    jsonCredArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
+    VERIFY_NON_NULL(TAG, jsonCredArray, ERROR);
+    if (cJSON_Array == jsonCredArray->type)
+    {
+        int numCred = cJSON_GetArraySize(jsonCredArray);
+        int idx = 0;
+
+        unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+        uint32_t outLen = 0;
+        B64Result b64Ret = B64_OK;
+
+        VERIFY_SUCCESS(TAG, numCred > 0, ERROR);
+        do
+        {
+            cJSON *jsonCred = cJSON_GetArrayItem(jsonCredArray, idx);
+            VERIFY_NON_NULL(TAG, jsonCred, ERROR);
+
+            OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+            VERIFY_NON_NULL(TAG, cred, ERROR);
+
+            headCred = (headCred) ? headCred : cred;
+            if (prevCred)
+            {
+                prevCred->next = cred;
+            }
+            size_t jsonObjLen = 0;
+            cJSON *jsonObj = NULL;
+
+            //CredId -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME);
+            if(jsonObj)
+            {
+                VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+                cred->credId = jsonObj->valueint;
+            }
+
+            //subject -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECT_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+            outLen = 0;
+            memset(base64Buff, 0, sizeof(base64Buff));
+            b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
+                    base64Buff, sizeof(base64Buff), &outLen);
+            VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(cred->subject.id)),
+                           ERROR);
+            memcpy(cred->subject.id, base64Buff, outLen);
+
+            //CredType -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+            cred->credType = jsonObj->valueint;
+
+            //PrivateData is mandatory for some of the credential types listed below.
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME);
+            if ((cred->credType & SYMMETRIC_PAIR_WISE_KEY) ||
+                (cred->credType & SYMMETRIC_GROUP_KEY) ||
+                (cred->credType & PIN_PASSWORD))
+            {
+                VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+                VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+            }
+            if(jsonObj && cJSON_String == jsonObj->type)
+            {
+                jsonObjLen = strlen(jsonObj->valuestring) + 1;
+                cred->privateData.data = (char *)OICMalloc(jsonObjLen);
+                VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+                strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
+            }
+
+            //Period -- Not Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PERIOD_NAME);
+            if(jsonObj && cJSON_String == jsonObj->type)
+            {
+                jsonObjLen = strlen(jsonObj->valuestring) + 1;
+                cred->period = (char *)OICMalloc(jsonObjLen);
+                VERIFY_NON_NULL(TAG, cred->period, ERROR);
+                strncpy(cred->period, jsonObj->valuestring, jsonObjLen);
+            }
+
+            //Owners -- Mandatory
+            jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OWNERS_NAME);
+            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR)
+            cred->ownersLen = cJSON_GetArraySize(jsonObj);
+            VERIFY_SUCCESS(TAG, cred->ownersLen > 0, ERROR);
+            cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
+            VERIFY_NON_NULL(TAG, (cred->owners), ERROR);
+            for(size_t i = 0; i < cred->ownersLen; i++)
+            {
+                cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, i);
+                VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
+                VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
+                outLen = 0;
+                memset(base64Buff, 0, sizeof(base64Buff));
+                b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring),
+                         base64Buff, sizeof(base64Buff), &outLen);
+                VERIFY_SUCCESS(TAG, (b64Ret == B64_OK &&
+                               outLen <= sizeof(cred->owners[i].id)), ERROR);
+                memcpy(cred->owners[i].id, base64Buff, outLen);
+            }
+            prevCred = cred;
+        } while( ++idx < numCred);
+    }
+
+    ret = OC_STACK_OK;
+
+exit:
+    cJSON_Delete(jsonRoot);
+    if (OC_STACK_OK != ret)
+    {
+        DeleteCredList(headCred);
+        headCred = NULL;
+    }
+    return headCred;
+}
+
+/**
+ * This function generates the bin credential data.
+ *
+ * @param subject pointer to subject of this credential.
+ * @param credType credential type.
+ * @param publicData public data such as public key.
+ * @param privateData private data such as private key.
+ *        The privateData is expected in base64 encoded format.
+ * @param ownersLen length of owners array
+ * @param owners array of owners.
+ *
+ * @retval
+ *      pointer to instance of OicSecCred_t  - success
+ *      NULL                                 - error
+ */
+OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
+                                 const char * publicData, const char * privateData,
+                                 size_t ownersLen, const OicUuid_t * owners)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+
+    //CredId is assigned before appending new cred to the existing
+    //credential list and updating svr database in AddCredential().
+    cred->credId = 0;
+
+    VERIFY_NON_NULL(TAG, subject, ERROR);
+    memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
+
+    VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
+            SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
+    cred->credType = credType;
+
+#if 0
+    if(publicData)
+    {
+        cred->publicData.data = (char *)OICMalloc(strlen(publicData)+1);
+        VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+        strncpy((char *)cred->publicData.data, publicData, strlen(publicData)+1);
+    }
+#endif
+
+    if(privateData)
+    {
+        cred->privateData.data = (char *)OICMalloc(strlen(privateData)+1);
+        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+        strncpy((char *)cred->privateData.data, privateData, strlen(privateData)+1);
+    }
+
+    VERIFY_SUCCESS(TAG, ownersLen > 0, ERROR);
+    cred->ownersLen = ownersLen;
+
+    cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
+    VERIFY_NON_NULL(TAG, cred->owners, ERROR);
+    for(size_t i = 0; i < cred->ownersLen; i++)
+    {
+        memcpy(cred->owners[i].id, owners[i].id, sizeof(cred->owners[i].id));
+    }
+
+    ret = OC_STACK_OK;
+exit:
+    if (OC_STACK_OK != ret)
+    {
+        DeleteCredList(cred);
+        cred = NULL;
+    }
+    return cred;
+}
+
+/*
+ * Compare function used LL_SORT for sorting credentials
+ *
+ * @param first   pointer to OicSecCred_t struct
+ * @param second  pointer to OicSecCred_t struct
+ *
+ *@retval
+ *  -1    if credId of first is less than credId of second
+ *   0    if credId of first is equal to credId of second
+ *   1    if credId of first is greater than credId of second
+ */
+static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
+{
+    if(first->credId < second->credId)
+    {
+        return -1;
+    }
+    else if(first->credId > second->credId)
+    {
+        return 1;
+    }
+    else
+        return 0;
+}
+
+/**
+ * GetCredId goes through the cred list and returns the next
+ * available credId. The next credId could be the credId that is
+ * available due deletion of OicSecCred_t object or one more than
+ * credId of last credential in the list.
+ *
+ * @retval
+ *      next available credId  - success
+ *      0                      - error
+ */
+
+static uint16_t GetCredId()
+{
+    //Sorts credential list in incremental order of credId
+    LL_SORT(gCred, CmpCredId);
+
+
+    OicSecCred_t *currentCred = NULL, *credTmp = NULL;
+    uint16_t nextCredId = 1;
+
+    LL_FOREACH_SAFE(gCred, currentCred, credTmp)
+    {
+        if(currentCred->credId == nextCredId)
+        {
+            nextCredId += 1;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
+    return nextCredId;
+
+exit:
+    return 0;
+}
+/**
+ * This function adds the new cred to the credential list.
+ *
+ * @param cred pointer to new credential.
+ *
+ * @retval
+ *      OC_STACK_OK     - cred not NULL and persistent storage gets updated
+ *      OC_STACK_ERROR  - cred is NULL or fails to update persistent storage
+ */
+OCStackResult AddCredential(OicSecCred_t * newCred)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    char * jsonStr = NULL;
+
+    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
+
+    //Assigning credId to the newCred
+    newCred->credId = GetCredId();
+
+    VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
+
+    //Append the new Cred to existing list
+    LL_APPEND(gCred, newCred);
+
+    //Convert CredList to JSON and update the persistent Storage
+    jsonStr = BinToCredJSON(gCred);
+
+    if(jsonStr)
+    {
+        cJSON *jsonCred = cJSON_Parse(jsonStr);
+        OICFree(jsonStr);
+
+        if((jsonCred) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, jsonCred)))
+        {
+            ret = OC_STACK_OK;
+        }
+        cJSON_Delete(jsonCred);
+    }
+
+exit:
+    return ret;
+}
+
+static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
+{
+    OCEntityHandlerResult ret = OC_EH_ERROR;
+
+    //Get binary representation of json
+    OicSecCred_t * cred  = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
+
+    if(cred)
+    {
+        //If the Post request credential has credId, it will be
+        //discarded and the next available credId will be assigned
+        //to it before getting appended to the existing credential
+        //list and updating svr database.
+        ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
+    }
+
+    return ret;
+}
+
+/*
+ * This internal method is the entity handler for Cred resources
+ * to handle REST request (PUT/POST/DEL)
+ */
+OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
+                                        OCEntityHandlerRequest * ehRequest,
+                                        void* callbackParameter)
+{
+    OCEntityHandlerResult ret = OC_EH_ERROR;
+
+    if(!ehRequest)
+    {
+        return OC_EH_ERROR;
+    }
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        //TODO :  Handle PUT/DEL methods
+        switch(ehRequest->method)
+        {
+            case OC_REST_GET:
+                ret = OC_EH_FORBIDDEN;
+                break;
+            case OC_REST_POST:
+                ret = HandlePostRequest(ehRequest);
+                break;
+            default:
+                ret = OC_EH_ERROR;
+                break;
+        }
+    }
+
+    //Send payload to request originator
+    ret = (SendSRMResponse(ehRequest, ret, NULL) == OC_STACK_OK ?
+                       ret : OC_EH_ERROR);
+
+    return ret;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/Cred' resource.
+ */
+OCStackResult CreateCredResource()
+{
+    OCStackResult ret;
+
+    ret = OCCreateResource(&gCredHandle,
+                           OIC_RSRC_TYPE_SEC_CRED,
+                           OIC_MI_DEF,
+                           OIC_RSRC_CRED_URI,
+                           CredEntityHandler,
+                           NULL,
+                           OC_RES_PROP_NONE);
+
+    if (OC_STACK_OK != ret)
+    {
+        OC_LOG (FATAL, TAG, PCF("Unable to instantiate Cred resource"));
+        DeInitCredResource();
+    }
+    return ret;
+}
+
+/**
+ * Get the default value
+ * @retval  NULL for now. Update it when we finalize the default info.
+ */
+static OicSecCred_t* GetCredDefault()
+{
+    return NULL;
+}
+
+/**
+ * Initialize Cred resource by loading data from persistent storage.
+ *
+ * @retval
+ *     OC_STACK_OK    - no errors
+ *     OC_STACK_ERROR - stack process error
+ */
+OCStackResult InitCredResource()
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    //Read Cred resource from PS
+    char* jsonSVRDatabase = GetSVRDatabase();
+
+    if (jsonSVRDatabase)
+    {
+        //Convert JSON Cred into binary format
+        gCred = JSONToCredBin(jsonSVRDatabase);
+    }
+    /*
+     * If SVR database in persistent storage got corrupted or
+     * is not available for some reason, a default Cred is created
+     * which allows user to initiate Cred provisioning again.
+     */
+    if (!jsonSVRDatabase || !gCred)
+    {
+        gCred = GetCredDefault();
+    }
+    //Instantiate 'oic.sec.cred'
+    ret = CreateCredResource();
+    OICFree(jsonSVRDatabase);
+    return ret;
+}
+
+/**
+ * Perform cleanup for Cred resources.
+ *
+ * @return
+ *     OC_STACK_OK              - no errors
+ *     OC_STACK_ERROR           - stack process error
+ *     OC_STACK_NO_RESOURCE     - resource not found
+ *     OC_STACK_INVALID_PARAM   - invalid param
+ */
+OCStackResult DeInitCredResource()
+{
+    OCStackResult result = OCDeleteResource(gCredHandle);
+    DeleteCredList(gCred);
+    gCred = NULL;
+    return result;
+}
+
+/**
+ * This method is used by tinydtls/SRM to retrieve credential for given Subject.
+ *
+ * @param subject - subject for which credential is required.
+ *
+ * @retval
+ *     reference to OicSecCred_t - if credential is found
+ *     NULL                      - if credential not found
+ */
+const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
+{
+    OicSecCred_t *cred = NULL;
+
+    if ( NULL == subject)
+    {
+        return NULL;
+    }
+
+    LL_FOREACH(gCred, cred)
+    {
+        if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
+        {
+             return cred;
+        }
+    }
+    return NULL;
+}
+
+
+#if defined(__WITH_DTLS__)
+/**
+ * This internal callback is used by lower stack (i.e. CA layer) to
+ * retrieve PSK credentials from RI security layer.
+ *
+ * Note: When finished, caller should initialize memory to zeros and
+ * invoke OICFree to delete @p credInfo.
+ *
+ * @param credInfo
+ *     binary blob containing PSK credentials
+ *
+ * @retval none
+ */
+void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
+{
+    CADtlsPskCredsBlob_t * caBlob = NULL;
+    if(credInfo)
+    {
+        caBlob = (CADtlsPskCredsBlob_t *)OICCalloc(sizeof(CADtlsPskCredsBlob_t), 1);
+        if (caBlob)
+        {
+            OicUuid_t deviceID = {};
+
+            // Retrieve Device ID from doxm resource and copy in PSK creds blob
+            VERIFY_SUCCESS(TAG, GetDoxmDeviceID(&deviceID) == OC_STACK_OK, ERROR);
+            memcpy(caBlob->identity, deviceID.id, sizeof(caBlob->identity));
+
+            OicSecCred_t *cred = NULL;
+            size_t count = 0;
+            LL_FOREACH(gCred, cred)
+            {
+                // Currently, Iotivity supports only symmetric pair wise key credentials
+                if (cred->credType == SYMMETRIC_PAIR_WISE_KEY)
+                {
+                    ++count;
+                }
+            }
+            caBlob->num = count;
+            if (caBlob->num)
+            {
+                caBlob->creds =
+                    (OCDtlsPskCreds*) OICMalloc(caBlob->num * sizeof(OCDtlsPskCreds));
+                VERIFY_NON_NULL(TAG, caBlob->creds, ERROR);
+
+                unsigned int i = 0;
+                LL_FOREACH(gCred, cred)
+                {
+                    if ((cred->credType == SYMMETRIC_PAIR_WISE_KEY) &&
+                            (i < count))
+
+                    {
+                        // Copy subject ID
+                        memcpy(caBlob->creds[i].id, cred->subject.id,
+                                sizeof(caBlob->creds[i].id));
+
+                        // Convert PSK from JSON to binary before copying
+                        uint32_t outLen = 0;
+                        B64Result b64Ret = b64Decode(cred->privateData.data,
+                                strlen(cred->privateData.data), caBlob->creds[i].psk,
+                                sizeof(caBlob->creds[i].psk), &outLen);
+                        VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+                        i++;
+                    }
+                }
+            }
+        }
+        *credInfo = caBlob;
+        // Return from here after making the credential list
+        return;
+    }
+
+exit:
+    if (caBlob)
+    {
+        memset(caBlob->creds, 0, caBlob->num * sizeof(OCDtlsPskCreds));
+        OICFree(caBlob->creds);
+    }
+    OICFree(caBlob);
+}
+#endif /* __WITH_DTLS__ */
diff --git a/resource/csdk/security/src/doxmresource.c b/resource/csdk/security/src/doxmresource.c
new file mode 100755 (executable)
index 0000000..5389595
--- /dev/null
@@ -0,0 +1,719 @@
+//******************************************************************
+//
+// 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 "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "resourcemanager.h"
+#include "doxmresource.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
+#include "base64.h"
+#include "ocrandom.h"
+#include "cainterface.h"
+#include "credresource.h"
+#include "ocserverrequest.h"
+#include "srmutility.h"
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#define TAG  PCF("SRM-DOXM")
+
+static OicSecDoxm_t        *gDoxm = NULL;
+static OCResourceHandle    gDoxmHandle = NULL;
+
+static OicSecOxm_t gOicSecDoxmJustWorks = OIC_JUST_WORKS;
+static OicSecDoxm_t gDefaultDoxm =
+{
+    NULL,                   /* OicUrn_t *oxmType */
+    0,                      /* size_t oxmTypeLen */
+    &gOicSecDoxmJustWorks,  /* uint16_t *oxm */
+    1,                      /* size_t oxmLen */
+    OIC_JUST_WORKS,         /* uint16_t oxmSel */
+    false,                  /* bool owned */
+    {},                     /* OicUuid_t deviceID */
+    {},                     /* OicUuid_t owner */
+};
+
+void DeleteDoxmBinData(OicSecDoxm_t* doxm)
+{
+    if (doxm)
+    {
+        //Clean oxmType
+        for(int i = 0; i < doxm->oxmTypeLen; i++)
+        {
+            OICFree(doxm->oxmType[i]);
+        }
+        OICFree(doxm->oxmType);
+
+        //clean oxm
+        OICFree(doxm->oxm);
+
+        //Clean doxm itself
+        OICFree(doxm);
+    }
+}
+
+char * BinToDoxmJSON(const OicSecDoxm_t * doxm)
+{
+    if (NULL == doxm)
+    {
+        return NULL;
+    }
+
+    char *jsonStr = NULL;
+    cJSON *jsonDoxm = NULL;
+    char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+    uint32_t outLen = 0;
+    B64Result b64Ret = B64_OK;
+
+    cJSON *jsonRoot = cJSON_CreateObject();
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    jsonDoxm = cJSON_CreateObject();
+    VERIFY_NON_NULL(TAG, jsonDoxm, ERROR);
+    cJSON_AddItemToObject(jsonRoot, OIC_JSON_DOXM_NAME, jsonDoxm );
+
+    //OxmType -- Not Mandatory
+    if(doxm->oxmTypeLen > 0)
+    {
+        cJSON *jsonOxmTyArray = cJSON_CreateArray();
+        VERIFY_NON_NULL(TAG, jsonOxmTyArray, ERROR);
+        cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_TYPE_NAME, jsonOxmTyArray );
+        for (size_t i = 0; i < doxm->oxmTypeLen; i++)
+        {
+            cJSON_AddItemToArray (jsonOxmTyArray, cJSON_CreateString(doxm->oxmType[i]));
+        }
+    }
+
+    //Oxm -- Not Mandatory
+    if(doxm->oxmLen > 0)
+    {
+        cJSON *jsonOxmArray = cJSON_CreateArray();
+        VERIFY_NON_NULL(TAG, jsonOxmArray, ERROR);
+        cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_NAME,jsonOxmArray );
+        for (size_t i = 0; i < doxm->oxmLen; i++)
+        {
+            cJSON_AddItemToArray (jsonOxmArray, cJSON_CreateNumber(doxm->oxm[i]));
+        }
+    }
+
+    //OxmSel -- Mandatory
+    cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_OXM_SEL_NAME, (int)doxm->oxmSel);
+
+    //Owned -- Mandatory
+    cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_OWNED_NAME, doxm->owned);
+
+    //TODO: Need more clarification on deviceIDFormat field type.
+#if 0
+    //DeviceIdFormat -- Mandatory
+    cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_DEVICE_ID_FORMAT_NAME, doxm->deviceIDFormat);
+#endif
+
+    //DeviceId -- Mandatory
+    outLen = 0;
+    b64Ret = b64Encode(doxm->deviceID.id, sizeof(doxm->deviceID.id), base64Buff,
+                    sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+    cJSON_AddStringToObject(jsonDoxm, OIC_JSON_DEVICE_ID_NAME, base64Buff);
+
+    //Owner -- Mandatory
+    outLen = 0;
+    b64Ret = b64Encode(doxm->owner.id, sizeof(doxm->owner.id), base64Buff,
+                    sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+    cJSON_AddStringToObject(jsonDoxm, OIC_JSON_OWNER_NAME, base64Buff);
+
+    jsonStr = cJSON_PrintUnformatted(jsonRoot);
+
+exit:
+    if (jsonRoot)
+    {
+        cJSON_Delete(jsonRoot);
+    }
+    return jsonStr;
+}
+
+OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
+{
+
+    if (NULL == jsonStr)
+    {
+        return NULL;
+    }
+
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecDoxm_t *doxm =  NULL;
+    cJSON *jsonDoxm = NULL;
+    cJSON *jsonObj = NULL;
+
+    size_t jsonObjLen = 0;
+    unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+    uint32_t outLen = 0;
+    B64Result b64Ret = B64_OK;
+
+    cJSON *jsonRoot = cJSON_Parse(jsonStr);
+    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+    jsonDoxm = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
+    VERIFY_NON_NULL(TAG, jsonDoxm, ERROR);
+
+    doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t));
+    VERIFY_NON_NULL(TAG, doxm, ERROR);
+
+    //OxmType -- not Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_TYPE_NAME);
+    if ((jsonObj) && (cJSON_Array == jsonObj->type))
+    {
+        doxm->oxmTypeLen = cJSON_GetArraySize(jsonObj);
+        VERIFY_SUCCESS(TAG, doxm->oxmTypeLen > 0, ERROR);
+
+        doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
+        VERIFY_NON_NULL(TAG, (doxm->oxmType), ERROR);
+
+        for(int i  = 0; i < doxm->oxmTypeLen ; i++)
+        {
+            cJSON *jsonOxmTy = cJSON_GetArrayItem(jsonObj, i);
+            VERIFY_NON_NULL(TAG, jsonOxmTy, ERROR);
+
+            jsonObjLen = strlen(jsonOxmTy->valuestring) + 1;
+            doxm->oxmType[i] = (char*)OICMalloc(jsonObjLen);
+            VERIFY_NON_NULL(TAG, doxm->oxmType[i], ERROR);
+            strncpy((char *)doxm->oxmType[i], (char *)jsonOxmTy->valuestring, jsonObjLen);
+        }
+    }
+
+    //Oxm -- not Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_NAME);
+    if (jsonObj && cJSON_Array == jsonObj->type)
+    {
+        doxm->oxmLen = cJSON_GetArraySize(jsonObj);
+        VERIFY_SUCCESS(TAG, doxm->oxmLen > 0, ERROR);
+
+        doxm->oxm = (OicSecOxm_t*)OICCalloc(doxm->oxmLen, sizeof(OicSecOxm_t));
+        VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
+
+        for(int i  = 0; i < doxm->oxmLen ; i++)
+        {
+            cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
+            VERIFY_NON_NULL(TAG, jsonOxm, ERROR);
+            doxm->oxm[i] = (OicSecOxm_t)jsonOxm->valueint;
+        }
+    }
+
+    //OxmSel -- Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
+    if(jsonObj)
+    {
+        VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR)
+        doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
+    }
+    else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
+    {
+        VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+        doxm->oxmSel = gDoxm->oxmSel;
+    }
+
+    //Owned -- Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
+    if(jsonObj)
+    {
+        VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR)
+        doxm->owned = jsonObj->valueint;
+    }
+    else // PUT/POST JSON may not have owned so set it to the gDomx->owned
+    {
+        VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+        doxm->owned = gDoxm->owned;
+    }
+
+    //DeviceId -- Mandatory
+    jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVICE_ID_NAME);
+    if(jsonObj)
+    {
+        VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+        if(cJSON_String == jsonObj->type)
+        {
+            //Check for empty string, in case DeviceId field has not been set yet
+            if (jsonObj->valuestring[0])
+            {
+                outLen = 0;
+                b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
+                        sizeof(base64Buff), &outLen);
+                VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(doxm->deviceID.id)),
+                                ERROR);
+                memcpy(doxm->deviceID.id, base64Buff, outLen);
+            }
+        }
+    }
+    else // PUT/POST JSON will not have deviceID so set it to the gDoxm->deviceID.id
+    {
+        VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+        VERIFY_SUCCESS(TAG, strcmp((char *)gDoxm->deviceID.id, "") != 0, ERROR);
+        strncpy((char *)doxm->deviceID.id, (char *)gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
+    }
+
+    // Owner -- will be empty when device state is unowned.
+    if (true == doxm->owned)
+    {
+        jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
+        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(doxm->owner.id)), ERROR);
+        memcpy(doxm->owner.id, base64Buff, outLen);
+    }
+
+    ret = OC_STACK_OK;
+
+exit:
+    cJSON_Delete(jsonRoot);
+    if (OC_STACK_OK != ret)
+    {
+        DeleteDoxmBinData(doxm);
+        doxm = NULL;
+    }
+
+    return doxm;
+}
+
+/**
+ * @todo document this function including why code might need to call this.
+ * The current suspicion is that it's not being called as much as it should.
+ */
+static bool UpdatePersistentStorage(OicSecDoxm_t * doxm)
+{
+    bool bRet = false;
+
+    if (NULL != doxm)
+    {
+        // Convert Doxm data into JSON for update to persistent storage
+        char *jsonStr = BinToDoxmJSON(doxm);
+        if (jsonStr)
+        {
+            cJSON *jsonDoxm = cJSON_Parse(jsonStr);
+            OICFree(jsonStr);
+
+            if (jsonDoxm &&
+                    (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_DOXM_NAME, jsonDoxm)))
+            {
+                bRet = true;
+            }
+            cJSON_Delete(jsonDoxm);
+        }
+    }
+
+    return bRet;
+}
+
+static bool ValidateQuery(unsigned char * query)
+{
+    // Send doxm resource data if the state of doxm resource
+    // matches with the query parameters.
+    // else send doxm resource data as NULL
+    // TODO Remove this check and rely on Policy Engine
+    // and Provisioning Mode to enforce provisioning-state
+    // access rules. Eventually, the PE and PM code will
+    // not send a request to the /doxm Entity Handler at all
+    // if it should not respond.
+    OC_LOG (INFO, TAG, PCF("In ValidateQuery"));
+    if(NULL == gDoxm)
+    {
+        return false;
+    }
+
+    OicParseQueryIter_t parseIter = {};
+
+    ParseQueryIterInit(query, &parseIter);
+
+    while(GetNextQuery(&parseIter))
+    {
+        if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_OWNED_NAME, parseIter.attrLen) == 0)
+        {
+            if((strncasecmp((char *)parseIter.valPos, OIC_SEC_TRUE, parseIter.valLen) == 0) &&
+                    (gDoxm->owned))
+            {
+                return true;
+            }
+            else if((strncasecmp((char *)parseIter.valPos, OIC_SEC_FALSE, parseIter.valLen) == 0)
+                    && (!gDoxm->owned))
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+    char* jsonStr = NULL;
+    OCEntityHandlerResult ehRet = OC_EH_OK;
+
+    OC_LOG (INFO, TAG, PCF("Doxm EntityHandle processing GET request"));
+
+    //Checking if Get request is a query.
+    if(ehRequest->query)
+    {
+        OC_LOG (INFO, TAG, PCF("HandleDoxmGetRequest processing query"));
+        if(!ValidateQuery((unsigned char *)ehRequest->query))
+        {
+            ehRet = OC_EH_ERROR;
+        }
+    }
+
+    /*
+     * For GET or Valid Query request return doxm resource json payload.
+     * For non-valid query return NULL json payload.
+     * A device will 'always' have a default Doxm, so BinToDoxmJSON will
+     * return valid doxm resource json.
+     */
+
+    jsonStr = (ehRet == OC_EH_OK) ? BinToDoxmJSON(gDoxm) : NULL;
+
+    // Send response payload to request originator
+    if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, jsonStr))
+    {
+        OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandleDoxmGetRequest"));
+    }
+
+    OICFree(jsonStr);
+
+    return ehRet;
+}
+
+
+static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest)
+{
+    OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  processing PUT request"));
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+    OicUuid_t emptyOwner = {};
+
+    /*
+     * Convert JSON Doxm data into binary. This will also validate
+     * the Doxm data received.
+     */
+    OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
+
+    if (newDoxm)
+    {
+        // Iotivity SRM ONLY supports OIC_JUST_WORKS now
+        if (OIC_JUST_WORKS == newDoxm->oxmSel)
+        {
+            /*
+             * If current state of the device is un-owned, enable
+             * anonymous ECDH cipher in tinyDTLS so that Provisioning
+             * tool can initiate JUST_WORKS ownership transfer process.
+             */
+            if ((false == gDoxm->owned) && (false == newDoxm->owned))
+            {
+                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  enabling AnonECDHCipherSuite"));
+#ifdef __WITH_DTLS__
+                ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
+#endif //__WITH_DTLS__
+                goto exit;
+            }
+
+            /*
+             * When current state of the device is un-owned and Provisioning
+             * Tool is attempting to change the state to 'Owned' with a
+             * qualified value for the field 'Owner'
+             */
+            if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
+                (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0))
+            {
+                /*
+                 * Generate OwnerPSK and create credential for Provisioning
+                 * tool with the generated OwnerPSK.
+                 * Update persistent storage and disable anonymous ECDH cipher
+                 *
+                 */
+#ifdef __WITH_DTLS__
+                CAResult_t pskRet;
+
+                OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
+                uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
+
+                //Generating OwnerPSK
+                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  generating OwnerPSK"));
+                pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr,
+                        (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS),
+                        newDoxm->owner.id, sizeof(newDoxm->owner.id),
+                        gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
+                        ownerPSK, OWNER_PSK_LENGTH_128);
+
+                VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
+
+                //Generating new credential for provisioning tool
+                size_t ownLen = 1;
+                uint32_t outLen = 0;
+
+                char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
+                B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff,
+                                sizeof(base64Buff), &outLen);
+                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+                OC_LOG (INFO, TAG, PCF("Doxm EntityHandle  generating Credential"));
+                OicSecCred_t *cred = GenerateCredential(&newDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
+                                        NULL, base64Buff, ownLen, &newDoxm->owner);
+                VERIFY_NON_NULL(TAG, cred, ERROR);
+
+                //Adding provisioning tool credential to cred Resource.
+                VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
+
+                gDoxm->owned = true;
+                memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+
+                // Update new state in persistent storage
+                if (true == UpdatePersistentStorage(gDoxm))
+                {
+                    ehRet = OC_EH_OK;
+                }
+                else
+                {
+                    ehRet = OC_EH_ERROR;
+
+                    /*
+                     * If persistent storage update failed, revert back the state
+                     * for global variable.
+                     */
+                    gDoxm->owned = false;
+                    memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
+                }
+
+                /*
+                 * Disable anonymous ECDH cipher in tinyDTLS since device is now
+                 * in owned state.
+                 */
+                CAEnableAnonECDHCipherSuite(false);
+#endif //__WITH_DTLS__
+            }
+        }
+    }
+
+exit:
+
+    //Send payload to request originator
+    if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
+    {
+        OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandlePstatPostRequest"));
+    }
+    DeleteDoxmBinData(newDoxm);
+
+    return ehRet;
+}
+
+/*
+ * This internal method is the entity handler for DOXM resources.
+ */
+OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag,
+                                        OCEntityHandlerRequest * ehRequest,
+                                        void* callbackParam)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+    if(NULL == ehRequest)
+    {
+        return ehRet;
+    }
+
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        switch (ehRequest->method)
+        {
+            case OC_REST_GET:
+                ehRet = HandleDoxmGetRequest(ehRequest);
+                break;
+
+            case OC_REST_PUT:
+                ehRet = HandleDoxmPutRequest(ehRequest);
+                break;
+
+            default:
+                ehRet = OC_EH_ERROR;
+                SendSRMResponse(ehRequest, ehRet, NULL);
+                break;
+        }
+    }
+
+    return ehRet;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/doxm' resource.
+ */
+OCStackResult CreateDoxmResource()
+{
+    OCStackResult ret;
+
+    ret = OCCreateResource(&gDoxmHandle,
+                           OIC_RSRC_TYPE_SEC_DOXM,
+                           OIC_MI_DEF,
+                           OIC_RSRC_DOXM_URI,
+                           DoxmEntityHandler,
+                           NULL,
+                           OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+
+    if (OC_STACK_OK != ret)
+    {
+        OC_LOG (FATAL, TAG, PCF("Unable to instantiate Doxm resource"));
+        DeInitDoxmResource();
+    }
+    return ret;
+}
+
+/**
+ * Checks if DeviceID is generated during provisioning for the new device.
+ * If DeviceID is NULL then generates the new DeviceID.
+ * Once DeviceID is assigned to the device it does not change for the lifetime of the device.
+ *
+ */
+void CheckDeviceID()
+{
+    if(strcmp((char *)gDoxm->deviceID.id, "") == 0 )
+    {
+        OCFillRandomMem(gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id));
+        UpdatePersistentStorage(gDoxm);
+    }
+}
+
+/**
+ * Get the default value.
+ * @retval  the gDefaultDoxm pointer;
+ */
+static OicSecDoxm_t* GetDoxmDefault()
+{
+    OC_LOG (INFO, TAG, PCF("GetDoxmToDefault"));
+    return &gDefaultDoxm;
+}
+
+/**
+ * This method is used by SRM to retrieve DOXM resource data.
+ *
+ * @retval  reference to @ref OicSecDoxm_t, binary format of Doxm resource data
+ */
+const OicSecDoxm_t* GetDoxmResourceData()
+{
+    return gDoxm;
+}
+
+/**
+ * Initialize DOXM resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitDoxmResource()
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    //Read DOXM resource from PS
+    char* jsonSVRDatabase = GetSVRDatabase();
+    if(jsonSVRDatabase)
+    {
+        //Convert JSON DOXM into binary format
+        gDoxm = JSONToDoxmBin(jsonSVRDatabase);
+    }
+    /*
+     * If SVR database in persistent storage got corrupted or
+     * is not available for some reason, a default doxm is created
+     * which allows user to initiate doxm provisioning again.
+     */
+    if(!jsonSVRDatabase || !gDoxm)
+    {
+        gDoxm = GetDoxmDefault();
+    }
+    CheckDeviceID();
+    //Instantiate 'oic.sec.doxm'
+    ret = CreateDoxmResource();
+    OICFree(jsonSVRDatabase);
+    return ret;
+}
+
+/**
+ * Perform cleanup for DOXM resources.
+ *
+ * @return
+ * OC_STACK_OK    - no error
+ * OC_STACK_ERROR - stack process error
+ *
+ */
+OCStackResult DeInitDoxmResource()
+{
+    OCStackResult ret = OCDeleteResource(gDoxmHandle);
+    if(gDoxm  != &gDefaultDoxm)
+    {
+        DeleteDoxmBinData(gDoxm);
+    }
+    gDoxm = NULL;
+
+    if(OC_STACK_OK == ret)
+    {
+        return OC_STACK_OK;
+    }
+    else
+    {
+        return OC_STACK_ERROR;
+    }
+}
+
+
+/**
+ * This method returns the SRM device ID for this device.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID)
+{
+    if(deviceID && gDoxm)
+    {
+       *deviceID = gDoxm->deviceID;
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+
+/**
+ * @brief Gets the OicUuid_t value for the owner of this device.
+ *
+ * @return OC_STACK_OK if devOwner is a valid UUID, otherwise OC_STACK_ERROR.
+ */
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if(gDoxm)
+    {
+        if(gDoxm->owned) {
+            *devOwner = gDoxm->owner; // TODO change to devOwner when available
+            retVal = OC_STACK_OK;
+        }
+    }
+    return retVal;
+}
diff --git a/resource/csdk/security/src/ocsecurity.c b/resource/csdk/security/src/ocsecurity.c
deleted file mode 100644 (file)
index 3dfe6e0..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "ocstack.h"
-#include "ocmalloc.h"
-#include "ocsecurity.h"
-#include "ocsecurityconfig.h"
-#include "cainterface.h"
-#include <string.h>
-
-static OCSecConfigData* secConfigData;
-static int secConfigDataLen;
-
-
-/**
- * This internal API removes/clears the global variable holding the security
- * config data. This needs to be invoked when OIC stack is shutting down.
- *
- * @retval none
- */
-void DeinitOCSecurityInfo()
-{
-    if (secConfigData)
-    {
-        // Initialize sensitive data to zeroes before freeing.
-        memset(secConfigData, 0, secConfigDataLen);
-
-        OCFree(secConfigData);
-        secConfigData = NULL;
-    }
-}
-
-/**
- * This internal callback is used by lower stack (i.e. CA layer) to
- * retrieve PSK credentials from RI security layer.
- *
- * Note: When finished, caller should initialize memory to zeroes and
- * invoke OCFree to delete @p credInfo.
- *
- * @param credInfo
- *     binary blob containing PSK credentials
- *
- * @retval none
- */
-#ifdef __WITH_DTLS__
-void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
-{
-    // CA layer interface publishes security data structures ONLY if
-    // stack is compiled in SECURED mode
-    CADtlsPskCredsBlob_t * caBlob = NULL;
-    if(secConfigData && credInfo)
-    {
-        unsigned int i = 0;
-        OCSecBlob * osb = (OCSecBlob*)secConfigData->blob;
-        for ( ;(i<secConfigData->numBlob) && osb; i++)
-        {
-            if (osb->type == OC_BLOB_TYPE_PSK)
-            {
-                caBlob = (CADtlsPskCredsBlob_t *)OCCalloc(sizeof(CADtlsPskCredsBlob_t), 1);
-                if (caBlob)
-                {
-                    OCDtlsPskCredsBlob * ocBlob = (OCDtlsPskCredsBlob *)osb->val;
-
-                    memcpy(caBlob->identity, ocBlob->identity, sizeof(caBlob->identity));
-                    caBlob->num = ocBlob->num;
-                    caBlob->creds =
-                        (OCDtlsPskCreds*) OCMalloc(caBlob->num * sizeof(OCDtlsPskCreds));
-                    if (caBlob->creds)
-                    {
-                        memcpy(caBlob->creds, ocBlob->creds,
-                                caBlob->num * sizeof(OCDtlsPskCreds));
-                        *credInfo = caBlob;
-                        // We copied the credential blob in the CA data structure.
-                        // Let's get out of here.
-                        return;
-                    }
-                }
-                break;
-            }
-            osb = config_data_next_blob(osb);
-        }
-    }
-
-    // Clear memory if any memory allocation failed above
-    if(caBlob)
-    {
-        OCFree(caBlob->creds);
-        OCFree(caBlob);
-    }
-}
-#endif //__WITH_DTLS__
-
-
-/**
- * This method validates the sanctity of OCDtlsPskCredsBlob.
- *
- * @param secBlob
- *     binary blob containing PSK credentials
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
-static
-OCStackResult ValidateBlobTypePSK(const OCSecBlob *secBlob)
-{
-    OCDtlsPskCredsBlob *pskCredsBlob;
-    uint16_t validLen;
-
-    if(!secBlob || secBlob->len == 0)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    pskCredsBlob = (OCDtlsPskCredsBlob *)secBlob->val;
-
-    //calculate the expected length of PSKCredsBlob
-    if(pskCredsBlob->num >= 1)
-    {
-        validLen = sizeof(OCDtlsPskCredsBlob) +
-            (pskCredsBlob->num - 1) * sizeof(OCDtlsPskCredsBlob);
-    }
-    else
-    {
-        validLen = sizeof(OCDtlsPskCredsBlob);
-    }
-
-    if(secBlob->len != validLen)
-        return OC_STACK_INVALID_PARAM;
-
-    return OC_STACK_OK;
-}
-
-
-/**
- * This method validates the sanctity of configuration data provided
- * by application to OC stack.
- *
- * @param cfgdata
- *     binary blob containing credentials and other config data
- * @param len
- *     length of binary blob
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
-static
-OCStackResult ValidateSecConfigData(const OCSecConfigData *cfgData,
-                size_t len)
-{
-    OCStackResult ret = OC_STACK_OK;
-    unsigned int i = 0;
-    OCSecBlob * osb = NULL;
-
-    if (!cfgData || (len == 0))
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    if (cfgData->version != OCSecConfigVer_CurrentVersion)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    osb = (OCSecBlob*)cfgData->blob;
-    for ( ;(i<cfgData->numBlob) && osb; i++)
-    {
-        if (osb->type == OC_BLOB_TYPE_PSK)
-        {
-            ret = ValidateBlobTypePSK(osb);
-        }
-        else
-        {
-            return OC_STACK_INVALID_PARAM;
-        }
-
-        if (ret != OC_STACK_OK)
-        {
-            return ret;
-        }
-        osb = config_data_next_blob(osb);
-    }
-
-    return ret;
-}
-
-
-
-/**
- * Provides the Security configuration data to OC stack.
- *
- * @param cfgdata
- *     binary blob containing credentials and other config data
- * @param len
- *     length of binary blob
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
-OCStackResult OCSecSetConfigData(const OCSecConfigData *cfgData,
-                size_t len)
-{
-    // Validate the data inside blob before consuming
-    if (cfgData && ValidateSecConfigData(cfgData, len) == OC_STACK_OK)
-    {
-        // Remove existing blob
-        DeinitOCSecurityInfo();
-        // Allocate storage for new blob
-        secConfigData = (OCSecConfigData*)OCMalloc(len);
-        if (secConfigData)
-        {
-            memcpy(secConfigData, cfgData, len);
-            secConfigDataLen = len;
-            return OC_STACK_OK;
-        }
-
-        return OC_STACK_NO_MEMORY;
-    }
-
-    return OC_STACK_INVALID_PARAM;
-}
-
-
-
diff --git a/resource/csdk/security/src/policyengine.c b/resource/csdk/security/src/policyengine.c
new file mode 100644 (file)
index 0000000..c39814d
--- /dev/null
@@ -0,0 +1,373 @@
+//******************************************************************
+//
+// 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 "oic_malloc.h"
+#include "policyengine.h"
+#include "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "logger.h"
+#include "aclresource.h"
+#include "srmutility.h"
+#include "doxmresource.h"
+#include <string.h>
+
+#define TAG PCF("SRM-PE")
+
+/**
+ * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t.
+ */
+uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method)
+{
+    uint16_t perm = 0;
+    switch(method)
+    {
+        case CA_GET:
+            perm = (uint16_t)PERMISSION_READ;
+            break;
+        case CA_POST: // For now we treat all PUT & POST as Write
+        case CA_PUT:  // because we don't know if resource exists yet.
+            perm = (uint16_t)PERMISSION_WRITE;
+            break;
+        case CA_DELETE:
+            perm = (uint16_t)PERMISSION_DELETE;
+            break;
+        default: // if not recognized, must assume requesting full control
+            perm = (uint16_t)PERMISSION_FULL_CONTROL;
+            break;
+    }
+    return perm;
+}
+
+/**
+ * @brief Compares two OicUuid_t structs.
+ * @return true if the two OicUuid_t structs are equal, else false.
+ */
+bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId)
+{
+    // TODO use VERIFY macros to check for null when they are merged.
+    if(NULL == firstId || NULL == secondId)
+    {
+        return false;
+    }
+    for(int i = 0; i < UUID_LENGTH; i++)
+    {
+        if(firstId->id[i] != secondId->id[i])
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+/**
+ * Set the state and clear other stateful context vars.
+ */
+void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
+{
+    // Clear stateful context variables.
+    OICFree(context->subject);
+    context->subject = NULL;
+    OICFree(context->resource);
+    context->resource = NULL;
+    context->permission = 0x0;
+    context->matchingAclFound = false;
+    context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+
+    // Set state.
+    context->state = state;
+}
+
+/**
+ * @brief Compare the request's subject to DevOwner.
+ *
+ * @return true if context->subjectId == GetDoxmDevOwner(), else false
+ */
+bool IsRequestFromDevOwner(PEContext_t *context)
+{
+    bool retVal = false;
+    OicUuid_t owner;
+
+    if(OC_STACK_OK == GetDoxmDevOwnerId(&owner))
+    {
+        retVal = UuidCmp(context->subject, &owner);
+    }
+
+    return retVal;
+}
+
+/**
+ * Bitwise check to see if 'permission' contains 'request'.
+ * @param   permission  The allowed CRUDN permission.
+ * @param   request     The CRUDN permission being requested.
+ * @return true if 'permission' bits include all 'request' bits.
+ */
+static inline bool IsPermissionAllowingRequest(const uint16_t permission,
+    const uint16_t request)
+{
+    if(request == (request & permission))
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+/**
+ * Compare the passed subject to the wildcard (aka anonymous) subjectId.
+ * @return true if 'subject' is the wildcard, false if it is not.
+ */
+static inline bool IsWildCardSubject(OicUuid_t *subject)
+{
+    // Because always comparing to string literal, use strcmp()
+    if(0 == memcmp(subject, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)))
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+/**
+ * Copy the subject, resource and permission into the context fields.
+ */
+void CopyParamsToContext(
+    PEContext_t     *context,
+    const OicUuid_t *subjectId,
+    const char      *resource,
+    const uint16_t  requestedPermission)
+{
+    size_t length = 0;
+
+    // Free any existing subject.
+    OICFree(context->subject);
+    // Copy the subjectId into context.
+    context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
+    VERIFY_NON_NULL(TAG, context->subject, ERROR);
+    memcpy(context->subject, subjectId, sizeof(OicUuid_t));
+
+    // Copy the resource string into context.
+    length = strlen(resource) + 1;
+    if(0 < length)
+    {
+        OICFree(context->resource);
+        context->resource = (char*)OICMalloc(length);
+        VERIFY_NON_NULL(TAG, context->resource, ERROR);
+        strncpy(context->resource, resource, length);
+        context->resource[length - 1] = '\0';
+    }
+
+    // Assign the permission field.
+    context->permission = requestedPermission;
+
+exit:
+    return;
+}
+
+/**
+ * Check whether 'resource' is in the passed ACL.
+ * @param   resource    The resource to search for.
+ * @param   acl         The ACL to check.
+ * @return true if 'resource' found, otherwise false.
+ */
+ bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl)
+ {
+    for(size_t n = 0; n < acl->resourcesLen; n++)
+    {
+        if(0 == strcmp(resource, acl->resources[n]) || // TODO null terms?
+         0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n]))
+        {
+            return true;
+        }
+    }
+    return false;
+ }
+
+/**
+ * Find ACLs containing context->subject.
+ * Search each ACL for requested resource.
+ * If resource found, check for context->permission.
+ * Set context->retVal to result from first ACL found which contains
+ * correct subject AND resource.
+ *
+ * @retval void
+ */
+void ProcessAccessRequest(PEContext_t *context)
+{
+    OC_LOG(INFO, TAG, PCF("Entering ProcessAccessRequest()"));
+    if(NULL != context)
+    {
+        const OicSecAcl_t *currentAcl = NULL;
+        OicSecAcl_t *savePtr = NULL;
+
+        // Start out assuming subject not found.
+        context->retVal = ACCESS_DENIED_SUBJECT_NOT_FOUND;
+        do
+        {
+            OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): getting ACL..."));
+            currentAcl = GetACLResourceData(context->subject, &savePtr);
+            if(NULL != currentAcl)
+            {
+                // Found the subject, so how about resource?
+                OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                    found ACL matching subject."));
+                context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
+                OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                    Searching for resource..."));
+                if(IsResourceInAcl(context->resource, currentAcl))
+                {
+                    OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                        found matching resource in ACL."));
+                    context->matchingAclFound = true;
+                    // Found the resource, so it's down to permission.
+                    context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION;
+                    if(IsPermissionAllowingRequest(currentAcl->permission, \
+                        context->permission))
+                    {
+                        context->retVal = ACCESS_GRANTED;
+                    }
+                }
+            }
+            else
+            {
+                OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                    no ACL found matching subject ."));
+            }
+        }
+        while((NULL != currentAcl) && (false == context->matchingAclFound));
+
+        if(IsAccessGranted(context->retVal))
+        {
+            OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                Leaving ProcessAccessRequest(ACCESS_GRANTED)"));
+        }
+        else
+        {
+            OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+                Leaving ProcessAccessRequest(ACCESS_DENIED)"));
+        }
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \
+            Leaving ProcessAccessRequest(context is NULL)"));
+    }
+
+}
+
+/**
+ * Check whether a request should be allowed.
+ * @param   context     Pointer to (Initialized) Policy Engine context to use.
+ * @param   subjectId   Pointer to Id of the requesting entity.
+ * @param   resource    Pointer to URI of Resource being requested.
+ * @param   permission  Requested permission.
+ * @return  ACCESS_GRANTED if request should go through,
+ *          otherwise some flavor of ACCESS_DENIED
+ */
+SRMAccessResponse_t CheckPermission(
+    PEContext_t     *context,
+    const OicUuid_t *subjectId,
+    const char      *resource,
+    const uint16_t  requestedPermission)
+{
+    SRMAccessResponse_t retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+
+    VERIFY_NON_NULL(TAG, context, ERROR);
+    VERIFY_NON_NULL(TAG, subjectId, ERROR);
+    VERIFY_NON_NULL(TAG, resource, ERROR);
+
+    // Each state machine context can only be processing one request at a time.
+    // Therefore if the context is not in AWAITING_REQUEST state, return error.
+    // Otherwise, change to BUSY state and begin processing request.
+    if(AWAITING_REQUEST == context->state)
+    {
+        SetPolicyEngineState(context, BUSY);
+        CopyParamsToContext(context, subjectId, resource, requestedPermission);
+        // Before doing any processing, check if request coming
+        // from DevOwner and if so, always GRANT.
+        if(IsRequestFromDevOwner(context))
+        {
+            context->retVal = ACCESS_GRANTED;
+        }
+        else
+        {
+            ProcessAccessRequest(context);
+            // If matching ACL not found, and subject != wildcard, try wildcard.
+            if((false == context->matchingAclFound) && \
+                (false == IsWildCardSubject(context->subject)))
+            {
+                OICFree(context->subject);
+                context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
+                VERIFY_NON_NULL(TAG, context->subject, ERROR);
+                memcpy(context->subject, &WILDCARD_SUBJECT_ID,
+                    sizeof(OicUuid_t));
+                ProcessAccessRequest(context); // TODO anonymous subj can result
+                                               // in confusing err code return.
+            }
+        }
+    }
+    else
+    {
+        context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+    }
+
+    // Capture retVal before resetting state for next request.
+    retVal = context->retVal;
+    SetPolicyEngineState(context, AWAITING_REQUEST);
+
+exit:
+    return retVal;
+}
+
+/**
+ * Initialize the Policy Engine. Call this before calling CheckPermission().
+ * @param   context     Pointer to Policy Engine context to initialize.
+ * @return  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitPolicyEngine(PEContext_t *context)
+{
+    if(NULL != context)
+    {
+        SetPolicyEngineState(context, AWAITING_REQUEST);
+    }
+
+    return OC_STACK_OK;
+}
+
+/**
+ * De-Initialize the Policy Engine.  Call this before exiting to allow Policy
+ * Engine to do cleanup on context.
+ * @param   context     Pointer to Policy Engine context to de-initialize.
+ * @return  none
+ */
+void DeInitPolicyEngine(PEContext_t *context)
+{
+    if(NULL != context)
+    {
+        SetPolicyEngineState(context, STOPPED);
+    }
+
+    return;
+}
diff --git a/resource/csdk/security/src/psinterface.c b/resource/csdk/security/src/psinterface.c
new file mode 100644 (file)
index 0000000..f295fce
--- /dev/null
@@ -0,0 +1,200 @@
+//******************************************************************
+//
+// 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 "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+#include "resourcemanager.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define TAG  PCF("SRM-PSI")
+
+//SVR database buffer block size
+const size_t DB_FILE_SIZE_BLOCK = 1023;
+
+/**
+ * Gets the Secure Virtual Database size.
+ *
+ * @param ps  pointer of OCPersistentStorage for the SVR name ("acl", "cred", "pstat" etc).
+ *
+ * @retval  total size of the SVR database.
+ */
+size_t GetSVRDatabaseSize(OCPersistentStorage* ps)
+{
+    size_t size = 0;
+    if (!ps)
+    {
+        return size;
+    }
+    size_t bytesRead  = 0;
+    char buffer[DB_FILE_SIZE_BLOCK];
+    FILE* fp = ps->open(SVR_DB_FILE_NAME, "r");
+    if (fp)
+    {
+        do
+        {
+            bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
+            size += bytesRead;
+        } while (bytesRead > 0);
+        ps->close(fp);
+    }
+    return size;
+}
+
+/**
+ * Reads the Secure Virtual Database from PS into dynamically allocated
+ * memory buffer.
+ *
+ * @note Caller of this method MUST use OICFree() method to release memory
+ *       referenced by return value.
+ *
+ * @retval  reference to memory buffer containing SVR database.
+ */
+char * GetSVRDatabase()
+{
+    char * jsonStr = NULL;
+    FILE * fp = NULL;
+    OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
+    int size = GetSVRDatabaseSize(ps);
+    if (0 == size)
+    {
+        OC_LOG (ERROR, TAG, PCF("FindSVRDatabaseSize failed"));
+        return NULL;
+    }
+
+    if (ps && ps->open)
+    {
+        // Open default SRM database file. An app could change the path for its server.
+        fp = ps->open(SVR_DB_FILE_NAME, "r");
+        if (fp)
+        {
+            jsonStr = (char*)OICMalloc(size + 1);
+            VERIFY_NON_NULL(TAG, jsonStr, FATAL);
+            size_t bytesRead = ps->read(jsonStr, 1, size, fp);
+            jsonStr[bytesRead] = '\0';
+
+            OC_LOG_V(INFO, TAG, PCF("Read %d bytes from SVR database file"), bytesRead);
+            ps->close(fp);
+            fp = NULL;
+        }
+        else
+        {
+            OC_LOG (ERROR, TAG, PCF("Unable to open SVR database file!!"));
+        }
+    }
+
+exit:
+    if (ps && fp)
+    {
+        ps->close(fp);
+    }
+    return jsonStr;
+}
+
+
+/**
+ * This method is used by a entity handlers of SVR's to update
+ * SVR database.
+ *
+ * @param rsrcName string denoting the SVR name ("acl", "cred", "pstat" etc).
+ * @param jsonObj JSON object containing the SVR contents.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    cJSON *jsonSVRDb = NULL;
+
+    // Read SVR database from PS
+    char* jsonSVRDbStr = GetSVRDatabase();
+    VERIFY_NON_NULL(TAG,jsonSVRDbStr, ERROR);
+
+    // Use cJSON_Parse to parse the existing SVR database
+    jsonSVRDb = cJSON_Parse(jsonSVRDbStr);
+    VERIFY_NON_NULL(TAG,jsonSVRDb, ERROR);
+
+    OICFree(jsonSVRDbStr);
+    jsonSVRDbStr = NULL;
+
+    if (jsonObj->child )
+    {
+        // Create a duplicate of the JSON object which was passed.
+        cJSON* jsonDuplicateObj = cJSON_Duplicate(jsonObj, 1);
+        VERIFY_NON_NULL(TAG,jsonDuplicateObj, ERROR);
+
+        cJSON* jsonObj = cJSON_GetObjectItem(jsonSVRDb, rsrcName);
+
+        /*
+         ACL, PStat & Doxm resources at least have default entries in the database but
+         Cred resource may have no entries. The first cred resource entry (for provisioning tool)
+         is created when the device is owned by provisioning tool and it's ownerpsk is generated.*/
+        if((strcmp(rsrcName, OIC_JSON_CRED_NAME) == 0) && (!jsonObj))
+        {
+            // Add the fist cred object in existing SVR database json
+            cJSON_AddItemToObject(jsonSVRDb, rsrcName, jsonDuplicateObj->child);
+        }
+        else
+        {
+            VERIFY_NON_NULL(TAG,jsonObj, ERROR);
+
+            // Replace the modified json object in existing SVR database json
+            cJSON_ReplaceItemInObject(jsonSVRDb, rsrcName, jsonDuplicateObj->child);
+        }
+
+        // Generate string representation of updated SVR database json object
+        jsonSVRDbStr = cJSON_PrintUnformatted(jsonSVRDb);
+        VERIFY_NON_NULL(TAG,jsonSVRDbStr, ERROR);
+
+        // Update the persistent storage with new SVR database
+        OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
+        if (ps && ps->open)
+        {
+            FILE* fp = ps->open(SVR_DB_FILE_NAME, "w");
+            if (fp)
+            {
+                size_t bytesWritten = ps->write(jsonSVRDbStr, 1, strlen(jsonSVRDbStr), fp);
+                if (bytesWritten == strlen(jsonSVRDbStr))
+                {
+                    ret = OC_STACK_OK;
+                }
+                OC_LOG_V(INFO, TAG, PCF("Written %d bytes into SVR database file"), bytesWritten);
+                ps->close(fp);
+                fp = NULL;
+            }
+            else
+            {
+                OC_LOG (ERROR, TAG, PCF("Unable to open SVR database file!! "));
+            }
+        }
+    }
+
+exit:
+    OICFree(jsonSVRDbStr);
+    cJSON_Delete(jsonSVRDb);
+
+    return ret;
+}
diff --git a/resource/csdk/security/src/pstatresource.c b/resource/csdk/security/src/pstatresource.c
new file mode 100644 (file)
index 0000000..aa798e0
--- /dev/null
@@ -0,0 +1,401 @@
+//******************************************************************
+//
+// 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 "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "resourcemanager.h"
+#include "pstatresource.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "base64.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define TAG  PCF("SRM-PSTAT")
+
+static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
+static OicSecPstat_t gDefaultPstat =
+{
+    false,                                    // bool isOwned
+    (OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
+    PROVISION_CREDENTIALS | PROVISION_ACLS),   // OicSecDpm_t cm
+    (OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
+    PROVISION_CREDENTIALS | PROVISION_ACLS),   // OicSecDpm_t tm
+    {},                                       // OicUuid_t deviceID
+    SINGLE_SERVICE_CLIENT_DRIVEN,             // OicSecDpom_t om */
+    1,                                        // the number of elts in Sms
+    &gSm,                                     // OicSecDpom_t *sm
+    0,                                        // uint16_t commitHash
+};
+static OicSecPstat_t    *gPstat = NULL;
+static OCResourceHandle gPstatHandle = NULL;
+
+void DeletePstatBinData(OicSecPstat_t* pstat)
+{
+    if (pstat)
+    {
+        //Clean 'supported modes' field
+        OICFree(pstat->sm);
+
+        //Clean pstat itself
+        OICFree(pstat);
+    }
+}
+
+char * BinToPstatJSON(const OicSecPstat_t * pstat)
+{
+    if(NULL == pstat)
+    {
+        return NULL;
+    }
+
+    cJSON *jsonPstat = NULL;
+    char *jsonStr = NULL;
+    cJSON *jsonSmArray = NULL;
+    char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] = {};
+    uint32_t outLen = 0;
+    B64Result b64Ret = B64_OK;
+
+    cJSON *jsonRoot = cJSON_CreateObject();
+    VERIFY_NON_NULL(TAG, jsonRoot, INFO);
+
+    cJSON_AddItemToObject(jsonRoot, OIC_JSON_PSTAT_NAME, jsonPstat=cJSON_CreateObject());
+    cJSON_AddBoolToObject(jsonPstat, OIC_JSON_ISOP_NAME, pstat->isOp);
+
+    b64Ret = b64Encode(pstat->deviceID.id,
+            sizeof(pstat->deviceID.id), base64Buff, sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+    cJSON_AddStringToObject(jsonPstat, OIC_JSON_DEVICE_ID_NAME, base64Buff);
+    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_COMMIT_HASH_NAME, pstat->commitHash);
+    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_CM_NAME, (int)pstat->cm);
+    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_TM_NAME, (int)pstat->tm);
+    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_OM_NAME, (int)pstat->om);
+
+    cJSON_AddItemToObject(jsonPstat, OIC_JSON_SM_NAME, jsonSmArray = cJSON_CreateArray());
+    VERIFY_NON_NULL(TAG, jsonSmArray, INFO);
+    for (int i = 0; i < pstat->smLen; i++)
+    {
+        cJSON_AddItemToArray(jsonSmArray, cJSON_CreateNumber((int )pstat->sm[i]));
+    }
+    jsonStr = cJSON_Print(jsonRoot);
+
+exit:
+    if (jsonRoot)
+    {
+        cJSON_Delete(jsonRoot);
+    }
+    return jsonStr;
+}
+
+OicSecPstat_t * JSONToPstatBin(const char * jsonStr)
+{
+    if(NULL == jsonStr)
+    {
+        return NULL;
+    }
+
+    OCStackResult ret = OC_STACK_ERROR;
+    OicSecPstat_t *pstat = NULL;
+    cJSON *jsonPstat = NULL;
+    cJSON *jsonObj = NULL;
+
+    unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
+    uint32_t outLen = 0;
+    B64Result b64Ret = B64_OK;
+
+    cJSON *jsonRoot = cJSON_Parse(jsonStr);
+    VERIFY_NON_NULL(TAG, jsonRoot, INFO);
+
+    jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
+    VERIFY_NON_NULL(TAG, jsonPstat, INFO);
+
+    pstat = (OicSecPstat_t*)OICCalloc(1, sizeof(OicSecPstat_t));
+    VERIFY_NON_NULL(TAG, pstat, INFO);
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ISOP_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);
+    pstat->isOp = jsonObj->valueint;
+
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_DEVICE_ID_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+    b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
+                sizeof(base64Buff), &outLen);
+    VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pstat->deviceID.id)), ERROR);
+    memcpy(pstat->deviceID.id, base64Buff, outLen);
+
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+    pstat->commitHash  = jsonObj->valueint;
+
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_CM_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+    pstat->cm  = (OicSecDpm_t)jsonObj->valueint;
+
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+    pstat->om  = (OicSecDpom_t)jsonObj->valueint;
+
+    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_SM_NAME);
+    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+    if (cJSON_Array == jsonObj->type)
+    {
+        pstat->smLen = cJSON_GetArraySize(jsonObj);
+        int idxx = 0;
+        VERIFY_SUCCESS(TAG, pstat->smLen != 0, ERROR);
+        pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
+        do
+        {
+            cJSON *jsonSm = cJSON_GetArrayItem(jsonObj, idxx);
+            VERIFY_NON_NULL(TAG, jsonSm, ERROR);
+            pstat->sm[idxx] = (OicSecDpom_t)jsonSm->valueint;
+        }while ( ++idxx < pstat->smLen);
+    }
+    ret = OC_STACK_OK;
+
+exit:
+    cJSON_Delete(jsonRoot);
+    if (OC_STACK_OK != ret)
+    {
+        OC_LOG (ERROR, TAG, PCF("JSONToPstatBin failed"));
+        DeletePstatBinData(pstat);
+        pstat = NULL;
+    }
+    return pstat;
+}
+
+/**
+ * The entity handler determines how to process a GET request.
+ */
+static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+    // Convert ACL data into JSON for transmission
+    char* jsonStr = BinToPstatJSON(gPstat);
+
+    // A device should always have a default pstat. Therefore, jsonStr should never be NULL.
+    OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+
+    // Send response payload to request originator
+    SendSRMResponse(ehRequest, ehRet, jsonStr);
+    OICFree(jsonStr);
+    return ehRet;
+}
+
+/**
+ * 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.
+ * For pstat, it updates only tm and om.
+ */
+static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest *ehRequest)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+    cJSON *postJson = NULL;
+
+    if (ehRequest->resource)
+    {
+        postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData);
+        VERIFY_NON_NULL(TAG, postJson, INFO);
+        cJSON *jsonPstat = cJSON_GetObjectItem(postJson, OIC_JSON_PSTAT_NAME);
+        VERIFY_NON_NULL(TAG, jsonPstat, INFO);
+        cJSON *commitHashJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
+        uint16_t commitHash = 0;
+        if (commitHashJson)
+        {
+            commitHash = commitHashJson->valueint;
+        }
+        cJSON *tmJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME);
+        if (tmJson && gPstat)
+        {
+            gPstat->tm = (OicSecDpm_t)tmJson->valueint;
+            if(0 == tmJson->valueint && gPstat->commitHash == commitHash)
+            {
+                gPstat->isOp = true;
+                gPstat->cm = NORMAL;
+                OC_LOG (INFO, TAG, PCF("CommitHash is valid and isOp is TRUE"));
+            }
+            else
+            {
+                OC_LOG (INFO, TAG, PCF("CommitHash is not valid"));
+            }
+        }
+        cJSON *omJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
+        if (omJson && gPstat)
+        {
+            /*
+             * Check if the operation mode is in the supported provisioning services
+             * operation mode list.
+             */
+            for(size_t i=0; i< gPstat->smLen; i++)
+            {
+                if(gPstat->sm[i] == omJson->valueint)
+                {
+                    gPstat->om = (OicSecDpom_t)omJson->valueint;
+                    break;
+                }
+            }
+        }
+        // Convert pstat data into JSON for update to persistent storage
+        char *jsonStr = BinToPstatJSON(gPstat);
+        if (jsonStr)
+        {
+            cJSON *jsonPstat = cJSON_Parse(jsonStr);
+            OICFree(jsonStr);
+            if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat))
+            {
+                ehRet = OC_EH_OK;
+            }
+        }
+    }
+ exit:
+    //Send payload to request originator
+    if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
+    {
+        OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandlePstatPostRequest"));
+    }
+    cJSON_Delete(postJson);
+    return ehRet;
+}
+
+/**
+ * This internal method is the entity handler for pstat resources.
+ */
+OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest * ehRequest,
+        void *callbackParam)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+    // This method will handle REST request (GET/POST) for /oic/sec/pstat
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        switch (ehRequest->method)
+        {
+            case OC_REST_GET:
+                ehRet = HandlePstatGetRequest(ehRequest);
+                break;
+            case OC_REST_PUT:
+                ehRet = HandlePstatPutRequest(ehRequest);
+                break;
+            default:
+                ehRet = OC_EH_ERROR;
+                SendSRMResponse(ehRequest, ehRet, NULL);
+                break;
+        }
+    }
+    return ehRet;
+}
+
+/**
+ * This internal method is used to create '/oic/sec/pstat' resource.
+ */
+OCStackResult CreatePstatResource()
+{
+    OCStackResult ret;
+
+    ret = OCCreateResource(&gPstatHandle,
+                           OIC_RSRC_TYPE_SEC_PSTAT,
+                           OIC_MI_DEF,
+                           OIC_RSRC_PSTAT_URI,
+                           PstatEntityHandler,
+                           NULL,
+                           OC_RES_PROP_NONE);
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG (FATAL, TAG, PCF("Unable to instantiate pstat resource"));
+        DeInitPstatResource();
+    }
+    return ret;
+}
+
+/**
+ * Post ACL hander update the commitHash during ACL provisioning.
+ */
+void SetCommitHash(uint16_t commitHash)
+{
+    gPstat->commitHash = commitHash;
+}
+
+/**
+ * Get the default value
+ * @retval  the gDefaultPstat pointer
+ */
+static OicSecPstat_t* GetPstatDefault()
+{
+    return &gDefaultPstat;
+}
+
+/**
+ * Initialize pstat resource by loading data from persistent storage.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitPstatResource()
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    // Read Pstat resource from PS
+    char* jsonSVRDatabase = GetSVRDatabase();
+    if (jsonSVRDatabase)
+    {
+        // Convert JSON Pstat into binary format
+        gPstat = JSONToPstatBin(jsonSVRDatabase);
+    }
+    /*
+     * If SVR database in persistent storage got corrupted or
+     * is not available for some reason, a default pstat is created
+     * which allows user to initiate pstat provisioning again.
+     */
+    if(!jsonSVRDatabase || !gPstat)
+    {
+        gPstat = GetPstatDefault();
+    }
+    // Instantiate 'oic.sec.pstat'
+    ret = CreatePstatResource();
+
+    OICFree(jsonSVRDatabase);
+    return ret;
+}
+
+/**
+ * Perform cleanup for pstat resources.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult DeInitPstatResource()
+{
+    if(gPstat != &gDefaultPstat)
+    {
+        DeletePstatBinData(gPstat);
+        gPstat = NULL;
+    }
+    return OCDeleteResource(gPstatHandle);
+}
+
diff --git a/resource/csdk/security/src/resourcemanager.c b/resource/csdk/security/src/resourcemanager.c
new file mode 100644 (file)
index 0000000..615dae4
--- /dev/null
@@ -0,0 +1,115 @@
+//******************************************************************
+//
+// 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 "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "aclresource.h"
+#include "pstatresource.h"
+#include "doxmresource.h"
+#include "credresource.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+#include "utlist.h"
+#include <string.h>
+
+#define TAG PCF("SRM-RM")
+
+/**
+ * This method is used by all secure resource modules to send responses to REST queries.
+ *
+ * @param ehRequest pointer to entity handler request data structure.
+ * @param ehRet result code from entity handler.
+ * @param rspPayload response payload in JSON.
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SendSRMResponse(const OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResult ehRet, const char *rspPayload)
+{
+    OC_LOG (INFO, TAG, PCF("SRM sending SRM response"));
+    OCEntityHandlerResponse response = {};
+    if (ehRequest)
+    {
+        OCSecurityPayload ocPayload = {};
+
+        response.requestHandle = ehRequest->requestHandle;
+        response.resourceHandle = ehRequest->resource;
+        response.ehResult = ehRet;
+        response.payload = (OCPayload*)(&ocPayload);
+        response.payload->type = PAYLOAD_TYPE_SECURITY;
+        ((OCSecurityPayload*)response.payload)->securityData = (char *)rspPayload;
+        response.persistentBufferFlag = 0;
+
+        return OCDoResponse(&response);
+    }
+    return OC_STACK_ERROR;
+}
+
+/**
+ * Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitSecureResources( )
+{
+    OCStackResult ret;
+
+    /*
+     * 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 = InitPstatResource();
+    }
+    if(OC_STACK_OK == ret)
+    {
+        ret = InitACLResource();
+    }
+    if(OC_STACK_OK == ret)
+    {
+        ret = InitCredResource();
+    }
+    if(OC_STACK_OK != ret)
+    {
+        //TODO: Update the default behavior if one of the SVR fails
+        DestroySecureResources();
+    }
+    return ret;
+}
+
+/**
+ * Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ *
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult DestroySecureResources( )
+{
+    DeInitACLResource();
+    DeInitCredResource();
+    DeInitDoxmResource();
+    DeInitPstatResource();
+
+    return OC_STACK_OK;
+}
diff --git a/resource/csdk/security/src/secureresourcemanager.c b/resource/csdk/security/src/secureresourcemanager.c
new file mode 100644 (file)
index 0000000..8dee8b1
--- /dev/null
@@ -0,0 +1,286 @@
+//******************************************************************
+//
+// 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 "ocstack.h"
+#include "logger.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+#include "resourcemanager.h"
+#include "credresource.h"
+#include "policyengine.h"
+#include <string.h>
+
+#define TAG  PCF("SRM")
+
+//Request Callback handler
+static CARequestCallback gRequestHandler = NULL;
+//Response Callback handler
+static CAResponseCallback gResponseHandler = NULL;
+//Error Callback handler
+static CAErrorCallback gErrorHandler = NULL;
+//Persistent Storage callback handler for open/read/write/close/unlink
+static OCPersistentStorage *gPersistentStorageHandler =  NULL;
+//Provisioning response callback
+static SPResponseCallback gSPResponseHandler = NULL;
+
+/**
+ * A single global Policy Engine context will suffice as long
+ * as SRM is single-threaded.
+ */
+PEContext_t g_policyEngineContext;
+
+/**
+ * @brief function to register provisoning API's response callback.
+ * @param respHandler response handler callback.
+ */
+void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler)
+{
+    gSPResponseHandler = respHandler;
+}
+/**
+ * @brief   Handle the request from the SRM.
+ * @param   endPoint       [IN] Endpoint object from which the response is received.
+ * @param   requestInfo    [IN] Information for the request.
+ * @return  NONE
+ */
+void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Received request from remote device"));
+
+    if (!endPoint || !requestInfo)
+    {
+        OC_LOG(ERROR, TAG, PCF("Invalid arguments"));
+        return;
+    }
+
+    // Copy the subjectID
+    OicUuid_t subjectId = {};
+    memcpy(subjectId.id, endPoint->identity.id, sizeof(subjectId.id));
+
+    //Check the URI has the query and skip it before checking the permission
+    char *uri = strstr(requestInfo->info.resourceUri, "?");
+    int position = 0;
+    if (uri)
+    {
+        position = uri - requestInfo->info.resourceUri;
+    }
+    if (position > MAX_URI_LENGTH)
+    {
+        OC_LOG(ERROR, TAG, PCF("URI length is too long"));
+        return;
+    }
+    SRMAccessResponse_t response = ACCESS_DENIED;
+    if (position > 0)
+    {
+        char newUri[MAX_URI_LENGTH + 1];
+        strncpy(newUri, requestInfo->info.resourceUri, (position));
+        newUri[position] = '\0';
+        //Skip query and pass the newUri.
+        response = CheckPermission(&g_policyEngineContext, &subjectId,
+                              newUri,
+                              GetPermissionFromCAMethod_t(requestInfo->method));
+    }
+    else
+    {
+        //Pass resourceUri if there is no query info.
+        response = CheckPermission(&g_policyEngineContext, &subjectId,
+                              requestInfo->info.resourceUri,
+                              GetPermissionFromCAMethod_t(requestInfo->method));
+    }
+    if (IsAccessGranted(response) && gRequestHandler)
+    {
+        return (gRequestHandler(endPoint, requestInfo));
+    }
+
+    // Form a 'access deny' or 'Error' response and send to peer
+    CAResponseInfo_t responseInfo = {};
+    memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
+    responseInfo.info.payload = NULL;
+    if (!gRequestHandler)
+    {
+        responseInfo.result = CA_INTERNAL_SERVER_ERROR;
+    }
+    else
+    {
+        /*
+         * TODO Enhance this logic more to decide between
+         * CA_UNAUTHORIZED_REQ or CA_FORBIDDEN_REQ depending
+         * upon SRMAccessResponseReasonCode_t
+         */
+        responseInfo.result = CA_UNAUTHORIZED_REQ;
+    }
+
+    if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed in sending response to a unauthorized request!"));
+    }
+}
+
+/**
+ * @brief   Handle the response from the SRM.
+ * @param   endPoint     [IN] The remote endpoint.
+ * @param   responseInfo [IN] Response information from the endpoint.
+ * @return  NONE
+ */
+void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Received response from remote device"));
+
+    // 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,
+    // gSPResponseHandler returns true and response is not sent to RI layer. In case
+    // gSPResponseHandler is null and isProvResponse is false response then the response is for
+    // RI layer.
+    bool isProvResponse = false;
+
+    if (gSPResponseHandler)
+    {
+        isProvResponse = gSPResponseHandler(endPoint, responseInfo);
+    }
+    if (!isProvResponse && gResponseHandler)
+    {
+        gResponseHandler(endPoint, responseInfo);
+    }
+}
+
+
+/**
+ * @brief   Handle the error from the SRM.
+ * @param   endPoint  [IN] The remote endpoint.
+ * @param   errorInfo [IN] Error information from the endpoint.
+ * @return  NONE
+ */
+void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Received error from remote device"));
+    if (gErrorHandler)
+    {
+        gErrorHandler(endPoint, errorInfo);
+    }
+}
+
+
+/**
+ * @brief   Register request and response callbacks.
+ *          Requests and responses are delivered in these callbacks.
+ * @param   reqHandler   [IN] Request handler callback ( for GET,PUT ..etc)
+ * @param   respHandler  [IN] Response handler callback.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - invalid parameter
+ */
+OCStackResult SRMRegisterHandler(CARequestCallback reqHandler,
+                                 CAResponseCallback respHandler,
+                                 CAErrorCallback errHandler)
+{
+    OC_LOG(INFO, TAG, PCF("SRMRegisterHandler !!"));
+    if( !reqHandler || !respHandler || !errHandler)
+    {
+        OC_LOG(ERROR, TAG, PCF("Callback handlers are invalid"));
+        return OC_STACK_INVALID_PARAM;
+    }
+    gRequestHandler = reqHandler;
+    gResponseHandler = respHandler;
+    gErrorHandler = errHandler;
+
+
+#if defined(__WITH_DTLS__)
+    CARegisterHandler(SRMRequestHandler, SRMResponseHandler, SRMErrorHandler);
+#else
+    CARegisterHandler(reqHandler, respHandler, errHandler);
+#endif /* __WITH_DTLS__ */
+    return OC_STACK_OK;
+}
+
+/**
+ * @brief   Register Persistent storage callback.
+ * @param   persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - Invalid parameter
+ */
+OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
+{
+    OC_LOG(INFO, TAG, PCF("SRMRegisterPersistentStorageHandler !!"));
+    if(!persistentStorageHandler)
+    {
+        OC_LOG(ERROR, TAG, PCF("The persistent storage handler is invalid"));
+        return OC_STACK_INVALID_PARAM;
+    }
+    gPersistentStorageHandler = persistentStorageHandler;
+    return OC_STACK_OK;
+}
+
+/**
+ * @brief   Get Persistent storage handler pointer.
+ * @return
+ *     The pointer to Persistent Storage callback handler
+ */
+
+OCPersistentStorage* SRMGetPersistentStorageHandler()
+{
+    OC_LOG(INFO, TAG, PCF("SRMGetPersistentStorageHandler !!"));
+    return gPersistentStorageHandler;
+}
+
+
+/**
+ * @brief   Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ * @retval  OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SRMInitSecureResources()
+{
+    // TODO: temporarily returning OC_STACK_OK every time until default
+    // behavior (for when SVR DB is missing) is settled.
+    InitSecureResources();
+
+#if defined(__WITH_DTLS__)
+    CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials);
+#endif // (__WITH_DTLS__)
+
+    return OC_STACK_OK;
+}
+
+/**
+ * @brief   Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ * @retval  none
+ */
+void SRMDeInitSecureResources()
+{
+    DestroySecureResources();
+}
+
+/**
+ * @brief   Initialize Policy Engine.
+ * @return  OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult SRMInitPolicyEngine()
+{
+    return InitPolicyEngine(&g_policyEngineContext);
+}
+
+/**
+ * @brief   Cleanup Policy Engine.
+ * @return  none
+ */
+void SRMDeInitPolicyEngine()
+{
+    return DeInitPolicyEngine(&g_policyEngineContext);
+}
diff --git a/resource/csdk/security/src/srmresourcestrings.c b/resource/csdk/security/src/srmresourcestrings.c
new file mode 100644 (file)
index 0000000..02a5f0e
--- /dev/null
@@ -0,0 +1,87 @@
+//******************************************************************
+//
+// 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 "securevirtualresourcetypes.h"
+
+const char * SVR_DB_FILE_NAME = "oic_svr_db.json";
+const char * OIC_MI_DEF = "oic.mi.def";
+
+//ACL
+const char * OIC_RSRC_TYPE_SEC_ACL = "oic.sec.acl";
+const char * OIC_RSRC_ACL_URI =  "/oic/sec/acl";
+const char * OIC_JSON_ACL_NAME = "acl";
+
+//Pstat
+const char * OIC_RSRC_TYPE_SEC_PSTAT = "oic.sec.pstat";
+const char * OIC_RSRC_PSTAT_URI =  "/oic/sec/pstat";
+const char * OIC_JSON_PSTAT_NAME = "pstat";
+
+//doxm
+const char * OIC_RSRC_TYPE_SEC_DOXM = "oic.sec.doxm";
+const char * OIC_RSRC_DOXM_URI =  "/oic/sec/doxm";
+const char * OIC_JSON_DOXM_NAME = "doxm";
+
+//cred
+const char * OIC_RSRC_TYPE_SEC_CRED = "oic.sec.cred";
+const char * OIC_RSRC_CRED_URI =  "/oic/sec/cred";
+const char * OIC_JSON_CRED_NAME = "cred";
+
+const char * OIC_JSON_SUBJECT_NAME = "sub";
+const char * OIC_JSON_RESOURCES_NAME = "rsrc";
+const char * OIC_JSON_PERMISSION_NAME = "perms";
+const char * OIC_JSON_OWNERS_NAME = "ownrs";
+const char * OIC_JSON_OWNER_NAME = "ownr";
+const char * OIC_JSON_OWNED_NAME = "owned";
+const char * OIC_JSON_OXM_NAME = "oxm";
+const char * OIC_JSON_OXM_TYPE_NAME = "oxmtype";
+const char * OIC_JSON_OXM_SEL_NAME = "oxmsel";
+const char * OIC_JSON_DEVICE_ID_FORMAT_NAME = "dvcidfrmt";
+const char * OIC_JSON_ISOP_NAME = "isop";
+const char * OIC_JSON_COMMIT_HASH_NAME = "ch";
+const char * OIC_JSON_DEVICE_ID_NAME = "deviceid";
+const char * OIC_JSON_CM_NAME = "cm";
+const char * OIC_JSON_TM_NAME = "tm";
+const char * OIC_JSON_OM_NAME = "om";
+const char * OIC_JSON_SM_NAME = "sm";
+const char * OIC_JSON_CREDID_NAME = "credid";
+const char * OIC_JSON_SUBJECTID_NAME = "subid";
+const char * OIC_JSON_ROLEIDS_NAME = "roleid";
+const char * OIC_JSON_CREDTYPE_NAME = "credtyp";
+const char * OIC_JSON_PUBLICDATA_NAME = "pbdata";
+const char * OIC_JSON_PRIVATEDATA_NAME = "pvdata";
+const char * OIC_JSON_PERIOD_NAME = "period";
+
+OicUuid_t WILDCARD_SUBJECT_ID = {"*"};
+size_t WILDCARD_SUBJECT_ID_LEN = 1;
+const char * WILDCARD_RESOURCE_URI = "*";
+
+//Ownership Transfer Methods
+const char * OXM_JUST_WORKS = "oic.sec.doxm.jw";
+const char * OXM_MODE_SWITCH = "oic.sec.doxm.ms";
+const char * OXM_RANDOM_DEVICE_PIN = "oic.sec.doxm.rdp";
+const char * OXM_PRE_PROVISIONED_DEVICE_PIN = "oic.sec.doxm.ppdp";
+const char * OXM_PRE_PROVISIONED_STRONG_CREDENTIAL = "oic.sec.doxm.ppsc";
+
+const char * OIC_SEC_TRUE = "true";
+const char * OIC_SEC_FALSE = "false";
+
+const char * OIC_SEC_REST_QUERY_SEPARATOR = "&";
+char OIC_SEC_REST_QUERY_DELIMETER = '=';
diff --git a/resource/csdk/security/src/srmutility.c b/resource/csdk/security/src/srmutility.c
new file mode 100644 (file)
index 0000000..3f97b57
--- /dev/null
@@ -0,0 +1,86 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define _POSIX_C_SOURCE 200112L
+#include <string.h>
+
+#include "srmutility.h"
+#include "srmresourcestrings.h"
+#include "logger.h"
+
+#define TAG  PCF("SRM-UTILITY")
+
+/**
+ * This method initializes the OicParseQueryIter_t struct
+ *
+ *@param query     - REST query, to be parsed
+ *@param parseIter - OicParseQueryIter_t struct, to be initialized
+ *
+ */
+void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter)
+{
+    OC_LOG (INFO, TAG, PCF("Initializing coap iterator"));
+    if((NULL == query) || (NULL == parseIter))
+        return;
+
+    parseIter->attrPos = NULL;
+    parseIter->attrLen = 0;
+    parseIter->valPos = NULL;
+    parseIter->valLen = 0;
+    coap_parse_iterator_init(query, strlen((char *)query),
+          (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR, (unsigned char *) "", 0, &parseIter->pi);
+}
+
+
+/**
+ * This method fills the OicParseQueryIter_t struct with next REST query's
+ * attribute's and value's information
+ *
+ *@param parseIter - OicParseQueryIter_t struct, has next query's attribute's & value's info
+ *
+ * @retval
+ *     OicParseQueryIter_t *  - has parsed query info
+ *     NULL                   - has no query to parse
+ */
+OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter)
+{
+    OC_LOG (INFO, TAG, PCF("Getting Next Query"));
+    if(NULL == parseIter)
+        return NULL;
+
+    unsigned char * qrySeg = NULL;
+    char * delimPos;
+
+    //Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR
+    qrySeg = coap_parse_next(&parseIter->pi);
+
+    if(qrySeg)
+    {
+        delimPos = strchr((char *)qrySeg, OIC_SEC_REST_QUERY_DELIMETER);
+        if(delimPos)
+        {
+            parseIter->attrPos = parseIter->pi.pos;
+            parseIter->attrLen = (unsigned char *)delimPos - parseIter->pi.pos;
+            parseIter->valPos  = (unsigned char *)delimPos + 1;
+            parseIter->valLen  = &qrySeg[parseIter->pi.segment_length] - parseIter->valPos;
+            return parseIter;
+        }
+    }
+    return NULL;
+}
diff --git a/resource/csdk/security/unittest/SConscript b/resource/csdk/security/unittest/SConscript
new file mode 100644 (file)
index 0000000..d1193ac
--- /dev/null
@@ -0,0 +1,105 @@
+# //******************************************************************
+# //
+# // 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.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+
+Import('env')
+import os
+import os.path
+srmtest_env = env.Clone()
+
+src_dir = srmtest_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+srmtest_env.PrependUnique(CPPPATH = [
+        '../../ocmalloc/include',
+               '../../connectivity/inc',
+               '../../connectivity/api',
+               '../../connectivity/external/inc',
+               '../../connectivity/lib/libcoap-4.1.1',
+               '../include',
+               '../include/internal',
+               '../../logger/include',
+               '../../ocmalloc/include',
+               '../../stack/include',
+               '../../stack/include/internal',
+               '../../../oc_logger/include',
+               '../../../../extlibs/gtest/gtest-1.7.0/include',
+               '../../../../extlibs/cjson/',
+#              '../../../../extlibs/tinydtls/',
+               '../include'
+               ])
+srmtest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+srmtest_env.AppendUnique(LIBS = ['-lpthread'])
+srmtest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+srmtest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
+srmtest_env.PrependUnique(LIBS = ['ocsrm',
+                                    'octbstack',
+                                    'oc_logger',
+                                    'connectivity_abstraction',
+                                    'coap',
+                                    'gtest',
+                                    'gtest_main'])
+
+if env.get('SECURED') == '1':
+    srmtest_env.AppendUnique(LIBS = ['tinydtls'])
+
+if not env.get('RELEASE'):
+       srmtest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+unittest = srmtest_env.Program('unittest', ['aclresourcetest.cpp',
+                                            'pstatresource.cpp',
+                                            'doxmresource.cpp',
+                                            'policyengine.cpp',
+                                            'securityresourcemanager.cpp',
+                                            'credentialresource.cpp',
+                                            'srmutility.cpp',
+                                            'base64tests.cpp'])
+
+Alias("test", [unittest])
+
+unittest_src_dir = src_dir + '/resource/csdk/security/unittest/'
+unittest_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/unittest'
+
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+    unittest_src_dir + 'oic_unittest.json'))
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+    unittest_src_dir + 'oic_unittest_acl1.json'))
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+    unittest_src_dir + 'oic_unittest_default_acl.json'))
+
+env.AppendTarget('test')
+if env.get('TEST') == '1':
+       target_os = env.get('TARGET_OS')
+       if target_os == 'linux':
+               out_dir = env.get('BUILD_DIR')
+               result_dir = env.get('BUILD_DIR') + '/test_out/'
+               if not os.path.isdir(result_dir):
+                       os.makedirs(result_dir)
+               srmtest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
+               srmtest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
+               srmtest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
+               ut = srmtest_env.Command ('ut', None, out_dir + '/resource/csdk/security/unittest/unittest')
+               AlwaysBuild ('ut')
+
diff --git a/resource/csdk/security/unittest/aclresourcetest.cpp b/resource/csdk/security/unittest/aclresourcetest.cpp
new file mode 100644 (file)
index 0000000..2cdb0f8
--- /dev/null
@@ -0,0 +1,252 @@
+//******************************************************************
+//
+// 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 <pwd.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include <sys/stat.h>
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "aclresource.h"
+
+using namespace std;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern char * BinToAclJSON(const OicSecAcl_t * acl);
+extern OicSecAcl_t * JSONToAclBin(const char * jsonStr);
+char* ReadFile(const char* filename);
+extern void DeleteACLList(OicSecAcl_t* acl);
+OCStackResult  GetDefaultACL(OicSecAcl_t** defaultAcl);
+OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
+                                        OCEntityHandlerRequest * ehRequest);
+#ifdef __cplusplus
+}
+#endif
+
+const char* JSON_FILE_NAME = "oic_unittest.json";
+const char* DEFAULT_ACL_JSON_FILE_NAME = "oic_unittest_default_acl.json";
+const char* ACL1_JSON_FILE_NAME = "oic_unittest_acl1.json";
+
+#define NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON (2)
+
+char* ReadFile(const char* filename)
+{
+
+    FILE *fp = NULL;
+    char *data = NULL;
+    struct stat st;
+    // TODO: Find the location of the executable and concatenate the SVR file name
+    // before opening it.
+    fp = fopen(filename, "r");
+    if (fp)
+    {
+        if (stat(filename, &st) == 0)
+        {
+            data = (char*)OICMalloc(st.st_size);
+            if (data)
+            {
+                if (fread(data, 1, st.st_size, fp) != (size_t)st.st_size)
+                {
+                    printf("Error in reading file %s", filename);
+                }
+            }
+        }
+        fclose(fp);
+    }
+    else
+    {
+        printf("Unable to open %s file", filename);
+    }
+
+    return data;
+}
+
+void SetPersistentHandler(OCPersistentStorage *ps, bool set)
+{
+    if (set)
+    {
+        ps->open = fopen;
+        ps->read = fread;
+        ps->write = fwrite;
+        ps->close = fclose;
+        ps->unlink = unlink;
+    }
+    else
+    {
+        memset(ps, 0, sizeof(OCPersistentStorage));
+    }
+    EXPECT_EQ(OC_STACK_OK,
+            OCRegisterPersistentStorageHandler(ps));
+}
+
+// JSON Marshalling Tests
+TEST(ACLResourceTest, JSONMarshallingTests)
+{
+    char *jsonStr1 = ReadFile(ACL1_JSON_FILE_NAME);
+    if (jsonStr1)
+    {
+        cJSON_Minify(jsonStr1);
+        /* Workaround : cJSON_Minify does not remove all the unwanted characters
+         from the end. Here is an attempt to remove those characters */
+        int len = strlen(jsonStr1);
+        while (len > 0)
+        {
+            if (jsonStr1[--len] == '}')
+            {
+                break;
+            }
+        }
+        jsonStr1[len + 1] = 0;
+
+        OicSecAcl_t * acl = JSONToAclBin(jsonStr1);
+        EXPECT_TRUE(NULL != acl);
+
+        char * jsonStr2 = BinToAclJSON(acl);
+        EXPECT_TRUE(NULL != jsonStr2);
+
+        EXPECT_STREQ(jsonStr1, jsonStr2);
+
+        OICFree(jsonStr1);
+        OICFree(jsonStr2);
+        DeleteACLList(acl);
+    }
+}
+
+// Default ACL tests
+TEST(ACLResourceTest, GetDefaultACLTests)
+{
+    // Read default ACL from the file
+    char *jsonStr = ReadFile(DEFAULT_ACL_JSON_FILE_NAME);
+    if (jsonStr)
+    {
+        OicSecAcl_t * acl = JSONToAclBin(jsonStr);
+        EXPECT_TRUE(NULL != acl);
+
+        // Invoke API to generate default ACL
+        OicSecAcl_t * defaultAcl = NULL;
+        OCStackResult ret = GetDefaultACL(&defaultAcl);
+        EXPECT_TRUE(NULL == defaultAcl);
+
+        EXPECT_TRUE(OC_STACK_ERROR == ret);
+
+        // Verify if the SRM generated default ACL matches with unit test default
+        if (acl && defaultAcl)
+        {
+            EXPECT_TRUE(memcmp(&(acl->subject), &(defaultAcl->subject), sizeof(OicUuid_t)) == 0);
+            EXPECT_EQ(acl->resourcesLen, defaultAcl->resourcesLen);
+            for (size_t i = 0; i < acl->resourcesLen; i++)
+            {
+                EXPECT_EQ(strlen(acl->resources[i]), strlen(defaultAcl->resources[i]));
+                EXPECT_TRUE(
+                        memcmp(acl->resources[i], defaultAcl->resources[i],
+                                strlen(acl->resources[i])) == 0);
+            }
+            EXPECT_EQ(acl->permission, defaultAcl->permission);
+        }
+
+        // Perform cleanup
+        DeleteACLList(acl);
+        DeleteACLList(defaultAcl);
+        OICFree(jsonStr);
+    }
+}
+
+
+// 'POST' ACL tests
+TEST(ACLResourceTest, ACLPostTest)
+{
+    OCEntityHandlerRequest ehReq = {};
+
+    // Read an ACL from the file
+    char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
+    if (jsonStr)
+    {
+        static OCPersistentStorage ps =
+        { };
+        SetPersistentHandler(&ps, true);
+
+        // Create Entity Handler POST request payload
+        ehReq.method = OC_REST_POST;
+        ehReq.payload = (OCPayload*)calloc(1, sizeof(OCSecurityPayload));
+        ehReq.payload->type = PAYLOAD_TYPE_SECURITY;
+        ((OCSecurityPayload*)ehReq.payload)->securityData = jsonStr;
+
+        OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
+        EXPECT_TRUE(OC_EH_ERROR == ehRet);
+
+        // Convert JSON into OicSecAcl_t for verification
+        OicSecAcl_t * acl = JSONToAclBin(jsonStr);
+        EXPECT_TRUE(NULL != acl);
+
+        // Verify if SRM contains ACL for the subject
+        OicSecAcl_t* savePtr = NULL;
+        const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
+        EXPECT_TRUE(NULL != subjectAcl);
+
+        // Perform cleanup
+        DeleteACLList(acl);
+        DeInitACLResource();
+        OICFree(jsonStr);
+    }
+}
+
+
+// GetACLResource tests
+TEST(ACLResourceTest, GetACLResourceTests)
+{
+    // gAcl is a pointer to the the global ACL used by SRM
+    extern OicSecAcl_t  *gAcl;
+
+    // Read an ACL from the file
+    char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
+    if (jsonStr)
+    {
+        gAcl = JSONToAclBin(jsonStr);
+        EXPECT_TRUE(NULL != gAcl);
+
+        // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
+        const OicSecAcl_t* acl = NULL;
+        OicSecAcl_t* savePtr = NULL;
+        OicUuid_t subject = WILDCARD_SUBJECT_ID;
+        int count = 0;
+
+        do
+        {
+            acl = GetACLResourceData(&subject, &savePtr);
+            count = (NULL != acl) ? count + 1 : count;
+        } while (acl != NULL);
+
+        EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON);
+
+        /* Perform cleanup */
+        DeleteACLList(gAcl);
+        gAcl = NULL;
+        OICFree(jsonStr);
+    }
+}
+
diff --git a/resource/csdk/security/unittest/base64tests.cpp b/resource/csdk/security/unittest/base64tests.cpp
new file mode 100644 (file)
index 0000000..4cce483
--- /dev/null
@@ -0,0 +1,260 @@
+ /******************************************************************
+  *
+  * 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 "gtest/gtest.h"
+#include "base64.h"
+#include <stdlib.h>
+#include <stdint.h>
+
+// Tests for base64 encode function
+TEST(B64EncodeTest, ValidInputForEncoding)
+{
+    char buf[128];
+    uint32_t outputLength;
+    uint32_t expectedLength;
+    uint32_t i=0;
+    B64Result res = B64_OK;
+
+    const char* input = "IoTivity base64~!@#$%^&*()-=0123456789<>?;:'[]{},.\"\\|";
+
+    /**< expected output is generated from
+             "http://www.convertstring.com/EncodeDecode/Base64Encode" */
+    const char* expectedOutput[53] = {
+        "SQ==",
+        "SW8=",
+        "SW9U",
+        "SW9UaQ==",
+        "SW9UaXY=",
+        "SW9UaXZp",
+        "SW9UaXZpdA==",
+        "SW9UaXZpdHk=",
+        "SW9UaXZpdHkg",
+        "SW9UaXZpdHkgYg==",
+        "SW9UaXZpdHkgYmE=",
+        "SW9UaXZpdHkgYmFz",
+        "SW9UaXZpdHkgYmFzZQ==",
+        "SW9UaXZpdHkgYmFzZTY=",
+        "SW9UaXZpdHkgYmFzZTY0",
+        "SW9UaXZpdHkgYmFzZTY0fg==",
+        "SW9UaXZpdHkgYmFzZTY0fiE=",
+        "SW9UaXZpdHkgYmFzZTY0fiFA",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIw==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQ=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQl",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiY=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYq",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCk=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCkt",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTA=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAx",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3OA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj8=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Og==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oic=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oidb",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXs=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4i",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4iXA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4iXHw="
+    };
+
+    for(i=0; i< strlen(input); i++)
+    {
+        memset(buf, 0, sizeof(buf));
+
+        expectedLength = strlen(expectedOutput[i]);
+
+        res = b64Encode((uint8_t*)input, i + 1, buf, 128, &outputLength);
+
+        EXPECT_EQ(B64_OK, res);
+        EXPECT_EQ(expectedLength, outputLength);
+        EXPECT_EQ(0, strcmp(expectedOutput[i], buf));
+    }
+}
+
+// Tests for base64 decode function
+TEST(B64DeodeTest, ValidInputForDecoding)
+{
+    uint8_t buf[128];
+    uint32_t outputLength;
+    uint32_t i=0;
+    B64Result res = B64_OK;
+
+    const char* input[53] = {
+        "SQ==",
+        "SW8=",
+        "SW9U",
+        "SW9UaQ==",
+        "SW9UaXY=",
+        "SW9UaXZp",
+        "SW9UaXZpdA==",
+        "SW9UaXZpdHk=",
+        "SW9UaXZpdHkg",
+        "SW9UaXZpdHkgYg==",
+        "SW9UaXZpdHkgYmE=",
+        "SW9UaXZpdHkgYmFz",
+        "SW9UaXZpdHkgYmFzZQ==",
+        "SW9UaXZpdHkgYmFzZTY=",
+        "SW9UaXZpdHkgYmFzZTY0",
+        "SW9UaXZpdHkgYmFzZTY0fg==",
+        "SW9UaXZpdHkgYmFzZTY0fiE=",
+        "SW9UaXZpdHkgYmFzZTY0fiFA",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIw==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQ=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQl",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiY=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYq",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCk=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCkt",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTA=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAx",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3OA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pg==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj8=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Og==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oic=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oidb",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXs=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4i",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4iXA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4iXHw="
+    };
+    const char* expectedOutput = "IoTivity base64~!@#$%^&*()-=0123456789<>?;:'[]{},.\"\\|";
+
+    for(i=0; i< (sizeof(input)/sizeof(char*)); i++)
+    {
+        memset(buf, 0, sizeof(buf));
+
+        res = b64Decode(input[i], strlen(input[i]), buf, 128, &outputLength);
+
+        EXPECT_EQ(B64_OK, res);
+        EXPECT_EQ(i + 1, outputLength);
+        EXPECT_EQ(0, memcmp(expectedOutput, buf, i + 1));
+    }
+}
+
+// Tests for base64 decode function
+TEST(B64DeodeTest, InvalidInputForDecoding)
+{
+    uint8_t buf[128];
+    uint32_t outputLength;
+    uint32_t i=0;
+
+    const char* input[53] = {
+        "SQ=",
+        "Sw8=",
+        "SW1U",
+        "SW9Uaq==",
+        "SW9uaXY=",
+        "SW91UaXZp",
+        "SW9UaXZpdA.==",
+        "Sw9UAXZpdHk=",
+        "SW9UAXZpdHkg",
+        "SW9UaXZpdhkgYg==",
+        "SW9UaXZpd5kgYmE=",
+        "SW9UaXZ1dHkgYmFz",
+        "SW9UaXZpdHkgymFzZQ==",
+        "SW9UaXZpdHkgYmFzZTY==",
+        "SW9UaXZpdHkgYmFzZTY0=",
+        "SW9UaXZpdHkgYmFzZTY0fg=",
+        "SW9UaXZpdHkgYmFzZTY0fiE==",
+        "SW8UaXZpdHkgYmFzZTY0fiFA",
+        "SW9UaxzPDHkgYmFzZTY0fiFAIw==",
+        "SW9UaXZpdHKGYmFzZTY0fiFAIyQ=",
+        "SW9UaXZpdHkgYmFZztY0fiFAIyQl=",
+        "SW8UaXZpdHkgYmFzZTY0fiFAIyQlXg=",
+        "#SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiY=",
+        "SSW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYq",
+        "SW9UaXZpdHkgYmFzZTY0fiFAiyQlXiYqKA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCk===",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKckt",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKcktpQ==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQiXiYqKCktPTA=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAx=",
+        "SW9UaXZpdHkgYmFzZTY0fifAIyQlXiYqKCktPTAxmg=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM#1=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM1",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0Nq==",
+        "sw9uaxzpdhkgymfzzty0fifaiyqlxiyqKcktptaxmjm0nty=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0nTY3",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3Ok==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3OA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pg",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pg=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjm0NTY3ODk8Pj9=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXqKCktPTAxMjM0NTY3ODk8Pj87=",
+        "SW9UaXZpdHkgYmFzZTY0fiFaIyiYqKCktPTAxMjM0NTY3ODk8Pj87Og==",
+        "W9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oic1=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCkTAxMjM0NTY3ODk8Pj87Oidb==",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYCktPTAxMjM0NTY3ODk8Pj87Oidbxq==",
+        "SW9UaXZpdHkgYmzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87Oidbxxs=",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCkPTAxMjM0NTY3ODk8Pj87OidbXXT9",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9la==",
+        "SW9UaXZpdHkgYzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9Lc4=",
+        "SW9UaXZpdHkgYmFzZ0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9lC4i",
+        "SW9UaXZpdHkgYmFzZTY0fiFAIyQlXiYqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9lc4iXA==",
+        "SW9UaXZpdHkgYmFzZTY0fiFqKCktPTAxMjM0NTY3ODk8Pj87OidbXXt9LC4ixHw="
+    };
+    const char* expectedOutput = "IoTivity base64~!@#$%^&*()-=0123456789<>?;:'[]{},.\"\\|";
+
+    for(i=0; i< (sizeof(input)/sizeof(char*)); i++)
+    {
+        memset(buf, 0, sizeof(buf));
+
+        if( B64_OK == b64Decode(input[i], strlen(input[i]), buf, 128, &outputLength) )
+        {
+            EXPECT_NE(0, memcmp(expectedOutput, buf, i + 1));
+        }
+    }
+}
+
diff --git a/resource/csdk/security/unittest/credentialresource.cpp b/resource/csdk/security/unittest/credentialresource.cpp
new file mode 100644 (file)
index 0000000..fcbb3ac
--- /dev/null
@@ -0,0 +1,260 @@
+// 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 "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "credresource.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+
+#define TAG PCF("SRM-CRED-UT")
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Declare Cred resource methods for testing
+OCStackResult CreateCredResource();
+OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
+                OCEntityHandlerRequest * ehRequest);
+char * BinToCredJSON(const OicSecCred_t * pstat);
+OicSecCred_t * JSONToCredBin(const char * jsonStr);
+void InitSecCredInstance(OicSecCred_t * cred);
+void DeleteCredList(OicSecCred_t* cred);
+const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject);
+#ifdef __cplusplus
+}
+#endif
+
+OicSecCred_t * getCredList()
+{
+    OicSecCred_t * cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    cred->credId = 1234;
+    OICStrcpy((char *)cred->subject.id, sizeof(cred->subject.id), "subject1");
+
+#if 0
+    cred->roleIdsLen = 2;
+    cred->roleIds = (OicSecRole_t *)OICCalloc(cred->roleIdsLen, sizeof(OicSecRole_t));
+    OICStrcpy((char *)cred->roleIds[0].id, sizeof(cred->roleIds[0].id), "role11");
+    OICStrcpy((char *)cred->roleIds[1].id, sizeof(cred->roleIds[1].id), "role12");
+#endif
+
+    cred->credType = 1;
+    cred->ownersLen = 1;
+    cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
+    OICStrcpy((char *)cred->owners[0].id, sizeof(cred->owners[0].id), "ownersId11");
+
+    cred->next = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    cred->next->credId = 5678;
+    OICStrcpy((char *)cred->next->subject.id, sizeof(cred->next->subject.id), "subject2");
+#if 0
+    cred->next->roleIdsLen = 0;
+#endif
+    cred->next->credType = 1;
+    size_t data_size = strlen("My private Key21") + 1;
+    cred->next->privateData.data = (char *)OICCalloc(1, data_size);
+    OICStrcpy(cred->next->privateData.data, data_size,"My private Key21");
+#if 0
+    cred->next->publicData.data = (char *)OICCalloc(1, strlen("My Public Key123") + 1);
+    OICStrcpy(cred->next->publicData.data, sizeof(cred->next->publicData.data),"My Public Key123");
+#endif
+    cred->next->ownersLen = 2;
+    cred->next->owners = (OicUuid_t*)OICCalloc(cred->next->ownersLen, sizeof(OicUuid_t));
+    OICStrcpy((char *)cred->next->owners[0].id, sizeof(cred->next->owners[0].id), "ownersId21");
+    OICStrcpy((char *)cred->next->owners[1].id, sizeof(cred->next->owners[1].id), "ownersId22");
+    return cred;
+}
+
+static void printCred(const OicSecCred_t * cred)
+{
+    EXPECT_TRUE(NULL != cred);
+
+    const OicSecCred_t *credTmp1 = NULL;
+    for(credTmp1 = cred; credTmp1; credTmp1 = credTmp1->next)
+    {
+        OC_LOG_V(INFO, TAG, PCF("\ncred->credId = %d"), credTmp1->credId);
+        OC_LOG_V(INFO, TAG, PCF("cred->subject.id = %s"), credTmp1->subject.id);
+        OC_LOG_V(INFO, TAG, PCF("cred->credType = %d"), credTmp1->credType);
+        if(credTmp1->privateData.data)
+        {
+            OC_LOG_V(INFO, TAG, PCF("cred->privateData.data = %s"), credTmp1->privateData.data);
+        }
+        if(credTmp1->publicData.data)
+        {
+           OC_LOG_V(INFO, TAG, PCF("cred->publicData.data = %s"), credTmp1->publicData.data);
+        }
+        OC_LOG_V(INFO, TAG, PCF("cred->ownersLen = %zd"), credTmp1->ownersLen);
+        for(size_t i = 0; i < cred->ownersLen; i++)
+        {
+            OC_LOG_V(INFO, TAG, PCF("cred->owners[%zd].id = %s"), i, credTmp1->owners[i].id);
+        }
+    }
+}
+
+ //InitCredResource Tests
+TEST(InitCredResourceTest, InitCredResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, InitCredResource());
+}
+
+//DeInitCredResource Tests
+TEST(DeInitCredResourceTest, DeInitCredResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitCredResource());
+}
+
+//CreateCredResource Tests
+TEST(CreateCredResourceTest, CreateCredResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, CreateCredResource());
+}
+
+ //CredEntityHandler Tests
+TEST(CredEntityHandlerTest, CredEntityHandlerWithDummyRequest)
+{
+    OCEntityHandlerRequest req;
+    EXPECT_EQ(OC_EH_ERROR, CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+}
+
+TEST(CredEntityHandlerTest, CredEntityHandlerWithNULLRequest)
+{
+    EXPECT_EQ(OC_EH_ERROR, CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL));
+}
+
+TEST(CredEntityHandlerTest, CredEntityHandlerInvalidFlag)
+{
+    OCEntityHandlerRequest req;
+    EXPECT_EQ(OC_EH_ERROR, CredEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req));
+}
+
+//BinToCredJSON Tests
+TEST(BinToCredJSONTest, BinToCredJSONNullCred)
+{
+    char* value = BinToCredJSON(NULL);
+    EXPECT_TRUE(value == NULL);
+}
+
+TEST(BinToCredJSONTest, BinToCredJSONValidCred)
+{
+    char* json = NULL;
+    OicSecCred_t * cred = getCredList();
+
+    json = BinToCredJSON(cred);
+
+    printf("BinToCredJSON:%s\n", json);
+    EXPECT_TRUE(json != NULL);
+    DeleteCredList(cred);
+    OICFree(json);
+}
+
+//JSONToCredBin Tests
+TEST(JSONToCredBinTest, JSONToCredBinValidJSON)
+{
+    OicSecCred_t* cred1 = getCredList();
+    char* json = BinToCredJSON(cred1);
+
+    EXPECT_TRUE(json != NULL);
+    OicSecCred_t *cred2 = JSONToCredBin(json);
+    EXPECT_TRUE(cred2 == NULL);
+    DeleteCredList(cred1);
+    DeleteCredList(cred2);
+    OICFree(json);
+}
+
+TEST(JSONToCredBinTest, JSONToCredBinNullJSON)
+{
+    OicSecCred_t *cred = JSONToCredBin(NULL);
+    EXPECT_TRUE(cred == NULL);
+}
+
+//GetCredResourceData Test
+TEST(CredGetResourceDataTest, GetCredResourceDataNULLSubject)
+{
+    EXPECT_TRUE(NULL == GetCredResourceData(NULL));
+}
+
+TEST(CredGenerateCredentialTest, GenerateCredentialValidInput)
+{
+    OicUuid_t owners[1];
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId21");
+
+    OicUuid_t subject = {};
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
+
+    char privateKey[] = "My private Key11";
+
+    OicSecCred_t * cred  = NULL;
+
+    cred = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                             privateKey, 1, owners);
+    printCred(cred);
+
+    DeleteCredList(cred);
+}
+
+TEST(GenerateAndAddCredentialTest, GenerateAndAddCredentialValidInput)
+{
+    OicUuid_t owners[1];
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId11");
+
+    OicUuid_t subject = {};
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
+
+    char privateKey[] = "My private Key11";
+
+    OicSecCred_t * cred1  = NULL;
+    OicSecCred_t * headCred = NULL;
+
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                 privateKey, 1, owners);
+
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+    headCred = cred1;
+
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId22");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject22");
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                     privateKey, 1, owners);
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId33");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject33");
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                     privateKey, 1, owners);
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+
+    const OicSecCred_t* credList = GetCredResourceData(&headCred->subject);
+
+    printCred(credList);
+
+    DeleteCredList(headCred);
+
+}
+
+#if 0
+TEST(CredGetResourceDataTest, GetCredResourceDataValidSubject)
+{
+    OicSecCred_t* cred = getCredList();
+    EXPECT_TRUE(NULL != GetCredResourceData(cred->subject));
+}
+#endif
+
+
diff --git a/resource/csdk/security/unittest/doxmresource.cpp b/resource/csdk/security/unittest/doxmresource.cpp
new file mode 100644 (file)
index 0000000..0b32cd9
--- /dev/null
@@ -0,0 +1,173 @@
+// 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 "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "doxmresource.h"
+#include "ocserverrequest.h"
+#include "oic_malloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Declare Doxm resource methods for testing
+OCStackResult CreateDoxmResource();
+OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag,
+                OCEntityHandlerRequest * ehRequest);
+char * BinToDoxmJSON(const OicSecDoxm_t * doxm);
+OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr);
+void InitSecDoxmInstance(OicSecDoxm_t * doxm);
+OCEntityHandlerResult HandleDoxmPostRequest (const OCEntityHandlerRequest * ehRequest);
+void DeleteDoxmBinData(OicSecDoxm_t* doxm);
+OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest);
+#ifdef __cplusplus
+}
+#endif
+
+OicSecDoxm_t * getBinDoxm()
+{
+    OicSecDoxm_t * doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t));
+    doxm->oxmTypeLen =  1;
+    doxm->oxmType    = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
+    doxm->oxmType[0] = (char*)OICMalloc(strlen(OXM_JUST_WORKS) + 1);
+    strcpy(doxm->oxmType[0], OXM_JUST_WORKS);
+    doxm->oxmLen     = 1;
+    doxm->oxm        = (OicSecOxm_t *)OICCalloc(doxm->oxmLen, sizeof(short));
+    doxm->oxm[0]     = OIC_JUST_WORKS;
+    doxm->oxmSel     = OIC_JUST_WORKS;
+    doxm->owned      = true;
+    //TODO: Need more clarification on deviceIDFormat field type.
+    //doxm.deviceIDFormat = URN;
+    strcpy((char *) doxm->deviceID.id, "deviceId");
+    strcpy((char *)doxm->owner.id, "ownersId");
+    return doxm;
+}
+
+ //InitDoxmResource Tests
+TEST(InitDoxmResourceTest, InitDoxmResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, InitDoxmResource());
+}
+
+//DeInitDoxmResource Tests
+TEST(DeInitDoxmResourceTest, DeInitDoxmResource)
+{
+    EXPECT_EQ(OC_STACK_ERROR, DeInitDoxmResource());
+}
+
+//CreateDoxmResource Tests
+TEST(CreateDoxmResourceTest, CreateDoxmResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, CreateDoxmResource());
+}
+
+ //DoxmEntityHandler Tests
+TEST(DoxmEntityHandlerTest, DoxmEntityHandlerWithDummyRequest)
+{
+    OCEntityHandlerRequest req;
+    EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+}
+
+TEST(DoxmEntityHandlerTest, DoxmEntityHandlerWithNULLRequest)
+{
+    EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL));
+}
+
+TEST(DoxmEntityHandlerTest, DoxmEntityHandlerInvalidFlag)
+{
+    OCEntityHandlerRequest req;
+    EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req));
+}
+
+TEST(DoxmEntityHandlerTest, DoxmEntityHandlerValidRequest)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, InitDoxmResource());
+    char query[] = "oxm=0&owned=false&owner=owner1";
+    OCEntityHandlerRequest req = {};
+    req.method = OC_REST_GET;
+    req.query = (char*)OICMalloc(strlen(query) + 1);
+    strcpy((char *)req.query, query);
+    EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+
+    OICFree(req.query);
+}
+
+//BinToDoxmJSON Tests
+TEST(BinToDoxmJSONTest, BinToDoxmJSONNullDoxm)
+{
+    char* value = BinToDoxmJSON(NULL);
+    EXPECT_TRUE(value == NULL);
+}
+
+TEST(BinToDoxmJSONTest, BinToDoxmJSONValidDoxm)
+{
+    OicSecDoxm_t * doxm =  getBinDoxm();
+
+    char * json = BinToDoxmJSON(doxm);
+    printf("BinToDoxmJSON:%s\n", json);
+    EXPECT_TRUE(json != NULL);
+
+    DeleteDoxmBinData(doxm);
+    OICFree(json);
+}
+
+//JSONToDoxmBin Tests
+TEST(JSONToDoxmBinTest, JSONToDoxmBinValidJSON)
+{
+    OicSecDoxm_t * doxm1 =  getBinDoxm();
+    char * json = BinToDoxmJSON(doxm1);
+    EXPECT_TRUE(json != NULL);
+
+    OicSecDoxm_t *doxm2 = JSONToDoxmBin(json);
+    EXPECT_TRUE(doxm2 != NULL);
+
+    DeleteDoxmBinData(doxm1);
+    OICFree(json);
+}
+
+TEST(JSONToDoxmBinTest, JSONToDoxmBinNullJSON)
+{
+    OicSecDoxm_t *doxm = JSONToDoxmBin(NULL);
+    EXPECT_TRUE(doxm == NULL);
+}
+
+#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/oic_svr_db.json b/resource/csdk/security/unittest/oic_svr_db.json
new file mode 100644 (file)
index 0000000..66212ee
--- /dev/null
@@ -0,0 +1,45 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad"
+                       ],
+                       "perms": 2,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat",
+                "/oic/sec/acl"
+           ],
+             "perms": 6,
+             "ownrs" : [
+                 "MjIyMjIyMjIyMjIyMjIyMg=="
+             ]
+        }
+       ],
+       "pstat":        {
+               "isop": false,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": false,
+               "deviceid":     "MjIyMjIyMjIyMjIyMjIyMg=="
+       }
+}
diff --git a/resource/csdk/security/unittest/oic_unittest.json b/resource/csdk/security/unittest/oic_unittest.json
new file mode 100644 (file)
index 0000000..9ebfbdd
--- /dev/null
@@ -0,0 +1,37 @@
+{
+    "acl": [
+        {
+            "sub": "MTExMTExMTExMTExMTExMQ==",
+            "rsrc": [
+                               "/oic/light",
+                               "/oic/fan"
+                       ],
+                       "perms": 255,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               },
+               {
+            "sub": "MzMzMzMzMzMzMzMzMzMzMw==",
+            "rsrc": [
+                               "/oic/light",
+                               "/oic/garage"
+                       ],
+                       "perms": 255,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg==",
+                "NDQ0NDQ0NDQ0NDQ0NDQ0NA=="
+                       ]
+               }
+       ],
+
+       "pstat":        {
+               "isop": false,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch":   1234,
+               "cm":   63,
+               "tm":   48,
+               "om":   0,
+               "sm":   [3, 1]
+       }
+}
diff --git a/resource/csdk/security/unittest/oic_unittest_acl1.json b/resource/csdk/security/unittest/oic_unittest_acl1.json
new file mode 100644 (file)
index 0000000..a179c2c
--- /dev/null
@@ -0,0 +1,53 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+                       ],
+                       "perms": 6,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               },
+        {
+            "sub": "MTExMTExMTExMTExMTExMQ==",
+            "rsrc": [
+                               "/oic/light",
+                               "/oic/fan"
+                       ],
+                       "perms": 255,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               },
+               {
+            "sub": "MzMzMzMzMzMzMzMzMzMzMw==",
+            "rsrc": [
+                               "/oic/light",
+                               "/oic/garage"
+                       ],
+                       "perms": 255,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg==",
+                "NDQ0NDQ0NDQ0NDQ0NDQ0NA=="
+                       ]
+               }
+       ]
+}
diff --git a/resource/csdk/security/unittest/oic_unittest_default_acl.json b/resource/csdk/security/unittest/oic_unittest_default_acl.json
new file mode 100644 (file)
index 0000000..7f3d449
--- /dev/null
@@ -0,0 +1,21 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl",
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+                       ],
+                       "perms": 2,
+                       "ownrs" : [
+                               "MjIyMjIyMjIyMjIyMjIyMg=="
+                       ]
+               }
+       ]
+}
diff --git a/resource/csdk/security/unittest/policyengine.cpp b/resource/csdk/security/unittest/policyengine.cpp
new file mode 100644 (file)
index 0000000..8ad43a8
--- /dev/null
@@ -0,0 +1,110 @@
+//******************************************************************
+//
+// 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 <pwd.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include "ocstack.h"
+#include "cainterface.h"
+#include "srmresourcestrings.h"
+
+using namespace std;
+
+#define PE_UT_TAG "\tPE-UT-message: "
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "policyengine.h"
+#include "doxmresource.h"
+
+// test parameters
+PEContext_t g_peContext;
+
+#ifdef __cplusplus
+}
+#endif
+
+OicUuid_t g_subjectIdA = {"SubjectA"};
+OicUuid_t g_subjectIdB = {"SubjectB"};
+OicUuid_t g_devOwner;
+char g_resource1[] = "Resource1";
+char g_resource2[] = "Resource2";
+
+//Policy Engine Core Tests
+TEST(PolicyEngineCore, InitPolicyEngine)
+{
+    EXPECT_EQ(OC_STACK_OK, InitPolicyEngine(&g_peContext));
+}
+
+TEST(PolicyEngineCore, CheckPermissionNoAcls)
+{
+    EXPECT_EQ(ACCESS_DENIED_SUBJECT_NOT_FOUND,
+        CheckPermission(&g_peContext,
+                        &g_subjectIdA,
+                        g_resource1,
+                        PERMISSION_READ));
+}
+
+//TODO This won't work until we figure out how to OcInit() or equivalent.
+TEST(PolicyEngineCore, CheckDevOwnerRequest)
+{
+    if(OC_STACK_OK == InitDoxmResource())
+    {
+        if(OC_STACK_OK == GetDoxmDevOwnerId(&g_devOwner))
+        {
+            printf("%s", PE_UT_TAG);
+            for(int i = 0; i < UUID_LENGTH; i++)
+            {
+                printf("%d", g_devOwner.id[i]);
+            }
+            printf("\n");
+                EXPECT_EQ(ACCESS_GRANTED,
+                    CheckPermission(&g_peContext,
+                        &g_devOwner,
+                        g_resource1,
+                        PERMISSION_FULL_CONTROL));
+        }
+        else
+        {
+            printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+                PE_UT_TAG);
+        }
+    }
+    else
+    {
+        printf("%s WARNING: GetDoxmDevOwnerId() returned ERROR!\n", PE_UT_TAG);
+    }
+
+
+}
+
+TEST(PolicyEngineCore, DeInitPolicyEngine)
+{
+    DeInitPolicyEngine(&g_peContext);
+    EXPECT_EQ(STOPPED, g_peContext.state);
+    EXPECT_EQ(NULL, g_peContext.subject);
+    EXPECT_EQ(NULL, g_peContext.resource);
+    EXPECT_EQ((uint16_t)0, g_peContext.permission);
+    EXPECT_FALSE(g_peContext.matchingAclFound);
+    EXPECT_EQ(ACCESS_DENIED_POLICY_ENGINE_ERROR, g_peContext.retVal);
+}
diff --git a/resource/csdk/security/unittest/pstatresource.cpp b/resource/csdk/security/unittest/pstatresource.cpp
new file mode 100644 (file)
index 0000000..10398c5
--- /dev/null
@@ -0,0 +1,162 @@
+//******************************************************************
+//
+// 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 "resourcemanager.h"
+#include "pstatresource.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+#include <unistd.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+//Declare Provision status resource methods for testing
+OCStackResult CreatePstatResource();
+OCEntityHandlerResult PstatEntityHandler (OCEntityHandlerFlag flag,
+                                        OCEntityHandlerRequest * ehRequest);
+char * BinToPstatJSON(const OicSecPstat_t * pstat);
+OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
+char* ReadFile(const char* filename);
+const char* UNIT_TEST_JSON_FILE_NAME = "oic_unittest.json";
+#ifdef __cplusplus
+}
+#endif
+
+//InitPstatResource Tests
+TEST(InitPstatResourceTest, InitPstatResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM,  InitPstatResource());
+}
+
+
+//DeInitPstatResource Tests
+TEST(DeInitPstatResourceTest, DeInitPstatResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitPstatResource());
+}
+
+//CreatePstatResource Tests
+TEST(CreatePstatResourceTest, CreatePstatResource)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM,  CreatePstatResource());
+}
+
+//PstatEntityHandler Tests
+TEST(PstatEntityHandlerTest, PstatEntityHandlerWithDummyRequest)
+{
+    OCEntityHandlerRequest req;
+    EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+}
+
+TEST(PstatEntityHandlerTest, PstatEntityHandlerWithPostRequest)
+{
+    OCEntityHandlerRequest req;
+    req.method = OC_REST_POST;
+    req.payload = (OCPayload*)calloc(1, sizeof(OCSecurityPayload));
+    req.payload->type = PAYLOAD_TYPE_SECURITY;
+    ((OCSecurityPayload*)req.payload)->securityData =
+        (char*)"{ \"pstat\": { \"tm\": 0, \"om\": 3 }}";
+    EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+}
+
+TEST(PstatEntityHandlerTest, PstatEntityHandlerInvalidRequest)
+{
+    EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, NULL));
+}
+
+//BinToJSON Tests
+TEST(BinToJSONTest, BinToNullJSON)
+{
+    char* value = BinToPstatJSON(NULL);
+    EXPECT_TRUE(value == NULL);
+}
+
+TEST(JSONToBinTest, NullJSONToBin)
+{
+    OicSecPstat_t *pstat1 = JSONToPstatBin(NULL);
+    EXPECT_TRUE(pstat1 == NULL);
+}
+
+TEST(MarshalingAndUnMarshalingTest, BinToPstatJSONAndJSONToPstatBin)
+{
+    const char* id = "ZGV2aWNlaWQAAAAAABhanw==";
+    OicSecPstat_t pstat;
+    pstat.cm = NORMAL;
+    pstat.commitHash = 0;
+    uint32_t outLen = 0;
+    unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
+    EXPECT_EQ(B64_OK, b64Decode(id, strlen(id), base64Buff, sizeof(base64Buff), &outLen));
+    memcpy(pstat.deviceID.id, base64Buff, outLen);
+    pstat.isOp = true;
+    pstat.tm = NORMAL;
+    pstat.om = SINGLE_SERVICE_CLIENT_DRIVEN;
+    pstat.smLen = 2;
+    pstat.sm = (OicSecDpom_t*)OICCalloc(pstat.smLen, sizeof(OicSecDpom_t));
+    pstat.sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
+    pstat.sm[1] = SINGLE_SERVICE_SERVER_DRIVEN;
+    char* jsonPstat = BinToPstatJSON(&pstat);
+    printf("BinToJSON Dump:\n%s\n\n", jsonPstat);
+    EXPECT_TRUE(jsonPstat != NULL);
+    OicSecPstat_t *pstat1 = JSONToPstatBin(jsonPstat);
+    EXPECT_TRUE(pstat1 != NULL);
+    OICFree(pstat1->sm);
+    OICFree(pstat1);
+    OICFree(jsonPstat);
+    OICFree(pstat.sm);
+}
+
+TEST(PstatTests, JSONMarshalliingTests)
+{
+    char *jsonStr1 = ReadFile(UNIT_TEST_JSON_FILE_NAME);
+    if (NULL != jsonStr1)
+    {
+        cJSON_Minify(jsonStr1);
+        /* Workaround : cJSON_Minify does not remove all the unwanted characters
+         from the end. Here is an attempt to remove those characters */
+        int len = strlen(jsonStr1);
+        while (len > 0)
+        {
+            if (jsonStr1[--len] == '}')
+            {
+                break;
+            }
+        }
+        jsonStr1[len + 1] = 0;
+
+        OicSecPstat_t* pstat = JSONToPstatBin(jsonStr1);
+        EXPECT_TRUE(NULL != pstat);
+
+        char* jsonStr2 = BinToPstatJSON(pstat);
+        printf("BinToPstatJSON Dump:\n%s\n\n", jsonStr2);
+        EXPECT_STRNE(jsonStr1, jsonStr2);
+
+        OICFree(jsonStr1);
+        OICFree(jsonStr2);
+        OICFree(pstat);
+   }
+    else
+    {
+        printf("Please copy %s into unittest folder\n", UNIT_TEST_JSON_FILE_NAME);
+    }
+}
diff --git a/resource/csdk/security/unittest/securityresourcemanager.cpp b/resource/csdk/security/unittest/securityresourcemanager.cpp
new file mode 100644 (file)
index 0000000..1a3f0d2
--- /dev/null
@@ -0,0 +1,156 @@
+//******************************************************************
+//
+// 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 <pwd.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include "ocstack.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+
+using namespace std;
+
+// Helper Methods
+void UTRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
+{
+    EXPECT_TRUE(true) << "UTRequestHandler\n";
+}
+
+void UTResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
+{
+     EXPECT_TRUE(true) << "UTResponseHandler\n";
+}
+
+void UTErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
+{
+     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
+TEST(RegisterHandlerTest, RegisterNullRequestHandler)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SRMRegisterHandler(NULL, UTResponseHandler, NULL));
+}
+
+TEST(RegisterHandlerTest, RegisterNullResponseHandler)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SRMRegisterHandler(UTRequestHandler, NULL, NULL));
+}
+
+TEST(RegisterHandlerTest, RegisterNullHandler)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SRMRegisterHandler(NULL, NULL, NULL));
+}
+
+TEST(RegisterHandlerTest, RegisterValidHandler)
+{
+    EXPECT_EQ(OC_STACK_OK, SRMRegisterHandler(UTRequestHandler, UTResponseHandler, UTErrorHandler));
+}
+
+// PersistentStorageHandler Tests
+TEST(PersistentStorageHandlerTest, RegisterNullHandler)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM,
+            SRMRegisterPersistentStorageHandler(NULL));
+}
+
+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));
+    OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
+    EXPECT_TRUE(&gpsi == ps);
+}
+
+TEST(PersistentStorageHandlerTest, PersistentStorageValidHandlers)
+{
+    OCPersistentStorage *psi = SRMGetPersistentStorageHandler();
+    EXPECT_TRUE(psi != NULL);
+
+    unsigned char buf[PATH_MAX];
+    FILE* streamIn = NULL;
+    FILE* streamOut = NULL;
+    struct passwd *pw = getpwuid(getuid());
+    const char *homeDir = pw->pw_dir;
+    char inFilePath [PATH_MAX];
+    char outFilePath [PATH_MAX];
+    snprintf(inFilePath, PATH_MAX, "%s/iotivity/Readme.scons.txt", homeDir );
+    snprintf(outFilePath, PATH_MAX, "%s/Downloads/Readme.scons.out.txt", homeDir );
+
+    streamIn = psi->open(inFilePath, "r");
+    streamOut = psi->open(outFilePath, "w");
+
+    if (streamIn && streamOut)
+    {
+        size_t value = 1;
+        while (value)
+        {
+            value = psi->read(buf, 1, sizeof(buf), streamIn);
+            psi->write(buf, 1, value, streamOut);
+        }
+    }
+
+    if (streamIn)
+    {
+        psi->close(streamIn);
+    }
+    if (streamOut)
+    {
+        psi->close(streamOut);
+    }
+    psi->unlink(outFilePath);
+}
diff --git a/resource/csdk/security/unittest/srmutility.cpp b/resource/csdk/security/unittest/srmutility.cpp
new file mode 100644 (file)
index 0000000..5e4b1fb
--- /dev/null
@@ -0,0 +1,71 @@
+// 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 "srmutility.h"
+
+
+//ParseRestQuery Tests
+TEST(ParseRestQueryTest, ParseRestQueryEmpty)
+{
+    unsigned char query[] = "";
+    OicParseQueryIter_t parseIter = {};
+    ParseQueryIterInit(query, &parseIter);
+    EXPECT_EQ(NULL,  GetNextQuery(&parseIter));
+}
+
+TEST(ParseRestQueryTest, ParseSingleRestQuery)
+{
+    char attr[10], val[10];
+    unsigned char query[] = "owned=false";
+
+    OicParseQueryIter_t parseIter = {};
+    ParseQueryIterInit(query, &parseIter);
+    EXPECT_NE((OicParseQueryIter_t *)NULL,  GetNextQuery(&parseIter));
+
+    strncpy(attr, (char *)parseIter.attrPos, parseIter.attrLen);
+    strncpy(val, (char *)parseIter.valPos, parseIter.valLen);
+    attr[parseIter.attrLen] = '\0';
+    val[parseIter.valLen] = '\0';
+    printf("\nAttribute: %s  value: %s\n\n", attr, val);
+
+}
+
+TEST(ParseRestQueryTest, ParseRestMultipleQuery)
+{
+    char attr[10], val[10];
+    unsigned char query[] = "oxm=0&owned=true&owner=owner1";
+
+    OicParseQueryIter_t parseIter = {};
+    ParseQueryIterInit(query, &parseIter);
+    printf("\n");
+    while(GetNextQuery(&parseIter))
+    {
+        EXPECT_NE(static_cast<size_t>(0),  parseIter.pi.segment_length);
+
+        strncpy(attr, (char *)parseIter.attrPos, parseIter.attrLen);
+        strncpy(val, (char *)parseIter.valPos, parseIter.valLen);
+        attr[parseIter.attrLen] = '\0';
+        val[parseIter.valLen] = '\0';
+        printf("Attribute: %s  value: %s\n", attr, val);
+
+    }
+    printf("\n");
+}
+
index 965b476..88af931 100644 (file)
@@ -1,24 +1,22 @@
 Build notes
 
-//-------------------------------------------------
-//  NOTICE - Transition to SCONS
-//-------------------------------------------------
-
-The IoTivity build system is transitioning to SCONS. Although the 
-makefiles are still available (until v1.0) and some developers are 
-still using them, they are currently no longer supported. To learn more 
-about building using SCONS see Readme.scons.txt in the repository root 
-directory. The build steps used in continuous integration can be found
+The build steps used in continuous integration can be found
 in auto_build.sh which is also in the the repository root directory.
 
+Go to the top directory of 'iotivity' project(Note: should always run 'scons'
+command in this directory)
+
 //-------------------------------------------------
 // Linux
 //-------------------------------------------------
-To build, run
-make
+To build release binaries:
+      $ scons resource/csdk/stack
+
+    Build debug binaries:
+      $ scons resource/csdk/stack RELEASE=false
 
-To enable logging, ensure that 
--D TB_LOG 
+To enable logging, ensure that
+-D TB_LOG
 is set in the compiler flags
 
 //-------------------------------------------------
@@ -31,7 +29,7 @@ LOCAL_CFLAGS := -DTB_LOG
 //-------------------------------------------------
 // Arduino
 //-------------------------------------------------
-To enable the logger for Arduino, TB_LOG should be defined in 
+To enable the logger for Arduino, TB_LOG should be defined in
 Properties|C/C++ Build|Settings|Tool Settings|AVR Compiler|Symbols
 and
 Properties|C/C++ Build|Settings|Tool Settings|AVR C++ Compiler|Symbols
index 15a7862..727a78d 100644 (file)
@@ -62,8 +62,10 @@ typedef struct ClientCB {
     OCMethod method;
     // This is the sequence identifier the server applies to the invocation tied to 'handle'.
     uint32_t sequenceNumber;
-    // This is the request uri associated with the call back
+    // The canonical form of the request uri associated with the call back
     char * requestUri;
+    // Remote address complete
+    OCDevAddr * devAddr;
     // Struct to hold TTL info for presence
     #ifdef WITH_PRESENCE
     OCPresence * presence;
@@ -112,7 +114,8 @@ OCStackResult
 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
              CAToken_t token, uint8_t tokenLength,
              OCDoHandle *handle, OCMethod method,
-             char * requestUri, char * resourceTypeName, OCConnectivityType conType, uint32_t ttl);
+             OCDevAddr *devAddr, char * requestUri,
+             char * resourceTypeName, uint32_t ttl);
 
 /** @ingroup ocstack
  *
index fc76777..37c8c09 100644 (file)
@@ -45,11 +45,8 @@ typedef struct ResourceObserver
     uint8_t tokenLength;
     // Resource handle
     OCResource *resource;
-    //TODO bundle it in Endpoint structure(address, uri, type, secured)
-    /** Remote Endpoint address **/
-    CAAddress_t addressInfo;
-    /** Connectivity of the endpoint**/
-    CATransportType_t connectivityType;
+    /** Remote Endpoint **/
+    OCDevAddr devAddr;
     // Quality of service of the request
     OCQualityOfService qos;
     // number of times the server failed to reach the observer
@@ -74,7 +71,7 @@ typedef struct ResourceObserver
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
-        OCResourceType *resourceType, OCQualityOfService qos);
+        OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos);
 #else
 /**
  * Create an observe response and send to all observers in the observe list.
@@ -95,14 +92,14 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
  * @param resource Observed resource
  * @param obsIdList List of observation ids that need to be notified.
  * @param numberOfIds Number of observation ids included in obsIdList.
- * @param notificationJSONPayload - JSON encoded payload to send in notification.
+ * @param payload - OCRepresentationPayload object representing the message
  * @param maxAge Time To Live (in seconds) of observation.
  * @param qos Desired quality of service of the observation notifications.
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 OCStackResult SendListObserverNotification (OCResource * resource,
         OCObservationId  *obsIdList, uint8_t numberOfIds,
-        const char *notificationJSONPayload, uint32_t maxAge,
+        const OCRepPayload *payload, uint32_t maxAge,
         OCQualityOfService qos);
 
 /**
@@ -128,8 +125,7 @@ OCStackResult GenerateObserverId (OCObservationId *observationId);
  * @param tokenLength Length of token.
  * @param resHandle Resource handle.
  * @param qos Quality of service of observation.
- * @param addressInfo Address of observer.
- * @param connectivityType Connection type.
+ * @param observer address
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 OCStackResult AddObserver (const char         *resUri,
@@ -139,8 +135,7 @@ OCStackResult AddObserver (const char         *resUri,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
-                           const CAAddress_t  *addressInfo,
-                           CATransportType_t connectivityType);
+                           const OCDevAddr    *devAddr);
 
 /**
  * Delete observer with specified token from list of observers.
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#ifndef OC_SECURITY_H
-#define OC_SECURITY_H
+#ifndef OC_PAYLOAD_CBOR_H
+#define OC_PAYLOAD_CBOR_H
 
-#include "ocstack.h"
-#include "ocsecurityconfig.h"
-#include <stdio.h>
+#include "octypes.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-/**
- * Provides the Security Configuration data to OC stack.
- *
- * @param cfgData
- *     binary blob containing config data
- * @param len
- *     length of binary blob
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
-OCStackResult OCSecSetConfigData(const OCSecConfigData *cfgData,
-                size_t len);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif //OC_SECURITY_H
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize);
 
+OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size);
+#endif
index acd6de4..6fe298e 100644 (file)
@@ -126,26 +126,24 @@ typedef struct resourceinterface_t {
     /*** Future placeholder for access control and policy ***/
 } OCResourceInterface;
 
-typedef struct rsrc_t {
-    struct rsrc_t *next; // Points to next resource in list
+typedef struct OCResource {
+    struct OCResource *next; // Points to next resource in list
     // Relative path on the device; will be combined with base url to create fully qualified path
-    char *host;
     char *uri;
     OCResourceType *rsrcType; // Resource type(s); linked list
     OCResourceInterface *rsrcInterface; // Resource interface(s); linked list
     OCAttribute *rsrcAttributes; // Resource interface(s); linked list
     // Array of pointers to resources; can be used to represent a container of resources
     // (i.e. hierarchies of resources) or for reference resources (i.e. for a resource collection)
-    struct rsrc_t *rsrcResources[MAX_CONTAINED_RESOURCES];
+    struct OCResource *rsrcResources[MAX_CONTAINED_RESOURCES];
     //struct rsrc_t *rsrcResources;
     // Pointer to function that handles the entity bound to the resource.
     // This handler has to be explicitly defined by the programmer
     OCEntityHandler entityHandler;
+    // callback parameter
+    void * entityHandlerCallbackParam;
     // Properties on the resource – defines meta information on the resource
     OCResourceProperty resourceProperties ; /* ACTIVE, DISCOVERABLE etc */
-    // Pointer to an opaque object where app/user specific data can be placed with the resource;
-    // this could be information for the entity handler between invocations
-    void *context;
     // NOTE: Methods supported by this resource should be based on the interface targeted
     // i.e. look into the interface structure based on the query request Can be removed here;
     // place holder for the note above
index a946686..432b2f7 100644 (file)
  * These details are exposed in ocstackconfig.h file in the form of documentation.
  * Remember to update the documentation there if these are changed.
  */
-#define OC_JSON_PREFIX                     "{\"oc\":["
+#define OC_JSON_PREFIX                     "{\"oic\":["
 #define OC_JSON_PREFIX_LEN                 (sizeof(OC_JSON_PREFIX) - 1)
 #define OC_JSON_SUFFIX                     "]}"
 #define OC_JSON_SUFFIX_LEN                 (sizeof(OC_JSON_SUFFIX) - 1)
 #define OC_JSON_SEPARATOR                  ','
 #define OC_JSON_SEPARATOR_STR              ","
+#define OC_KEY_VALUE_DELIMITER             "="
 
 /**
  * Static values for various JSON attributes.
 #define OC_RESOURCE_SECURE       1
 
 /**
+ * OIC Virtual resources supported by every OIC device.
+ */
+typedef enum
+{
+    OC_UNKNOWN_URI =0,
+    OC_WELL_KNOWN_URI,          ///< "/oic/res"
+    OC_DEVICE_URI,              ///< "/oic/d"
+    OC_PLATFORM_URI,            ///< "/oic/p"
+    OC_RESOURCE_TYPES_URI,      ///< "/oic/res/types/d"
+#ifdef WITH_PRESENCE
+    OC_PRESENCE,                ///< "/oic/ad"
+#endif
+} OCVirtualResources;
+
+/**
  * The type of query a request/response message is.
  */
 typedef enum
@@ -74,12 +90,7 @@ typedef enum
  * no entity handler.
  */
 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest * request);
-
-/**
- * Get string value associated with a virtual resource type.
- */
-const char * GetVirtualResourceUri(OCVirtualResources resource);
+        OCEntityHandlerRequest * request, void* callbackParam);
 
 /**
  * Find and retrieve pointer to a resource associated with a specific resource
@@ -116,6 +127,14 @@ OCStackResult ProcessRequest(ResourceHandling resHandling,
 OCStackResult SavePlatformInfo(OCPlatformInfo info);
 
 /**
+ * Internal API used to save all of the device's information for use in platform
+ * discovery requests.
+ * The device name is received from the appliation.
+ * The deviceID, spec version and data model verson are initialized by the stack.
+ */
+OCStackResult SaveDeviceInfo(OCDeviceInfo info);
+
+/**
  * Internal API used to clear the platform information.
  */
 void DeletePlatformInfo();
@@ -125,15 +144,18 @@ void DeletePlatformInfo();
  */
 void DeleteDeviceInfo();
 
+/*
+ * Prepare payload for resource representation.
+ */
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+                    OCRepPayload** payload);
+
 /**
- * Prepares a JSON string for response.
+ * Prepares a Payload for response.
  */
 OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
-                                           uint8_t filterOn,
-                                           const char *filterValue,
-                                           char * out,
-                                           uint16_t *remaining,
-                                           CATransportType_t connType);
+                                           OCDiscoveryPayload* payload,
+                                           OCDevAddr *endpoint);
 
 /**
  * A helper function that Maps an @ref OCEntityHandlerResult type to an
index 7909399..228055b 100644 (file)
@@ -45,10 +45,8 @@ typedef struct OCServerRequest
     OCStackResult observeResult;
     uint8_t numResponses;
     OCEHResponseHandler ehResponseHandler;
-    /** Remote Endpoint address **/
-    CAAddress_t addressInfo;
-    /** Connectivity of the endpoint**/
-    CATransportType_t connectivityType;
+    /** Remote endpoint address **/
+    OCDevAddr devAddr;
     // token for the request
     CAToken_t requestToken;
     // token length the request
@@ -56,7 +54,6 @@ typedef struct OCServerRequest
     // The ID of CoAP pdu                                   //Kept in
     uint16_t coapID;                                        //CoAP
     uint8_t delayedResNeeded;
-    uint8_t secured;
     //////////////////////////////////////////////////////////
     // An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
@@ -66,16 +63,16 @@ typedef struct OCServerRequest
     // Flag indicating slow response
     uint8_t slowFlag;
     uint8_t notificationFlag;
-    // reqJSON is retrieved from the payload of the received request PDU
-    char reqJSONPayload[1];
+    size_t payloadSize;
+    // payload is retrieved from the payload of the received request PDU
+    uint8_t payload[1];
 } OCServerRequest;
 
 // following structure will be created in ocstack to aggregate responses (in future: for block transfer)
 typedef struct OCServerResponse {
     struct OCServerResponse * next;
     // this is the pointer to server payload data to be transferred
-    char *payload;
-    uint16_t remainingPayloadSize;
+    OCPayload* payload;
     OCRequestHandle requestHandle;
 } OCServerResponse;
 
@@ -152,21 +149,20 @@ OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
  * @param tokenLength - request token length
  * @param resourceUrl - URL of resource
  * @param reqTotalSize - total size of the request
- * @param addressInfo - CA Address
- * @param connectivityType - connection type
+ * @param devAddr - OCDevAddr
  *
  * @return
  *     OCStackResult
  */
 OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
-        uint8_t delayedResNeeded, uint8_t secured, uint8_t notificationFlag, OCMethod method,
+        uint8_t delayedResNeeded, uint8_t notificationFlag, OCMethod method,
         uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
         OCQualityOfService qos, char * query,
         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
-        char * reqJSONPayload, CAToken_t requestToken,
+        uint8_t * payload, CAToken_t requestToken,
         uint8_t tokenLength,
         char * resourceUrl, size_t reqTotalSize,
-        CAAddress_t *addressInfo, CATransportType_t connectivityType);
+        const OCDevAddr *devAddr);
 
 /**
  * Form the OCEntityHandlerRequest struct that is passed to a resource's entity handler
@@ -174,9 +170,11 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
  * @param entityHandlerRequest - pointer to the OCEntityHandlerRequest struct that is created
  * @param request          - request handle
  * @param method           - RESTful method
+ * @param endpoint         - requesting endpoint
  * @param resource         - resource handle
  * @param queryBuf         - resource query of request
- * @param bufReqPayload    - JSON payload of request
+ * @param payload          - payload of request
+ * @param payloadSize      - size of the payload request
  * @param numVendorOptions - number of vendor options
  * @param vendorOptions    - vendor options
  * @param observeAction    - observe action flag
@@ -185,10 +183,19 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
  * @return
  *     OCStackResult
  */
-OCStackResult FormOCEntityHandlerRequest(OCEntityHandlerRequest * entityHandlerRequest, OCRequestHandle request,
-        OCMethod method, OCResourceHandle resource, char * queryBuf, char * bufReqPayload,
-        uint8_t numVendorOptions, OCHeaderOption * vendorOptions, OCObserveAction observeAction,
-        OCObservationId observeID);
+OCStackResult FormOCEntityHandlerRequest(
+                                OCEntityHandlerRequest *entityHandlerRequest,
+                                OCRequestHandle request,
+                                OCMethod method,
+                                OCDevAddr *endpoint,
+                                OCResourceHandle resource,
+                                char *queryBuf,
+                                uint8_t *payload,
+                                size_t payloadSize,
+                                uint8_t numVendorOptions,
+                                OCHeaderOption *vendorOptions,
+                                OCObserveAction observeAction,
+                                OCObservationId observeID);
 
 /**
  * Find a server request in the server request list and delete
index 83989a5..709a4b0 100644 (file)
@@ -47,6 +47,7 @@ extern "C" {
 // Global variables
 //-----------------------------------------------------------------------------
 extern OCDeviceEntityHandler defaultDeviceHandler;
+extern void* defaultDeviceHandlerCallbackParameter;
 
 //-----------------------------------------------------------------------------
 // Defines
@@ -68,19 +69,15 @@ typedef struct
     // resource query send by client
     char query[MAX_QUERY_LENGTH];
     // reqJSON is retrieved from the payload of the received request PDU
-    char reqJSONPayload[MAX_REQUEST_LENGTH];
+    uint8_t payload[MAX_REQUEST_LENGTH];
     // qos is indicating if the request is CON or NON
     OCQualityOfService qos;
     // An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
     OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
 
-    /** Remote Endpoint address **/
-    //////////////////////////////////////////////////////////
-    // TODO: bundle this up as endpoint
-    CAAddress_t addressInfo;
-    /** Connectivity of the endpoint**/
-    CATransportType_t connectivityType;
+    /** Remote endpoint address **/
+    OCDevAddr devAddr;
 
     //token for the observe request
     CAToken_t requestToken;
@@ -88,8 +85,6 @@ typedef struct
     // The ID of CoAP pdu
     uint16_t coapID;
     uint8_t delayedResNeeded;
-    uint8_t secured;
-    //////////////////////////////////////////////////////////
     uint8_t reqMorePacket;
     uint32_t reqPacketNum;
     uint16_t reqPacketSize;
@@ -135,21 +130,25 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
 
 OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest);
 
-OCStackResult SendDirectStackResponse(const CARemoteEndpoint_t* endPoint, const uint16_t coapID,
+OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16_t coapID,
         const CAResponseResult_t responseResult, const CAMessageType_t type,
         const uint8_t numOptions, const CAHeaderOption_t *options,
         CAToken_t token, uint8_t tokenLength);
 
-
 #ifdef WITH_PRESENCE
+
 /**
  * Notify Presence subscribers that a resource has been modified.
  *
  * @param resourceType Handle to the resourceType linked list of resource
  *                     that was modified.
+ * @param trigger The simplified reason this API was invoked. Valid values are
+ *                  @ref OC_PRESENCE_TRIGGER_CREATE, @ref OC_PRESENCE_TRIGGER_CHANGE,
+ *                  @ref OC_PRESENCE_TRIGGER_DELETE.
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult SendPresenceNotification(OCResourceType *resourceType);
+OCStackResult SendPresenceNotification(OCResourceType *resourceType,
+        OCPresenceTrigger trigger);
 
 /**
  * Send Stop Notification to Presence subscribers.
@@ -236,6 +235,14 @@ OCStackResult OCChangeResourceProperty(OCResourceProperty * inputProperty,
         OCResourceProperty resourceProperties, uint8_t enable);
 #endif
 
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
+
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+
+void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out);
+
+void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h
new file mode 100644 (file)
index 0000000..91776c4
--- /dev/null
@@ -0,0 +1,384 @@
+//******************************************************************
+//
+// 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 OCPAYLOAD_H_
+#define OCPAYLOAD_H_
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include "logger.h"
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct OCResource OCResource;
+
+#ifdef TB_LOG
+    #define OC_LOG_PAYLOAD(level, tag, payload) OCPayloadLog((level),(tag),(payload))
+    #define UUID_SIZE (16)
+    #define UUID_LENGTH (37)
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+
+static inline void OCPayloadLogRep(LogLevel level, const char* tag, OCRepPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Representation"));
+    OCRepPayload* rep = payload;
+    int i = 1;
+    while(rep)
+    {
+        OC_LOG_V(level, tag, "\tResource #%d", i);
+        OC_LOG_V(level, tag, "\tURL:%s", rep->uri);
+        OC_LOG(level, tag, PCF("\tResource Types:"));
+        OCStringLL* strll =  rep->types;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+        OC_LOG(level, tag, PCF("\tInterfaces:"));
+        strll =  rep->interfaces;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+
+        // TODO Finish Logging: Values
+        OCRepPayloadValue* val = rep->values;
+
+        OC_LOG(level, tag, PCF("\tValues:"));
+
+        while(val)
+        {
+            switch(val->type)
+            {
+                case OCREP_PROP_NULL:
+                    OC_LOG_V(level, tag, "\t\t%s: NULL", val->name);
+                    break;
+                case OCREP_PROP_INT:
+                    OC_LOG_V(level, tag, "\t\t%s(int):%lld", val->name, val->i);
+                    break;
+                case OCREP_PROP_DOUBLE:
+                    OC_LOG_V(level, tag, "\t\t%s(double):%f", val->name, val->d);
+                    break;
+                case OCREP_PROP_BOOL:
+                    OC_LOG_V(level, tag, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
+                    break;
+                case OCREP_PROP_STRING:
+                    OC_LOG_V(level, tag, "\t\t%s(string):%s", val->name, val->str);
+                    break;
+                case OCREP_PROP_OBJECT:
+                    // Note: Only prints the URI (if available), to print further, you'll
+                    // need to dig into the object better!
+                    OC_LOG_V(level, tag, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
+                    break;
+                case OCREP_PROP_ARRAY:
+                    switch(val->arr.type)
+                    {
+                        case OCREP_PROP_INT:
+                            OC_LOG_V(level, tag, "\t\t%s(int array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_DOUBLE:
+                            OC_LOG_V(level, tag, "\t\t%s(double array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_BOOL:
+                            OC_LOG_V(level, tag, "\t\t%s(bool array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_STRING:
+                            OC_LOG_V(level, tag, "\t\t%s(string array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_OBJECT:
+                            OC_LOG_V(level, tag, "\t\t%s(OCRep array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        default:
+                            OC_LOG_V(ERROR, tag, "\t\t%s <-- Unknown/unsupported array type!",
+                                    val->name);
+                            break;
+                    }
+                    break;
+                default:
+                    OC_LOG_V(ERROR, tag, "\t\t%s <-- Unknown type!", val->name);
+                    break;
+            }
+            val = val -> next;
+        }
+
+        ++i;
+        rep = rep->next;
+    }
+
+}
+
+static inline void OCPayloadLogDiscovery(LogLevel level, const char* tag,
+        OCDiscoveryPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Discovery"));
+    int i = 1;
+
+    if(!payload->resources)
+    {
+        OC_LOG(level, tag, PCF("\tNO Resources"));
+        return;
+    }
+
+    OCResourcePayload* res = payload->resources;
+
+    while(res)
+    {
+        OC_LOG_V(level, tag, "\tResource #%d", i);
+        OC_LOG_V(level, tag, "\tURI:%s", res->uri);
+        OC_LOG(level, tag, PCF("\tSID:"));
+        OC_LOG_BUFFER(level, tag, res->sid, UUID_SIZE);
+        OC_LOG(level, tag, PCF("\tResource Types:"));
+        OCStringLL* strll =  res->types;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+        OC_LOG(level, tag, PCF("\tInterfaces:"));
+        strll =  res->interfaces;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+
+        OC_LOG_V(level, tag, "\tBitmap: %u", res->bitmap);
+        OC_LOG_V(level, tag, "\tSecure?: %s", res->secure ? "true" : "false");
+        OC_LOG_V(level, tag, "\tPort: %u", res->port);
+        OC_LOG(level, tag, PCF(""));
+        res = res->next;
+        ++i;
+    }
+}
+
+static inline void OCPayloadLogDevice(LogLevel level, const char* tag, OCDevicePayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Device"));
+    OC_LOG_V(level, tag, "\tURI:%s", payload->uri);
+    OC_LOG(level, tag, PCF("\tSID:"));
+    OC_LOG_BUFFER(level, tag, payload->sid, UUID_SIZE);
+    OC_LOG_V(level, tag, "\tDevice Name:%s", payload->deviceName);
+    OC_LOG_V(level, tag, "\tSpec Version%s", payload->specVersion);
+    OC_LOG_V(level, tag, "\tData Model Version:%s", payload->dataModelVersion);
+}
+
+static inline void OCPayloadLogPlatform(LogLevel level, const char* tag, OCPlatformPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Platform"));
+    OC_LOG_V(level, tag, "\tURI:%s", payload->uri);
+    OC_LOG_V(level, tag, "\tPlatform ID:%s", payload->info.platformID);
+    OC_LOG_V(level, tag, "\tMfg Name:%s", payload->info.manufacturerName);
+    OC_LOG_V(level, tag, "\tMfg URL:%s", payload->info.manufacturerUrl);
+    OC_LOG_V(level, tag, "\tModel Number:%s", payload->info.modelNumber);
+    OC_LOG_V(level, tag, "\tDate of Mfg:%s", payload->info.dateOfManufacture);
+    OC_LOG_V(level, tag, "\tPlatform Version:%s", payload->info.platformVersion);
+    OC_LOG_V(level, tag, "\tOS Version:%s", payload->info.operatingSystemVersion);
+    OC_LOG_V(level, tag, "\tHardware Version:%s", payload->info.hardwareVersion);
+    OC_LOG_V(level, tag, "\tFirmware Version:%s", payload->info.firmwareVersion);
+    OC_LOG_V(level, tag, "\tSupport URL:%s", payload->info.supportUrl);
+    OC_LOG_V(level, tag, "\tSystem Time:%s", payload->info.systemTime);
+}
+
+static inline void OCPayloadLogPresence(LogLevel level, const char* tag, OCPresencePayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Presence"));
+    OC_LOG_V(level, tag, "\tSequence Number:%u", payload->sequenceNumber);
+    OC_LOG_V(level, tag, "\tMax Age:%d", payload->maxAge);
+    OC_LOG_V(level, tag, "\tTrigger:%s", convertTriggerEnumToString(payload->trigger));
+    OC_LOG_V(level, tag, "\tResource Type:%s", payload->resourceType);
+}
+
+static inline void OCPayloadLogSecurity(LogLevel level, const char* tag,
+                                        OCSecurityPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Security"));
+    OC_LOG_V(level, tag, "\tSecurity Data: %s", payload->securityData);
+}
+
+static inline void OCPayloadLog(LogLevel level, const char* tag, OCPayload* payload)
+{
+    if(!payload)
+    {
+        OC_LOG(level, tag, PCF("NULL Payload"));
+        return;
+    }
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_REPRESENTATION:
+            OCPayloadLogRep(level, tag, (OCRepPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DISCOVERY:
+            OCPayloadLogDiscovery(level, tag, (OCDiscoveryPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DEVICE:
+            OCPayloadLogDevice(level, tag, (OCDevicePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PLATFORM:
+            OCPayloadLogPlatform(level, tag, (OCPlatformPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PRESENCE:
+            OCPayloadLogPresence(level, tag, (OCPresencePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_SECURITY:
+            OCPayloadLogSecurity(level, tag, (OCSecurityPayload*)payload);
+            break;
+        default:
+            OC_LOG_V(level, tag, "Unknown Payload Type: %d", payload->type);
+            break;
+    }
+}
+#else
+    #define OC_LOG_PAYLOAD(level, tag, payload)
+#endif
+
+void OCPayloadDestroy(OCPayload* payload);
+
+// Representation Payload
+OCRepPayload* OCRepPayloadCreate();
+
+size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+OCRepPayload* OCRepPayloadClone(const OCRepPayload* payload);
+
+void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child);
+
+bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri);
+
+bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType);
+bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface);
+
+bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType);
+bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface);
+
+bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name);
+bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name);
+
+bool OCRepPayloadSetPropInt(OCRepPayload* payload, const char* name, int64_t value);
+bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value);
+
+bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value);
+bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value);
+
+bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value);
+bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value);
+bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, const char** value);
+
+bool OCRepPayloadSetPropBool(OCRepPayload* payload, const char* name, bool value);
+bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value);
+
+bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value);
+bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload* value);
+bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value);
+
+bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
+        int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
+        const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
+        int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
+        double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
+        const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
+        double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
+        const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
+        char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
+        bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
+        const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
+        bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
+        const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
+        OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+void OCRepPayloadDestroy(OCRepPayload* payload);
+
+// Discovery Payload
+OCDiscoveryPayload* OCDiscoveryPayloadCreate();
+
+OCSecurityPayload* OCSecurityPayloadCreate(char* securityData);
+void OCSecurityPayloadDestroy(OCSecurityPayload* payload);
+
+void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
+        uint16_t port);
+void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res);
+size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload);
+OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index);
+
+void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload);
+
+// Device Payload
+OCDevicePayload* OCDevicePayloadCreate(const char* uri, const uint8_t* sid, const char* dname,
+        const char* specVer, const char* dmVer);
+void OCDevicePayloadDestroy(OCDevicePayload* payload);
+
+// Platform Payload
+OCPlatformPayload* OCPlatformPayloadCreate(const char* uri, const OCPlatformInfo* platformInfo);
+OCPlatformPayload* OCPlatformPayloadCreateAsOwner(char* uri, OCPlatformInfo* platformInfo);
+
+void OCPlatformPayloadDestroy(OCPlatformPayload* payload);
+
+// Presence Payload
+OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
+        OCPresenceTrigger trigger, const char* resourceType);
+void OCPresencePayloadDestroy(OCPresencePayload* payload);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/resource/csdk/stack/include/ocpresence.h b/resource/csdk/stack/include/ocpresence.h
new file mode 100644 (file)
index 0000000..688b7d9
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// 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 OCPRESENCE_H_
+#define OCPRESENCE_H_
+
+#ifdef WITH_PRESENCE
+/**
+ * The OCPresenceTrigger enum delineates the three spec-compliant modes for
+ * "Trigger." These enum values are then mapped to strings
+ * "create", "change", "delete", respectively, before getting encoded into
+ * the payload payload.
+ *
+ * @enum OC_PRESENCE_TRIGGER_CREATE The creation of a resource is associated with
+ *                            this invocation of @ref SendPresenceNotification.
+ * @enum OC_PRESENCE_TRIGGER_CHANGE The change/update of a resource is associated
+ *                            this invocation of @ref SendPresenceNotification.
+ * @enum OC_PRESENCE_TRIGGER_DELETE The deletion of a resource is associated with
+ *                            this invocation of @ref SendPresenceNotification.
+ *
+ */
+typedef enum
+{
+    OC_PRESENCE_TRIGGER_CREATE = 0,
+    OC_PRESENCE_TRIGGER_CHANGE = 1,
+    OC_PRESENCE_TRIGGER_DELETE = 2
+} OCPresenceTrigger;
+#endif
+
+#endif
index 73bcd8c..44c926d 100644 (file)
 #ifndef OCSTACK_H_
 #define OCSTACK_H_
 
+#include <stdio.h>
 #include <stdint.h>
 #include "octypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
-#define WITH_PRESENCE
 #define USE_RANDOM_PORT (0)
 
 //-----------------------------------------------------------------------------
@@ -37,6 +37,20 @@ extern "C" {
 /**
  * Initialize the OC Stack.  Must be called prior to starting the stack.
  *
+ * @param mode
+ *     Host device is client, server, or client-server.
+ * @param serverFlags
+ *     Default server transport flags.
+ * @param clientFlags
+ *     Default client transport flags.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags);
+
+/**
+ * Initialize the OC Stack.  Must be called prior to starting the stack.
+ *
  * @param ipAddr
  *     IP Address of host device. Deprecated parameter.
  * @param port
@@ -48,6 +62,16 @@ extern "C" {
  */
 OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode);
 
+#ifdef RA_ADAPTER
+/**
+ * @brief   Set Remote Access information for XMPP Client.
+ * @param   raInfo            [IN] remote access info.
+ *
+ * @return  #CA_STATUS_OK
+ */
+OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo);
+#endif
+
 /**
  * Stop the OC stack.  Use for a controlled shutdown.
  *
@@ -79,11 +103,11 @@ OCStackResult OCProcess();
  *                           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             @ref OCMethod to perform on the resource.
- * @param requiredUri        URI of the resource to interact with.
- * @param referenceUri       URI of the reference resource.
+ * @param requiredUri        URI of the resource to interact with. (Address prefix
+ *                           is deprecated in favor of destination.)
+ * @param destination        Complete description of destination.
  * @param request            JSON encoded request.
- * @param conType            @ref OCConnectivityType type of connectivity indicating the
- *                           interface. Example: ::OC_WIFI, ::OC_ETHERNET, ::OC_ALL.
+ * @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
@@ -100,11 +124,16 @@ OCStackResult OCProcess();
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
-            const char *referenceUri, const char *request, OCConnectivityType conType,
-            OCQualityOfService qos, OCCallbackData *cbData,
-            OCHeaderOption * options, uint8_t numOptions);
-
+OCStackResult OCDoResource(OCDoHandle *handle,
+                            OCMethod method,
+                            const char *requestUri,
+                            const OCDevAddr *destination,
+                            OCPayload* payload,
+                            OCConnectivityType connectivityType,
+                            OCQualityOfService qos,
+                            OCCallbackData *cbData,
+                            OCHeaderOption *options,
+                            uint8_t numOptions);
 /**
  * Cancel a request associated with a specific @ref OCDoResource invocation.
  *
@@ -119,6 +148,15 @@ OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requ
 OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption * options,
         uint8_t numOptions);
 
+/**
+ * @brief   Register Persistent storage callback.
+ * @param   persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - Invalid parameter
+ */
+OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler);
+
 #ifdef WITH_PRESENCE
 /**
  * When operating in @ref OCServer or @ref OCClientServer mode, this API will start sending out
@@ -159,10 +197,11 @@ OCStackResult OCStopPresence();
  * @param entityHandler Entity handler function that is called by ocstack to handle requests for
  *                      any undefined resources or default actions.
  *                      If NULL is passed it removes the device default entity handler.
+ * @param callbackParameter paramter passed back when entityHandler is called.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler);
+OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler, void* callbackParameter);
 
 /**
  * Set device information.
@@ -202,6 +241,7 @@ OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo);
  * @param uri URI of the resource.  Example:  "/a/led".
  * @param entityHandler Entity handler function that is called by ocstack to handle requests, etc.
  *                      NULL for default entity handler.
+ * @param callbackParameter paramter passed back when entityHandler is called.
  * @param resourceProperties Properties supported by resource.
  *                           Example: ::OC_DISCOVERABLE|::OC_OBSERVABLE.
  *
@@ -212,31 +252,9 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
                                const char *resourceInterfaceName,
                                const char *uri,
                                OCEntityHandler entityHandler,
+                               void* callbackParam,
                                uint8_t resourceProperties);
 
-/**
- * Create a resource. with host ip address for remote resource.
- *
- * @param handle Pointer to handle to newly created resource.  Set by ocstack.
- *               Used to refer to resource.
- * @param resourceTypeName Name of resource type.  Example: "core.led".
- * @param resourceInterfaceName Name of resource interface.  Example: "core.rw".
- * @param host HOST address of the remote resource.  Example:  "coap://xxx.xxx.xxx.xxx:xxxxx".
- * @param uri URI of the resource.  Example:  "/a/led".
- * @param entityHandler Entity handler function that is called by ocstack to handle requests, etc.
- *                      NULL for default entity handler.
- * @param resourceProperties Properties supported by resource.
- *                           Example: ::OC_DISCOVERABLE|::OC_OBSERVABLE
- *
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-OCStackResult OCCreateResourceWithHost(OCResourceHandle *handle,
-                               const char *resourceTypeName,
-                               const char *resourceInterfaceName,
-                               const char *host,
-                               const char *uri,
-                               OCEntityHandler entityHandler,
-                               uint8_t resourceProperties);
 
 /**
  * Add a resource to a collection resource.
@@ -284,9 +302,11 @@ OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
  *
  * @param handle Handle to the resource that the contained resource is to be bound.
  * @param entityHandler Entity handler function that is called by ocstack to handle requests, etc.
+ * @param callbackParameter context paremeter that will be passed to entityHandler
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCBindResourceHandler(OCResourceHandle handle, OCEntityHandler entityHandler);
+OCStackResult OCBindResourceHandler(OCResourceHandle handle, OCEntityHandler entityHandler,
+                                        void *callbackParameter);
 
 /**
  * Get the number of resources that have been created in the stack.
@@ -428,7 +448,7 @@ OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService q
  * @param handle Handle of resource.
  * @param obsIdList List of observation ids that need to be notified.
  * @param numberOfIds Number of observation ids included in obsIdList.
- * @param notificationJSONPayload JSON encoded payload to send in notification.
+ * @param payload OCRepresentationPayload object representing the notification
  * @param qos Desired quality of service of the observation notifications.
  * NOTE: The memory for obsIdList and notificationJSONPayload is managed by the
  * entity invoking the API. The maximum size of the notification is 1015 bytes
@@ -440,7 +460,7 @@ OCStackResult
 OCNotifyListOfObservers (OCResourceHandle handle,
                             OCObservationId  *obsIdList,
                             uint8_t          numberOfIds,
-                            const char    *notificationJSONPayload,
+                            const OCRepPayload *payload,
                             OCQualityOfService qos);
 
 
@@ -455,37 +475,8 @@ OCNotifyListOfObservers (OCResourceHandle handle,
  */
 OCStackResult OCDoResponse(OCEntityHandlerResponse *response);
 
-
-//Utility methods
-
-/**
- * This method is used to retrieved the IPv4 address from OCDev address
- * data structure.
- *
- * @param ipAddr OCDevAddr address.
- * @param a first byte of IPv4 address.
- * @param b second byte of IPv4 address.
- * @param c third byte of IPv4 address.
- * @param d fourth byte of IPv4 address.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-int32_t OCDevAddrToIPv4Addr(OCDevAddr *ipAddr, uint8_t *a, uint8_t *b,
-            uint8_t *c, uint8_t *d );
-
-/**
- * This method is used to retrieve the port number from OCDev address
- * data structure.
- *
- * @param ipAddr OCDevAddr address.
- * @param port Port number.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-int32_t OCDevAddrToPort(OCDevAddr *ipAddr, uint16_t *port);
-
 #ifdef __cplusplus
 }
 #endif // __cplusplus
 
 #endif /* OCSTACK_H_ */
-
-
index 0213def..d1463eb 100644 (file)
  * Maximum length of the response supported by Server for any REST request.
  * The actual repsonse length is 256 for Arduino and 1024 for other platforms.
  * Note that the stack will add a prefix and suffix to the payload.
- * Prefix : {"oc":[
+ * Prefix : {"oic":[
  * Suffix : ]}
- * They have a combined size of 9 bytes.
+ * They have a combined size of 10 bytes.
  */
 #ifdef WITH_ARDUINO
-#define MAX_RESPONSE_LENGTH (247)
+#define MAX_RESPONSE_LENGTH (256)
 #else
-#define MAX_RESPONSE_LENGTH (1015)
+#define MAX_RESPONSE_LENGTH (1024)
 #endif
 
 /**
index c597771..61aa3ce 100644 (file)
 #define OCTYPES_H_
 
 #include "ocstackconfig.h"
-
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
 #ifdef __cplusplus
+#include <string.h>
+
 extern "C" {
 #endif // __cplusplus
 #define WITH_PRESENCE
+#include "ocpresence.h"
 //-----------------------------------------------------------------------------
 // Defines
 //-----------------------------------------------------------------------------
 
-//TODO: May want to refactor this in upcoming sprints.
-//Don't want to expose to application layer that lower level stack is using CoAP.
-
-/// Authority + URI string to prefix well known queries
-#define OC_WELL_KNOWN_QUERY                  "224.0.1.187:5683/oc/core"
-#define OC_MULTICAST_DISCOVERY_URI           "/oc/core"
-#define OC_EXPLICIT_DEVICE_DISCOVERY_URI     "224.0.1.187:5683/oc/core/d?rt=core.led"
-/// Multicast address and port string to prefix multicast queries
-#define OC_MULTICAST_PREFIX                  "224.0.1.187:5683"
-/// IP Multicast address to use for multicast requests
-#define OC_MULTICAST_IP                      "224.0.1.187"
-/// IP Multicast port to use for multicast requests
-#define OC_MULTICAST_PORT                    5683
-
+/**
+ * OIC Virtual resources supported by every OIC device.
+ */
+#define OC_RSRVD_WELL_KNOWN_URI               "/oic/res"
+#define OC_RSRVD_DEVICE_URI                   "/oic/d"
+#define OC_RSRVD_PLATFORM_URI                 "/oic/p"
+#define OC_RSRVD_RESOURCE_TYPES_URI           "/oic/res/types/d"
 #ifdef WITH_PRESENCE
+#define OC_RSRVD_PRESENCE_URI                 "/oic/ad"
 #define OC_DEFAULT_PRESENCE_TTL_SECONDS (60)
 /// OC_MAX_PRESENCE_TTL_SECONDS sets the maximum time to live (TTL) for presence.
 /// NOTE: Changing the setting to a longer duration may lead to unsupported and untested
 /// operation.
 #define OC_MAX_PRESENCE_TTL_SECONDS     (60 * 60 * 24) // 60 sec/min * 60 min/hr * 24 hr/day
-#define OC_PRESENCE_URI                      "/oic/ad"
 #endif
+
+///Separtor for multiple query string
+#define OC_QUERY_SEPARATOR                "&;"
+
 /**
  * Attributes used to form a proper OIC conforming JSON message.
  */
-#define OC_RSRVD_OC                     "oic"
+//#define OC_RSRVD_OC                     "oic"
 #define OC_RSRVD_PAYLOAD                "payload"
 #define OC_RSRVD_HREF                   "href"
 #define OC_RSRVD_PROPERTY               "prop"
@@ -65,21 +67,32 @@ extern "C" {
 #define OC_RSRVD_RESOURCE_TYPE          "rt"
 #define OC_RSRVD_RESOURCE_TYPE_PRESENCE "oic.wk.ad"
 #define OC_RSRVD_INTERFACE              "if"
-#define OC_RSRVD_DEVICE_ID              "di"
-#define OC_RSRVD_DEVICE_NAME            "dn"
+#define OC_RSRVD_TTL                    "ttl"
+#define OC_RSRVD_NONCE                  "non"
+#define OC_RSRVD_TRIGGER                "trg"
+#define OC_RSRVD_LINKS                  "links"
+
 #define OC_RSRVD_INTERFACE_DEFAULT      "oic.if.baseline"
 #define OC_RSRVD_INTERFACE_LL           "oic.if.ll"
 #define OC_RSRVD_INTERFACE_BATCH        "oic.if.b"
-#define OC_RSRVD_INTERFACE_GROUP        "oc.mi.grp"
+#define OC_RSRVD_INTERFACE_GROUP        "oic.mi.grp"
+#define OC_RSRVD_MFG_DATE               "mndt"
 #define OC_RSRVD_FW_VERSION             "mnfv"
 #define OC_RSRVD_HOST_NAME              "hn"
 #define OC_RSRVD_VERSION                "icv"
-#define OC_RSRVD_OBSERVABLE             "obs"
+#define OC_RSRVD_POLICY                 "p"
+#define OC_RSRVD_BITMAP                 "bm"
 #define OC_RSRVD_SECURE                 "sec"
 #define OC_RSRVD_HOSTING_PORT           "port"
 #define OC_RSRVD_SERVER_INSTANCE_ID     "sid"
 
-  //**** Platform ****
+//**** Presence "Announcement Triggers" ****
+#define OC_RSRVD_TRIGGER_CREATE         "create"
+#define OC_RSRVD_TRIGGER_CHANGE         "change"
+#define OC_RSRVD_TRIGGER_DELETE         "delete"
+//*******************
+
+//**** Platform ****
 #define OC_RSRVD_PLATFORM_ID            "pi"
 #define OC_RSRVD_MFG_NAME               "mnmn"
 #define OC_RSRVD_MFG_URL                "mnml"
@@ -93,54 +106,184 @@ extern "C" {
 #define OC_RSRVD_SYSTEM_TIME             "st"
 //*******************
 
+//**** Device ****
+#define OC_RSRVD_DEVICE_ID              "di"
+#define OC_RSRVD_DEVICE_NAME            "n"
+#define OC_RSRVD_SPEC_VERSION           "lcv"
+#define OC_RSRVD_DATA_MODEL_VERSION     "dmv"
+
+#define OC_SPEC_VERSION                "0.9.0"
+#define OC_DATA_MODEL_VERSION          "sec.0.95"
+//*******************
+
+// These provide backward compatibility - their use is deprecated
+#ifndef GOING_AWAY
+#define OC_MULTICAST_PREFIX                  "224.0.1.187:5683"
+#define OC_MULTICAST_IP                      "224.0.1.187"
+#define OC_MULTICAST_PORT                    5683
+#endif // GOING_AWAY
+
 //-----------------------------------------------------------------------------
 // Typedefs
 //-----------------------------------------------------------------------------
+#ifdef RA_ADAPTER
+#define MAX_ADDR_STR_SIZE (256)
+#else
+#define MAX_ADDR_STR_SIZE (40)
+ #endif
+
+#define MAX_IDENTITY_SIZE (32)
+
+
+/*
+ * These enums (OCTransportAdapter and OCTransportFlags) must
+ * be kept synchronized with OCConnectivityType (below) as well as
+ * CATransportAdapter and CATransportFlags (in CACommon.h).
+ */
+
+typedef enum
+{
+    OC_DEFAULT_ADAPTER = 0,
+
+    // value zero indicates discovery
+    OC_ADAPTER_IP            = (1 << 0),   // IPv4 and IPv6, including 6LoWPAN
+    OC_ADAPTER_GATT_BTLE     = (1 << 1),   // GATT over Bluetooth LE
+    OC_ADAPTER_RFCOMM_BTEDR  = (1 << 2),   // RFCOMM over Bluetooth EDR
+
+    #ifdef RA_ADAPTER
+    OC_ADAPTER_REMOTE_ACCESS = (1 << 3)    // Remote Access over XMPP.
+    #endif
+} OCTransportAdapter;
+
+// enum layout assumes some targets have 16-bit integer (e.g., Arduino)
+typedef enum
+{
+    OC_DEFAULT_FLAGS = 0,
+
+    // Insecure transport is the default (subject to change)
+    OC_FLAG_SECURE     = (1 << 4),   // secure the transport path
+
+    // IPv4 & IPv6 autoselection is the default
+    OC_IP_USE_V6       = (1 << 5),   // IP adapter only
+    OC_IP_USE_V4       = (1 << 6),   // IP adapter only
+
+    OC_RESERVED1       = (1 << 7),   // internal use only
+
+    // Link-Local multicast is the default multicast scope for IPv6.
+    // These are placed here to correspond to the IPv6 multicast address bits.
+    OC_SCOPE_INTERFACE = 0x1, // IPv6 Interface-Local scope (loopback)
+    OC_SCOPE_LINK      = 0x2, // IPv6 Link-Local scope (default)
+    OC_SCOPE_REALM     = 0x3, // IPv6 Realm-Local scope
+    OC_SCOPE_ADMIN     = 0x4, // IPv6 Admin-Local scope
+    OC_SCOPE_SITE      = 0x5, // IPv6 Site-Local scope
+    OC_SCOPE_ORG       = 0x8, // IPv6 Organization-Local scope
+    OC_SCOPE_GLOBAL    = 0xE, // IPv6 Global scope
+} OCTransportFlags;
+
+#define OC_MASK_SCOPE    (0x000F)
+#define OC_MASK_MODS     (0x0FF0)
+#define OC_MASK_FAMS     (OC_IP_USE_V6|OC_IP_USE_V4)
+
+/*
+ * endpoint identity
+ */
+typedef struct
+{
+    uint16_t id_length;
+    unsigned char id[MAX_IDENTITY_SIZE];
+} OCIdentity;
 
 /**
  * Data structure to encapsulate IPv4/IPv6/Contiki/lwIP device addresses.
+ *
+ * OCDevAddr must be the same as CAEndpoint (in CACommon.h).
  */
-typedef struct OCDevAddr
+typedef struct
 {
-    uint32_t     size;                    ///< length of the address stored in addr field.
-    uint8_t      addr[DEV_ADDR_SIZE_MAX]; ///< device address.
+    OCTransportAdapter      adapter;    // adapter type
+    OCTransportFlags        flags;      // transport modifiers
+    char                    addr[MAX_ADDR_STR_SIZE]; // address for all adapters
+    uint32_t                interface;  // usually zero for default interface
+    uint16_t                port;       // for IP
+    OCIdentity              identity;   // secure node identity
 } OCDevAddr;
 
-/**
- * OC Virtual resources supported by every OC device.
+/*
+ * OCConnectivityType includes elements of both OCTransportAdapter
+ * and OCTransportFlags. It is defined conditionally because the
+ * smaller definition limits expandability on 32/64 bit integer machines,
+ * and the larger definition won't fit into an enum on 16-bit integer
+ * machines like Arduino.
+ *
+ * This structure must directly correspond to OCTransportAdapter
+ * and OCTransportFlags.
  */
 typedef enum
 {
-    OC_WELL_KNOWN_URI= 0,       ///< "/oc/core"
-    OC_DEVICE_URI,              ///< "/oc/core/d"
-    OC_PLATFORM_URI,            ///< "/oic/p"
-    OC_RESOURCE_TYPES_URI,      ///< "/oc/core/d/type"
-    #ifdef WITH_PRESENCE
-    OC_PRESENCE,                ///< "/oic/ad"
+    CT_DEFAULT = 0,                // use when defaults are ok
+
+    #if defined (__UINT32_MAX__) && (__UINT32_MAX__ == 65535) // 16-bit int
+    CT_ADAPTER_IP           = (1 << 10),  // IPv4 and IPv6, including 6LoWPAN
+    CT_ADAPTER_GATT_BTLE    = (1 << 11),  // GATT over Bluetooth LE
+    CT_ADAPTER_RFCOMM_BTEDR = (1 << 12),  // RFCOMM over Bluetooth EDR
+    #ifdef RA_ADAPTER
+    CT_ADAPTER_REMOTE_ACCESS = (1 << 13),  // Remote Access over XMPP
+    #endif
+    #define CT_ADAPTER_SHIFT 10
+    #define CT_MASK_FLAGS 0x03FF
+    #define CT_MASK_ADAPTER 0xFC00
+    #else   // assume 32-bit int
+    CT_ADAPTER_IP           = (1 << 16),  // IPv4 and IPv6, including 6LoWPAN
+    CT_ADAPTER_GATT_BTLE    = (1 << 17),  // GATT over Bluetooth LE
+    CT_ADAPTER_RFCOMM_BTEDR = (1 << 18),  // RFCOMM over Bluetooth EDR
+    #ifdef RA_ADAPTER
+    CT_ADAPTER_REMOTE_ACCESS = (1 << 19),  // Remote Access over XMPP
+    #endif
+    #define CT_ADAPTER_SHIFT 16
+    #define CT_MASK_FLAGS 0xFFFF
+    #define CT_MASK_ADAPTER 0xFFFF0000
     #endif
-    OC_MAX_VIRTUAL_RESOURCES    ///<s Max items in the list
-} OCVirtualResources;
+
+    // Insecure transport is the default (subject to change)
+    CT_FLAG_SECURE     = (1 << 4), // secure the transport path
+
+    // IPv4 & IPv6 autoselection is the default
+    CT_IP_USE_V6       = (1 << 5), // IP adapter only
+    CT_IP_USE_V4       = (1 << 6), // IP adapter only
+
+    // Link-Local multicast is the default multicast scope for IPv6.
+    // These are placed here to correspond to the IPv6 address bits.
+    CT_SCOPE_INTERFACE = 0x1, // IPv6 Interface-Local scope (loopback)
+    CT_SCOPE_LINK      = 0x2, // IPv6 Link-Local scope (default)
+    CT_SCOPE_REALM     = 0x3, // IPv6 Realm-Local scope
+    CT_SCOPE_ADMIN     = 0x4, // IPv6 Admin-Local scope
+    CT_SCOPE_SITE      = 0x5, // IPv6 Site-Local scope
+    CT_SCOPE_ORG       = 0x8, // IPv6 Organization-Local scope
+    CT_SCOPE_GLOBAL    = 0xE, // IPv6 Global scope
+} OCConnectivityType;
 
 /**
- * Standard RESTful HTTP Methods.
+ *  OCDoResource methods
  */
 typedef enum
 {
-    OC_REST_NOMETHOD    = 0,
-    OC_REST_GET         = (1 << 0),     ///< Read
-    OC_REST_PUT         = (1 << 1),     ///< Write
-    OC_REST_POST        = (1 << 2),     ///< Update
-    OC_REST_DELETE      = (1 << 3),     ///< Delete
+    OC_REST_NOMETHOD       = 0,
+    OC_REST_GET            = (1 << 0),     ///< Read
+    OC_REST_PUT            = (1 << 1),     ///< Write
+    OC_REST_POST           = (1 << 2),     ///< Update
+    OC_REST_DELETE         = (1 << 3),     ///< Delete
     /// Register observe request for most up date notifications ONLY.
-    OC_REST_OBSERVE     = (1 << 4),
+    OC_REST_OBSERVE        = (1 << 4),
     /// Register observe request for all notifications, including stale notifications.
-    OC_REST_OBSERVE_ALL = (1 << 5),
+    OC_REST_OBSERVE_ALL    = (1 << 5),
     /// Deregister observation, intended for internal use
     OC_REST_CANCEL_OBSERVE = (1 << 6),
     #ifdef WITH_PRESENCE
     /// Subscribe for all presence notifications of a particular resource.
-    OC_REST_PRESENCE    = (1 << 7)
+    OC_REST_PRESENCE       = (1 << 7),
     #endif
+    /// Allows OCDoResource caller to do discovery.
+    OC_REST_DISCOVER       = (1 << 8)
 } OCMethod;
 
 /**
@@ -175,24 +318,34 @@ typedef enum
 
 /**
  * Resource Properties.
+ * The value of a policy property is defined as bitmap.
+ * The LSB represents OC_DISCOVERABLE and Second LSB bit represents OC_OBSERVABLE and so on.
+ * Not including the policy property is equivalent to zero.
  *
- * ::OC_ACTIVE       When this bit is set, the resource is initialized, otherwise the resource
- *                   is 'inactive'. 'inactive' signifies that the resource has been marked for
- *                   deletion or is already deleted.
+ * ::OC_RES_PROP_NONE When none of the bits are set, the resource is non-discoverable &
+ *                    non-observable by the client.
  * ::OC_DISCOVERABLE When this bit is set, the resource is allowed to be discovered by clients.
  * ::OC_OBSERVABLE   When this bit is set, the resource is allowed to be observed by clients.
- * ::OC_SLOW         When this bit is set, the resource has been marked as 'slow'. 'slow' signifies
- *                   that responses from this resource can expect delays in processing its
- *                   requests from clients.
- * ::OC_SECURE       When this bit is set, the resource is a secure resource.
+ * ::OC_ACTIVE        When this bit is set, the resource is initialized, otherwise the resource
+ *                    is 'inactive'. 'inactive' signifies that the resource has been marked for
+ *                    deletion or is already deleted.
+ * ::OC_SLOW          When this bit is set, the resource has been marked as 'slow'. 'slow'
+ *                    signifies that responses from this resource can expect delays in
+ *                    processing its requests from clients.
+ * ::OC_SECURE        When this bit is set, the resource is a secure resource.
+ * ::OC_EXPLICIT_DISCOVERABLE   When this bit is set, the resource is allowed to be discovered only
+ *                              if discovery request contains an explicit querystring.
+ *                              Ex: GET /oic/res?rt=oic.sec.acl
  */
 typedef enum
 {
-    OC_ACTIVE       = (1 << 0),
-    OC_DISCOVERABLE = (1 << 1),
-    OC_OBSERVABLE   = (1 << 2),
-    OC_SLOW         = (1 << 3),
-    OC_SECURE       = (1 << 4)
+    OC_RES_PROP_NONE = (0),
+    OC_DISCOVERABLE  = (1 << 0),
+    OC_OBSERVABLE    = (1 << 1),
+    OC_ACTIVE        = (1 << 2),
+    OC_SLOW          = (1 << 3),
+    OC_SECURE        = (1 << 4),
+    OC_EXPLICIT_DISCOVERABLE   = (1 << 5)
 } OCResourceProperty;
 
 /**
@@ -205,18 +358,6 @@ typedef enum
 } OCTransportProtocolID;
 
 /**
- * Adaptor types.
- */
-typedef enum
-{
-    OC_IPV4 = 0,
-    OC_IPV6,
-    OC_EDR,
-    OC_LE,
-    OC_ALL // Multicast message: send over all the interfaces.
-} OCConnectivityType;
-
-/**
  * Declares Stack Results & Errors.
  */
 typedef enum
@@ -254,6 +395,7 @@ typedef enum
     OC_STACK_INVALID_REQUEST_HANDLE,
     OC_STACK_INVALID_DEVICE_INFO,
     OC_STACK_INVALID_JSON,
+    OC_STACK_UNAUTHORIZED_REQ,          /**< Request is not authorized by Resource Server. */
     /* NOTE: Insert all new error codes here!*/
     #ifdef WITH_PRESENCE
     OC_STACK_PRESENCE_STOPPED = 128,
@@ -294,6 +436,27 @@ typedef enum
     OC_OBSERVE_NO_OPTION = 2
 } OCObserveAction;
 
+
+/**
+ * Persistent storage handlers. An app must provide OCPersistentStorage handler pointers when it
+ * calls OCRegisterPersistentStorageHandler.
+ */
+typedef struct {
+    /*
+     *  Persistent storage open handler points to default file path.
+     *  Application can point to appropriate SVR database path for its Iotivity Server.
+     */
+    FILE* (* open)(const char *path, const char *mode);
+    // Persistent storage read handler
+    size_t (* read)(void *ptr, size_t size, size_t nmemb, FILE *stream);
+    // Persistent storage write handler
+    size_t (* write)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
+    // Persistent storage close handler
+    int (* close)(FILE *fp);
+    // Persistent storage unlink handler
+    int (* unlink)(const char *path);
+} OCPersistentStorage;
+
 typedef struct
 {
     // Action associated with observation request
@@ -330,9 +493,207 @@ typedef struct OCHeaderOption
     uint16_t optionLength;
     // pointer to its data
     uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
+
+#ifdef __cplusplus
+    OCHeaderOption() = default;
+    OCHeaderOption(OCTransportProtocolID pid,
+                   uint16_t optId,
+                   uint16_t optlen,
+                   const uint8_t* optData)
+        : protocolID(pid),
+          optionID(optId),
+          optionLength(optlen)
+    {
+
+        // parameter includes the null terminator.
+        optionLength = optionLength < MAX_HEADER_OPTION_DATA_LENGTH ?
+                        optionLength : MAX_HEADER_OPTION_DATA_LENGTH;
+        memcpy(optionData, optData, optionLength);
+        optionData[optionLength - 1] = '\0';
+    }
+#endif
 } OCHeaderOption;
 
 /**
+ * This structure describes the platform properties. All non-Null properties will be included
+ * in a platform discovery request.
+ */
+typedef struct
+{
+    char *platformID;
+    char *manufacturerName;
+    char *manufacturerUrl;
+    char *modelNumber;
+    char *dateOfManufacture;
+    char *platformVersion;
+    char *operatingSystemVersion;
+    char *hardwareVersion;
+    char *firmwareVersion;
+    char *supportUrl;
+    char *systemTime;
+
+} OCPlatformInfo;
+
+#ifdef RA_ADAPTER
+/**
+ * @brief CA Remote Access information for XMPP Client
+ *
+ */
+typedef struct
+{
+    char *hostname;     /**< XMPP server hostname */
+    uint16_t   port;    /**< XMPP server serivce port */
+    char *xmpp_domain;  /**< XMPP login domain */
+    char *username;     /**< login username */
+    char *password;     /**< login password */
+    char *resource;     /**< specific resource for login */
+    char *user_jid;     /**< specific JID for login */
+} OCRAInfo_t;
+#endif  /* RA_ADAPTER */
+
+/**
+ * This structure is expected as input for device properties.
+ * device name is mandatory and expected from the application.
+ * device id of type UUID will be generated by the stack.
+ */
+typedef struct
+{
+    char *deviceName;
+
+} OCDeviceInfo;
+
+// Enum to describe the type of object held by the OCPayload object
+typedef enum
+{
+    PAYLOAD_TYPE_INVALID,
+    PAYLOAD_TYPE_DISCOVERY,
+    PAYLOAD_TYPE_DEVICE,
+    PAYLOAD_TYPE_PLATFORM,
+    PAYLOAD_TYPE_REPRESENTATION,
+    PAYLOAD_TYPE_SECURITY,
+    PAYLOAD_TYPE_PRESENCE
+} OCPayloadType;
+
+typedef struct
+{
+    // The type of message that was received
+    OCPayloadType type;
+} OCPayload;
+
+typedef enum
+{
+    OCREP_PROP_NULL,
+    OCREP_PROP_INT,
+    OCREP_PROP_DOUBLE,
+    OCREP_PROP_BOOL,
+    OCREP_PROP_STRING,
+    OCREP_PROP_OBJECT,
+    OCREP_PROP_ARRAY
+}OCRepPayloadPropType;
+
+#define MAX_REP_ARRAY_DEPTH 3
+typedef struct
+{
+    OCRepPayloadPropType type;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH];
+
+    union
+    {
+        int64_t* iArray;
+        double* dArray;
+        bool* bArray;
+        char** strArray;
+        struct OCRepPayload** objArray;
+    };
+} OCRepPayloadValueArray;
+
+typedef struct OCRepPayloadValue
+{
+    char* name;
+    OCRepPayloadPropType type;
+    union
+    {
+        int64_t i;
+        double d;
+        bool b;
+        char* str;
+        struct OCRepPayload* obj;
+        OCRepPayloadValueArray arr;
+    };
+    struct OCRepPayloadValue* next;
+
+} OCRepPayloadValue;
+
+typedef struct OCStringLL
+{
+    struct OCStringLL *next;
+    char* value;
+} OCStringLL;
+
+// used for get/set/put/observe/etc representations
+typedef struct OCRepPayload
+{
+    OCPayload base;
+    char* uri;
+    OCStringLL* types;
+    OCStringLL* interfaces;
+    OCRepPayloadValue* values;
+    struct OCRepPayload* next;
+} OCRepPayload;
+
+// used inside a discovery payload
+typedef struct OCResourcePayload
+{
+    char* uri;
+    uint8_t* sid;
+    OCStringLL* types;
+    OCStringLL* interfaces;
+    uint8_t bitmap;
+    bool secure;
+    uint16_t port;
+    struct OCResourcePayload* next;
+} OCResourcePayload;
+
+typedef struct
+{
+    OCPayload base;
+    OCResourcePayload* resources;
+} OCDiscoveryPayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* uri;
+    uint8_t* sid;
+    char* deviceName;
+    char* specVersion;
+    char* dataModelVersion;
+} OCDevicePayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* uri;
+    OCPlatformInfo info;
+} OCPlatformPayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* securityData;
+} OCSecurityPayload;
+#ifdef WITH_PRESENCE
+typedef struct
+{
+    OCPayload base;
+    uint32_t sequenceNumber;
+    uint32_t maxAge;
+    OCPresenceTrigger trigger;
+    char* resourceType;
+} OCPresencePayload;
+#endif
+
+/**
  * Incoming requests handled by the server. Requests are passed in as a parameter to the
  * @ref OCEntityHandler callback API.
  * @brief The @ref OCEntityHandler callback API must be implemented in the application in order
@@ -345,6 +706,8 @@ typedef struct
     OCRequestHandle requestHandle;
     // the REST method retrieved from received request PDU
     OCMethod method;
+    // description of endpoint that sent the request
+    OCDevAddr devAddr;
     // resource query send by client
     char * query;
     // Information associated with observation - valid only when OCEntityHandler
@@ -353,8 +716,8 @@ typedef struct
     // An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
     OCHeaderOption * rcvdVendorSpecificHeaderOptions;
-    // reqJSON is retrieved from the payload of the received request PDU
-    char * reqJSONPayload;
+    // the payload from the request PDU
+    OCPayload *payload;
 } OCEntityHandlerRequest;
 
 /**
@@ -363,59 +726,22 @@ typedef struct
 typedef struct
 {
     /// Address of remote server
-    OCDevAddr * addr;
-    /// Indicates adaptor type on which the response was received
-    OCConnectivityType connType;
+    OCDevAddr devAddr;
+    OCDevAddr *addr;            // backward compatibility (points to devAddr)
+    OCConnectivityType connType;  // backward compatibility
     /// the is the result of our stack, OCStackResult should contain coap/other error codes;
     OCStackResult result;
     /// If associated with observe, this will represent the sequence of notifications from server.
     uint32_t sequenceNumber;
-    /// resJSONPayload is retrieved from the payload of the received request PDU
-    const char * resJSONPayload;
+    /// resourceURI
+    const char * resourceUri;
+    // the payload for the response PDU
+    OCPayload *payload;
     /// An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
     OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
 } OCClientResponse;
 
-/**
- * This structure describes the platform properties. All non-Null properties will be included
- * in a platform discovery request.
- */
-typedef struct
-{
-    char *platformID;
-    char *manufacturerName;
-    char *manufacturerUrl;
-    char *modelNumber;
-    char *dateOfManufacture;
-    char *platformVersion;
-    char *operatingSystemVersion;
-    char *hardwareVersion;
-    char *firmwareVersion;
-    char *supportUrl;
-    char *systemTime;
-
-} OCPlatformInfo;
-
-/**
- * TODO : Modify these. This is just so sample apps compile.
- */
-typedef struct
-{
-    char *deviceName;
-    char *hostName;
-    char *deviceUUID;
-    char *contentType;
-    char *version;
-    char *manufacturerName;
-    char *manufacturerUrl;
-    char *modelNumber;
-    char *dateOfManufacture;
-    char *platformVersion;
-    char *firmwareVersion;
-    char *supportUrl;
-} OCDeviceInfo;
-
 typedef struct
 {
     // Request handle is passed to server via the entity handler for each incoming request.
@@ -426,9 +752,7 @@ typedef struct
     // Allow the entity handler to pass a result with the response
     OCEntityHandlerResult  ehResult;
     // this is the pointer to server payload data to be transferred
-    char *payload;
-    // size of server payload data.  I don't think we should rely on null terminated data for size
-    uint16_t payloadSize;
+    OCPayload* payload;
     // An array of the vendor specific header options the entity handler wishes to use in response
     uint8_t numSendVendorSpecificHeaderOptions;
     OCHeaderOption sendVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
@@ -472,13 +796,18 @@ typedef void (* OCClientContextDeleter)(void *context);
 /**
  * This info is passed from application to OC Stack when initiating a request to Server.
  */
-typedef struct
+typedef struct OCCallbackData
 {
     void *context;
     /// The pointer to a function the stack will call to handle the requests
     OCClientResponseHandler cb;
     /// A pointer to a function to delete the context when this callback is removed
     OCClientContextDeleter cd;
+#ifdef __cplusplus
+    OCCallbackData() = default;
+    OCCallbackData(void* ctx, OCClientResponseHandler callback, OCClientContextDeleter deleter)
+        :context(ctx), cb(callback), cd(deleter){}
+#endif
 } OCCallbackData;
 
 /**
@@ -486,13 +815,13 @@ typedef struct
  * Entity handler callback needs to fill the resPayload of the entityHandlerRequest.
  */
 typedef OCEntityHandlerResult (*OCEntityHandler)
-(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest);
+(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, void* callbackParam);
 
 /**
  * Device Entity handler need to use this call back instead of OCEntityHandler.
  */
 typedef OCEntityHandlerResult (*OCDeviceEntityHandler)
-(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, char* uri);
+(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, char* uri, void* callbackParam);
 
 #ifdef __cplusplus
 }
index 6f03453..bc37c05 100644 (file)
@@ -33,13 +33,16 @@ arduino_simplecs_env.PrependUnique(CPPPATH = [
 arduino_simplecs_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 arduino_simplecs_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
-arduino_simplecs_env.PrependUnique(LIBS = ['octbstack', 'connectivity_abstraction','coap'])
+arduino_simplecs_env.PrependUnique(LIBS = ['octbstack', 'ocsrm', 'connectivity_abstraction','coap'])
 
 arduino_simplecs = arduino_simplecs_env.Program('SimpleClientServer', 'ocserver.cpp')
 env.CreateBin('SimpleClientServer')
 
 i_arduino_simplecs = arduino_simplecs_env.Install(env.get('BUILD_DIR'), arduino_simplecs)
 
+#The map file is intermediate file, make sure it's removed when clean build
+arduino_simplecs_env.Clean(arduino_simplecs, 'SimpleClientServer.map')
+
 Alias('arduino_simplecs', i_arduino_simplecs)
 env.AppendTarget('arduino_simplecs')
 
index fb1c61f..52e42f2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "logger.h"
 #include "ocstack.h"
+#include "ocpayload.h"
 #include <string.h>
 
 #ifdef ARDUINOWIFI
@@ -57,9 +58,6 @@ typedef struct LIGHTRESOURCE{
 
 static LightResource Light;
 
-static char responsePayloadGet[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":true,\"power\":10}}";
-static char responsePayloadPut[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":false,\"power\":0}}";
-
 #ifdef ARDUINOWIFI
 // Arduino WiFi Shield
 // Note : Arduino WiFi Shield currently does NOT support multicast and therefore
@@ -149,11 +147,17 @@ void PrintArduinoMemoryStats()
 
 // This is the entity handler for the registered resource.
 // This is invoked by OCStack whenever it recevies a request for this resource.
-OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest )
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest,
+                                        void *callbackParam)
 {
     OCEntityHandlerResult ehRet = OC_EH_OK;
     OCEntityHandlerResponse response = {0};
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return OC_EH_ERROR;
+    }
 
     if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
     {
@@ -161,28 +165,16 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
 
         if(OC_REST_GET == entityHandlerRequest->method)
         {
-            size_t responsePayloadGetLength = strlen(responsePayloadGet);
-            if (responsePayloadGetLength < (sizeof(payload) - 1))
-            {
-                strncpy(payload, responsePayloadGet, responsePayloadGetLength);
-            }
-            else
-            {
-                ehRet = OC_EH_ERROR;
-            }
+            OCRepPayloadSetUri(payload, "/a/light");
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "power", 10);
         }
         else if(OC_REST_PUT == entityHandlerRequest->method)
         {
             //Do something with the 'put' payload
-            size_t responsePayloadPutLength = strlen(responsePayloadPut);
-            if (responsePayloadPutLength < (sizeof(payload) - 1))
-            {
-                strncpy((char *)payload, responsePayloadPut, responsePayloadPutLength);
-            }
-            else
-            {
-                ehRet = OC_EH_ERROR;
-            }
+            OCRepPayloadSetUri(payload, "/a/light");
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "power", 0);
         }
 
         if (ehRet == OC_EH_OK)
@@ -191,8 +183,7 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehRet;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = (OCPayload*) payload;
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions, 0,
                     sizeof response.sendVendorSpecificHeaderOptions);
@@ -218,9 +209,10 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
         {
             OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+            gLightUnderObservation = 0;
         }
     }
-
+    OCRepPayloadDestroy(payload);
     return ehRet;
 }
 
@@ -301,6 +293,7 @@ void createLightResource()
             OC_RSRVD_INTERFACE_DEFAULT,
             "/a/light",
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
 }
index b3250b7..ba5da01 100644 (file)
 Import('env')
 target_os = env.get('TARGET_OS')
 samples_env = env.Clone()
+with_ra = env.get ('WITH_RA')
 ######################################################################
 # Build flags
 ######################################################################
 samples_env.PrependUnique(CPPPATH = [
                '../../../../logger/include',
                '../../../../stack/include',
-               '../../../../ocmalloc/include',
                '../../../../../../extlibs/cjson',
                '../../../../../oc_logger/include',
                '../../../../../connectivity/lib/libcoap-4.1.1'
@@ -39,9 +39,9 @@ samples_env.AppendUnique(LIBS = ['-lpthread' ])
 samples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 
 if target_os in ['darwin', 'ios']:
-       samples_env.PrependUnique(LIBS = ['m','octbstack', 'connectivity_abstraction','coap' ])
+       samples_env.PrependUnique(LIBS = ['m','octbstack', 'ocsrm', 'connectivity_abstraction','coap' ])
 elif target_os not in ['arduino']:
-       samples_env.PrependUnique(LIBS = ['m', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap'])
+       samples_env.PrependUnique(LIBS = ['m', 'octbstack', 'ocsrm', 'oc_logger', 'connectivity_abstraction', 'coap'])
        samples_env.AppendUnique(LIBS = ['rt'])
 
 if env.get('SECURED') == '1':
@@ -60,12 +60,18 @@ ocservercoll     = samples_env.Program('ocservercoll', ['ocservercoll.cpp', 'com
 occlientcoll     = samples_env.Program('occlientcoll', ['occlientcoll.cpp', 'common.cpp'])
 ocserverbasicops = samples_env.Program('ocserverbasicops', ['ocserverbasicops.cpp', 'common.cpp'])
 occlientbasicops = samples_env.Program('occlientbasicops', ['occlientbasicops.cpp', 'common.cpp'])
+if with_ra:
+       ocremoteaccessclient = samples_env.Program('ocremoteaccessclient',
+                                               ['ocremoteaccessclient.cpp','common.cpp'])
 
-Alias("samples", [ocserver, occlient,
+list_of_samples = [ocserver, occlient,
                                ocservercoll, occlientcoll,
                                ocserverbasicops, occlientbasicops,
                                ocserverslow, occlientslow
-                ])
+                ]
+if with_ra:
+       list_of_samples.append (ocremoteaccessclient)
+Alias("samples", list_of_samples)
 
 env.AppendTarget('samples')
 
index 0ea86ae..3ebf005 100644 (file)
@@ -60,6 +60,8 @@ const char *getResult(OCStackResult result)
             return "OC_STACK_SLOW_RESOURCE";
         case OC_STACK_NO_OBSERVERS:
             return "OC_STACK_NO_OBSERVERS";
+        case OC_STACK_UNAUTHORIZED_REQ:
+            return "OC_STACK_UNAUTHORIZED_REQ";
 #ifdef WITH_PRESENCE
         case OC_STACK_PRESENCE_STOPPED:
             return "OC_STACK_PRESENCE_STOPPED";
index fae9406..8aa54a2 100644 (file)
 #include "ocstack.h"
 #include "logger.h"
 #include "occlient.h"
+#include "ocpayload.h"
 
+// Tracking user input
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
-static const char * UNICAST_DISCOVERY_QUERY = "coap://%s:6298/oc/core";
-static const char * UNICAST_DEVICE_DISCOVERY_QUERY = "coap://%s:6298/oc/core/d";
-static const char * UNICAST_PLATFORM_DISCOVERY_QUERY = "coap://%s:6298/oic/p";
-static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oc/core/d";
+static int CONNECTIVITY = 0;
+
+static const char * UNICAST_DEVICE_DISCOVERY_QUERY = "coap://%s/oic/d";
+static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
+static const char * UNICAST_PLATFORM_DISCOVERY_QUERY = "coap://%s/oic/p";
 static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
-static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oc/core";
+
+static const char * UNICAST_RESOURCE_DISCOVERY_QUERY = "coap://%s/oic/res";
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
 //The following variable determines the interface protocol (IPv4, IPv6, etc)
 //to be used for sending unicast messages. Default set to IPv4.
-static OCConnectivityType OC_CONNTYPE = OC_IPV4;
-static std::string putPayload = "{\"oc\":[{\"rep\":{\"power\":15,\"state\":true}}]}";
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
 static std::string coapServerIP = "255.255.255.255";
 static std::string coapServerPort = "5683";
 static std::string coapServerResource = "/a/light";
-static const int IPV4_ADDR_SIZE = 16;
-//Use ipv4addr for both InitDiscovery and InitDeviceDiscovery
+// Size to hold IPV4_ADDRESS:PORT
+static const int IPV4_ADDR_SIZE = 24;
+//Use ipv4addr for both InitDiscovery and InitPlatformOrDeviceDiscovery
 char ipv4addr[IPV4_ADDR_SIZE];
 void StripNewLineChar(char* str);
 
@@ -72,11 +77,28 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1..17> -c <0|1>");
     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
-    OC_LOG(INFO, TAG, "-c <0|1> : IPv4/IPv6 (IPv6 not currently supported)");
+    OC_LOG(INFO, TAG, "-c 0 : Use Default connectivity(IP)");
+    OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
     OC_LOG(INFO, TAG, "-t 1  :  Discover Resources");
     OC_LOG(INFO, TAG, "-t 2  :  Discover Resources and Initiate Nonconfirmable Get Request");
     OC_LOG(INFO, TAG, "-t 3  :  Discover Resources and Initiate Nonconfirmable Get Request"
@@ -88,7 +110,7 @@ static void PrintUsage()
     OC_LOG(INFO, TAG, "-t 8  :  Discover Resources and Initiate Nonconfirmable Get Request "\
             "for a resource which is unavailable");
     OC_LOG(INFO, TAG, "-t 9  :  Discover Resources and Initiate Confirmable Get Request");
-    OC_LOG(INFO, TAG, "-t 10  :  Discover Resources and Initiate Confirmable Post Request");
+    OC_LOG(INFO, TAG, "-t 10 :  Discover Resources and Initiate Confirmable Post Request");
     OC_LOG(INFO, TAG, "-t 11 :  Discover Resources and Initiate Confirmable Delete Requests");
     OC_LOG(INFO, TAG, "-t 12 :  Discover Resources and Initiate Confirmable Observe Requests"\
             " and cancel with Low QoS");
@@ -107,6 +129,7 @@ static void PrintUsage()
     OC_LOG(INFO, TAG, "-t 18 :  Discover Resources and Initiate Nonconfirmable Get Request and "\
             "add  vendor specific header options");
     OC_LOG(INFO, TAG, "-t 19 :  Discover Platform");
+    OC_LOG(INFO, TAG, "-t 20 :  Discover Devices");
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -125,7 +148,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(&handle, method, query.str().c_str(), 0,
-                       (method == OC_REST_PUT) ? putPayload.c_str() : NULL,
+                       (method == OC_REST_PUT) ? putPayload() : NULL,
                        (OC_CONNTYPE), qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -156,8 +179,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Put Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     else
     {
@@ -176,8 +199,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientRespons
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Post Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     else
     {
@@ -197,8 +220,8 @@ OCStackApplicationResult deleteReqCB(void *ctx,
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Delete Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Delete Response"));
     }
     else
     {
@@ -222,10 +245,10 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 
     OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
     OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-    OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response", clientResponse->resJSONPayload);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+    OC_LOG(INFO, TAG, PCF("=============> Get Response"));
 
-    if(clientResponse->rcvdVendorSpecificHeaderOptions &&
-            clientResponse->numRcvdVendorSpecificHeaderOptions)
+    if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
     {
         OC_LOG (INFO, TAG, "Received vendor specific options");
         uint8_t i = 0;
@@ -258,8 +281,8 @@ OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse
         OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
         OC_LOG_V(INFO, TAG, "Callback Context for OBSERVE notification recvd successfully %d",
                 gNumObserveNotifies);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Obs Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Obs Response"));
         gNumObserveNotifies++;
         if (gNumObserveNotifies == 15) //large number to test observing in DELETE case.
         {
@@ -314,8 +337,8 @@ OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientRespon
         OC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
         OC_LOG_V(INFO, TAG, "Callback Context for Presence notification recvd successfully %d",
                 gNumPresenceNotifies);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Presence Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Presence Response"));
         gNumPresenceNotifies++;
         if (gNumPresenceNotifies == 20)
         {
@@ -338,9 +361,6 @@ OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientRespon
 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "Callback Context for DISCOVER query recvd successfully");
@@ -350,17 +370,15 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
 
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
         std::string connectionType = getConnectivityType (clientResponse->connType);
         OC_LOG_V(INFO, TAG, "Discovered on %s", connectionType.c_str());
         OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
-                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
+        OC_CONNTYPE = clientResponse->connType;
         parseClientResponse(clientResponse);
 
         switch(TEST_CASE)
@@ -410,6 +428,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             case TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS:
                 InitGetRequest(OC_LOW_QOS, 1, 0);
                 break;
+            case TEST_DISCOVER_PLATFORM_REQ:
+                InitPlatformDiscovery(OC_LOW_QOS);
+                break;
             case TEST_DISCOVER_DEV_REQ:
                 InitDeviceDiscovery(OC_LOW_QOS);
                 break;
@@ -435,9 +456,29 @@ OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        //OC_LOG truncates the response as it is too long.
-        fprintf(stderr, "Discovery response: \n %s\n", clientResponse->resJSONPayload);
-        fflush(stderr);
+        OC_LOG(INFO, TAG, PCF("Discovery Response:"));
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
+    }
+
+    return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse)
+{
+    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
+    }
+
+    if(clientResponse)
+    {
+        OC_LOG(INFO, TAG, PCF("Discovery Response:"));
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
     }
     else
     {
@@ -454,7 +495,7 @@ int InitPresence()
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
     std::ostringstream query;
     std::ostringstream querySuffix;
-    query << "coap://" << coapServerIP << ":" << coapServerPort << OC_PRESENCE_URI;
+    query << "coap://" << coapServerIP << ":" << coapServerPort << OC_RSRVD_PRESENCE_URI;
     if(TEST_CASE == TEST_OBS_PRESENCE)
     {
         result = InvokeOCDoResource(query, OC_REST_PRESENCE, OC_LOW_QOS,
@@ -483,7 +524,7 @@ int InitPresence()
         {
             std::ostringstream multicastPresenceQuery;
             multicastPresenceQuery.str("");
-            multicastPresenceQuery << "coap://" << OC_MULTICAST_PREFIX << OC_PRESENCE_URI;
+            multicastPresenceQuery << "coap://" << OC_MULTICAST_PREFIX << OC_RSRVD_PRESENCE_URI;
             result = InvokeOCDoResource(multicastPresenceQuery, OC_REST_PRESENCE, OC_LOW_QOS,
                     presenceCB, NULL, 0);
         }
@@ -622,8 +663,8 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
     // ocserver is written to only process "power<X" query.
     if (getWithQuery)
     {
-        OC_LOG(INFO, TAG, "Using query power<30");
-        query << "?power<30";
+        OC_LOG(INFO, TAG, "Using query power<50");
+        query << "?power<50";
     }
 
     if (withVendorSpecificHeaderOptions)
@@ -652,8 +693,10 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
     }
 }
 
-int InitDeviceDiscovery(OCQualityOfService qos)
+int InitPlatformDiscovery(OCQualityOfService qos)
 {
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
     OCStackResult ret;
     OCCallbackData cbData;
     char szQueryUri[64] = { 0 };
@@ -668,10 +711,9 @@ int InitDeviceDiscovery(OCQualityOfService qos)
     }
     else
     {
-        strncpy(szQueryUri, MULTICAST_PLATFORM_DISCOVERY_QUERY,
-                sizeof(szQueryUri) -1 );
-        szQueryUri[sizeof(szQueryUri) -1] = '\0';
+        strncpy(szQueryUri, MULTICAST_PLATFORM_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
     }
+    szQueryUri[sizeof(szQueryUri) -1] = '\0';
 
     if(UNICAST_DISCOVERY)
     {
@@ -680,9 +722,51 @@ int InitDeviceDiscovery(OCQualityOfService qos)
     }
     else
     {
-        ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, (OC_ALL),
+
+        ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+                        (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+    }
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack device error");
+    }
+
+    return ret;
+}
+
+int InitDeviceDiscovery(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+    OCStackResult ret;
+    OCCallbackData cbData;
+    char szQueryUri[64] = { 0 };
+
+    cbData.cb = DeviceDiscoveryReqCB;
+    cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    if(UNICAST_DISCOVERY)
+    {
+        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_DEVICE_DISCOVERY_QUERY, ipv4addr);
+    }
+    else
+    {
+        strncpy(szQueryUri, MULTICAST_DEVICE_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
+    }
+    szQueryUri[sizeof(szQueryUri) -1] = '\0';
+
+    if(UNICAST_DISCOVERY)
+    {
+        ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
                 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
     }
+    else
+    {
+        ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+                        (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+    }
 
     if (ret != OC_STACK_OK)
     {
@@ -701,7 +785,7 @@ int InitDiscovery(OCQualityOfService qos)
 
     if (UNICAST_DISCOVERY)
     {
-        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_DISCOVERY_QUERY, ipv4addr);
+        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_RESOURCE_DISCOVERY_QUERY, ipv4addr);
     }
     else
     {
@@ -718,8 +802,8 @@ int InitDiscovery(OCQualityOfService qos)
     }
     else
     {
-        ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, (OC_ALL),
-                (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+        ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+                        (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
     }
     if (ret != OC_STACK_OK)
     {
@@ -743,10 +827,7 @@ int main(int argc, char* argv[])
                 TEST_CASE = atoi(optarg);
                 break;
             case 'c':
-                // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                // OC_CONNTYPE = OCConnectivityType(atoi(optarg));
-                OC_CONNTYPE = OC_IPV4;
-                OC_LOG(INFO, TAG, "IPv6 not currently supported, using IPv4.");
+                CONNECTIVITY = atoi(optarg);
                 break;
             default:
                 PrintUsage();
@@ -755,7 +836,8 @@ int main(int argc, char* argv[])
     }
 
     if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
-            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) )
+            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
+            (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
     {
         PrintUsage();
         return -1;
@@ -767,9 +849,22 @@ int main(int argc, char* argv[])
         OC_LOG(ERROR, TAG, "OCStack init error");
         return 0;
     }
+
+    if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IP)
+    {
+        OC_CONNTYPE = CT_ADAPTER_IP;
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Default Connectivity type selected...");
+        PrintUsage();
+    }
+
     if (UNICAST_DISCOVERY)
     {
-        printf("Enter IPv4 address of the Server hosting resource (Ex: 192.168.0.15)\n");
+        OC_LOG(INFO, TAG, "Enter IP address with port number of the Server hosting resource");
+        OC_LOG(INFO, TAG, "as follows - eg: 192.168.0.15:45454 (IP:Port) \n");
+
         if (fgets(ipv4addr, IPV4_ADDR_SIZE, stdin))
         {
             //Strip newline char from ipv4addr
@@ -780,12 +875,16 @@ int main(int argc, char* argv[])
             OC_LOG(ERROR, TAG, "!! Bad input for IPV4 address. !!");
             return OC_STACK_INVALID_PARAM;
         }
-     }
+    }
 
     if(UNICAST_DISCOVERY  == 0  && TEST_CASE == TEST_DISCOVER_DEV_REQ)
     {
         InitDeviceDiscovery(OC_LOW_QOS);
     }
+    else if(UNICAST_DISCOVERY  == 0  && TEST_CASE == TEST_DISCOVER_PLATFORM_REQ)
+    {
+        InitPlatformDiscovery(OC_LOW_QOS);
+    }
     else
     {
         InitDiscovery(OC_LOW_QOS);
@@ -825,16 +924,8 @@ std::string getIPAddrTBServer(OCClientResponse * clientResponse)
     {
         return "";
     }
-    uint8_t a, b, c, d = 0;
-    if (0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d))
-    {
-        return "";
-    }
 
-    char ipaddr[16] = {'\0'};
-    // ostringstream not working correctly here, hence snprintf
-    snprintf(ipaddr,  sizeof(ipaddr), "%d.%d.%d.%d", a,b,c,d);
-    return std::string (ipaddr);
+    return std::string(clientResponse->devAddr.addr);
 }
 
 std::string getPortTBServer(OCClientResponse * clientResponse)
@@ -847,31 +938,29 @@ std::string getPortTBServer(OCClientResponse * clientResponse)
     {
         return "";
     }
-    uint16_t p = 0;
-    if (0 != OCDevAddrToPort(clientResponse->addr, &p))
-    {
-        return "";
-    }
     std::ostringstream ss;
-    ss << p;
+    ss << clientResponse->devAddr.port;
     return ss.str();
 }
 
 std::string getConnectivityType (OCConnectivityType connType)
 {
-    switch (connType)
+    switch (connType & CT_MASK_ADAPTER)
     {
-        case OC_IPV4:
+        case CT_ADAPTER_IP:
+            return "IP";
+
+        case CT_IP_USE_V4:
             return "IPv4";
 
-        case OC_IPV6:
+        case CT_IP_USE_V6:
             return "IPv6";
 
-        case OC_LE:
-            return "BLE";
+        case CT_ADAPTER_GATT_BTLE:
+            return "GATT";
 
-        case OC_EDR:
-            return "BT";
+        case CT_ADAPTER_RFCOMM_BTEDR:
+            return "RFCOMM";
 
         default:
             return "Incorrect connectivity";
index 1570a94..2ed2e3d 100644 (file)
@@ -38,7 +38,7 @@
 //-----------------------------------------------------------------------------
 
 /**
- * List of methods that can be inititated from the client
+ * List of methods that can be initiated from the client
  */
 typedef enum {
     TEST_DISCOVER_REQ = 1,
@@ -61,10 +61,21 @@ typedef enum {
 #endif
     TEST_OBS_REQ_NON_CANCEL_IMM,
     TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
+    TEST_DISCOVER_PLATFORM_REQ,
     TEST_DISCOVER_DEV_REQ,
     MAX_TESTS
 } CLIENT_TEST;
 
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+    CT_ADAPTER_DEFAULT = 0,
+    CT_IP,
+    MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
 #ifdef WITH_PRESENCE
 int InitPresence();
 #endif
@@ -97,6 +108,7 @@ int InitPostRequest(OCQualityOfService qos);
 int InitDeleteRequest(OCQualityOfService qos);
 int InitGetRequest(OCQualityOfService qos);
 int InitDeviceDiscovery(OCQualityOfService qos);
+int InitPlatformDiscovery(OCQualityOfService qos);
 int InitDiscovery(OCQualityOfService qos);
 
 /* Function to retrieve ip address, port no. of the server
index 30f79d9..70c69a1 100644 (file)
 #include <unistd.h>
 #include <stdint.h>
 #include <sstream>
+#include <iostream>
 
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientbasicops.h"
-#include "cJSON.h"
-#include "ocmalloc.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
 
 #define MAX_IP_ADDR_ST_SZ  16 //string size of "155.255.255.255" (15 + 1)
 #define MAX_PORT_ST_SZ  6     //string size of "65535" (5 + 1)
 
-static int IPV4_ADDR_SIZE = 16;
+static int IPV4_ADDR_SIZE = 24;
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
+static int CONNECTIVITY = 0;
 
-static const char UNICAST_DISCOVERY_QUERY[] = "coap://%s:6298/oc/core";
-static std::string putPayload = "{\"state\":\"off\",\"power\":10}";
+static const char UNICAST_DISCOVERY_QUERY[] = "coap://%s/oic/res";
 
-//The following variable determines the interface protocol (IPv4, IPv6, etc)
-//to be used for sending unicast messages. Default set to IPv4.
-static OCConnectivityType OC_CONNTYPE = OC_IPV4;
-static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oc/core";
+//The following variable determines the interface protocol (IP, etc)
+//to be used for sending unicast messages. Default set to IP.
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
 
 int gQuitFlag = 0;
 
@@ -60,6 +62,22 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3> -c <0|1>");
@@ -69,8 +87,8 @@ static void PrintUsage()
             " Initiate Nonconfirmable Get/Put/Post Requests");
     OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate "
             "Confirmable Get/Put/Post Requests");
-    OC_LOG(INFO, TAG, "-c <0|1> : IPv4/IPv6 (IPv6 not currently supported)");
-    OC_LOG(INFO, TAG, "Default connectivityType IPv4");
+    OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
+    OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
 }
 
 /*
@@ -93,7 +111,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query, OCMethod method,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-        (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload.c_str() : NULL,
+        (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
          connType, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -108,9 +126,6 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query, OCMethod method,
 OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle,
                                 OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "<====Callback Context for PUT received successfully====>");
@@ -122,13 +137,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                            remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
-        OC_LOG_V(INFO, TAG,"PUT Response: %s \nFrom %d.%d.%d.%d:%d\n",
-                 clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     else
     {
@@ -140,9 +150,6 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle,
 OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle,
                           OCClientResponse *clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "<====Callback Context for POST received successfully====>");
@@ -154,13 +161,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                            remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
-        OC_LOG_V(INFO, TAG,"POST Response: %s \nFrom %d.%d.%d.%d:%d\n",
-                    clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                    remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     else
     {
@@ -173,9 +175,6 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle,
 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
                            OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>");
@@ -187,16 +186,12 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
 
     if (clientResponse)
     {
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr, remoteIpAddr + 1,
-                remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
-        OC_LOG_V(INFO, TAG,"Get Response: %s \nFrom %d.%d.%d.%d:%d\n",
-                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+        OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
+        OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Get Response"));
 
-        if (clientResponse->rcvdVendorSpecificHeaderOptions
-                && clientResponse->numRcvdVendorSpecificHeaderOptions)
+        if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0 )
         {
             OC_LOG (INFO, TAG, "Received vendor specific options");
             uint8_t i = 0;
@@ -227,8 +222,6 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
     if (ctx == (void*)DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "\n<====Callback Context for DISCOVERY query "
@@ -241,14 +234,11 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
 
     if (clientResponse)
     {
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
         OC_LOG_V(INFO, TAG,
-                "Device Discovered %s \n @ %d.%d.%d.%d:%d\n",
-                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
         collectUniqueResource(clientResponse);
     }
@@ -347,8 +337,9 @@ int InitDiscovery()
     if (UNICAST_DISCOVERY)
     {
         char ipv4addr[IPV4_ADDR_SIZE];
-        printf("Enter IPv4 address of the Server hosting "
-               "resource (Ex: 192.168.0.15)\n");
+        OC_LOG(INFO, TAG, "Enter IP address with port of the Server hosting resource"\
+                    "(Ex: 192.168.0.15:1234) ");
+
         if (fgets(ipv4addr, IPV4_ADDR_SIZE, stdin))
         {
             //Strip newline char from ipv4addr
@@ -375,7 +366,7 @@ int InitDiscovery()
     }
     else
     {
-        ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, (OC_ALL),
+        ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, CT_DEFAULT,
                 OC_LOW_QOS, &cbData, NULL, 0);
     }
 
@@ -386,20 +377,18 @@ int InitDiscovery()
     return ret;
 }
 
-
-
-const char * getIPAddr(const OCClientResponse * clientResponse)
+const char *getIPAddr(const OCClientResponse *clientResponse)
 {
-    uint8_t a, b, c, d;
-   if(!clientResponse || 0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d))
+    if (!clientResponse)
     {
         return "";
     }
 
-    char * ipaddr = NULL;
-    if((ipaddr = (char *) OCCalloc(1, MAX_IP_ADDR_ST_SZ)))
+    const OCDevAddr *devAddr = &clientResponse->devAddr;
+    char *ipaddr = (char *) OICCalloc(1, strlen(devAddr->addr) +1);
+    if (ipaddr)
     {
-        snprintf(ipaddr, MAX_IP_ADDR_ST_SZ, "%d.%d.%d.%d", a,b,c,d);
+        snprintf(ipaddr, MAX_IP_ADDR_ST_SZ, "%s", devAddr->addr);
     }
     else
     {
@@ -408,18 +397,17 @@ const char * getIPAddr(const OCClientResponse * clientResponse)
     return ipaddr;
 }
 
-const char * getPort(const OCClientResponse * clientResponse)
+const char *getPort(const OCClientResponse *clientResponse)
 {
-    uint16_t p = 0;
-    if(!clientResponse || 0 != OCDevAddrToPort(clientResponse->addr, &p) )
+    if(!clientResponse)
     {
         return "";
     }
 
-    char * port = NULL;
-    if((port = (char *) OCCalloc(1, MAX_PORT_ST_SZ)))
+    char *port = NULL;
+    if((port = (char *)OICCalloc(1, MAX_PORT_ST_SZ)))
     {
-        snprintf(port, MAX_PORT_ST_SZ, "%d", p);
+        snprintf(port, MAX_PORT_ST_SZ, "%d", clientResponse->devAddr.port);
     }
     else
     {
@@ -428,102 +416,8 @@ const char * getPort(const OCClientResponse * clientResponse)
     return port;
 }
 
-int parseJSON(const char * resJSONPayload, char ** sid_c,
-              char *** uri_c, int * totalRes)
-{
-    cJSON * root = NULL;
-    cJSON * oc = NULL;
-
-    root = cJSON_Parse((char *)(resJSONPayload));
-
-    if (!root)
-    {
-        OC_LOG(ERROR, TAG, "JSON Parsing Error");
-        return OC_STACK_INVALID_JSON;
-    }
-
-    oc = cJSON_GetObjectItem(root,"oc");
-    if (!oc)
-    {
-        OC_LOG(ERROR, TAG, "Invalid JSON : Missing oc object");
-        return OC_STACK_INVALID_JSON;
-    }
-
-    * totalRes = cJSON_GetArraySize(oc);
-
-    if(oc->type == cJSON_Array)
-    {
-        cJSON * resource = cJSON_GetArrayItem(oc, 0);
-
-        if(!resource)
-        {
-            return OC_STACK_INVALID_JSON;
-        }
-
-        if (cJSON_GetObjectItem(resource, "sid"))
-        {
-            char * sid = cJSON_GetObjectItem(resource, "sid")->valuestring;
-            if((* sid_c = (char *)OCCalloc(1, strlen (sid) + 1)))
-            {
-                memcpy(* sid_c, sid, strlen(sid) + 1);
-            }
-            else
-            {
-                OC_LOG(ERROR, TAG, "Memory not allocated to sid");
-                return OC_STACK_NO_MEMORY;
-            }
-        }
-        else
-        {
-            OC_LOG(ERROR, TAG, "Invalid JSON : Missing sid object");
-            return OC_STACK_INVALID_JSON;
-        }
-
-        if(!(* uri_c =  (char ** )OCMalloc ((* totalRes) * sizeof(char **))))
-        {
-            OC_LOG(ERROR, TAG, "Memory not allocated to sid_c array");
-            return OC_STACK_NO_MEMORY;
-        }
-
-        int i = 0;
-
-        while(true)
-        {
-            if (cJSON_GetObjectItem(resource, "href"))
-            {
-                char *uri= cJSON_GetObjectItem(resource, "href")->valuestring;
-                if(((*uri_c)[i] = (char *)OCCalloc(1, strlen (uri) + 1)))
-                {
-                    memcpy((*uri_c)[i], uri, strlen(uri) + 1);
-                }
-                else
-                {
-                    OC_LOG(ERROR, TAG, "Memory not allocated to uri");
-                    return OC_STACK_NO_MEMORY;
-                }
-                i++;
-                if(i >= (* totalRes))
-                    break;
-                resource = cJSON_GetArrayItem(oc, i);
-            }
-            else
-            {
-               OC_LOG(ERROR, TAG, "Invalid JSON : Missing uri object");
-               return OC_STACK_INVALID_JSON;
-           }
-        }
-    }
-    else
-    {
-        return OC_STACK_INVALID_JSON;
-        OC_LOG(ERROR, TAG, "Invalid JSON : oc object type is not an array");
-    }
-    return OC_STACK_OK;
-}
-
 void queryResource()
 {
-    printf("\n");
     switch(TEST_CASE)
     {
         case TEST_DISCOVER_REQ:
@@ -542,43 +436,44 @@ void queryResource()
             PrintUsage();
             break;
     }
-    printf("\n");
 }
 
 
 void collectUniqueResource(const OCClientResponse * clientResponse)
 {
-    char * sid = NULL;
-    char ** uri = NULL;
-    int totalRes = 0;
+    OCResourcePayload* res = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+    char sidStr[UUID_LENGTH];
 
-    if(parseJSON(clientResponse->resJSONPayload, & sid, & uri, &totalRes)
-            != OC_STACK_OK)
-    {
-        OC_LOG(ERROR, TAG, "Error while parsing JSON payload in OCClientResponse");
-        OCFree(sid);
-        OCFree(uri);
-        return;
-    }
+    while(res) {
 
-    int i;
-    for(i = 0; i < totalRes; i++)
-    {
-        if(insertResource(sid, uri[i], clientResponse) == 1)
+        int ret = snprintf(sidStr, UUID_LENGTH,
+                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                res->sid[0], res->sid[1], res->sid[2], res->sid[3],
+                res->sid[4], res->sid[5], res->sid[6], res->sid[7],
+                res->sid[8], res->sid[9], res->sid[10], res->sid[11],
+                res->sid[12], res->sid[13], res->sid[14], res->sid[15]
+                );
+
+        if (ret == UUID_LENGTH - 1)
         {
-            printf("%s%s%s%s\n",sid, ":", uri[i], " is new");
-            printResourceList();
-            queryResource();
+            if(insertResource(sidStr, res->uri, clientResponse) == 1)
+            {
+                OC_LOG_V(INFO,TAG,"%s%s%s%s\n",sidStr, ":", res->uri, " is new");
+                printResourceList();
+                queryResource();
+            }
+            else {
+                OC_LOG_V(INFO,TAG,"%s%s%s%s\n",sidStr, ":", res->uri, " is old");
+            }
         }
         else
         {
-            printf("%s%s%s%s\n\n",sid, ":", uri[i], " has been seen before");
+            OC_LOG(ERROR, TAG, "Could Not Retrieve the Server ID");
         }
-    }
 
-    OCFree(sid);
-    OCFree(uri);
- }
+        res = res->next;
+    }
+}
 
 /* This function searches for the resource(sid:uri) in the ResourceList.
  * If the Resource is found in the list then it returns 0 else insert
@@ -588,12 +483,16 @@ int insertResource(const char * sid, char const * uri,
             const OCClientResponse * clientResponse)
 {
     ResourceNode * iter = resourceList;
+    char * sid_cpy =  OICStrdup(sid);
+    char * uri_cpy = OICStrdup(uri);
 
     //Checking if the resource(sid:uri) is new
     while(iter)
     {
         if((strcmp(iter->sid, sid) == 0) && (strcmp(iter->uri, uri) == 0))
         {
+            OICFree(sid_cpy);
+            OICFree(uri_cpy);
             return 0;
         }
         else
@@ -603,10 +502,10 @@ int insertResource(const char * sid, char const * uri,
     }
 
     //Creating new ResourceNode
-    if((iter = (ResourceNode *) OCMalloc(sizeof(ResourceNode))))
+    if((iter = (ResourceNode *) OICMalloc(sizeof(ResourceNode))))
     {
-        iter->sid = sid;
-        iter->uri = uri;
+        iter->sid = sid_cpy;
+        iter->uri = uri_cpy;
         iter->ip = getIPAddr(clientResponse);
         iter->port = getPort(clientResponse);
         iter->connType = clientResponse->connType;
@@ -615,6 +514,8 @@ int insertResource(const char * sid, char const * uri,
     else
     {
         OC_LOG(ERROR, TAG, "Memory not allocated to ResourceNode");
+        OICFree(sid_cpy);
+        OICFree(uri_cpy);
         return -1;
     }
 
@@ -635,37 +536,30 @@ void printResourceList()
 {
     ResourceNode * iter;
     iter = resourceList;
-    printf("\nResource List\n");
+    OC_LOG(INFO, TAG, "Resource List: ");
     while(iter)
     {
-        printf("*****************************************************\n");
-        printf("sid = %s \n",iter->sid);
-        printf("uri = %s\n", iter->uri);
-        printf("ip = %s\n", iter->ip);
-        printf("port = %s\n", iter->port);
-        switch (iter->connType)
+        OC_LOG(INFO, TAG, "*****************************************************");
+        OC_LOG_V(INFO, TAG, "sid = %s",iter->sid);
+        OC_LOG_V(INFO, TAG, "uri = %s", iter->uri);
+        OC_LOG_V(INFO, TAG, "ip = %s", iter->ip);
+        OC_LOG_V(INFO, TAG, "port = %s", iter->port);
+        switch (iter->connType & CT_MASK_ADAPTER)
         {
-            case OC_IPV4:
-                printf("connType = %s\n","IPv4");
-                break;
-            case OC_IPV6:
-                // TODO: Allow IPv6 when support is added
-                printf("IPv6 not currently supported, default to IPv4\n");
-                //printf("connType = %s\n","IPv6");
-                printf("connType = %s\n","IPv4");
+            case CT_ADAPTER_IP:
+                OC_LOG(INFO, TAG, "connType = Default (IPv4)");
                 break;
-            case OC_LE:
-                printf("connType = %s\n","BLE");
+            case OC_ADAPTER_GATT_BTLE:
+                OC_LOG(INFO, TAG, "connType = BLE");
                 break;
-            case OC_EDR:
-                printf("connType = %s\n","BT");
+            case OC_ADAPTER_RFCOMM_BTEDR:
+                OC_LOG(INFO, TAG, "connType = BT");
                 break;
-            case OC_ALL:
             default:
-                printf("connType = %s\n","Invalid connType");
+                OC_LOG(INFO, TAG, "connType = Invalid connType");
                 break;
         }
-        printf("*****************************************************\n");
+        OC_LOG(INFO, TAG, "*****************************************************");
         iter = iter->next;
     }
 }
@@ -676,14 +570,16 @@ void freeResourceList()
     ResourceNode * temp;
     while(resourceList)
     {
+
         temp = resourceList;
         resourceList = resourceList->next;
-        OCFree((void *)temp->sid);
-        OCFree((void *)temp->uri);
-        OCFree((void *)temp->ip);
-        OCFree((void *)temp->port);
-        OCFree(temp);
+        OICFree((void *)temp->sid);
+        OICFree((void *)temp->uri);
+        OICFree((void *)temp->ip);
+        OICFree((void *)temp->port);
+        OICFree(temp);
     }
+    resourceList = NULL;
 }
 
 int main(int argc, char* argv[])
@@ -701,10 +597,8 @@ int main(int argc, char* argv[])
                 TEST_CASE = atoi(optarg);
                 break;
             case 'c':
-                // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                // OC_CONNTYPE = OCConnectivityType(atoi(optarg));
-                OC_CONNTYPE = OC_IPV4;
-                OC_LOG(INFO, TAG, "Using default IPv4, IPv6 not currently supported.");
+
+                CONNECTIVITY = atoi(optarg);
                 break;
             default:
                 PrintUsage();
@@ -713,7 +607,8 @@ int main(int argc, char* argv[])
     }
 
     if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
-            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) )
+        (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
+        (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
     {
         PrintUsage();
         return -1;
@@ -726,6 +621,16 @@ int main(int argc, char* argv[])
         return 0;
     }
 
+    if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY ==  CT_IP)
+    {
+        OC_CONNTYPE =  CT_ADAPTER_IP;//CT_DEFAULT;
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Default Connectivity type selected");
+        PrintUsage();
+    }
+
     InitDiscovery();
 
     // Break from loop with Ctrl+C
index c9d0dc9..012a11a 100644 (file)
@@ -46,6 +46,16 @@ typedef enum {
     MAX_TESTS
 } CLIENT_TEST;
 
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+    CT_ADAPTER_DEFAULT = 0,
+    CT_IP,
+    MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
 //-----------------------------------------------------------------------------
 //ResourceNode
 //-----------------------------------------------------------------------------
index f609aea..94e9e14 100644 (file)
 #include <ocstack.h>
 #include <iostream>
 #include <sstream>
+#include "ocpayload.h"
 #include "logger.h"
 const char *getResult(OCStackResult result);
 std::string getIPAddrTBServer(OCClientResponse * clientResponse);
 std::string getPortTBServer(OCClientResponse * clientResponse);
-std::string getQueryStrForGetPut(const char * responsePayload);
+std::string getQueryStrForGetPut();
 
 #define TAG PCF("occlient")
 #define DEFAULT_CONTEXT_VALUE 0x99
@@ -53,7 +54,18 @@ typedef enum
     MAX_TESTS
 } CLIENT_TEST;
 
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+    CT_ADAPTER_DEFAULT = 0,
+    CT_IP,
+    MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
 unsigned static int TEST = TEST_INVALID;
+unsigned static int CONNECTIVITY = 0;
 
 typedef struct
 {
@@ -74,12 +86,11 @@ testToTextMap queryInterface[] = {
         {"?if=oic.if.ll", TEST_PUT_LINK_LIST},
 };
 
-static std::string putPayload = "{\"state\":\"off\",\"power\":\"0\"}";
 
-//The following variable determines the interface protocol (IPv4, IPv6, etc)
-//to be used for sending unicast messages. Default set to IPv4.
-static OCConnectivityType OC_CONNTYPE = OC_IPV4;
-static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oc/core";
+//The following variable determines the interface protocol (IP, etc)
+//to be used for sending unicast messages. Default set to IP.
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
 
 // The handle for the observe registration
 OCDoHandle gObserveDoHandle;
@@ -104,10 +115,27 @@ int InitPutRequest(OCClientResponse * clientResponse);
 int InitGetRequest(OCClientResponse * clientResponse);
 int InitDiscovery();
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlientcoll -t <Test Case> -c <CA connectivity Type>");
-    OC_LOG(INFO, TAG, "-c <0|1> : IPv4/IPv6 (IPv6 not currently supported)");
+    OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
+    OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
     OC_LOG(INFO, TAG, "Test Case 1 : Discover Resources && Initiate GET Request on an "\
             "available resource using default interface.");
     OC_LOG(INFO, TAG, "Test Case 2 : Discover Resources && Initiate GET Request on an "\
@@ -138,7 +166,7 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG_V(INFO, TAG, "Callback Context for PUT query recvd successfully");
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Discovered", clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
     }
 
     return OC_STACK_KEEP_TRANSACTION;
@@ -154,13 +182,13 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
         if(clientResponse->sequenceNumber == 0)
         {
             OC_LOG_V(INFO, TAG, "Callback Context for GET query recvd successfully");
-            OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
+            OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
         }
         else
         {
             OC_LOG_V(INFO, TAG, "Callback Context for Get recvd successfully %d",
                     gNumObserveNotifies);
-            OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
+            OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);;
             gNumObserveNotifies++;
             if (gNumObserveNotifies == 3)
             {
@@ -183,9 +211,6 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     OC_LOG(INFO, TAG,
             "Entering discoveryReqCB (Application Layer CB)");
     OC_LOG_V(INFO, TAG, "StackResult: %s",
@@ -196,14 +221,13 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OC_LOG_V(INFO, TAG, "Callback Context recvd successfully");
     }
 
-    OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-            remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
     OC_LOG_V(INFO, TAG,
-            "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
-            clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-            remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+            "Device =============> Discovered @ %s:%d",
+            clientResponse->devAddr.addr,
+            clientResponse->devAddr.port);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+    OC_CONNTYPE = clientResponse->connType;
 
     if(TEST == TEST_UNKNOWN_RESOURCE_GET_DEFAULT || TEST == TEST_UNKNOWN_RESOURCE_GET_BATCH ||\
             TEST == TEST_UNKNOWN_RESOURCE_GET_LINK_LIST)
@@ -223,8 +247,8 @@ int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse)
     OCStackResult ret;
     OCCallbackData cbData;
     std::ostringstream getQuery;
-    getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" <<
-            getPortTBServer(clientResponse) << "/SomeUnknownResource";
+    getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
+            clientResponse->devAddr.port << "/SomeUnknownResource";
     cbData.cb = getReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
@@ -245,13 +269,14 @@ int InitObserveRequest(OCClientResponse * clientResponse)
     OCCallbackData cbData;
     OCDoHandle handle;
     std::ostringstream obsReg;
-    obsReg << "coap://" << getIPAddrTBServer(clientResponse) << ":" <<
-            getPortTBServer(clientResponse) <<
-            getQueryStrForGetPut(clientResponse->resJSONPayload);
+    obsReg << "coap://" << clientResponse->devAddr.addr << ":" <<
+            clientResponse->devAddr.addr <<
+            getQueryStrForGetPut();
     cbData.cb = getReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    OC_LOG_V(INFO, TAG, "OBSERVE payload from client = %s ", putPayload.c_str());
+    OC_LOG_V(INFO, TAG, "OBSERVE payload from client =");
+    OC_LOG_PAYLOAD(INFO, TAG, putPayload());
 
     ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(), 0, 0, OC_CONNTYPE,
             OC_LOW_QOS, &cbData, NULL, 0);
@@ -273,15 +298,16 @@ int InitPutRequest(OCClientResponse * clientResponse)
     OCCallbackData cbData;
     //* Make a PUT query*/
     std::ostringstream getQuery;
-    getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" <<
-            getPortTBServer(clientResponse) <<
+    getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
+            clientResponse->devAddr.port <<
             "/a/room" << queryInterface[TEST].text;
     cbData.cb = putReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str());
+    OC_LOG_V(INFO, TAG, "PUT payload from client = ");
+    OC_LOG_PAYLOAD(INFO, TAG, putPayload());
 
-    ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(),
+    ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload(),
                         OC_CONNTYPE, OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
@@ -296,17 +322,10 @@ int InitGetRequest(OCClientResponse * clientResponse)
     OCStackResult ret;
     OCCallbackData cbData;
 
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
-    OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-            remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
     //* Make a GET query*/
     std::ostringstream getQuery;
-    getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" <<
-            getPortTBServer(clientResponse) <<
+    getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
+            clientResponse->devAddr.port <<
             "/a/room" << queryInterface[TEST].text;
 
     std::cout << "Get Query: " << getQuery.str() << std::endl;
@@ -336,7 +355,7 @@ int InitDiscovery()
     cbData.cb = discoveryReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_ALL,
+    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
                         OC_LOW_QOS,
             &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
@@ -358,16 +377,15 @@ int main(int argc, char* argv[])
                 TEST = atoi(optarg);
                 break;
             case 'c':
-                // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                // OC_CONNTYPE = OCConnectivityType(atoi(optarg));
-                OC_CONNTYPE = OC_IPV4;
+                CONNECTIVITY = atoi(optarg);
                 break;
             default:
                 PrintUsage();
                 return -1;
         }
     }
-    if (TEST <= TEST_INVALID || TEST >= MAX_TESTS)
+    if ((TEST <= TEST_INVALID || TEST >= MAX_TESTS) ||
+        (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
     {
         PrintUsage();
         return -1;
@@ -380,6 +398,16 @@ int main(int argc, char* argv[])
         return 0;
     }
 
+    if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IP)
+    {
+        OC_CONNTYPE = CT_ADAPTER_IP;
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Default Connectivity type selected...");
+        OC_CONNTYPE = CT_ADAPTER_IP;
+    }
+
     InitDiscovery();
 
     // Break from loop with Ctrl+C
@@ -405,53 +433,8 @@ int main(int argc, char* argv[])
     return 0;
 }
 
-std::string getIPAddrTBServer(OCClientResponse * clientResponse)
+std::string getQueryStrForGetPut()
 {
-    if (!clientResponse)
-    {
-        return "";
-    }
-    if (!clientResponse->addr)
-    {
-        return "";
-    }
-    uint8_t a, b, c, d = 0;
-    if (0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d))
-    {
-        return "";
-    }
-
-    char ipaddr[16] = {'\0'};
-    // ostringstream not working correctly here, hence snprintf
-    snprintf(ipaddr,  sizeof(ipaddr), "%d.%d.%d.%d", a,b,c,d);
-    return std::string (ipaddr);
-}
-
-std::string getPortTBServer(OCClientResponse * clientResponse)
-{
-    if (!clientResponse)
-    {
-        return "";
-    }
-    if (!clientResponse->addr)
-    {
-        return "";
-    }
-    uint16_t p = 0;
-    if (0 != OCDevAddrToPort(clientResponse->addr, &p))
-    {
-        return "";
-    }
-    std::ostringstream ss;
-    ss << p;
-    return ss.str();
-}
-
-std::string getQueryStrForGetPut(const char * responsePayload)
-{
-
-    std::string jsonPayload(responsePayload);
-
     return "/a/room";
 }
 
index 5fc29c6..e875cf2 100644 (file)
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientslow.h"
+#include "ocpayload.h"
 
+// Tracking user input
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
-static const char * UNICAST_DISCOVERY_QUERY = "coap://%s:6298/oc/core";
-static std::string putPayload = "{\"state\":\"off\",\"power\":10}";
+static int CONNECTIVITY = 0;
+
+static const char * UNICAST_DISCOVERY_QUERY = "coap://%s/oic/res";
 static std::string coapServerIP = "255.255.255.255";
-static std::string coapServerPort = "5683";
+static uint16_t coapServerPort = 5683;
 static std::string coapServerResource = "/a/led";
 
-//The following variable determines the interface protocol (IPv4, IPv6, etc)
-//to be used for sending unicast messages. Default set to IPv4.
-static OCConnectivityType OC_CONNTYPE = OC_IPV4;
-static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oc/core";
-static int IPV4_ADDR_SIZE = 16;
+//The following variable determines the interface protocol (IP, etc)
+//to be used for sending unicast messages. Default set to IP.
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
+static int IPV4_ADDR_SIZE = 24;
 void StripNewLineChar(char* str);
 
 int gQuitFlag = 0;
@@ -57,12 +60,31 @@ void handleSigInt(int signum)
 
 static void PrintUsage()
 {
-    OC_LOG(INFO, TAG, "Usage : occlient -c <0|1> -u <0|1> -t <1|2|3>");
-    OC_LOG(INFO, TAG, "-c <0|1> : IPv4/IPv6 (IPv6 not currently supported)");
+    OC_LOG(INFO, TAG, "Usage : occlient -c <0|1|2> -u <0|1> -t <1|2|3>");
+    OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
+    OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
     OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
     OC_LOG(INFO, TAG, "-t 2 : Discover Resources and Initiate Nonconfirmable Get Request");
     OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate Confirmable Get Request");
+    OC_LOG(INFO, TAG, "-t 4 : Discover Resources and Initiate NonConfirmable Put Request");
+    OC_LOG(INFO, TAG, "-t 5 : Discover Resources and Initiate Confirmable Put Request");
+}
+
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -77,7 +99,8 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-            NULL, OC_CONNTYPE, qos, &cbData, options, numOptions);
+            (method == OC_REST_PUT) ? putPayload() : NULL,
+            OC_CONNTYPE, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
     {
@@ -101,8 +124,8 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 
     OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
     OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-    OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response",
-            clientResponse->resJSONPayload);
+    OC_LOG(INFO, TAG, "Get Response =============> ");
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
     if(clientResponse->rcvdVendorSpecificHeaderOptions &&
             clientResponse->numRcvdVendorSpecificHeaderOptions)
@@ -129,9 +152,6 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(INFO, TAG, "Callback Context for DISCOVER query recvd successfully");
@@ -141,14 +161,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
 
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
-        OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
-                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+        OC_LOG_V(INFO, TAG, "Discovered @ %s:%u =============> ",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD (INFO, TAG, clientResponse->payload);
 
         parseClientResponse(clientResponse);
 
@@ -160,6 +175,12 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             case TEST_CON_OP:
                 InitGetRequest(OC_HIGH_QOS);
                 break;
+            case TEST_NON_CON_PUT:
+                InitPutRequest(OC_LOW_QOS);
+                break;
+            case TEST_CON_PUT:
+                InitPutRequest(OC_HIGH_QOS);
+                break;
             default:
                 PrintUsage();
                 break;
@@ -175,11 +196,21 @@ int InitGetRequest(OCQualityOfService qos)
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
     std::ostringstream query;
     query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
-
+    OC_LOG_V (INFO, TAG, "Performing GET with query : %s", query.str().c_str());
     return (InvokeOCDoResource(query, OC_REST_GET, (qos == OC_HIGH_QOS)?
             OC_HIGH_QOS:OC_LOW_QOS, getReqCB, NULL, 0));
 }
 
+int InitPutRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+    OC_LOG_V (INFO, TAG, "Performing PUT with query : %s", query.str().c_str());
+    return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)?
+            OC_HIGH_QOS:OC_LOW_QOS, getReqCB, NULL, 0));
+}
+
 int InitDiscovery()
 {
     OCStackResult ret;
@@ -189,7 +220,8 @@ int InitDiscovery()
     if (UNICAST_DISCOVERY)
     {
         char ipv4addr[IPV4_ADDR_SIZE];
-        printf("Enter IPv4 address of the Server hosting resource (Ex: 192.168.0.15)\n");
+        OC_LOG(INFO, TAG, "Enter IPv4:port of the Server hosting resource"\
+                "(Ex: 192.168.0.15:1234)");
         if (fgets(ipv4addr, IPV4_ADDR_SIZE, stdin))
         {
             //Strip newline char from ipv4addr
@@ -216,7 +248,7 @@ int InitDiscovery()
     }
     else
     {
-        ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_ALL,
+        ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, CT_DEFAULT,
                 OC_LOW_QOS, &cbData, NULL, 0);
     }
     if (ret != OC_STACK_OK)
@@ -241,9 +273,7 @@ int main(int argc, char* argv[])
                 TEST_CASE = atoi(optarg);
                 break;
             case 'c':
-                // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                // OC_CONNTYPE = OCConnectivityType(atoi(optarg));
-                OC_CONNTYPE = OC_IPV4;
+                CONNECTIVITY = atoi(optarg);
                 break;
             default:
                 PrintUsage();
@@ -252,7 +282,8 @@ int main(int argc, char* argv[])
     }
 
     if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
-            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) )
+            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
+            (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
     {
         PrintUsage();
         return -1;
@@ -265,6 +296,16 @@ int main(int argc, char* argv[])
         return 0;
     }
 
+    if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IP)
+    {
+        OC_CONNTYPE = CT_ADAPTER_IP;
+    }
+    else
+    {
+        OC_LOG(INFO, TAG, "Default Connectivity type selected...");
+        OC_CONNTYPE = CT_ADAPTER_IP;
+    }
+
     InitDiscovery();
 
     // Break from loop with Ctrl+C
@@ -290,30 +331,6 @@ int main(int argc, char* argv[])
     return 0;
 }
 
-std::string getIPAddrTBServer(OCClientResponse * clientResponse)
-{
-    if(!clientResponse) return "";
-    if(!clientResponse->addr) return "";
-    uint8_t a, b, c, d = 0;
-    if(0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) ) return "";
-
-    char ipaddr[16] = {'\0'};
-    // ostringstream not working correctly here, hence snprintf
-    snprintf(ipaddr,  sizeof(ipaddr), "%d.%d.%d.%d", a,b,c,d);
-    return std::string (ipaddr);
-}
-
-std::string getPortTBServer(OCClientResponse * clientResponse)
-{
-    if(!clientResponse) return "";
-    if(!clientResponse->addr) return "";
-    uint16_t p = 0;
-    if(0 != OCDevAddrToPort(clientResponse->addr, &p) ) return "";
-    std::ostringstream ss;
-    ss << p;
-    return ss.str();
-}
-
 std::string getQueryStrForGetPut(OCClientResponse * clientResponse)
 {
     return "/a/led";
@@ -321,8 +338,8 @@ std::string getQueryStrForGetPut(OCClientResponse * clientResponse)
 
 void parseClientResponse(OCClientResponse * clientResponse)
 {
-    coapServerIP = getIPAddrTBServer(clientResponse);
-    coapServerPort = getPortTBServer(clientResponse);
+    coapServerIP = clientResponse->devAddr.addr;
+    coapServerPort = clientResponse->devAddr.port;
     coapServerResource = getQueryStrForGetPut(clientResponse);
 }
 
index 8b6bcc4..c6e9486 100644 (file)
@@ -44,9 +44,21 @@ typedef enum
     TEST_DISCOVER_REQ = 1,
     TEST_NON_CON_OP,
     TEST_CON_OP,
+    TEST_NON_CON_PUT,
+    TEST_CON_PUT,
     MAX_TESTS
 } CLIENT_TEST;
 
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+    CT_ADAPTER_DEFAULT = 0,
+    CT_IP,
+    MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
 //-----------------------------------------------------------------------------
 // Function prototype
 //-----------------------------------------------------------------------------
@@ -67,6 +79,7 @@ std::string getQueryStrForGetPut(OCClientResponse * clientResponse);
  * POST & Discovery operations
  */
 int InitGetRequest(OCQualityOfService qos);
+int InitPutRequest(OCQualityOfService qos);
 int InitDiscovery();
 
 /* Function to retrieve ip address, port no. of the server
diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp
new file mode 100644 (file)
index 0000000..89da3ff
--- /dev/null
@@ -0,0 +1,523 @@
+//******************************************************************
+//
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <iostream>
+#include <sstream>
+#include "ocstack.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "ocremoteaccessclient.h"
+
+// Tracking user input
+static int TEST_CASE = 0;
+
+static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
+static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
+
+static std::string coapServerIP = "255.255.255.255";
+static std::string coapServerPort = "5683";
+static std::string coapServerResource = "/a/light";
+static OCDevAddr responseAddr;
+//Use ipv4addr for both InitDiscovery and InitPlatformOrDeviceDiscovery
+char remoteServerJabberID[MAX_ADDR_STR_SIZE];
+void StripNewLineChar(char* str);
+static uint16_t maxNotification = 15;
+
+// The handle for the observe registration
+OCDoHandle gObserveDoHandle;
+#ifdef WITH_PRESENCE
+// The handle for observe registration
+OCDoHandle gPresenceHandle;
+#endif
+// After this crosses a threshold client deregisters for further notifications
+int gNumObserveNotifies = 0;
+
+#ifdef WITH_PRESENCE
+int gNumPresenceNotifies = 0;
+#endif
+
+int gQuitFlag = 0;
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
+        gQuitFlag = 1;
+    }
+}
+
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+    OCRepPayloadSetPropInt(payload, "power", 42);
+    OCRepPayloadSetPropBool(payload, "state", true);
+    return (OCPayload*) payload;
+}
+
+static void PrintUsage()
+{
+    OC_LOG(INFO, TAG, "This sample makes all requests via the remote access adapter");
+    OC_LOG(INFO, TAG, "Usage : ocremoteaccessclient -t <number>");
+    OC_LOG(INFO, TAG, "-t 1  :  Discover Resources");
+    OC_LOG(INFO, TAG, "-t 2  :  Discover & Get");
+    OC_LOG(INFO, TAG, "-t 3  :  Discover & Put");
+    OC_LOG(INFO, TAG, "-t 4  :  Discover & Post");
+    OC_LOG(INFO, TAG, "-t 5  :  Discover & Delete");
+    OC_LOG(INFO, TAG, "-t 6  :  Discover & Observe");
+    OC_LOG(INFO, TAG, "-t 7  :  Discover & Observe then cancel immediately with High QOS");
+}
+
+OCStackResult InvokeOCDoResource(std::ostringstream &query,
+                                 OCMethod method,
+                                 OCQualityOfService qos,
+                                 OCClientResponseHandler cb,
+                                 OCHeaderOption * options,
+                                 uint8_t numOptions)
+{
+    OCCallbackData cbData;
+    OCDoHandle handle;
+
+    cbData.cb       = cb;
+    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);
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
+    }
+    else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
+    {
+        gObserveDoHandle = handle;
+    }
+#ifdef WITH_PRESENCE
+    else if (method == OC_REST_PRESENCE)
+    {
+        gPresenceHandle = handle;
+    }
+#endif
+
+    return ret;
+}
+
+OCStackApplicationResult restRequestCB(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    if(clientResponse == NULL)
+    {
+        OC_LOG(INFO, TAG, "Received NULL response");
+        return   OC_STACK_DELETE_TRANSACTION;
+    }
+    if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+    }
+
+    OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
+    OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+    if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
+    {
+        OC_LOG (INFO, TAG, "Received vendor specific options. Ignoring");
+    }
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    if(!clientResponse)
+    {
+        OC_LOG_V(INFO, TAG, "obsReqCB received NULL response");
+    }
+    if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+    }
+    OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
+    OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+    OC_LOG_V(INFO, TAG, "OBSERVE notification %d recvd", gNumObserveNotifies);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+    gNumObserveNotifies++;
+    if (gNumObserveNotifies == maxNotification)
+    {
+        if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "Observe cancel error");
+        }
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+    if (gNumObserveNotifies == 1 && TEST_CASE == TEST_OBS_REQ_NON_CANCEL_IMM)
+    {
+        if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "Observe cancel error");
+        }
+    }
+    if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
+    {
+        OC_LOG(INFO, TAG, "Registration confirmed");
+    }
+    else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
+    {
+        OC_LOG(INFO, TAG, "de-registration confirmed");
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+    else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
+    {
+        OC_LOG(INFO, TAG, "Registration/deregistration failed");
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+#ifdef WITH_PRESENCE
+OCStackApplicationResult presenceCB(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+    }
+
+    if (clientResponse)
+    {
+        OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+        OC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
+        OC_LOG_V(INFO, TAG, "PRESENCE notification %d recvd", gNumPresenceNotifies);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+        gNumPresenceNotifies++;
+        if (gNumPresenceNotifies == maxNotification)
+        {
+            if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+            {
+                OC_LOG(ERROR, TAG, "Presence cancel error");
+            }
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "presenceCB received Null clientResponse");
+    }
+    return OC_STACK_KEEP_TRANSACTION;
+}
+#endif
+
+// This is a function called back when a device is discovered
+OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse)
+{
+    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "DISCOVER  callback recvd");
+    }
+
+    if (!clientResponse)
+    {
+        OC_LOG_V(INFO, TAG, "discoveryReqCB received Null clientResponse");
+    }
+
+    OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+    responseAddr = clientResponse->devAddr;
+
+    switch(TEST_CASE)
+    {
+        OC_LOG_V(INFO, TAG, "TEST_CASE %u\n", TEST_CASE);
+        case TEST_GET_REQ_NON:
+            InitGetRequest(OC_LOW_QOS);
+            break;
+        case TEST_PUT_REQ_NON:
+            InitPutRequest(OC_LOW_QOS);
+            break;
+        case TEST_POST_REQ_NON:
+            InitPostRequest(OC_LOW_QOS);
+            break;
+        case TEST_DELETE_REQ_NON:
+            InitDeleteRequest(OC_LOW_QOS);
+            break;
+        case TEST_OBS_REQ_NON:
+        case TEST_OBS_REQ_NON_CANCEL_IMM:
+            InitObserveRequest(OC_LOW_QOS);
+            break;
+        default:
+            PrintUsage();
+            break;
+    }
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
+                OCClientResponse * clientResponse)
+{
+    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context for Platform DISCOVER query recvd successfully");
+    }
+
+    if(clientResponse)
+    {
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
+    }
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse)
+{
+    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
+    }
+
+    if(clientResponse)
+    {
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
+    }
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+int InitObserveRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << coapServerResource;
+    return (InvokeOCDoResource(query,
+            OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
+}
+
+int InitPutRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << coapServerResource;
+    return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
+            restRequestCB, NULL, 0));
+}
+
+int InitPostRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << coapServerResource;
+    // First POST operation (to create an Light instance)
+    OCStackResult result = InvokeOCDoResource(query, OC_REST_POST,
+                               ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+                               restRequestCB, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        // Error can happen if for example, network connectivity is down
+        OC_LOG(INFO, TAG, "First POST call did not succeed");
+    }
+
+    // Second POST operation (to create an Light instance)
+    result = InvokeOCDoResource(query, OC_REST_POST,
+                               ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+                               restRequestCB, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        OC_LOG(INFO, TAG, "Second POST call did not succeed");
+    }
+
+    // This POST operation will update the original resourced /a/light
+    return (InvokeOCDoResource(query, OC_REST_POST,
+                               ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+                               restRequestCB, NULL, 0));
+}
+
+int InitDeleteRequest(OCQualityOfService qos)
+{
+    std::ostringstream query;
+    query << coapServerResource;
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+    // First DELETE operation
+    OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
+                               qos,
+                               restRequestCB, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        // Error can happen if for example, network connectivity is down
+        OC_LOG(INFO, TAG, "DELETE call did not succeed");
+    }
+    return result;
+}
+
+int InitGetRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << coapServerResource;
+    return (InvokeOCDoResource(query, OC_REST_GET,
+                (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, restRequestCB, NULL, 0));
+}
+
+int InitDiscovery(OCQualityOfService qos)
+{
+    OCCallbackData cbData;
+    cbData.cb       = discoveryReqCB;
+    cbData.context  = (void*)DEFAULT_CONTEXT_VALUE;
+    cbData.cd       = NULL;
+
+    OCDevAddr dest;
+    dest.adapter    = OC_ADAPTER_REMOTE_ACCESS;
+    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
+            );
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG_V(ERROR, TAG, "Error %u in OCDoResource with discovery", ret);
+    }
+    return ret;
+}
+
+OCStackResult initRemoteAccessAdapter ()
+{
+    OCRAInfo_t rainfo;
+    rainfo.hostname = "localhost";
+    rainfo.port = 5222;
+    rainfo.xmpp_domain = "localhost";
+    rainfo.username = "test1";
+    rainfo.password = "intel123";
+    rainfo.resource = "";
+    rainfo.user_jid = "";
+
+    return OCSetRAInfo(&rainfo);
+}
+
+int main(int argc, char* argv[])
+{
+    int opt;
+
+    while ((opt = getopt(argc, argv, "t:")) != -1)
+    {
+        switch(opt)
+        {
+            case 't':
+                TEST_CASE = atoi(optarg);
+                break;
+            default:
+                PrintUsage();
+                return -1;
+        }
+    }
+
+    if (initRemoteAccessAdapter() != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "Error initiating remote access adapter");
+        return 0;
+    }
+
+    if ((TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS))
+    {
+        PrintUsage();
+        return -1;
+    }
+
+    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack init error");
+        return 0;
+    }
+
+    OC_LOG(INFO, TAG, "Enter JID of remote server");
+    if (fgets(remoteServerJabberID, MAX_ADDR_STR_SIZE, stdin))
+    {
+        StripNewLineChar(remoteServerJabberID);
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "Bad input for jabberID");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    InitDiscovery(OC_LOW_QOS);
+
+    // Break from loop with Ctrl+C
+    OC_LOG(INFO, TAG, "Press CTRL+C to stop the stack");
+    signal(SIGINT, handleSigInt);
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "OCStack process error");
+            return 0;
+        }
+
+        sleep(2);
+    }
+    OC_LOG(INFO, TAG, "Exiting ocremoteaccessclient main loop...");
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack stop error");
+    }
+
+    return 0;
+}
diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h
new file mode 100644 (file)
index 0000000..f121a12
--- /dev/null
@@ -0,0 +1,93 @@
+//******************************************************************
+//
+// 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 OCREMOTECLIENT_H_
+#define OCREMOTECLIENT_H_
+
+#include "ocstack.h"
+
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "occlient_remoteaccess"
+#define DEFAULT_CONTEXT_VALUE 0x99
+#ifndef MAX_LENGTH_IPv4_ADDR
+#define MAX_LENGTH_IPv4_ADDR 16
+#endif
+
+/**
+ * List of methods that can be initiated from the client
+ */
+typedef enum {
+    TEST_DISCOVER_REQ = 1,
+    TEST_GET_REQ_NON,
+    TEST_PUT_REQ_NON,
+    TEST_POST_REQ_NON,
+    TEST_DELETE_REQ_NON,
+    TEST_OBS_REQ_NON,
+    TEST_OBS_REQ_NON_CANCEL_IMM,
+    TEST_DISCOVER_PLATFORM_REQ,
+    TEST_DISCOVER_DEV_REQ,
+    MAX_TESTS
+} CLIENT_TEST;
+
+/* call getResult in common.cpp to get the result in string format. */
+const char *getResult(OCStackResult result);
+
+/* Following are initialization functions for GET, Observe, PUT
+ * POST, Delete & Discovery operations
+ */
+int InitGetRequestToUnavailableResource(OCQualityOfService qos);
+int InitObserveRequest(OCQualityOfService qos);
+int InitPutRequest(OCQualityOfService qos);
+int InitGetRequest(OCQualityOfService qos);
+int InitPostRequest(OCQualityOfService qos);
+int InitDeleteRequest(OCQualityOfService qos);
+int InitDeviceDiscovery(OCQualityOfService qos);
+int InitPlatformDiscovery(OCQualityOfService qos);
+int InitDiscovery(OCQualityOfService qos);
+
+
+/*
+ * This method calls OCDoResource() which in turn makes calls
+ * to the lower layers
+ */
+OCStackResult InvokeOCDoResource(std::ostringstream &query,
+        OCMethod method, OCQualityOfService qos,
+        OCClientResponseHandler cb, OCHeaderOption * options, uint8_t numOptions);
+
+/*
+ * Following are callback functions for the  GET, Observe, PUT
+ * POST, Delete, Presence & Discovery operations
+ */
+OCStackApplicationResult putReqCB   (void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+OCStackApplicationResult postReqCB  (void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+OCStackApplicationResult getReqCB   (void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+OCStackApplicationResult obsReqCB   (void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+OCStackApplicationResult presenceCB (void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+OCStackApplicationResult deleteReqCB(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse);
+
+OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
+    OCClientResponse *clientResponse);
+
+
+#endif
+
index d263b09..e40f06a 100644 (file)
@@ -29,7 +29,7 @@
 #include <array>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "ocserver.h"
 
 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
@@ -55,24 +55,11 @@ static int stopPresenceCount = 10;
 #define numPresenceResources (2)
 #endif
 
-//TODO: Follow the pattern used in constructJsonResponse() when the payload is decided.
-const char responsePayloadDeleteOk[] =
-        "{App determines payload: Delete Resource operation succeeded.}";
-const char responsePayloadDeleteNotOK[] =
-        "{App determines payload: Delete Resource operation failed.}";
-const char responsePayloadResourceDoesNotExist[] =
-        "{App determines payload: The resource does not exist.}";
-const char responsePayloadDeleteResourceNotSupported[] =
-        "{App determines payload: The request is received for a non-support resource.}";
-
-
 char *gResourceUri= (char *)"/a/light";
-const char *contentType = "myContentType";
 const char *dateOfManufacture = "myDateOfManufacture";
 const char *deviceName = "myDeviceName";
 const char *deviceUUID = "myDeviceUUID";
 const char *firmwareVersion = "myFirmwareVersion";
-const char *hostName = "myHostName";
 const char *manufacturerName = "myName";
 const char *operatingSystemVersion = "myOS";
 const char *hardwareVersion = "myHardwareVersion";
@@ -90,14 +77,35 @@ const char *resourceTypeName = "core.light";
 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
 
 OCPlatformInfo platformInfo;
+OCDeviceInfo deviceInfo;
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return nullptr;
+    }
+
+    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
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-    cJSON *format;
-    char *jsonResponse;
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+        return nullptr;
+    }
+
+    OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
     LightResource *currLightResource = &Light;
 
     if (ehRequest->resource == gLightInstance[0].handle)
@@ -113,49 +121,26 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        // Get cJSON pointer to query
-        cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-
-        if(!putJson)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
-            return NULL;
-        }
-
-        // Get root of JSON payload, then the 1st resource.
-        cJSON* carrier = cJSON_GetObjectItem(putJson, "oc");
-        carrier = cJSON_GetArrayItem(carrier, 0);
-        carrier = cJSON_GetObjectItem(carrier, "rep");
-
-        cJSON* prop = cJSON_GetObjectItem(carrier,"power");
-        if (prop)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            currLightResource->power =prop->valueint;
+            currLightResource->power =pow;
         }
 
-        prop = cJSON_GetObjectItem(carrier,"state");
-        if (prop)
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
         {
-            currLightResource->state = prop->valueint;
+            currLightResource->state = state;
         }
-
-        cJSON_Delete(putJson);
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-    cJSON_AddBoolToObject(format, "state", currLightResource->state);
-    cJSON_AddNumberToObject(format, "power", currLightResource->power);
-
-    jsonResponse = cJSON_Print(json);
-    cJSON_Delete(json);
-
-    return jsonResponse;
+    return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
 }
 
 /*
  * Very simple example of query parsing.
- * The query may have multiple filters separated by '&'.
+ * The query may have multiple filters separated by ';'.
  * It is upto the entity handler to parse the query for the individual filters,
  * VALIDATE them and respond as it sees fit.
 
@@ -194,7 +179,7 @@ OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandler
 }
 
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
     bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
@@ -202,26 +187,15 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
     // Empty payload if the query has no match.
     if (queryPassed)
     {
-        char *getResp = constructJsonResponse(ehRequest);
+        OCRepPayload *getResp = constructResponse(ehRequest);
         if(!getResp)
         {
-            OC_LOG(ERROR, TAG, "constructJsonResponse failed");
+            OC_LOG(ERROR, TAG, "constructResponse failed");
             return OC_EH_ERROR;
         }
 
-        if (maxPayloadSize > strlen (getResp))
-        {
-            strncpy(payload, getResp, strlen(getResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
+        *payload = getResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -232,10 +206,10 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+        OCRepPayload** payload)
 {
     OCEntityHandlerResult ehResult;
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(!putResp)
     {
@@ -243,30 +217,17 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
         return OC_EH_ERROR;
     }
 
-    if (maxPayloadSize > strlen ((char *)putResp))
-    {
-        strncpy(payload, putResp, strlen((char *)putResp));
-        ehResult = OC_EH_OK;
-    }
-    else
-    {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-        ehResult = OC_EH_ERROR;
-    }
-
-    free(putResp);
+    *payload = putResp;
+    ehResult = OC_EH_OK;
 
     return ehResult;
 }
 
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-        OCEntityHandlerResponse *response, char *payload, uint16_t maxPayloadSize)
+        OCEntityHandlerResponse *response, OCRepPayload** payload)
 {
     OCEntityHandlerResult ehResult = OC_EH_OK;
-    char *respPLPost_light = NULL;
-    cJSON *json;
-    cJSON *format;
+    OCRepPayload *respPLPost_light = nullptr;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -287,10 +248,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             char newLightUri[URI_MAXSIZE];
             snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
 
-            json = cJSON_CreateObject();
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-            cJSON_AddStringToObject(format, "createduri", (char *) newLightUri);
+            respPLPost_light = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_light, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
 
             if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
             {
@@ -298,19 +258,16 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLightInstance[gCurrLightInstance].state = 0;
                 gLightInstance[gCurrLightInstance].power = 0;
                 gCurrLightInstance++;
-                respPLPost_light = cJSON_Print(json);
                 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
                 ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
             // Update repesentation of /a/light
             Light.state = true;
             Light.power = 11;
-            respPLPost_light = constructJsonResponse(ehRequest);
+            respPLPost_light = constructResponse(ehRequest);
         }
     }
     else
@@ -323,34 +280,31 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLightInstance[i].power = 22;
                 if (i == 0)
                 {
-                    respPLPost_light = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_light = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_light != NULL) && (maxPayloadSize > strlen ((char *)respPLPost_light)))
+    if ((respPLPost_light != NULL))
     {
-        strncpy(payload, respPLPost_light, strlen((char *)respPLPost_light));
+        *payload = respPLPost_light;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG(INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_light);
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
 {
     if(ehRequest == NULL)
     {
@@ -370,8 +324,6 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
      * 2. optionally, app removes observers out of its array 'interestedObservers'
      */
 
-    const char* deleteResponse = NULL;
-
     if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
     {
         //Step 1: Ask stack to do the work.
@@ -381,7 +333,6 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
         {
             OC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
             ehResult = OC_EH_OK;
-            deleteResponse = responsePayloadDeleteOk;
 
             //Step 2: clear observers who wanted to observe this resource at the app level.
             for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
@@ -397,13 +348,11 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
         else if (result == OC_STACK_NO_RESOURCE)
         {
             OC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
-            deleteResponse = responsePayloadResourceDoesNotExist;
             ehResult = OC_EH_RESOURCE_DELETED;
         }
         else
         {
             OC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
-            deleteResponse = responsePayloadDeleteNotOK;
             ehResult = OC_EH_ERROR;
         }
     }
@@ -412,43 +361,16 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
         //Let's this app not supporting DELETE on some resources so
         //consider the DELETE request is received for a non-support resource.
         OC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
-        deleteResponse = responsePayloadDeleteResourceNotSupported;
         ehResult = OC_EH_FORBIDDEN;
     }
 
-    if (maxPayloadSize > strlen ((char *)deleteResponse))
-    {
-        strncpy(payload, deleteResponse, strlen((char *)deleteResponse));
-    }
-    else
-    {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-        ehResult = OC_EH_ERROR;
-    }
-
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
 {
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
 
-    const char* response = NULL;
-    response = responsePayloadResourceDoesNotExist;
-
-    if ( (ehRequest != NULL) &&
-         (maxPayloadSize > strlen ((char *)response)) )
-    {
-        strncpy((char *)payload, response, strlen((char *)response));
-    }
-    else
-    {
-        OC_LOG_V (ERROR, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-    }
-
     return OC_EH_RESOURCE_NOT_FOUND;
 }
 
@@ -492,13 +414,12 @@ void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
 
 OCEntityHandlerResult
 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest, char* uri)
+        OCEntityHandlerRequest *entityHandlerRequest, char* uri, void* callbackParam)
 {
     OC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
 
     // Validate pointer
     if (!entityHandlerRequest)
@@ -511,6 +432,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
     memset(response.sendVendorSpecificHeaderOptions, 0,
             sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
 
 
     if (flag & OC_REQUEST_FLAG)
@@ -520,23 +442,22 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         if (entityHandlerRequest->resource == NULL)
         {
             OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
-            ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest,
-                           payload, sizeof(payload) - 1);
+            ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
         }
         else if (OC_REST_GET == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
         }
         else if (OC_REST_PUT == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-            ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
         }
         else if (OC_REST_DELETE == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessDeleteRequest (entityHandlerRequest);
         }
         else
         {
@@ -551,8 +472,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehResult;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             // Indicate that response is NOT in a persistent buffer
             response.persistentBufferFlag = 0;
 
@@ -582,7 +502,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
 
 OCEntityHandlerResult
 OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+        OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
 {
     // This is callback is associated with the 2 presence notification
     // resources. They are non-operational.
@@ -591,13 +511,12 @@ OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
 
 OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback)
 {
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
-    OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCEntityHandlerResponse response = { 0 };
 
     // Validate pointer
     if (!entityHandlerRequest)
@@ -611,6 +530,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
     memset(response.sendVendorSpecificHeaderOptions,
             0, sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -619,22 +539,22 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         if (OC_REST_GET == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
         }
         else if (OC_REST_PUT == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-            ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
         }
         else if (OC_REST_POST == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-            ehResult = ProcessPostRequest (entityHandlerRequest, &response, payload, sizeof(payload) - 1);
+            ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
         }
         else if (OC_REST_DELETE == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessDeleteRequest (entityHandlerRequest);
         }
         else
         {
@@ -649,8 +569,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehResult;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             // Indicate that response is NOT in a persistent buffer
             response.persistentBufferFlag = 0;
 
@@ -711,6 +630,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
@@ -752,17 +672,10 @@ void *ChangeLightRepresentation (void *param)
                     }
                 }
 
-                cJSON *json = cJSON_CreateObject();
-                cJSON *format;
-                cJSON_AddStringToObject(json,"href",gResourceUri);
-                cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-                cJSON_AddBoolToObject(format, "state", Light.state);
-                cJSON_AddNumberToObject(format, "power", Light.power);
-                char * obsResp = cJSON_Print(json);
-                cJSON_Delete(json);
+                OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
                 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
-                        obsResp, OC_NA_QOS);
-                free(obsResp);
+                        payload, OC_NA_QOS);
+                OCRepPayloadDestroy(payload);
             }
             else if (gObserveNotifyType == 0)
             {
@@ -798,7 +711,7 @@ void *ChangeLightRepresentation (void *param)
 #ifdef WITH_PRESENCE
 void *presenceNotificationGenerator(void *param)
 {
-    sleep(5);
+    sleep(10);
     (void)param;
     OCDoHandle presenceNotificationHandles[numPresenceResources];
     OCStackResult res = OC_STACK_OK;
@@ -820,6 +733,7 @@ void *presenceNotificationGenerator(void *param)
                     OC_RSRVD_INTERFACE_DEFAULT,
                     presenceNotificationUris.at(i).c_str(),
                     OCNOPEntityHandlerCb,
+                    NULL,
                     OC_DISCOVERABLE|OC_OBSERVABLE);
         }
         if(res != OC_STACK_OK)
@@ -867,6 +781,7 @@ int createLightResource (char *uri, LightResource *lightResource)
             "oc.mi.def",
             uri,
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
 
@@ -888,6 +803,11 @@ void DeletePlatformInfo()
     free (platformInfo.systemTime);
 }
 
+void DeleteDeviceInfo()
+{
+    free (deviceInfo.deviceName);
+}
+
 bool DuplicateString(char** targetString, const char* sourceString)
 {
     if(!sourceString)
@@ -989,6 +909,15 @@ OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerNa
     return OC_STACK_ERROR;
 }
 
+OCStackResult SetDeviceInfo(const char* deviceName)
+{
+    if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+    {
+        return OC_STACK_ERROR;
+    }
+    return OC_STACK_OK;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
@@ -1020,6 +949,18 @@ int main(int argc, char* argv[])
         PrintUsage();
         return -1;
     }
+    #ifdef RA_ADAPTER
+    OCRAInfo_t rainfo;
+    rainfo.hostname = "localhost";
+    rainfo.port = 5222;
+    rainfo.xmpp_domain = "localhost";
+    rainfo.username = "test1";
+    rainfo.password = "intel123";
+    rainfo.resource = "";
+    rainfo.user_jid = "";
+
+    OCSetRAInfo(&rainfo);
+    #endif
 
     OC_LOG(DEBUG, TAG, "OCServer is starting...");
 
@@ -1036,27 +977,43 @@ int main(int argc, char* argv[])
     }
 #endif
 
-    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
+    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
 
-    OCStackResult platformRegistrationResult =
+    OCStackResult registrationResult =
         SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
             dateOfManufacture, platformVersion,  operatingSystemVersion,  hardwareVersion,
             firmwareVersion,  supportUrl, systemTime);
 
-    if (platformRegistrationResult != OC_STACK_OK)
+    if (registrationResult != OC_STACK_OK)
     {
         OC_LOG(INFO, TAG, "Platform info setting failed locally!");
         exit (EXIT_FAILURE);
     }
 
-    platformRegistrationResult = OCSetPlatformInfo(platformInfo);
+    registrationResult = OCSetPlatformInfo(platformInfo);
 
-    if (platformRegistrationResult != OC_STACK_OK)
+    if (registrationResult != OC_STACK_OK)
     {
         OC_LOG(INFO, TAG, "Platform Registration failed!");
         exit (EXIT_FAILURE);
     }
 
+    registrationResult = SetDeviceInfo(deviceName);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device info setting failed locally!");
+        exit (EXIT_FAILURE);
+    }
+
+    registrationResult = OCSetDeviceInfo(deviceInfo);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
     /*
      * Declare and create the example resource: Light
      */
@@ -1084,8 +1041,12 @@ int main(int argc, char* argv[])
 
     // Break from loop with Ctrl-C
     OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+
     DeletePlatformInfo();
+    DeleteDeviceInfo();
+
     signal(SIGINT, handleSigInt);
+
     while (!gQuitFlag)
     {
         if (OCProcess() != OC_STACK_OK)
@@ -1113,4 +1074,4 @@ int main(int argc, char* argv[])
     }
 
     return 0;
-}
\ No newline at end of file
+}
index e6d123e..8c87326 100644 (file)
@@ -62,8 +62,8 @@ const char *getResult(OCStackResult result);
  */
 int createLightResource (char *uri, LightResource *lightResource);
 
-/* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+/* This method constructs a response from the request */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* This method changes the Light power using an independent thread
  * and notifies the observers of new state of the resource.
@@ -78,22 +78,15 @@ OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandler
 /* Following methods process the PUT, GET, POST, Delete,
  * & Observe requests */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                                           OCEntityHandlerResponse *response,
-                                          char *payload,
-                                          uint16_t maxPayloadSize);
-OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
-                                            char *payload,
-                                            uint16_t maxPayloadSize);
-
-OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest *ehRequest,
-                                                         char *payload,
-                                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest);
+
+OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest *ehRequest);
 
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest);
 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest);
index 43b913f..e389865 100644 (file)
@@ -26,8 +26,8 @@
 #include <pthread.h>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
 #include "ocserverbasicops.h"
+#include "ocpayload.h"
 
 //string length of "/a/led/" + std::numeric_limits<int>::digits10 + '\0'"
 // 7 + 9 + 1 = 17
@@ -44,90 +44,76 @@ static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
 
 char *gResourceUri= (char *)"/a/led";
 
-//This function takes the request as an input and returns the response
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
 {
-    cJSON *json = cJSON_CreateObject();
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return nullptr;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
+
+    return payload;
+}
 
-    if(!json)
+//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)
     {
-        OC_LOG (ERROR, TAG, "json object not created properly");
-        return NULL;
+        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+        return nullptr;
     }
 
-    cJSON *format;
-    char *jsonResponse;
+    OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
     LEDResource *currLEDResource = &LED;
 
     if (ehRequest->resource == gLedInstance[0].handle)
     {
         currLEDResource = &gLedInstance[0];
-        gResourceUri = (char *) "a/led/0";
+        gResourceUri = (char *) "/a/led/0";
     }
     else if (ehRequest->resource == gLedInstance[1].handle)
     {
         currLEDResource = &gLedInstance[1];
-        gResourceUri = (char *) "a/led/1";
+        gResourceUri = (char *) "/a/led/1";
     }
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
-
-        if(!putJson)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            OC_LOG (ERROR, TAG, "putJson object not created properly");
-            cJSON_Delete(json);
-            return NULL;
+            currLEDResource->power =pow;
         }
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring ,
-                "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
-        cJSON_Delete(putJson);
-    }
-
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    format = cJSON_CreateObject();
 
-    if(!format)
-    {
-        OC_LOG (ERROR, TAG, "format object not created properly");
-        cJSON_Delete(json);
-        return NULL;
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
     }
 
-    cJSON_AddItemToObject(json, "rep", format);
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
-
-    jsonResponse = cJSON_Print(json);
-    cJSON_Delete(json);
-    return jsonResponse;
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
 }
 
-OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
-    char *getResp = constructJsonResponse(ehRequest);
+    OCRepPayload *getResp = constructResponse(ehRequest);
 
     if(getResp)
     {
-        if (maxPayloadSize > strlen ((char *)getResp))
-        {
-            strncpy(payload, getResp, strlen((char *)getResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
-    }
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+     }
     else
     {
         ehResult = OC_EH_ERROR;
@@ -136,27 +122,16 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, char
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(putResp)
     {
-        if (maxPayloadSize > strlen ((char *)putResp))
-        {
-            strncpy(payload, putResp, strlen((char *)putResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(putResp);
+        *payload = putResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -166,13 +141,11 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, char
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
 {
-    char *respPLPost_led = NULL;
-    cJSON *json;
-    cJSON *format;
-    OCEntityHandlerResult ehResult;
+    OCRepPayload *respPLPost_led = nullptr;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -193,22 +166,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
             char newLedUri[URI_MAXSIZE ];
             snprintf(newLedUri, URI_MAXSIZE, "/a/led/%d", gCurrLedInstance);
 
-            json = cJSON_CreateObject();
-            if(!json)
-            {
-                return OC_EH_ERROR;
-            }
-
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            format = cJSON_CreateObject();
-
-            if(!format)
-            {
-                return OC_EH_ERROR;
-            }
-
-            cJSON_AddItemToObject(json, "rep", format);
-            cJSON_AddStringToObject(format, "createduri", (char *) newLedUri);
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
 
             if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
             {
@@ -216,14 +176,13 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
                 gLedInstance[gCurrLedInstance].state = 0;
                 gLedInstance[gCurrLedInstance].power = 0;
                 gCurrLedInstance++;
-                respPLPost_led = cJSON_Print(json);
+                strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+                ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
-            respPLPost_led = constructJsonResponse(ehRequest);
+            respPLPost_led = constructResponse(ehRequest);
         }
     }
     else
@@ -234,43 +193,48 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
             {
                 if (i == 0)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_led != NULL) && (maxPayloadSize > strlen ((char *)respPLPost_led)))
+    if ((respPLPost_led != NULL))
     {
-        strncpy(payload, respPLPost_led, strlen((char *)respPLPost_led));
+        *payload = respPLPost_led;
         ehResult = OC_EH_OK;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG_V (INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_led);
-
     return ehResult;
 }
 
 OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+        OCEntityHandlerRequest *entityHandlerRequest,void* callbackParam)
 {
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
 
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -280,17 +244,17 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             if (OC_REST_GET == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_PUT == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-                ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_POST == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-                ehResult = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
             }
             else
             {
@@ -298,14 +262,13 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                         entityHandlerRequest->method);
             }
 
-            if (ehResult == OC_EH_OK)
+            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 = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
                 memset(response.resourceUri, 0, sizeof(response.resourceUri));
@@ -321,6 +284,8 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             }
         }
     }
+
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
@@ -386,6 +351,7 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState,
             OC_RSRVD_INTERFACE_DEFAULT,
             uri,
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
 
index aec3923..bd223cf 100644 (file)
@@ -48,21 +48,19 @@ typedef struct LEDRESOURCE{
  */
 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
 
-/* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+/* This method constructs a response from the request */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* Following methods process the PUT, GET, POST
  * requests
  */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                        OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                        OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                                          char *payload,
-                                          uint16_t maxPayloadSize);
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
 
 /* call getResult in common.cpp to get the result in string format. */
 const char *getResult(OCStackResult result);
index aff73b6..d3fed5a 100644 (file)
@@ -28,6 +28,7 @@
 #include <pthread.h>
 #include <ocstack.h>
 #include <logger.h>
+#include "ocpayload.h"
 
 const char *getResult(OCStackResult result);
 
@@ -44,32 +45,9 @@ typedef struct LIGHTRESOURCE{
 
 static LightResource light;
 
-// TODO : hard coded for now, change after Sprint10
-const char rspGetRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
-const char rspGetRoomCollection[] = "{\"href\":\"/a/room\"}";
-// TODO : Needs to be changed to retrieve current status of room and return that in response
-const char rspPutRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
-const char rspPutRoomCollection[] = "{\"href\":\"/a/room\"}";
-const char rspFailureRoom[] = "{\"href\":\"/a/room\",\"rep\":{\"error\":\"ROOM_OP_FAIL\"}}";
-
-// TODO : hard coded for now, change after Sprint4
-const char rspGetLightDefault[] =
-        "{\"href\":\"/a/light\",\"rep\":{\"state\":\"false\",\"color\":\"0\"}}";
-const char rspGetLightCollection[] = "{\"href\":\"/a/light\"}";
-// TODO : Needs to be changed to retrieve current status of light and return that in response
-const char rspPutLightDefault[] =
-        "{\"href\":\"/a/light\",\"rep\":{\"state\":\"true\",\"color\":\"0\"}}";
-const char rspPutLightCollection[] = "{\"href\":\"/a/light\"}";
-const char rspFailureLight[] = "{\"href\":\"/a/light\",\"rep\":{\"error\":\"LIGHT_OP_FAIL\"}}";
-
-
-// TODO : hard coded for now, change after Sprint4
-const char rspGetFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"true\",\"speed\":10}}";
-const char rspGetFanCollection[] = "{\"href\":\"/a/fan\"}";
-// TODO : Needs to be changed to retrieve current status of fan and return that in response
-const char rspPutFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"false\",\"speed\":0}}";
-const char rspPutFanCollection[] = "{\"href\":\"/a/fan\"}";
-const char rspFailureFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"error\":\"FAN_OP_FAIL\"}}";
+char *gLightResourceUri= (char *)"/a/light";
+char *gRoomResourceUri= (char *)"/a/room";
+char *gFanResourceUri= (char *)"/a/fan";
 
 typedef enum
 {
@@ -90,38 +68,11 @@ void PrintUsage()
 
 unsigned static int TEST = TEST_INVALID;
 
-static OCEntityHandlerResult
-HandleCallback(OCEntityHandlerRequest * ehRequest,
-               const char* opStr,
-               const char* errStr,
-               char *payload,
-               uint16_t maxPayloadSize)
-{
-    OCEntityHandlerResult ret = OC_EH_OK;
-
-    // Append opStr or errStr, after making sure there is
-    // enough room in the payload
-    if (strlen(opStr) < (maxPayloadSize - strlen(payload)))
-    {
-        strncat((char*)payload, opStr, strlen(opStr));
-    }
-    else if (strlen(errStr) < (maxPayloadSize - strlen(payload)))
-    {
-        strncat((char*)payload, errStr, strlen(errStr));
-        ret = OC_EH_ERROR;
-    }
-    else
-    {
-        ret = OC_EH_ERROR;
-    }
-
-    return ret;
-}
-
 static void
 PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest)
 {
     const char* typeOfMessage;
+    const char* typeOfMethod;
 
     switch (flag)
     {
@@ -135,17 +86,81 @@ PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehReques
             typeOfMessage = "UNKNOWN";
     }
 
-    OC_LOG_V(INFO, TAG, "Receiving message type: %s, method %s",
-            typeOfMessage,
-            (ehRequest->method == OC_REST_GET) ? "OC_REST_GET" : "OC_REST_PUT" );
+    if (ehRequest == NULL)
+    {
+        typeOfMethod = "UNKNOWN";
+    }
+    else if (ehRequest->method == OC_REST_GET)
+    {
+        typeOfMethod = "OC_REST_GET";
+    }
+    else
+    {
+        typeOfMethod = "OC_REST_PUT";
+    }
+
+    OC_LOG_V(INFO, TAG, "Receiving message type: %s, method %s", typeOfMessage,
+            typeOfMethod);
+}
+
+//The only case when this entity handler is for a non-existing resource.
+OCEntityHandlerResult
+OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest, char* uri, void* callbackParam)
+{
+    OC_LOG_V(INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
+
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+    OCEntityHandlerResponse response;
+
+    if (!entityHandlerRequest)
+    {
+        OC_LOG(ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    if (entityHandlerRequest->resource == NULL)
+    {
+        OC_LOG(INFO, TAG, "Received request from client to a non-existing resource");
+        ehResult = OC_EH_RESOURCE_NOT_FOUND;
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "Device Handler: Received unsupported request from client %d",
+                        entityHandlerRequest->method);
+        ehResult = OC_EH_ERROR;
+    }
+
+    if (!((ehResult == OC_EH_ERROR) || (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 = nullptr;
+        response.numSendVendorSpecificHeaderOptions = 0;
+        memset(response.sendVendorSpecificHeaderOptions,
+                0, sizeof response.sendVendorSpecificHeaderOptions);
+        // Indicate that response is NOT in a persistent buffer
+        response.persistentBufferFlag = 0;
+
+        // Send the response
+        if (OCDoResponse(&response) != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "Error sending response");
+            ehResult = OC_EH_ERROR;
+        }
+    }
+    return ehResult;
 }
 
 OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
-                                            OCEntityHandlerRequest * ehRequest)
+                                            OCEntityHandlerRequest * ehRequest,
+                                            void* callback)
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Room");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -158,54 +173,45 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
         {
             if(query.find(OC_RSRVD_INTERFACE_DEFAULT) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomDefault, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
-                }
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+                OCRepPayloadSetPropString(payload, "name", "John's Room");
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             else if(query.find(OC_RSRVD_INTERFACE_LL) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
-                }
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             else if(query.find(OC_RSRVD_INTERFACE_BATCH) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanDefault, rspFailureFan, payload, sizeof(payload));
-                }
+
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadSetPropBool(tempPayload, "state", false);
+                OCRepPayloadSetPropInt(tempPayload, "power", 0);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadSetPropBool(tempPayload2, "state", true);
+                OCRepPayloadSetPropInt(tempPayload2, "speed", 10);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             if (ret == OC_EH_OK)
             {
@@ -213,8 +219,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
                 response.requestHandle = ehRequest->requestHandle;
                 response.resourceHandle = ehRequest->resource;
                 response.ehResult = ret;
-                response.payload = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions,
                         0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -235,48 +240,50 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomDefault, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
+                    OCRepPayloadSetPropString(payload, "name", "John's Room");
                 }
             }
             if(query.find(OC_RSRVD_INTERFACE_LL) != std::string::npos)
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutLightCollection, rspFailureLight, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutFanCollection, rspFailureFan, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gFanResourceUri);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
             }
             if(query.find(OC_RSRVD_INTERFACE_BATCH ) != std::string::npos)
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                    OCRepPayloadSetPropBool(tempPayload, "state", true);
+                    OCRepPayloadSetPropInt(tempPayload, "power", 0);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutFanDefault, rspFailureFan, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gFanResourceUri);
+                    OCRepPayloadSetPropBool(tempPayload, "state", false);
+                    OCRepPayloadSetPropInt(tempPayload, "speed", 0);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
             }
             if (ret == OC_EH_OK)
@@ -285,8 +292,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
                 response.requestHandle = ehRequest->requestHandle;
                 response.resourceHandle = ehRequest->resource;
                 response.ehResult = ret;
-                response.payload = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions,
                         0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -316,11 +322,11 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
 }
 
 OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest * ehRequest)
+        OCEntityHandlerRequest * ehRequest,void* callbackParam)
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Light");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -329,13 +335,15 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest,
-                    rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gLightResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "power", 0);
         }
         else if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest,
-                    rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gLightResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "power", 0);
         }
         else
         {
@@ -350,8 +358,7 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
             response.requestHandle = ehRequest->requestHandle;
             response.resourceHandle = ehRequest->resource;
             response.ehResult = ret;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions,
                     0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -376,11 +383,11 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
 }
 
 OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest * ehRequest)
+        OCEntityHandlerRequest * ehRequest, void* callback)
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Fan");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -389,13 +396,15 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspGetFanDefault,
-                    rspFailureFan, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gFanResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "speed", 10);
         }
         else if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspPutFanDefault,
-                    rspFailureFan, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gFanResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "speed", 0);
         }
         else
         {
@@ -410,8 +419,7 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
             response.requestHandle = ehRequest->requestHandle;
             response.resourceHandle = ehRequest->resource;
             response.ehResult = ret;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions,
                     0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -499,6 +507,8 @@ int main(int argc, char* argv[])
         return 0;
     }
 
+    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
+
     /*
      * Declare and create the example resource: light
      */
@@ -537,6 +547,7 @@ int main(int argc, char* argv[])
 
     return 0;
 }
+
 void createResources()
 {
     light.state = false;
@@ -547,6 +558,7 @@ void createResources()
             OC_RSRVD_INTERFACE_DEFAULT,
             "/a/fan",
             OCEntityHandlerFanCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created fan resource with result: %s", getResult(res));
 
@@ -556,6 +568,7 @@ void createResources()
             OC_RSRVD_INTERFACE_DEFAULT,
             "/a/light",
             OCEntityHandlerLightCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created light resource with result: %s", getResult(res));
 
@@ -568,6 +581,7 @@ void createResources()
                 OC_RSRVD_INTERFACE_BATCH,
                 "/a/room",
                 OCEntityHandlerRoomCb,
+                NULL,
                 OC_DISCOVERABLE);
     }
     else
@@ -577,6 +591,7 @@ void createResources()
                 OC_RSRVD_INTERFACE_BATCH,
                 "/a/room",
                 NULL,
+                NULL,
                 OC_DISCOVERABLE);
     }
 
index eb015e4..99a0b52 100644 (file)
 #include <sys/time.h>
 #include <list>
 #include "ocstack.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
 #include "logger.h"
 #include "cJSON.h"
 #include "ocserverslow.h"
+#include "ocpayload.h"
 
 volatile sig_atomic_t gQuitFlag = 0;
 
@@ -47,21 +48,11 @@ char *gResourceUri= (char *)"/a/led";
 
 //This function takes the request as an input and returns the response
 //in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-
-    if(!json)
-    {
-        OC_LOG(ERROR, TAG, "CreateObject result in null for json");
-        return NULL;
-    }
-
-    cJSON *format;
-    char *jsonResponse;
     LEDResource *currLEDResource = &LED;
 
-    OC_LOG(INFO, TAG, "Entering constructJsonResponse");
+    OC_LOG(INFO, TAG, "Entering constructResponse");
 
     if (ehRequest->resource == gLedInstance[0].handle)
     {
@@ -78,63 +69,60 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
-
-        if(!putJson)
+        if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
         {
-            OC_LOG(ERROR, TAG, "CreateObject result in null for putJson");
-            cJSON_Delete(json);
-            return NULL;
+            OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+            return nullptr;
         }
 
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring ,
-                "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
-        cJSON_Delete(putJson);
+        OCRepPayload *putPayload = reinterpret_cast<OCRepPayload*> (ehRequest->payload);
+
+        int64_t power;
+        bool state;
+
+        if (OCRepPayloadGetPropBool(putPayload, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+        if (OCRepPayloadGetPropInt (putPayload, "power", &power))
+        {
+            currLEDResource->power = power;
+        }
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    format = cJSON_CreateObject();
+    OCRepPayload *response = OCRepPayloadCreate();
 
-    if(!format)
+    if (!response)
     {
-        OC_LOG(ERROR, TAG, "CreateObject result in null for format");
-        cJSON_Delete(json);
-        return NULL;
+        OC_LOG_V(ERROR, TAG, "Memory allocation for response payload failed.");
     }
 
-    cJSON_AddItemToObject(json, "rep", format);
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
+    OCRepPayloadSetUri (response, gResourceUri);
+    OCRepPayloadSetPropBool(response, "state", currLEDResource->state);
+    OCRepPayloadSetPropInt(response, "power", currLEDResource->power);
 
-    OC_LOG(INFO, TAG, "Before constructJsonResponse print");
-    jsonResponse = cJSON_Print(json);
-    OC_LOG(INFO, TAG, "Before constructJsonResponse delete");
-    cJSON_Delete(json);
-
-    OC_LOG(INFO, TAG, "Before constructJsonResponse return");
-    return jsonResponse;
+    return response;
 }
 
-void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
+void ProcessGetPutRequest (OCEntityHandlerRequest *ehRequest)
 {
-    OC_LOG(INFO, TAG, "Entering ProcessGetRequest");
-    char *getResp = constructJsonResponse(ehRequest);
+    OC_LOG(INFO, TAG, "Entering ProcessGetPutRequest");
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
 
     if(!getResp)
     {
-        OC_LOG(ERROR, TAG, "Failed to constructJsonResponse");
+        OC_LOG(ERROR, TAG, "Failed to construct response");
         return;
     }
-    OC_LOG(INFO, TAG, "After constructJsonResponse");
+
     OCEntityHandlerResponse response;
 
     // Format the response.  Note this requires some info about the request
     response.requestHandle = ehRequest->requestHandle;
     response.resourceHandle = ehRequest->resource;
     response.ehResult = OC_EH_OK;
-    response.payload = getResp;
-    response.payloadSize = strlen(getResp) + 1;
+    response.payload = reinterpret_cast<OCPayload*> (getResp);
     response.numSendVendorSpecificHeaderOptions = 0;
     memset(response.sendVendorSpecificHeaderOptions,
             0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -154,46 +142,37 @@ void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
 OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
 {
     OC_LOG(INFO, TAG, "Copying received request for slow response");
-    OCEntityHandlerRequest *request =
-            (OCEntityHandlerRequest *)OCMalloc(sizeof(OCEntityHandlerRequest));
-    if (request)
+
+    OCEntityHandlerRequest *copyOfRequest =
+            (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
+
+    if (copyOfRequest)
     {
         // Do shallow copy
-        memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
-        // Do deep copy of query
-        request->query =
-                (char * )OCMalloc(strlen((const char *)entityHandlerRequest->query) + 1);
-        if (request->query)
-        {
-            strcpy((char *)request->query, (const char *)entityHandlerRequest->query);
+        memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
 
-            // Copy the request payload
-            request->reqJSONPayload = (char * )OCMalloc(
-                            strlen((const char *)entityHandlerRequest->reqJSONPayload) + 1);
-            if (request->reqJSONPayload)
-            {
-                strcpy((char *)request->reqJSONPayload,
-                        (const char *)entityHandlerRequest->reqJSONPayload);
 
-                // Ignore vendor specific header options for example
-                request->numRcvdVendorSpecificHeaderOptions = 0;
-                request->rcvdVendorSpecificHeaderOptions = NULL;
-            }
-            else
-            {
-                OCFree(request->query);
-                OCFree(request);
-                request = NULL;
-            }
+        if (copyOfRequest->query)
+        {
+            // Do deep copy of query
+            copyOfRequest->query = (char *) OICMalloc(
+                    strlen((const char *)entityHandlerRequest->query) + 1);
+
+            strcpy((char *)copyOfRequest->query, (const char *)entityHandlerRequest->query);
         }
-        else
+
+        if (entityHandlerRequest->payload)
         {
-            OCFree(request);
-            request = NULL;
+            copyOfRequest->payload = reinterpret_cast<OCPayload*>
+                    (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
         }
+
+        // Ignore vendor specific header options for example
+        copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+        copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
     }
 
-    if (request)
+    if (copyOfRequest)
     {
         OC_LOG(INFO, TAG, "Copied client request");
     }
@@ -201,17 +180,17 @@ OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest
     {
         OC_LOG(ERROR, TAG, "Error copying client request");
     }
-    return request;
+    return copyOfRequest;
 }
 
-OCEntityHandlerResult
-OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
     OCEntityHandlerRequest *request = NULL;
 
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
@@ -219,10 +198,11 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         {
             OC_LOG_V (INFO, TAG, "request query %s from client",
                                         entityHandlerRequest->query);
-            OC_LOG_V (INFO, TAG, "request payload %s from client",
-                                        entityHandlerRequest->reqJSONPayload);
+            OC_LOG_PAYLOAD (INFO, TAG, entityHandlerRequest->payload);
+
             // Make deep copy of received request and queue it for slow processing
             request = CopyRequest(entityHandlerRequest);
+
             if (request)
             {
 
@@ -277,7 +257,12 @@ void AlarmHandler(int sig)
         if (entityHandlerRequest->method == OC_REST_GET)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ProcessGetRequest (entityHandlerRequest);
+            ProcessGetPutRequest (entityHandlerRequest);
+        }
+        else if (entityHandlerRequest->method == OC_REST_PUT)
+        {
+            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+            ProcessGetPutRequest (entityHandlerRequest);
         }
         else
         {
@@ -285,9 +270,9 @@ void AlarmHandler(int sig)
                     entityHandlerRequest->method);
         }
         // Free the request
-        OCFree(entityHandlerRequest->query);
-        OCFree(entityHandlerRequest->reqJSONPayload);
-        OCFree(entityHandlerRequest);
+        OICFree(entityHandlerRequest->query);
+        OCPayloadDestroy(entityHandlerRequest->payload);
+        OICFree(entityHandlerRequest);
 
         // If there are more requests in list, re-arm the alarm signal
         if (gRequestList.empty())
@@ -307,10 +292,8 @@ int main(int argc, char* argv[])
         return 0;
     }
 
-    /*
-     * Declare and create the example resource: LED
-     */
-    createLEDResource(gResourceUri, &LED, false, 0);
+    // Declare and create the example resource: LED
+    createLEDResource(gResourceUri, &LED, false, 42);
 
     // Initialize slow response alarm
     signal(SIGALRM, AlarmHandler);
@@ -326,7 +309,6 @@ int main(int argc, char* argv[])
             OC_LOG(ERROR, TAG, "OCStack process error");
             return 0;
         }
-
         sleep(2);
     }
 
@@ -337,9 +319,9 @@ int main(int argc, char* argv[])
     {
         for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
         {
-            OCFree((*iter)->query);
-            OCFree((*iter)->reqJSONPayload);
-            OCFree(*iter);
+            OICFree((*iter)->query);
+            OCPayloadDestroy((*iter)->payload);
+            OICFree(*iter);
         }
         gRequestList.clear();
     }
@@ -367,6 +349,7 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState,
             OC_RSRVD_INTERFACE_DEFAULT,
             uri,
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
 
index 71e298f..12bc216 100644 (file)
@@ -63,12 +63,20 @@ samples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 ######################################################################
 # Source files and Targets
 ######################################################################
+
 ocserverbasicops = samples_env.Program('ocserverbasicops', ['common.cpp', 'ocserverbasicops.cpp'])
 occlientbasicops = samples_env.Program('occlientbasicops', ['common.cpp', 'occlientbasicops.cpp'])
-gen_sec_bin = samples_env.Program('gen_sec_bin', ['gen_sec_bin.cpp'])
-
 
 Alias("samples", [ocserverbasicops, occlientbasicops])
 
 env.AppendTarget('samples')
 
+src_dir = samples_env.get('SRC_DIR')
+sec_samples_src_dir = src_dir + '/resource/csdk/stack/samples/linux/secure/'
+sec_samples_build_dir = env.get('BUILD_DIR') +'/resource/csdk/stack/samples/linux/secure'
+
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+    sec_samples_src_dir + 'oic_svr_db_server.json'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+    sec_samples_src_dir + 'oic_svr_db_client.json'))
+
index 7c04494..6eb7521 100644 (file)
@@ -19,7 +19,7 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 #include "common.h"
 
-#include "ocsecurity.h"
+#include "ocstack.h"
 #include "logger.h"
 #include <stdio.h>
 #include <stdlib.h>
 
 #define TAG "sample-common"
 
-OCStackResult SetCredentials(const char* filename) {
-
-    FILE *fp = NULL;
-    uint8_t *data = NULL;
-    struct stat st;
-    OCStackResult ret = OC_STACK_ERROR;
-
-    fp = fopen(filename, "rb");
-    if (fp)
-    {
-        if (stat(filename, &st) == 0)
-        {
-            data = (uint8_t*)malloc(st.st_size);
-            if (data)
-            {
-                if (fread(data, 1, st.st_size, fp) == (size_t)st.st_size)
-                {
-                    // Provide credentials to OC Stack
-                    ret = OCSecSetConfigData((OCSecConfigData *)data,
-                            st.st_size);
-                }
-                else
-                {
-                    OC_LOG_V(FATAL, TAG, "Error in reading file %s", filename);
-                }
-            }
-        }
-        fclose(fp);
-    }
-    else
-    {
-        OC_LOG_V(FATAL, TAG, "Unable to open %s file", filename);
-    }
-
-    free(data);
-
-    return ret;
-}
-
 const char *getResult(OCStackResult result) {
     switch (result) {
     case OC_STACK_OK:
@@ -103,6 +64,8 @@ const char *getResult(OCStackResult result) {
         return "OC_STACK_SLOW_RESOURCE";
     case OC_STACK_NO_OBSERVERS:
         return "OC_STACK_NO_OBSERVERS";
+    case OC_STACK_UNAUTHORIZED_REQ:
+        return "OC_STACK_UNAUTHORIZED_REQ";
     #ifdef WITH_PRESENCE
     case OC_STACK_PRESENCE_STOPPED:
         return "OC_STACK_PRESENCE_STOPPED";
index ac73c1d..ea899c3 100644 (file)
@@ -26,9 +26,6 @@
 /* Get the result in string format. */
 const char *getResult(OCStackResult result);
 
-/* Read the credentials from persistent storage and provide to OC stack. */
-OCStackResult SetCredentials(const char* filename);
-
 /* Removes the new line character from a NULL terminated C string. */
 void StripNewLineChar(char* str);
 
diff --git a/resource/csdk/stack/samples/linux/secure/gen_sec_bin.cpp b/resource/csdk/stack/samples/linux/secure/gen_sec_bin.cpp
deleted file mode 100644 (file)
index c30aada..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "ocsecurityconfig.h"
-#include "logger.h"
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#define TAG "gen_sec_bin"
-
-//scratch buffer
-const int WORK_BUF_LEN = 512;
-
-const char SERVER_CRED_FILE[] = "server_cred.bin";
-const char CLIENT_CRED_FILE[] = "client_cred.bin";
-
-static void printStruct(const char * device, OCSecConfigData* s)
-{
-    if (device && s)
-    {
-        OC_LOG(INFO, TAG, device);
-        OC_LOG_V(INFO, TAG, "Version - %d", s->version);
-        OC_LOG_V(INFO, TAG, "Number of blobs - %d", s->numBlob);
-
-        OCSecBlob* osb = (OCSecBlob*)(s->blob);
-        OC_LOG_V(INFO, TAG, "Blob Type - %d", osb->type);
-        OC_LOG_V(INFO, TAG, "Blob Data Length - %d", osb->len);
-
-        OCDtlsPskCredsBlob* odpcb = (OCDtlsPskCredsBlob*)(osb->val);
-        OC_LOG(INFO, TAG, "My Identity :");
-        OC_LOG_BUFFER(INFO, TAG, odpcb->identity, DTLS_PSK_ID_LEN);
-
-        OC_LOG_V(INFO, TAG, "Number of trusted Peers  - %d", odpcb->num);
-        OC_LOG(INFO, TAG, "Peer Identity :");
-        OC_LOG_BUFFER(INFO, TAG, odpcb->creds[0].id, DTLS_PSK_ID_LEN);
-        OC_LOG(INFO, TAG, "Peer Psk :");
-        OC_LOG_BUFFER(INFO, TAG, odpcb->creds[0].psk, DTLS_PSK_PSK_LEN);
-    }
-}
-
-
-static int SizeOfOCConfigData (OCSecConfigData *oscd)
-{
-    int len = 0;
-    if(oscd)
-    {
-        int i = 0;
-        OCSecBlob * osb;
-        len = len + sizeof(OCSecConfigData) - sizeof(uint8_t);
-
-        //go to first blob
-        osb = (OCSecBlob*)(oscd->blob);
-        for( i =0; i < oscd->numBlob; i++)
-        {
-            len += (sizeof(OCSecBlob) - sizeof(uint8_t) + osb->len);
-            osb = config_data_next_blob(osb);
-        }
-    }
-    return len;
-}
-
-int main()
-{
-    unsigned char buf_s[WORK_BUF_LEN];
-    unsigned char buf_c[WORK_BUF_LEN];
-
-    srand(time(NULL));
-
-    OCSecConfigData * oscd_s = (OCSecConfigData*)buf_s;
-    OCSecConfigData * oscd_c = (OCSecConfigData*)buf_c;
-    oscd_s->version = oscd_c->version = OCSecConfigVer_CurrentVersion;
-
-    //Only storing 1 blob of type 'OC_BLOB_TYPE_PSK'
-    oscd_s->numBlob = oscd_c->numBlob = 1;
-
-    OCSecBlob * osb_s = (OCSecBlob*)oscd_s->blob;
-    OCSecBlob * osb_c = (OCSecBlob*)oscd_c->blob;
-    osb_s->type = osb_c->type = OC_BLOB_TYPE_PSK;
-    //length of this blob will be the length to contain PSK credentials
-    // for '1' peer device
-    osb_s->len = osb_c->len = sizeof(OCDtlsPskCredsBlob);
-
-    OCDtlsPskCredsBlob * odpcb_s = (OCDtlsPskCredsBlob*)(osb_s->val);
-    OCDtlsPskCredsBlob * odpcb_c = (OCDtlsPskCredsBlob*)(osb_c->val);
-
-    odpcb_s->num = odpcb_c->num = 1;
-
-    for(int i = 0; i < DTLS_PSK_ID_LEN; i++)
-    {
-        odpcb_c->creds[0].id[i] = odpcb_s->identity[i] = rand() % (2^8);
-
-        odpcb_s->creds[0].id[i] = odpcb_c->identity[i] = rand() % (2^8);
-
-        odpcb_c->creds[0].psk[i] = odpcb_s->creds[0].psk[i] = rand() % (2^8);
-    }
-
-    // Print Credentials
-    printStruct("Server", oscd_s);
-    printStruct("Client", oscd_c);
-
-    // Write to files
-    FILE* fps, *fpc;
-    if ((fps = (FILE*) fopen("server_cred.bin", "wb")) != NULL)
-    {
-        fwrite(oscd_s, SizeOfOCConfigData(oscd_s), 1, fps);
-        fclose(fps);
-    }
-
-
-    if ((fpc = (FILE*) fopen("client_cred.bin", "wb")) != NULL)
-    {
-        fwrite(oscd_c, SizeOfOCConfigData(oscd_c), 1, fpc);
-        fclose(fpc);
-    }
-
-    struct stat st;
-    memset(buf_s, 0, sizeof(buf_s));
-    memset(buf_c, 0, sizeof(buf_c));
-    // Read from files; print and verify manually
-    if ((fps = (FILE*) fopen(SERVER_CRED_FILE, "rb")) != NULL)
-    {
-        stat(SERVER_CRED_FILE, &st);
-        if ((sizeof(buf_s) < (unsigned int)st.st_size) ||
-            (fread(buf_s, 1, st.st_size, fps) != (unsigned int)st.st_size))
-        {
-            OC_LOG(INFO, TAG, PCF("Reading from the file failed."));
-        }
-        fclose(fps);
-    }
-
-
-    if ((fpc = (FILE*) fopen(CLIENT_CRED_FILE, "rb")) != NULL)
-    {
-        stat(CLIENT_CRED_FILE, &st);
-        if ((sizeof(buf_c) < (unsigned int)st.st_size) ||
-            (fread(buf_c, 1, st.st_size, fpc) != (unsigned int)st.st_size))
-        {
-            OC_LOG(INFO, TAG, PCF("Reading from the file failed."));
-        }
-        fclose(fpc);
-    }
-
-    printf("\n\n");
-    OC_LOG(INFO, TAG, PCF("Reading from file and printing again to verify manually"));
-    printStruct("Server", (OCSecConfigData*)buf_s);
-    printStruct("Client", (OCSecConfigData*)buf_c);
-
-    return 1;
-}
-
-
index 5f8d7b6..dd84fc3 100644 (file)
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientbasicops.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "common.h"
 
 #define TAG "occlientbasicops"
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
+static int CONN_TYPE = 0;
 
-static int IPV4_ADDR_SIZE = 16;
-static char UNICAST_DISCOVERY_QUERY[] = "coap://%s:6298/oc/core";
-static char MULTICAST_DISCOVERY_QUERY[] = "/oc/core";
+static int IPV4_ADDR_SIZE = 24;
+static char UNICAST_DISCOVERY_QUERY[] = "coap://%s/oic/res";
+static char MULTICAST_DISCOVERY_QUERY[] = "/oic/res";
+OCConnectivityType discoveryReqConnType = CT_ADAPTER_IP;
 
-static std::string putPayload = "{\"state\":\"off\",\"power\":10}";
 static std::string coapServerIP;
 static std::string coapServerPort;
 static std::string coapServerResource;
@@ -47,10 +48,10 @@ static int coapSecureResource;
 static OCConnectivityType ocConnType;
 
 
-//File containing Client's Identity and the PSK credentials
+//Secure Virtual Resource database for Iotivity Client application
+//It contains Client's Identity and the PSK credentials
 //of other devices which the client trusts
-//This can be generated using 'gen_sec_bin' application
-static char CRED_FILE[] = "client_cred.bin";
+static char CRED_FILE[] = "oic_svr_db_client.json";
 
 
 int gQuitFlag = 0;
@@ -64,14 +65,32 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
-    OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3>");
+    OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3> -c <0|1>");
     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
     OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
     OC_LOG(INFO, TAG, "-t 2 : Discover Resources and"
             " Initiate Nonconfirmable Get/Put/Post Requests");
     OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate Confirmable Get/Put/Post Requests");
+    OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
+    OC_LOG(INFO, TAG, "-c 1 : IPv4 Connectivity Type");
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -86,7 +105,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-            (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload.c_str() : NULL,
+            (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
             ocConnType, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -104,7 +123,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Put Response", clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -116,8 +136,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientRespons
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Post Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -130,8 +150,8 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
         OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Get Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -140,40 +160,37 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         OCClientResponse * clientResponse)
 {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
-
     OC_LOG(INFO, TAG, "Callback Context for DISCOVER query recvd successfully");
 
     if (clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
-
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-
         OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
-                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
-                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
-
-        ocConnType = clientResponse->connType;
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
 
-        if (parseClientResponse(clientResponse) != -1)
+        if (clientResponse->result == OC_STACK_OK)
         {
-            switch(TEST_CASE)
+            OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+            ocConnType = clientResponse->connType;
+
+            if (parseClientResponse(clientResponse) != -1)
             {
-                case TEST_NON_CON_OP:
-                    InitGetRequest(OC_LOW_QOS);
-                    InitPutRequest(OC_LOW_QOS);
-                    //InitPostRequest(OC_LOW_QOS);
-                    break;
-                case TEST_CON_OP:
-                    InitGetRequest(OC_HIGH_QOS);
-                    InitPutRequest(OC_HIGH_QOS);
-                    //InitPostRequest(OC_HIGH_QOS);
-                    break;
+                switch(TEST_CASE)
+                {
+                    case TEST_NON_CON_OP:
+                        InitGetRequest(OC_LOW_QOS);
+                        InitPutRequest(OC_LOW_QOS);
+                        //InitPostRequest(OC_LOW_QOS);
+                        break;
+                    case TEST_CON_OP:
+                        InitGetRequest(OC_HIGH_QOS);
+                        InitPutRequest(OC_HIGH_QOS);
+                        //InitPostRequest(OC_HIGH_QOS);
+                        break;
+                }
             }
         }
     }
@@ -239,14 +256,15 @@ int InitGetRequest(OCQualityOfService qos)
 int InitDiscovery()
 {
     OCStackResult ret;
+    OCMethod method;
     OCCallbackData cbData;
     char szQueryUri[MAX_URI_LENGTH] = { 0 };
-    OCConnectivityType discoveryReqConnType;
 
     if (UNICAST_DISCOVERY)
     {
         char ipv4addr[IPV4_ADDR_SIZE];
-        printf("Enter IPv4 address of the Server hosting secure resource (Ex: 11.12.13.14)\n");
+        OC_LOG(INFO, TAG, "Enter IPv4 address:port of the Server hosting secure resource"\
+                "(Ex: 11.12.13.14:1234)\n");
         if (fgets(ipv4addr, IPV4_ADDR_SIZE, stdin))
         {
             //Strip newline char from ipv4addr
@@ -258,13 +276,14 @@ int InitDiscovery()
             OC_LOG(ERROR, TAG, "!! Bad input for IPV4 address. !!");
             return OC_STACK_INVALID_PARAM;
         }
-        discoveryReqConnType = OC_IPV4;
+        method = OC_REST_GET;
     }
     else
     {
         //Send discovery request on Wifi and Ethernet interface
-        discoveryReqConnType = OC_ALL;
+        discoveryReqConnType = CT_DEFAULT;
         strcpy(szQueryUri, MULTICAST_DISCOVERY_QUERY);
+        method = OC_REST_DISCOVER;
     }
 
     cbData.cb = discoveryReqCB;
@@ -276,7 +295,7 @@ int InitDiscovery()
         (UNICAST_DISCOVERY) ? "Unicast" : "Multicast",
         szQueryUri);
 
-    ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0,
+    ret = OCDoResource(NULL, method, szQueryUri, 0, 0,
             discoveryReqConnType, OC_LOW_QOS,
             &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
@@ -286,12 +305,18 @@ int InitDiscovery()
     return ret;
 }
 
+FILE* client_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(CRED_FILE, mode);
+}
+
 int main(int argc, char* argv[])
 {
     int opt;
     struct timespec timeout;
 
-    while ((opt = getopt(argc, argv, "u:t:")) != -1)
+    while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
     {
         switch(opt)
         {
@@ -301,6 +326,9 @@ int main(int argc, char* argv[])
             case 't':
                 TEST_CASE = atoi(optarg);
                 break;
+            case 'c':
+                CONN_TYPE = atoi(optarg);
+                break;
             default:
                 PrintUsage();
                 return -1;
@@ -308,26 +336,38 @@ int main(int argc, char* argv[])
     }
 
     if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
-            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) )
+            (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS)||
+            (CONN_TYPE < CT_ADAPTER_DEFAULT || CONN_TYPE >= MAX_CT))
     {
         PrintUsage();
         return -1;
     }
 
-    /* Initialize OCStack*/
-    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
+
+    if(CONN_TYPE == CT_ADAPTER_DEFAULT || CONN_TYPE ==  CT_IP)
     {
-        OC_LOG(ERROR, TAG, "OCStack init error");
-        return 0;
+        discoveryReqConnType = CT_DEFAULT;
     }
+    else
+    {
+        OC_LOG(INFO, TAG, "Using Default Connectivity type");
+        PrintUsage();
+    }
+
+
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {};
+    ps.open = client_fopen;
+    ps.read = fread;
+    ps.write = fwrite;
+    ps.close = fclose;
+    ps.unlink = unlink;
+    OCRegisterPersistentStorageHandler(&ps);
 
-    /*
-     * Read DTLS PSK credentials from persistent storage and
-     * set in the OC stack.
-     */
-    if (SetCredentials(CRED_FILE) != OC_STACK_OK)
+    /* Initialize OCStack*/
+    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
     {
-        OC_LOG(ERROR, TAG, "SetCredentials failed");
+        OC_LOG(ERROR, TAG, "OCStack init error");
         return 0;
     }
 
@@ -359,36 +399,17 @@ int main(int argc, char* argv[])
     return 0;
 }
 
-std::string getIPAddrTBServer(OCClientResponse * clientResponse)
-{
-    if(!clientResponse) return "";
-    if(!clientResponse->addr) return "";
-    uint8_t a, b, c, d = 0;
-    if(0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) ) return "";
-
-    char ipaddr[16] = {'\0'};
-    // ostringstream not working correctly here, hence snprintf
-    snprintf(ipaddr,  sizeof(ipaddr), "%d.%d.%d.%d", a,b,c,d);
-    return std::string (ipaddr);
-}
-
-
 std::string getPortTBServer(OCClientResponse * clientResponse)
 {
     if(!clientResponse) return "";
-    if(!clientResponse->addr) return "";
-    uint16_t p = 0;
-    if(0 != OCDevAddrToPort(clientResponse->addr, &p) ) return "";
     std::ostringstream ss;
-    ss << p;
+    ss << clientResponse->devAddr.port;
     return ss.str();
 }
 
 int parseClientResponse(OCClientResponse * clientResponse)
 {
-    int port = -1;
-    cJSON * root = NULL;
-    cJSON * oc = NULL;
+    OCResourcePayload* res = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
 
     // Initialize all global variables
     coapServerResource.clear();
@@ -396,66 +417,40 @@ int parseClientResponse(OCClientResponse * clientResponse)
     coapServerIP.clear();
     coapSecureResource = 0;
 
-    root = cJSON_Parse((char *)(clientResponse->resJSONPayload));
-    if (!root)
+    while(res)
     {
-        return -1;
-    }
+        coapServerResource.assign(res->uri);
+        OC_LOG_V(INFO, TAG, "Uri -- %s", coapServerResource.c_str());
 
-    oc = cJSON_GetObjectItem(root,"oc");
-    if (!oc)
-    {
-        return -1;
-    }
-
-    if (oc->type == cJSON_Array)
-    {
-        if (cJSON_GetArraySize(oc) > 0)
+        if(res->secure)
         {
-            cJSON * resource = cJSON_GetArrayItem(oc, 0);
-            if (cJSON_GetObjectItem(resource, "href"))
-            {
-                coapServerResource.assign(cJSON_GetObjectItem(resource, "href")->valuestring);
-            }
-            else
-            {
-                coapServerResource = "";
-            }
-            OC_LOG_V(INFO, TAG, "Uri -- %s", coapServerResource.c_str());
+            coapSecureResource = 1;
+        }
 
-            cJSON * prop = cJSON_GetObjectItem(resource,"prop");
-            if (prop)
-            {
-                // If this is a secure resource, the info about the port at which the
-                // resource is hosted on server is embedded inside discovery JSON response
-                if (cJSON_GetObjectItem(prop, "sec"))
-                {
-                    if ((cJSON_GetObjectItem(prop, "sec")->valueint) == 1)
-                    {
-                        coapSecureResource = 1;
-                    }
-                }
-                OC_LOG_V(INFO, TAG, "Secure -- %s", coapSecureResource == 1 ? "YES" : "NO");
-                if (cJSON_GetObjectItem(prop, "port"))
-                {
-                    port = cJSON_GetObjectItem(prop, "port")->valueint;
-                    OC_LOG_V(INFO, TAG, "Hosting Server Port (embedded inside JSON) -- %u", port);
+        OC_LOG_V(INFO, TAG, "Secure -- %s", coapSecureResource == 1 ? "YES" : "NO");
 
-                    std::ostringstream ss;
-                    ss << port;
-                    coapServerPort = ss.str();
-                }
-            }
+        std::ostringstream ss;
+        ss << res->port;
+        coapServerPort = ss.str();
+        std::cout<<"PORT: "<<coapServerPort;
+
+        // If we discovered a secure resource, exit from here
+        if (coapSecureResource)
+        {
+            break;
         }
+
+        res = res->next;
     }
-    cJSON_Delete(root);
 
-    coapServerIP = getIPAddrTBServer(clientResponse);
-    if (port == -1)
+    coapServerIP = clientResponse->devAddr.addr;
+
+    if(coapServerPort.length() == 0 || coapServerPort == "0")
     {
         coapServerPort = getPortTBServer(clientResponse);
         OC_LOG_V(INFO, TAG, "Hosting Server Port -- %s", coapServerPort.c_str());
     }
+
     return 0;
 }
 
index 8dee2f2..3fed75a 100644 (file)
@@ -37,6 +37,16 @@ typedef enum {
     MAX_TESTS
 } CLIENT_TEST;
 
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+    CT_ADAPTER_DEFAULT = 0,
+    CT_IP,
+    MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
 //-----------------------------------------------------------------------------
 // Function prototype
 //-----------------------------------------------------------------------------
index 440b667..6e212fe 100644 (file)
@@ -26,7 +26,7 @@
 #include <pthread.h>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "ocserverbasicops.h"
 #include "common.h"
 
@@ -41,77 +41,81 @@ static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
 
 char *gResourceUri= (char *)"/a/led";
 
-//File containing Server's Identity and the PSK credentials
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
 //of other devices which the server trusts
-//This can be generated using 'gen_sec_bin' application
-static char CRED_FILE[] = "server_cred.bin";
+static char CRED_FILE[] = "oic_svr_db_server.json";
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return nullptr;
+    }
+
+    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
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-    cJSON *format;
-    char *jsonResponse;
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+        return nullptr;
+    }
+
+    OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
     LEDResource *currLEDResource = &LED;
 
     if (ehRequest->resource == gLedInstance[0].handle)
     {
         currLEDResource = &gLedInstance[0];
-        gResourceUri = (char *) "a/led/0";
+        gResourceUri = (char *) "/a/led/0";
     }
     else if (ehRequest->resource == gLedInstance[1].handle)
     {
         currLEDResource = &gLedInstance[1];
-        gResourceUri = (char *) "a/led/1";
+        gResourceUri = (char *) "/a/led/1";
     }
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-        if(!putJson)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
-            return NULL;
+            currLEDResource->power =pow;
         }
 
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring ,
-                "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
-        cJSON_Delete(putJson);
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
-
-    jsonResponse = cJSON_Print(json);
-    cJSON_Delete(json);
-    return jsonResponse;
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
 }
 
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
 
-    char *getResp = constructJsonResponse(ehRequest);
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
     if(getResp)
     {
-        if (maxPayloadSize > strlen (getResp))
-        {
-            strcpy(payload, getResp);
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
+        *payload = getResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -122,27 +126,16 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
 
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(putResp)
     {
-        if (maxPayloadSize > strlen (putResp))
-        {
-            strcpy(payload, putResp);
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(putResp);
+        *payload = putResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -153,12 +146,10 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
 {
-    char *respPLPost_led = NULL;
-    cJSON *json;
-    cJSON *format;
-    OCEntityHandlerResult ehResult;
+    OCRepPayload *respPLPost_led = nullptr;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -180,11 +171,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             int newLedUriLength = strlen(newLedUri);
             snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
 
-            json = cJSON_CreateObject();
-
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-            cJSON_AddStringToObject(format, "createduri", (char *) newLedUri);
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
 
             if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
             {
@@ -192,14 +181,13 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLedInstance[gCurrLedInstance].state = 0;
                 gLedInstance[gCurrLedInstance].power = 0;
                 gCurrLedInstance++;
-                respPLPost_led = cJSON_Print(json);
+                strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+                ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
-            respPLPost_led = constructJsonResponse(ehRequest);
+            respPLPost_led = constructResponse(ehRequest);
         }
     }
     else
@@ -210,43 +198,49 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             {
                 if (i == 0)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_led != NULL) && (maxPayloadSize > strlen (respPLPost_led)))
+    if (respPLPost_led != NULL)
     {
-        strcpy(payload, respPLPost_led);
+        *payload = respPLPost_led;
         ehResult = OC_EH_OK;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG_V (INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_led);
-
     return ehResult;
 }
 
 OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam)
 {
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
 
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -256,17 +250,17 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             if (OC_REST_GET == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload));
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_PUT == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-                ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload));
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_POST == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-                ehResult = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload));
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
             }
             else
             {
@@ -275,14 +269,13 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                 ehResult = OC_EH_ERROR;
             }
 
-            if (ehResult == OC_EH_OK)
+            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 = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
                 memset(response.resourceUri, 0, sizeof(response.resourceUri));
@@ -298,6 +291,8 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             }
         }
     }
+
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
@@ -310,12 +305,27 @@ void handleSigInt(int signum)
     }
 }
 
+FILE* server_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(CRED_FILE, mode);
+}
+
 int main(int argc, char* argv[])
 {
     struct timespec timeout;
 
     OC_LOG(DEBUG, TAG, "OCServer is starting...");
 
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {};
+    ps.open = server_fopen;
+    ps.read = fread;
+    ps.write = fwrite;
+    ps.close = fclose;
+    ps.unlink = unlink;
+    OCRegisterPersistentStorageHandler(&ps);
+
     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
     {
         OC_LOG(ERROR, TAG, "OCStack init error");
@@ -323,15 +333,6 @@ int main(int argc, char* argv[])
     }
 
     /*
-     * Read DTLS PSK credentials from persistent storage and
-     * set in the OC stack.
-     */
-    if (SetCredentials(CRED_FILE) != OC_STACK_OK)
-    {
-        OC_LOG(ERROR, TAG, "SetCredentials failed");
-        return 0;
-    }
-    /*
      * Declare and create the example resource: LED
      */
     createLEDResource(gResourceUri, &LED, false, 0);
@@ -377,6 +378,7 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState,
             OC_RSRVD_INTERFACE_DEFAULT,
             uri,
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
     OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
 
index 4e1f7eb..f8b72db 100644 (file)
@@ -49,20 +49,18 @@ typedef struct LEDRESOURCE{
 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
 
 /* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* Following methods process the PUT, GET, POST
  * requests
  */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         size_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         size_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                                          char *payload,
-                                          size_t maxPayloadSize);
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
 
 //-----------------------------------------------------------------------------
 // Callback functions
diff --git a/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json b/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json
new file mode 100644 (file)
index 0000000..17dc43f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MjIyMjIyMjIyMjIyMjIyMg==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MTExMTExMTExMTExMTExMQ==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
diff --git a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json
new file mode 100644 (file)
index 0000000..1f8ad5c
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        },
+        {
+            "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+            "rsrc": ["/a/led"],
+            "perms": 6,
+            "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MTExMTExMTExMTExMTExMQ==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index c2b324f..9ea19ee 100644 (file)
@@ -22,7 +22,7 @@
 #include "occlientcb.h"
 #include "utlist.h"
 #include "logger.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
 #include <string.h>
 
 #ifdef WITH_ARDUINO
@@ -45,7 +45,8 @@ OCStackResult
 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
              CAToken_t token, uint8_t tokenLength,
              OCDoHandle *handle, OCMethod method,
-             char * requestUri, char * resourceTypeName, OCConnectivityType conType, uint32_t ttl)
+             OCDevAddr *devAddr, char * requestUri,
+             char * resourceTypeName, uint32_t ttl)
 {
     if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
     {
@@ -63,7 +64,7 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
 
     if(!cbNode)// If it does not already exist, create new node.
     {
-        cbNode = (ClientCB*) OCMalloc(sizeof(ClientCB));
+        cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
         if(!cbNode)
         {
             *clientCB = NULL;
@@ -71,6 +72,8 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
         }
         else
         {
+            OC_LOG(INFO, TAG, PCF("Adding client callback with token"));
+            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
             cbNode->callBack = cbData->cb;
             cbNode->context = cbData->context;
             cbNode->deleteCallback = cbData->cd;
@@ -96,8 +99,9 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             {
                 cbNode->TTL = ttl;
             }
-            cbNode->requestUri = requestUri;
-            cbNode->conType = conType;
+            cbNode->requestUri = requestUri;    // I own it now
+            cbNode->devAddr = devAddr;          // I own it now
+            OC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
             LL_APPEND(cbList, cbNode);
             *clientCB = cbNode;
         }
@@ -113,9 +117,10 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             cbData->cd(cbData->context);
         }
 
-        OCFree(token);
-        OCFree(*handle);
-        OCFree(requestUri);
+        OICFree(token);
+        OICFree(*handle);
+        OICFree(requestUri);
+        OICFree(devAddr);
         *handle = cbNode->handle;
     }
 
@@ -124,13 +129,14 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
     {
         // Amend the found or created node by adding a new resourceType to it.
         return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
+        // I own resourceTypName now.
     }
     else
     {
-        OCFree(resourceTypeName);
+        OICFree(resourceTypeName);
     }
     #else
-    OCFree(resourceTypeName);
+    OICFree(resourceTypeName);
     #endif
 
     return OC_STACK_OK;
@@ -144,11 +150,13 @@ void DeleteClientCB(ClientCB * cbNode)
     if(cbNode)
     {
         LL_DELETE(cbList, cbNode);
-        OC_LOG(INFO, TAG, PCF("deleting tokens"));
+        OC_LOG (INFO, TAG, PCF("Deleting token"));
         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
         CADestroyToken (cbNode->token);
-        OCFree(cbNode->handle);
-        OCFree(cbNode->requestUri);
+        OICFree(cbNode->devAddr);
+        OICFree(cbNode->handle);
+        OC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
+        OICFree(cbNode->requestUri);
         if(cbNode->deleteCallback)
         {
             cbNode->deleteCallback(cbNode->context);
@@ -157,8 +165,8 @@ void DeleteClientCB(ClientCB * cbNode)
         #ifdef WITH_PRESENCE
         if(cbNode->presence)
         {
-            OCFree(cbNode->presence->timeOut);
-            OCFree(cbNode->presence);
+            OICFree(cbNode->presence->timeOut);
+            OICFree(cbNode->presence);
         }
         if(cbNode->method == OC_REST_PRESENCE)
         {
@@ -167,13 +175,13 @@ void DeleteClientCB(ClientCB * cbNode)
             while(pointer)
             {
                 next = pointer->next;
-                OCFree(pointer->resourcetypename);
-                OCFree(pointer);
+                OICFree(pointer->resourcetypename);
+                OICFree(pointer);
                 pointer = next;
             }
         }
         #endif // WITH_PRESENCE
-        OCFree(cbNode);
+        OICFree(cbNode);
         cbNode = NULL;
     }
 }
@@ -213,10 +221,11 @@ ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
 
     if(token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
     {
+        OC_LOG (INFO, TAG, PCF ("Looking for token"));
+        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+        OC_LOG(INFO, TAG, PCF("\tFound in callback list"));
         LL_FOREACH(cbList, out)
         {
-            OC_LOG(INFO, TAG, PCF("comparing tokens"));
-            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
 
             if(memcmp(out->token, token, tokenLength) == 0)
@@ -239,8 +248,10 @@ ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
     }
     else if(requestUri)
     {
+        OC_LOG_V(INFO, TAG, "Looking for uri %s", requestUri);
         LL_FOREACH(cbList, out)
         {
+            OC_LOG_V(INFO, TAG, "\tFound %s", out->requestUri);
             if(out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
             {
                 return out;
@@ -259,7 +270,7 @@ OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeNam
     if(cbNode && resourceTypeName)
     {
         // Form a new resourceType member.
-        newResourceType = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
+        newResourceType = (OCResourceType *) OICMalloc(sizeof(OCResourceType));
         if(!newResourceType)
         {
             return OC_STACK_NO_MEMORY;
@@ -311,7 +322,7 @@ OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, char* uri, uint32_t n
 
     OCMulticastNode *node;
 
-    node = (OCMulticastNode*) OCMalloc(sizeof(OCMulticastNode));
+    node = (OCMulticastNode*) OICMalloc(sizeof(OCMulticastNode));
 
     if (node)
     {
index 622288e..b1822de 100644 (file)
 #include "ocstackinternal.h"
 #include "ocresourcehandler.h"
 #include "logger.h"
-#include "ocmalloc.h"
 #include "cJSON.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
 
 /// Module Name
 #include <stdio.h>
@@ -118,8 +119,10 @@ ValidateQuery (const char *query, OCResourceHandle resource,
 
     // Break the query string to validate it and determine IF and RT parameters
     // Validate there are atmost 2 parameters in string and that one is 'if' and other 'rt'
+    // separated by token '&' or ';'. Stack will accept both the versions.
+
     char *endStr, *ifPtr = NULL, *rtPtr = NULL;
-    char *token = strtok_r ((char *)query, "&", &endStr);
+    char *token = strtok_r ((char *)query, OC_QUERY_SEPARATOR , &endStr);
 
     // External loop breaks query string into fields using the & separator
     while (token != NULL)
@@ -155,7 +158,7 @@ ValidateQuery (const char *query, OCResourceHandle resource,
             // Query parameter should be of the form if=<string>. String should not have & or =
             return OC_STACK_INVALID_QUERY;
         }
-        token = strtok_r (NULL, "&", &endStr);
+        token = strtok_r (NULL, OC_QUERY_SEPARATOR, &endStr);
     }
     if (numFields > NUM_FIELDS_IN_QUERY)
     {
@@ -217,171 +220,75 @@ ValidateQuery (const char *query, OCResourceHandle resource,
     return OC_STACK_OK;
 }
 
-
-static OCStackResult BuildRootResourceJSON(OCResource *resource,
-        char * bufferPtr, uint16_t *remaining)
-{
-    OCStackResult ret = OC_STACK_ERROR;
-    cJSON *resObj = NULL;
-    char *jsonStr = NULL;
-    uint16_t jsonLen;
-
-    OC_LOG(INFO, TAG, PCF("Entering BuildRootResourceJSON"));
-    resObj = cJSON_CreateObject();
-
-    if ( ! resObj)
-    {
-        ret = OC_STACK_NO_MEMORY;
-    }
-    else if (resource)
-    {
-        cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resource->uri));
-        jsonStr = cJSON_PrintUnformatted (resObj);
-
-        if(!jsonStr)
-        {
-            cJSON_Delete(resObj);
-            return OC_STACK_NO_MEMORY;
-        }
-
-        jsonLen = strlen(jsonStr);
-        if (jsonLen < *remaining)
-        {
-            strncpy(bufferPtr, jsonStr, jsonLen);
-            *remaining -= jsonLen;
-            bufferPtr += jsonLen;
-            ret = OC_STACK_OK;
-        }
-    }
-    else
-    {
-        ret = OC_STACK_INVALID_PARAM;
-    }
-
-    cJSON_Delete (resObj);
-    OCFree(jsonStr);
-
-    return ret;
-}
-
-
 static OCStackResult
-HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest,
-                       uint8_t filterOn, char *filterValue)
+HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest, uint8_t filterOn, char *filterValue)
 {
     if(!ehRequest)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCStackResult ret = OC_STACK_ERROR;
-    char jsonbuffer[MAX_RESPONSE_LENGTH] = {};
-    size_t jsonbufferLength = 0;
-    uint16_t remaining = 0;
-    char * ptr = NULL;
-    OCResource * collResource = (OCResource *) ehRequest->resource;
-
-    ptr = jsonbuffer;
-    remaining = MAX_RESPONSE_LENGTH;
+    OCStackResult ret = OC_STACK_OK;
+    OCResource *collResource = (OCResource *)ehRequest->resource;
 
-    ret = BuildRootResourceJSON(collResource, ptr, &remaining);
+    OCRepPayload* payload = NULL;
 
-    if (ret == OC_STACK_OK && remaining >= (sizeof(OC_JSON_SEPARATOR) + 1))
+    if(ret == OC_STACK_OK)
     {
-        ptr += strlen((char*)ptr);
-        *ptr = OC_JSON_SEPARATOR;
-        ptr++;
-        remaining--;
-    }
-    else
-    {
-        ret = OC_STACK_ERROR;
+        ret = BuildResponseRepresentation(collResource, &payload);
     }
 
     if (ret == OC_STACK_OK)
     {
-        for  (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
+        for  (int i = 0; i < MAX_CONTAINED_RESOURCES && ret == OC_STACK_OK; i++)
         {
             OCResource* temp = collResource->rsrcResources[i];
             if (temp)
             {
-                //TODO : Update needed here to get correct connectivity type
-                //from ServerRequest data structure.
-
-                // Function will return error if not enough space in buffer.
-                ret = BuildVirtualResourceResponse(temp, filterOn, filterValue,
-                         (char*)ptr, &remaining, CA_IPV4 );
-                if (ret != OC_STACK_OK)
-                {
-                    break;
-                }
-                ptr += strlen((char*)ptr);
-
-                // Check if we have added all resources.
-                if ((i + 1) == MAX_CONTAINED_RESOURCES)
-                {
-                    break;
-                }
-                // Add separator if more resources and enough space present.
-                if (collResource->rsrcResources[i+1] && remaining > sizeof(OC_JSON_SEPARATOR))
-                {
-                    *ptr = OC_JSON_SEPARATOR;
-                    ptr++;
-                    remaining--;
-                }
-                // No point continuing as no more space on buffer
-                // and/or no more resources.
-                else
-                {
-                    break;
-                }
-            }
-            else
-            {
-                break;
+                //TODO : Add resource type filtering once collections
+                // start supporting queries.
+                ret = BuildResponseRepresentation(temp, &payload);
             }
         }
     }
 
-    jsonbufferLength = strlen((const char *)jsonbuffer);
-    if(ret == OC_STACK_OK && jsonbufferLength)
+    if(ret == OC_STACK_OK)
     {
         OCEntityHandlerResponse response = {};
         response.ehResult = OC_EH_OK;
-        response.payload = jsonbuffer;
-        response.payloadSize = jsonbufferLength + 1;
+        response.payload = (OCPayload*)payload;
         response.persistentBufferFlag = 0;
         response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
         response.resourceHandle = (OCResourceHandle) collResource;
         ret = OCDoResponse(&response);
     }
+    OCRepPayloadDestroy(payload);
     return ret;
 }
 
 static OCStackResult
 HandleBatchInterface(OCEntityHandlerRequest *ehRequest)
 {
-    OCStackResult stackRet = OC_STACK_ERROR;
+    OCStackResult stackRet = OC_STACK_OK;
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
-    char jsonbuffer[MAX_RESPONSE_LENGTH] = {0};
-    size_t jsonbufferLength = 0;
-    uint16_t remaining = 0;
-    char * ptr = NULL;
     OCResource * collResource = (OCResource *) ehRequest->resource;
 
-    ptr = jsonbuffer;
-    remaining = MAX_RESPONSE_LENGTH;
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        stackRet = OC_STACK_NO_MEMORY;
+    }
 
-    stackRet = BuildRootResourceJSON(collResource, ptr, &remaining);
-    ptr += strlen((char*)ptr);
+    if(stackRet == OC_STACK_OK)
+    {
+        OCRepPayloadSetUri(payload, collResource->uri);
+    }
 
-    jsonbufferLength = strlen((const char *)jsonbuffer);
-    if(jsonbufferLength)
+    if(stackRet == OC_STACK_OK)
     {
         OCEntityHandlerResponse response = {};
         response.ehResult = OC_EH_OK;
-        response.payload = jsonbuffer;
-        response.payloadSize = jsonbufferLength + 1;
+        response.payload = (OCPayload*)payload;
         response.persistentBufferFlag = 0;
         response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
         response.resourceHandle = (OCResourceHandle) collResource;
@@ -400,7 +307,8 @@ HandleBatchInterface(OCEntityHandlerRequest *ehRequest)
                 // is ehRequest->resource
                 ehRequest->resource = (OCResourceHandle) temp;
 
-                ehResult = temp->entityHandler(OC_REQUEST_FLAG, ehRequest);
+                ehResult = temp->entityHandler(OC_REQUEST_FLAG, ehRequest,
+                                        temp->entityHandlerCallbackParam);
 
                 // The default collection handler is returning as OK
                 if(stackRet != OC_STACK_SLOW_RESOURCE)
@@ -500,9 +408,12 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
                 OC_LOG(INFO, TAG, PCF("STACK_IF_BATCH"));
                 ((OCServerRequest *)ehRequest->requestHandle)->ehResponseHandler =
                                                                         HandleAggregateResponse;
+
                 ((OCServerRequest *)ehRequest->requestHandle)->numResponses =
                         GetNumOfResourcesInCollection((OCResource *)ehRequest->resource) + 1;
+
                 return HandleBatchInterface(ehRequest);
+
             case STACK_IF_GROUP:
                 return BuildCollectionGroupActionJSONResponse(OC_REST_GET/*flag*/,
                         (OCResource *) ehRequest->resource, ehRequest);
@@ -531,8 +442,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
 
             case STACK_IF_GROUP:
             {
-                OC_LOG_V(INFO, TAG, "IF_COLLECTION PUT with request ::\n%s\n ",
-                        ehRequest->reqJSONPayload);
+                OC_LOG(INFO, TAG, PCF("IF_COLLECTION PUT with request ::\n"));
+                OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
                 return BuildCollectionGroupActionJSONResponse(OC_REST_PUT/*flag*/,
                         (OCResource *) ehRequest->resource, ehRequest);
             }
@@ -547,8 +458,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
         {
             case STACK_IF_GROUP:
             {
-                OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ",
-                        ehRequest->reqJSONPayload);
+                OC_LOG(INFO, TAG, PCF("IF_COLLECTION POST with request ::\n"));
+                OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
                 return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/,
                         (OCResource *) ehRequest->resource, ehRequest);
             }
@@ -561,8 +472,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
 
         if(ifQueryParam == STACK_IF_GROUP)
         {
-            OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ",
-                    ehRequest->reqJSONPayload);
+            OC_LOG(INFO, TAG, PCF("IF_COLLECTION POST with request ::\n"));
+            OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
             return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/,
                     (OCResource *) ehRequest->resource, ehRequest);
         }
@@ -573,5 +484,3 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
     }
     return result;
 }
-
-
index 654078d..201dac8 100644 (file)
 #include "ocobserve.h"
 #include "ocresourcehandler.h"
 #include "ocrandom.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
 #include "ocserverrequest.h"
 
 #include "utlist.h"
 #include "pdu.h"
 
+
 // Module Name
 #define MOD_NAME PCF("ocobserve")
 
@@ -39,7 +42,6 @@
 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
 
 static struct ResourceObserver * serverObsList = NULL;
-
 /**
  * Determine observe QOS based on the QOS of the request.
  * The qos passed as a parameter overrides what the client requested.
@@ -95,7 +97,7 @@ static OCQualityOfService DetermineObserverQoS(OCMethod method,
 
 #ifdef WITH_PRESENCE
 OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
-        OCResourceType *resourceType, OCQualityOfService qos)
+        OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos)
 #else
 OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
         OCQualityOfService qos)
@@ -127,27 +129,35 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
             #endif
                 qos = DetermineObserverQoS(method, resourceObserver, qos);
 
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
                         resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        &resourceObserver->devAddr);
 
                 if(request)
                 {
                     request->observeResult = OC_STACK_OK;
                     if(result == OC_STACK_OK)
                     {
-                        result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-                                    request->method, (OCResourceHandle) resPtr, request->query,
-                                    request->reqJSONPayload,
+                        result = FormOCEntityHandlerRequest(
+                                    &ehRequest,
+                                    (OCRequestHandle) request,
+                                    request->method,
+                                    &request->devAddr,
+                                    (OCResourceHandle) resPtr,
+                                    request->query,
+                                    request->payload,
+                                    request->payloadSize,
                                     request->numRcvdVendorSpecificHeaderOptions,
                                     request->rcvdVendorSpecificHeaderOptions,
-                                    OC_OBSERVE_NO_OPTION, 0);
+                                    OC_OBSERVE_NO_OPTION,
+                                    0);
                         if(result == OC_STACK_OK)
                         {
-                            ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest);
+                            ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest,
+                                                resPtr->entityHandlerCallbackParam);
                             if(ehResult == OC_EH_ERROR)
                             {
                                 FindAndDeleteServerRequest(request);
@@ -160,39 +170,40 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
             else
             {
                 OCEntityHandlerResponse ehResponse = {};
-                char presenceResBuf[MAX_RESPONSE_LENGTH] = {};
 
                 //This is effectively the implementation for the presence entity handler.
                 OC_LOG(DEBUG, TAG, PCF("This notification is for Presence"));
-
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
                         resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        &resourceObserver->devAddr);
 
                 if(result == OC_STACK_OK)
                 {
-                    // we create the payload here
-                    if(resourceType && resourceType->resourcetypename)
+                    OCPresencePayload* presenceResBuf = OCPresencePayloadCreate(
+                            resPtr->sequenceNum, maxAge, trigger,
+                            resourceType ? resourceType->resourcetypename : NULL);
+
+                    if(!presenceResBuf)
                     {
-                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u:%s",
-                                resPtr->sequenceNum, maxAge, resourceType->resourcetypename);
+                        return OC_STACK_NO_MEMORY;
                     }
-                    else
+
+                    if(result == OC_STACK_OK)
                     {
-                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u",
-                                resPtr->sequenceNum, maxAge);
+                        ehResponse.ehResult = OC_EH_OK;
+                        ehResponse.payload = (OCPayload*)presenceResBuf;
+                        ehResponse.persistentBufferFlag = 0;
+                        ehResponse.requestHandle = (OCRequestHandle) request;
+                        ehResponse.resourceHandle = (OCResourceHandle) resPtr;
+                        OICStrcpy(ehResponse.resourceUri, sizeof(ehResponse.resourceUri),
+                                resourceObserver->resUri);
+                        result = OCDoResponse(&ehResponse);
                     }
-                    ehResponse.ehResult = OC_EH_OK;
-                    ehResponse.payload = presenceResBuf;
-                    ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1;
-                    ehResponse.persistentBufferFlag = 0;
-                    ehResponse.requestHandle = (OCRequestHandle) request;
-                    ehResponse.resourceHandle = (OCResourceHandle) resPtr;
-                    strcpy((char *)ehResponse.resourceUri, (const char *)resourceObserver->resUri);
-                    result = OCDoResponse(&ehResponse);
+
+                    OCPresencePayloadDestroy(presenceResBuf);
                 }
             }
             #endif
@@ -221,10 +232,11 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
 OCStackResult SendListObserverNotification (OCResource * resource,
         OCObservationId  *obsIdList, uint8_t numberOfIds,
-        const char *notificationJSONPayload, uint32_t maxAge,
+        const OCRepPayload *payload,
+        uint32_t maxAge,
         OCQualityOfService qos)
 {
-    if(!resource || !obsIdList || !notificationJSONPayload)
+    if(!resource || !obsIdList || !payload)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -248,11 +260,11 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                 qos = DetermineObserverQoS(OC_REST_GET, observer, qos);
 
 
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resource->sequenceNum, qos, observer->query,
                         NULL, NULL, observer->token, observer->tokenLength,
                         observer->resUri, 0,
-                        &(observer->addressInfo), observer->connectivityType);
+                        &observer->devAddr);
 
                 if(request)
                 {
@@ -261,15 +273,13 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                     {
                         OCEntityHandlerResponse ehResponse = {};
                         ehResponse.ehResult = OC_EH_OK;
-                        ehResponse.payload = (char *) OCMalloc(MAX_RESPONSE_LENGTH + 1);
+                        ehResponse.payload = (OCPayload*)OCRepPayloadCreate();
                         if(!ehResponse.payload)
                         {
                             FindAndDeleteServerRequest(request);
                             continue;
                         }
-                        strncpy(ehResponse.payload, notificationJSONPayload, MAX_RESPONSE_LENGTH-1);
-                        ehResponse.payload[MAX_RESPONSE_LENGTH] = '\0';
-                        ehResponse.payloadSize = strlen(ehResponse.payload) + 1;
+                        memcpy(ehResponse.payload, payload, sizeof(*payload));
                         ehResponse.persistentBufferFlag = 0;
                         ehResponse.requestHandle = (OCRequestHandle) request;
                         ehResponse.resourceHandle = (OCResourceHandle) resource;
@@ -281,7 +291,7 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                             // Increment only if OCDoResponse is successful
                             numSentNotification++;
 
-                            OCFree(ehResponse.payload);
+                            OICFree(ehResponse.payload);
                             FindAndDeleteServerRequest(request);
                         }
                         else
@@ -349,8 +359,7 @@ OCStackResult AddObserver (const char         *resUri,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
-                           const CAAddress_t  *addressInfo,
-                           CATransportType_t connectivityType)
+                           const OCDevAddr    *devAddr)
 {
     // Check if resource exists and is observable.
     if (!resHandle)
@@ -368,44 +377,44 @@ OCStackResult AddObserver (const char         *resUri,
         return OC_STACK_INVALID_PARAM;
     }
 
-    obsNode = (ResourceObserver *) OCCalloc(1, sizeof(ResourceObserver));
+    obsNode = (ResourceObserver *) OICCalloc(1, sizeof(ResourceObserver));
     if (obsNode)
     {
         obsNode->observeId = obsId;
 
-        obsNode->resUri = (char *)OCMalloc(strlen(resUri)+1);
+        obsNode->resUri = OICStrdup(resUri);
         VERIFY_NON_NULL (obsNode->resUri);
-        memcpy (obsNode->resUri, resUri, strlen(resUri)+1);
 
         obsNode->qos = qos;
         if(query)
         {
-            obsNode->query = (char *)OCMalloc(strlen(query)+1);
+            obsNode->query = OICStrdup(query);
             VERIFY_NON_NULL (obsNode->query);
-            memcpy (obsNode->query, query, strlen(query)+1);
         }
         // If tokenLength is zero, the return value depends on the
         // particular library implementation (it may or may not be a null pointer).
         if(tokenLength)
         {
-            obsNode->token = (CAToken_t)OCMalloc(tokenLength);
+            obsNode->token = (CAToken_t)OICMalloc(tokenLength);
             VERIFY_NON_NULL (obsNode->token);
             memcpy(obsNode->token, token, tokenLength);
         }
         obsNode->tokenLength = tokenLength;
-        obsNode->addressInfo = *addressInfo;
-        obsNode->connectivityType = connectivityType;
+
+        obsNode->devAddr = *devAddr;
         obsNode->resource = resHandle;
+
         LL_APPEND (serverObsList, obsNode);
+
         return OC_STACK_OK;
     }
 
 exit:
     if (obsNode)
     {
-        OCFree(obsNode->resUri);
-        OCFree(obsNode->query);
-        OCFree(obsNode);
+        OICFree(obsNode->resUri);
+        OICFree(obsNode->query);
+        OICFree(obsNode);
     }
     return OC_STACK_NO_MEMORY;
 }
@@ -434,10 +443,12 @@ ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLen
 
     if(token && *token)
     {
+        OC_LOG(INFO, TAG,PCF("Looking for token"));
+        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+        OC_LOG(INFO, TAG,PCF("\tFound token:"));
+
         LL_FOREACH (serverObsList, out)
         {
-            OC_LOG(INFO, TAG,PCF("comparing tokens"));
-            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
             if((memcmp(out->token, token, tokenLength) == 0))
             {
@@ -445,6 +456,11 @@ ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLen
             }
         }
     }
+    else
+    {
+        OC_LOG(ERROR, TAG,PCF("Passed in NULL token"));
+    }
+
     OC_LOG(INFO, TAG, PCF("Observer node not found!!"));
     return NULL;
 }
@@ -461,13 +477,13 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength)
     obsNode = GetObserverUsingToken (token, tokenLength);
     if (obsNode)
     {
-        OC_LOG_V(INFO, TAG, PCF("deleting tokens"));
+        OC_LOG_V(INFO, TAG, "deleting observer id  %u with token", obsNode->observeId);
         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)obsNode->token, tokenLength);
         LL_DELETE (serverObsList, obsNode);
-        OCFree(obsNode->resUri);
-        OCFree(obsNode->query);
-        OCFree(obsNode->token);
-        OCFree(obsNode);
+        OICFree(obsNode->resUri);
+        OICFree(obsNode->query);
+        OICFree(obsNode->token);
+        OICFree(obsNode);
     }
     // it is ok if we did not find the observer...
     return OC_STACK_OK;
@@ -508,7 +524,7 @@ CreateObserveHeaderOption (CAHeaderOption_t **caHdrOpt,
 
     CAHeaderOption_t *tmpHdrOpt = NULL;
 
-    tmpHdrOpt = (CAHeaderOption_t *) OCCalloc ((numOptions+1), sizeof(CAHeaderOption_t));
+    tmpHdrOpt = (CAHeaderOption_t *) OICCalloc ((numOptions+1), sizeof(CAHeaderOption_t));
     if (NULL == tmpHdrOpt)
     {
         return OC_STACK_NO_MEMORY;
@@ -558,10 +574,7 @@ GetObserveHeaderOption (uint32_t * observationOption,
             *observationOption = options[i].optionData[0];
             for(uint8_t c = i; c < *numOptions-1; c++)
             {
-                options[i].protocolID = options[i+1].protocolID;
-                options[i].optionID = options[i+1].optionID;
-                options[i].optionLength = options[i+1].optionLength;
-                memcpy(options[i].optionData, options[i+1].optionData, options[i+1].optionLength);
+                options[i] = options[i+1];
             }
             (*numOptions)--;
             return OC_STACK_OK;
diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c
new file mode 100644 (file)
index 0000000..afb8700
--- /dev/null
@@ -0,0 +1,1402 @@
+//******************************************************************
+//
+// 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 "ocpayload.h"
+#include "octypes.h"
+#include <string.h>
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocstackinternal.h"
+#include "ocresource.h"
+#include "logger.h"
+
+#define TAG "OCPayload"
+static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
+
+void OCPayloadDestroy(OCPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_REPRESENTATION:
+            OCRepPayloadDestroy((OCRepPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DISCOVERY:
+            OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DEVICE:
+            OCDevicePayloadDestroy((OCDevicePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PLATFORM:
+            OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PRESENCE:
+            OCPresencePayloadDestroy((OCPresencePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_SECURITY:
+            OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
+            break;
+        default:
+            OC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
+            OICFree(payload);
+            break;
+    }
+}
+OCRepPayload* OCRepPayloadCreate()
+{
+    OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
+
+    return payload;
+}
+
+void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
+{
+    if(!parent)
+    {
+        return;
+    }
+
+    while(parent->next)
+    {
+        parent = parent->next;
+    }
+
+    parent->next= child;
+    child->next = NULL;
+}
+
+static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
+{
+    if(!payload || !name)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue* val = payload->values;
+    while(val)
+    {
+        if(0 == strcmp(val->name, name))
+        {
+            return val;
+        }
+        val = val->next;
+    }
+
+    return NULL;
+
+}
+
+static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* 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));
+            memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
+            break;
+        case OCREP_PROP_DOUBLE:
+            dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
+            memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
+            break;
+        case OCREP_PROP_BOOL:
+            dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+            memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
+            break;
+        case OCREP_PROP_STRING:
+            dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
+            }
+            break;
+        case OCREP_PROP_ARRAY:
+            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
+            }
+            break;
+        default:
+            OC_LOG(ERROR, TAG, PCF("CopyPropertyValueArray invalid type"));
+            break;
+    }
+}
+
+static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
+{
+    if (!source || !dest)
+    {
+        return;
+    }
+
+    switch(source->type)
+    {
+        case OCREP_PROP_STRING:
+            dest->str = OICStrdup(source->str);
+            break;
+        case OCREP_PROP_OBJECT:
+            dest->obj = OCRepPayloadClone(source->obj);
+            break;
+        case OCREP_PROP_ARRAY:
+            OCCopyPropertyValueArray(dest, source);
+            break;
+        default:
+            // Nothing to do for the trivially copyable types.
+            break;
+    }
+}
+
+static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
+{
+    if(!val)
+    {
+        return;
+    }
+
+    if(val->type == OCREP_PROP_STRING)
+    {
+        OICFree(val->str);
+    }
+    else if (val->type == OCREP_PROP_OBJECT)
+    {
+        OCRepPayloadDestroy(val->obj);
+    }
+    else if (val->type == OCREP_PROP_ARRAY)
+    {
+        size_t dimTotal = calcDimTotal(val->arr.dimensions);
+        switch(val->arr.type)
+        {
+            case OCREP_PROP_INT:
+            case OCREP_PROP_DOUBLE:
+            case OCREP_PROP_BOOL:
+                // Since this is a union, iArray will
+                // point to all of the above
+                OICFree(val->arr.iArray);
+                break;
+            case OCREP_PROP_STRING:
+                for(size_t i = 0; i< dimTotal;++i)
+                {
+                    OICFree(val->arr.strArray[i]);
+                }
+                OICFree(val->arr.strArray);
+                break;
+            case OCREP_PROP_OBJECT:
+                for(size_t i = 0; i< dimTotal;++i)
+                {
+                    OCRepPayloadDestroy(val->arr.objArray[i]);
+                }
+                OICFree(val->arr.objArray);
+                break;
+            case OCREP_PROP_NULL:
+            case OCREP_PROP_ARRAY:
+                OC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
+                        inside an array: %d", val->arr.type);
+                break;
+        }
+    }
+}
+
+static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
+{
+    if(!val)
+    {
+        return;
+    }
+
+    OICFree(val->name);
+    OCFreeRepPayloadValueContents(val);
+    OCFreeRepPayloadValue(val->next);
+    OICFree(val);
+}
+static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
+{
+    if (!source)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue *sourceIter = source;
+    OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
+    if (!destIter)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue *headOfClone = destIter;
+
+    // Copy payload type and non pointer types in union.
+    *destIter = *sourceIter;
+    destIter->name = OICStrdup (sourceIter->name);
+    OCCopyPropertyValue (destIter, sourceIter);
+
+    sourceIter = sourceIter->next;
+
+    while (sourceIter)
+    {
+        destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
+        if (!destIter->next)
+        {
+            OCFreeRepPayloadValue (headOfClone);
+            return NULL;
+        }
+
+        *(destIter->next) = *sourceIter;
+        destIter->next->name = OICStrdup (sourceIter->name);
+        OCCopyPropertyValue (destIter->next, sourceIter);
+
+        sourceIter = sourceIter->next;
+        destIter = destIter->next;
+    }
+    return headOfClone;
+}
+
+static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
+        OCRepPayloadPropType type)
+{
+    if(!payload || !name)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue* val = payload->values;
+    if(val == NULL)
+    {
+        payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
+        payload->values->name = OICStrdup(name);
+        payload->values->type =type;
+        return payload->values;
+    }
+
+    while(val)
+    {
+        if(0 == strcmp(val->name, name))
+        {
+            OCFreeRepPayloadValueContents(val);
+            val->type = type;
+            return val;
+        }
+        else if(val->next == NULL)
+        {
+            val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
+            val->next->name = OICStrdup(name);
+            val->next->type =type;
+            return val->next;
+        }
+
+        val = val->next;
+    }
+
+    OC_LOG(ERROR, TAG, PCF("FindAndSetValue reached point after while loop, pointer corruption?"));
+    return NULL;
+}
+
+bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
+{
+    return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
+}
+
+bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
+{
+    if(!payload || !resourceType)
+    {
+        return false;
+    }
+
+    if(payload->types)
+    {
+        OCStringLL* cur = payload->types;
+        while(cur->next)
+        {
+            cur = cur->next;
+        }
+        cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+
+        if(!cur->next)
+        {
+            return false;
+        }
+
+        cur->next->value = resourceType;
+        return true;
+    }
+    else
+    {
+        payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        if(!payload->types)
+        {
+            return false;
+        }
+        payload->types->value = resourceType;
+        return true;
+    }
+}
+
+bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface)
+{
+    return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface));
+}
+
+bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface)
+{
+    if(!payload || !interface)
+    {
+        return false;
+    }
+
+    if(payload->interfaces)
+    {
+        OCStringLL* cur = payload->interfaces;
+        while(cur->next)
+        {
+            cur = cur->next;
+        }
+        cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+
+        if(!cur->next)
+        {
+            return false;
+        }
+        cur->next->value = interface;
+        return true;
+    }
+    else
+    {
+        payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        if(!payload->interfaces)
+        {
+            return false;
+        }
+        payload->interfaces->value = interface;
+        return true;
+    }
+}
+
+bool OCRepPayloadSetUri(OCRepPayload* payload, const char*  uri)
+{
+    if(!payload)
+    {
+        return false;
+    }
+
+    payload->uri = OICStrdup(uri);
+    return payload->uri != NULL;
+}
+
+bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    return val->type == OCREP_PROP_NULL;
+}
+
+bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_NULL);
+    return val != NULL;
+}
+
+bool OCRepPayloadSetPropInt(OCRepPayload* payload,
+        const char* name, int64_t value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_INT);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->i = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_INT)
+    {
+        return false;
+    }
+
+    *value = val->i;
+    return true;
+}
+
+bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
+        const char* name, double value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_DOUBLE);
+
+    if(!val )
+    {
+        return false;
+    }
+
+    val->d = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_DOUBLE)
+    {
+        return false;
+    }
+
+    *value = val->d;
+    return true;
+}
+
+bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
+{
+    char* temp = OICStrdup(value);
+    bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
+
+    if(!b)
+    {
+        OICFree(temp);
+    }
+    return b;
+}
+
+bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_STRING);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->str = value;
+    return val->str != NULL;
+}
+
+bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, const char** value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_STRING)
+    {
+        return false;
+    }
+
+    *value = OICStrdup(val->str);
+    return *value != NULL;
+}
+
+bool OCRepPayloadSetPropBool(OCRepPayload* payload,
+        const char* name, bool value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_BOOL);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->b = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_BOOL)
+    {
+        return false;
+    }
+
+    *value = val->b;
+    return true;
+}
+
+bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
+{
+    OCRepPayload* temp = OCRepPayloadClone(value);
+    bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
+
+    if(!b)
+    {
+        OCRepPayloadDestroy(temp);
+    }
+    return b;
+}
+
+bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_OBJECT);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->obj = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_OBJECT)
+    {
+        return false;
+    }
+
+    *value = OCRepPayloadClone(val->obj);
+    return *value != NULL;
+}
+
+size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    if(dimensions[0] == 0)
+    {
+        return 0;
+    }
+
+    size_t total = 1;
+    for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
+    {
+        total *= dimensions[i];
+    }
+    return total;
+}
+
+bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
+        int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_INT;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.iArray = array;
+
+    return true;
+}
+
+bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
+        const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(int64_t));
+
+
+    bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
+        int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
+            || !val->arr.iArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
+        double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_DOUBLE;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.dArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
+        const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(double));
+
+    bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
+        double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
+            || !val->arr.dArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (double*)OICMalloc(dimTotal * sizeof(double));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_STRING;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.strArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
+        const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        newArray[i] = OICStrdup(array[i]);
+    }
+
+    bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
+
+    if(!b)
+    {
+        for(size_t i = 0; i < dimTotal; ++i)
+        {
+            OICFree(newArray[i]);
+        }
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
+        char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
+            || !val->arr.strArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (char**)OICMalloc(dimTotal * sizeof(char*));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        (*array)[i] = OICStrdup(val->arr.strArray[i]);
+    }
+
+    return true;
+
+}
+
+bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
+        bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_BOOL;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.bArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
+        const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(bool));
+
+
+    bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
+        bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
+            || !val->arr.bArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_OBJECT;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.objArray = array;
+
+    return true;
+}
+
+bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
+        const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        newArray[i] = OCRepPayloadClone(array[i]);
+    }
+
+    bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
+
+    if(!b)
+    {
+        for(size_t i = 0; i < dimTotal; ++i)
+        {
+           OCRepPayloadDestroy(newArray[i]);
+        }
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
+        OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
+            || !val->arr.objArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
+    }
+
+    return true;
+}
+
+void OCFreeOCStringLL(OCStringLL* ll)
+{
+    if(!ll)
+    {
+        return;
+    }
+
+    OCFreeOCStringLL(ll->next);
+    OICFree(ll->value);
+    OICFree(ll);
+}
+
+OCStringLL* CloneOCStringLL (OCStringLL* ll)
+{
+    if (!ll)
+    {
+        return NULL;
+    }
+
+    OCStringLL *sourceIter = ll;
+
+    OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
+    if (!destIter)
+    {
+        return NULL;
+    }
+    destIter->value = OICStrdup (sourceIter->value);
+
+    OCStringLL *headOfClone = destIter;
+
+    sourceIter = sourceIter->next;
+
+    while (sourceIter)
+    {
+        destIter->next  = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
+        if (!destIter->next)
+        {
+            OCFreeOCStringLL (headOfClone);
+            return NULL;
+        }
+        destIter->next->value = OICStrdup (sourceIter->value);
+
+        destIter = destIter->next;
+        sourceIter = sourceIter->next;
+    }
+    return headOfClone;
+}
+
+OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
+{
+    if (!payload)
+    {
+        return NULL;
+    }
+
+    OCRepPayload *clone = OCRepPayloadCreate();
+
+    if (!clone)
+    {
+        return NULL;
+    }
+
+    clone->uri = OICStrdup (payload->uri);
+    clone->types = CloneOCStringLL (payload->types);
+    clone->interfaces = CloneOCStringLL (payload->interfaces);
+    clone->values = OCRepPayloadValueClone (payload->values);
+
+    return clone;
+}
+
+
+void OCRepPayloadDestroy(OCRepPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OCFreeOCStringLL(payload->types);
+    OCFreeOCStringLL(payload->interfaces);
+    OCFreeRepPayloadValue(payload->values);
+    OCRepPayloadDestroy(payload->next);
+    OICFree(payload);
+}
+
+OCDiscoveryPayload* OCDiscoveryPayloadCreate()
+{
+    OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_DISCOVERY;
+
+    return payload;
+}
+
+OCSecurityPayload* OCSecurityPayloadCreate(char* securityData)
+{
+    OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_SECURITY;
+    payload->securityData = OICStrdup(securityData);
+
+    return payload;
+}
+
+void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->securityData);
+    OICFree(payload);
+}
+
+size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
+{
+    size_t i = 0;
+    OCResourcePayload* p = payload->resources;
+    while(p)
+    {
+        ++i;
+        p = p->next;
+    }
+    return i;
+}
+
+OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
+{
+    size_t i = 0;
+    OCResourcePayload* p = payload->resources;
+    while(p)
+    {
+        if(i == index)
+        {
+            return p;
+        }
+        ++i;
+        p = p->next;
+    }
+    return NULL;
+}
+
+static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port)
+{
+    OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
+    if(!pl)
+    {
+        return NULL;
+    }
+
+    pl->uri = OICStrdup(res->uri);
+    pl->sid = (uint8_t*)OICCalloc(1, UUID_SIZE);
+    memcpy(pl->sid, OCGetServerInstanceID(), UUID_SIZE);
+
+    // types
+    OCResourceType* typePtr = res->rsrcType;
+
+    if(typePtr != NULL)
+    {
+        pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        pl->types->value = OICStrdup(typePtr->resourcetypename);
+
+        OCStringLL* cur = pl->types;
+        typePtr = typePtr->next;
+        while(typePtr)
+        {
+            cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+            cur->next->value = OICStrdup(typePtr->resourcetypename);
+            cur = cur->next;
+            typePtr = typePtr->next;
+        }
+    }
+
+    // interfaces
+    OCResourceInterface* ifPtr = res->rsrcInterface;
+    if(ifPtr != NULL)
+    {
+        pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        pl->interfaces->value = OICStrdup(ifPtr->name);
+
+        OCStringLL* cur = pl->interfaces;
+        ifPtr = ifPtr->next;
+        while(ifPtr)
+        {
+            cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+            cur->next->value = OICStrdup(ifPtr->name);
+            cur = cur->next;
+            ifPtr = ifPtr->next;
+        }
+    }
+
+    pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
+    pl->secure = (res->resourceProperties & OC_SECURE) != 0;
+    pl->port = port;
+
+    return pl;
+}
+
+void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
+        uint16_t port)
+{
+    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port));
+}
+
+void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
+{
+    if(!payload->resources)
+    {
+        payload->resources = res;
+    }
+    else
+    {
+        OCResourcePayload* p = payload->resources;
+        while(p->next)
+        {
+            p = p->next;
+        }
+        p->next = res;
+    }
+}
+
+void FreeOCDiscoveryResource(OCResourcePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OICFree(payload->sid);
+    OCFreeOCStringLL(payload->types);
+    OCFreeOCStringLL(payload->interfaces);
+    FreeOCDiscoveryResource(payload->next);
+    OICFree(payload);
+
+}
+void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    FreeOCDiscoveryResource(payload->resources);
+    OICFree(payload);
+}
+
+OCDevicePayload* OCDevicePayloadCreate(const char* uri, const uint8_t* sid, const char* dname,
+        const char* specVer, const char* dmVer)
+{
+
+    OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_DEVICE;
+
+    payload->uri = OICStrdup(uri);
+    if(uri && !payload->uri)
+    {
+        goto exit;
+    }
+
+    if(sid)
+    {
+        payload->sid = (uint8_t*)OICMalloc(UUID_SIZE);
+        if(!payload->sid)
+        {
+            goto exit;
+        }
+        memcpy(payload->sid, sid, UUID_SIZE);
+    }
+
+    payload->deviceName = OICStrdup(dname);
+    if(dname && !payload->deviceName)
+    {
+        goto exit;
+    }
+
+    payload->specVersion = OICStrdup(specVer);
+    if(specVer && !payload->specVersion)
+    {
+        goto exit;
+    }
+
+    payload->dataModelVersion = OICStrdup(dmVer);
+    if(dmVer && !payload->dataModelVersion)
+    {
+        goto exit;
+    }
+
+    return payload;
+
+exit:
+    OCDevicePayloadDestroy((OCDevicePayload*)payload);
+    return NULL;
+}
+
+void OCDevicePayloadDestroy(OCDevicePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OICFree(payload->sid);
+    OICFree(payload->deviceName);
+    OICFree(payload->specVersion);
+    OICFree(payload->dataModelVersion);
+    OICFree(payload);
+}
+
+static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
+{
+    target->info.platformID = OICStrdup(platformInfo->platformID);
+    target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
+    target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
+    target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
+    target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
+    target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
+    target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
+    target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
+    target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
+    target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
+    target->info.systemTime = OICStrdup(platformInfo->systemTime);
+}
+
+OCPlatformPayload* OCPlatformPayloadCreateAsOwner(char* uri, OCPlatformInfo* platformInfo)
+{
+    OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PLATFORM;
+    payload->uri = uri;
+    payload->info = *platformInfo;
+
+    return payload;
+}
+
+OCPlatformPayload* OCPlatformPayloadCreate(const char* uri, const OCPlatformInfo* platformInfo)
+{
+    OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PLATFORM;
+    payload->uri = OICStrdup(uri);
+    OCCopyPlatformInfo(platformInfo, payload);
+
+    return payload;
+}
+
+void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+    OICFree(payload->uri);
+    OICFree(payload->info.platformID);
+    OICFree(payload->info.manufacturerName);
+    OICFree(payload->info.manufacturerUrl);
+    OICFree(payload->info.modelNumber);
+    OICFree(payload->info.dateOfManufacture);
+    OICFree(payload->info.platformVersion);
+    OICFree(payload->info.operatingSystemVersion);
+    OICFree(payload->info.hardwareVersion);
+    OICFree(payload->info.firmwareVersion);
+    OICFree(payload->info.supportUrl);
+    OICFree(payload->info.systemTime);
+    OICFree(payload);
+}
+
+OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
+        OCPresenceTrigger trigger, const char* resourceType)
+{
+    OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PRESENCE;
+    payload->sequenceNumber = seqNum;
+    payload->maxAge = maxAge;
+    payload->trigger = trigger;
+    payload->resourceType = OICStrdup(resourceType);
+    return payload;
+}
+
+void OCPresencePayloadDestroy(OCPresencePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+    OICFree(payload->resourceType);
+    OICFree(payload);
+}
diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c
new file mode 100644 (file)
index 0000000..3b6bd02
--- /dev/null
@@ -0,0 +1,760 @@
+//******************************************************************
+//
+// 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 "ocpayloadcbor.h"
+#include <stdlib.h>
+#include "oic_malloc.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "ocrandom.h"
+#include "ocresourcehandler.h"
+#include "cbor.h"
+
+#define TAG PCF("OCPayloadConvert")
+
+static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size);
+static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
+        size_t* size);
+
+bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value);
+
+bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value);
+
+
+OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
+{
+    OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_DISCOVERY:
+            return OCConvertDiscoveryPayload((OCDiscoveryPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_DEVICE:
+            return OCConvertDevicePayload((OCDevicePayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_PLATFORM:
+            return OCConvertPlatformPayload((OCPlatformPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_REPRESENTATION:
+            return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_PRESENCE:
+            return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_SECURITY:
+            return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
+        default:
+            OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
+            return OC_STACK_NOTIMPL;
+    }
+}
+
+static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder;
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY);
+
+    CborEncoder map;
+
+    err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+    if(payload->securityData)
+    {
+        err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION,
+                sizeof(OC_RSRVD_REPRESENTATION) - 1,
+                payload->securityData);
+    }
+
+    err = err || cbor_encoder_close_container(&rootArray, &map);
+
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err);
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+    size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY);
+
+    for(size_t i = 0; i < resourceCount; ++i)
+    {
+        CborEncoder map;
+        OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
+        err = err || cbor_encoder_create_map(&rootArray, &map, 3);
+        // Uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF,
+                sizeof(OC_RSRVD_HREF) - 1,
+                resource->uri);
+
+        // Server ID
+        err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID,
+                sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1);
+        err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);
+        // Prop Tag
+        {
+            CborEncoder propMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY,
+                    sizeof(OC_RSRVD_PROPERTY) -1 );
+            err = err || cbor_encoder_create_map(&map, &propMap, 3);
+
+            // Resource Type
+            {
+                CborEncoder rtArray;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE,
+                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
+                err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength);
+
+                OCStringLL* rtPtr = resource->types;
+                while(rtPtr)
+                {
+                    err = err || cbor_encode_text_string(&rtArray, rtPtr->value,
+                            strlen(rtPtr->value));
+                    rtPtr = rtPtr->next;
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &rtArray);
+            }
+
+            // Interface Types
+            {
+                CborEncoder ifArray;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE,
+                        sizeof(OC_RSRVD_INTERFACE) - 1);
+                err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength);
+                OCStringLL* ifPtr = resource->interfaces;
+
+                while(ifPtr)
+                {
+                    err = err || cbor_encode_text_string(&ifArray, ifPtr->value,
+                        strlen(ifPtr->value));
+                    ifPtr= ifPtr->next;
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &ifArray);
+            }
+            // Policy
+            {
+                CborEncoder policyMap;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY,
+                        sizeof(OC_RSRVD_POLICY) - 1);
+                err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength);
+
+                // Bitmap
+                err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+                        sizeof(OC_RSRVD_BITMAP) - 1);
+                err = err || cbor_encode_uint(&policyMap, resource->bitmap);
+
+                if(resource->secure)
+                {
+                    err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
+                            sizeof(OC_RSRVD_SECURE) - 1);
+                    err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
+
+                    if(resource->port != 0)
+                    {
+                        err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
+                                sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+                        err = err || cbor_encode_uint(&policyMap, resource->port);
+                    }
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &policyMap);
+            }
+            // Close
+            err = err || cbor_encoder_close_container(&map, &propMap);
+        }
+        // Close Item
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE);
+
+    {
+        CborEncoder map;
+        err = err || cbor_encoder_create_map(&rootArray, &map, 2);
+
+        // uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+                payload->uri);
+
+        // Rep Map
+        {
+            CborEncoder repMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
+                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
+            err = err || cbor_encoder_create_map(&map, &repMap, 4);
+
+            // Device ID
+            err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID,
+                    sizeof(OC_RSRVD_DEVICE_ID) - 1);
+            err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE);
+
+            // Device Name
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME,
+                    sizeof(OC_RSRVD_DEVICE_NAME) - 1,
+                    payload->deviceName);
+
+            // Device Spec Version
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION,
+                    sizeof(OC_RSRVD_SPEC_VERSION) - 1,
+                    payload->specVersion);
+
+            // Device data Model Version
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
+                    sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1,
+                    payload->dataModelVersion);
+
+            err = err || cbor_encoder_close_container(&map, &repMap);
+        }
+
+        // Close Map
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM);
+    {
+        CborEncoder map;
+        err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+        // uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+                payload->uri);
+
+        // Rep Map
+        {
+            CborEncoder repMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
+                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
+            err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
+
+            // Platform ID
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID,
+                    sizeof(OC_RSRVD_PLATFORM_ID) - 1,
+                    payload->info.platformID);
+
+            // MFG Name
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME,
+                    sizeof(OC_RSRVD_MFG_NAME) - 1,
+                    payload->info.manufacturerName);
+
+            // MFG Url
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL,
+                    sizeof(OC_RSRVD_MFG_URL) - 1,
+                    payload->info.manufacturerUrl);
+
+            // Model Num
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM,
+                    sizeof(OC_RSRVD_MODEL_NUM) - 1,
+                    payload->info.modelNumber);
+
+            // Date of Mfg
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE,
+                    sizeof(OC_RSRVD_MFG_DATE) - 1,
+                    payload->info.dateOfManufacture);
+
+            // Platform Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION,
+                    sizeof(OC_RSRVD_PLATFORM_VERSION) - 1,
+                    payload->info.platformVersion);
+
+            // OS Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION,
+                    sizeof(OC_RSRVD_OS_VERSION) - 1,
+                    payload->info.operatingSystemVersion);
+
+            // Hardware Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION,
+                    sizeof(OC_RSRVD_HARDWARE_VERSION) - 1,
+                    payload->info.hardwareVersion);
+
+            // Firmware Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION,
+                    sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1,
+                    payload->info.firmwareVersion);
+
+            // Support URL
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL,
+                    sizeof(OC_RSRVD_SUPPORT_URL) - 1,
+                    payload->info.supportUrl);
+
+            // System Time
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME,
+                    sizeof(OC_RSRVD_SYSTEM_TIME) - 1,
+                    payload->info.systemTime);
+            err = err || cbor_encoder_close_container(&map, &repMap);
+        }
+
+        // Close Map
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+
+    return OC_STACK_OK;
+}
+
+static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload);
+
+static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray)
+{
+    CborEncoder array;
+    bool err = false;
+
+    err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength);
+    err = err || cbor_encode_uint(&array, valArray->type);
+    for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i)
+    {
+        err = err || cbor_encode_uint(&array, valArray->dimensions[i]);
+    }
+
+    size_t dimTotal = calcDimTotal(valArray->dimensions);
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        switch(valArray->type)
+        {
+            case OCREP_PROP_NULL:
+                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL"));
+                err = CborUnknownError;
+                break;
+            case OCREP_PROP_INT:
+                err = err || cbor_encode_int(&array, valArray->iArray[i]);
+                break;
+            case OCREP_PROP_DOUBLE:
+                err = err || cbor_encode_double(&array, valArray->dArray[i]);
+                break;
+            case OCREP_PROP_BOOL:
+                err = err || cbor_encode_boolean(&array, valArray->bArray[i]);
+                break;
+            case OCREP_PROP_STRING:
+                err = err || cbor_encode_text_string(&array, valArray->strArray[i],
+                        strlen(valArray->strArray[i]));
+                break;
+            case OCREP_PROP_OBJECT:
+                err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
+                break;
+            case OCREP_PROP_ARRAY:
+                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array"));
+                err = CborUnknownError;
+                break;
+        }
+    }
+
+    err = err || cbor_encoder_close_container(parent, &array);
+    return err;
+}
+
+static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload)
+{
+    bool err = false;
+    CborEncoder map;
+    err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength);
+
+    // Uri
+    err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF,
+            sizeof(OC_RSRVD_HREF) - 1,
+            payload->uri);
+
+    // Prop Map
+    // resource types, interfaces
+    if(payload->types || payload->interfaces)
+    {
+        OC_LOG_V(INFO, TAG, "Payload has types or interfaces");
+        err = err || cbor_encode_text_string(&map,
+                OC_RSRVD_PROPERTY,
+                sizeof(OC_RSRVD_PROPERTY) - 1);
+        CborEncoder propMap;
+        err = err || cbor_encoder_create_map(&map, &propMap, 2);
+
+        CborEncoder curArray;
+        if(payload->types)
+        {
+            err = err || cbor_encode_text_string(&propMap,
+                    OC_RSRVD_RESOURCE_TYPE,
+                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
+            err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
+            OCStringLL* val = payload->types;
+            while(val)
+            {
+                err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
+                val = val->next;
+            }
+            err = err || cbor_encoder_close_container(&propMap, &curArray);
+        }
+        if(payload->interfaces)
+        {
+            err = err || cbor_encode_text_string(&propMap,
+                    OC_RSRVD_INTERFACE,
+                    sizeof(OC_RSRVD_INTERFACE) - 1);
+            err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
+            OCStringLL* val = payload->interfaces;
+            while(val)
+            {
+                err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
+                val = val->next;
+            }
+            err = err || cbor_encoder_close_container(&propMap, &curArray);
+        }
+        err = err || cbor_encoder_close_container(&map, &propMap);
+    }
+
+    // Rep Map
+    {
+        CborEncoder repMap;
+        err = err || cbor_encode_text_string(&map,
+                OC_RSRVD_REPRESENTATION,
+                sizeof(OC_RSRVD_REPRESENTATION) - 1);
+        err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
+        OCRepPayloadValue* value = payload->values;
+        while(value)
+        {
+            err = err || cbor_encode_text_string(&repMap,
+                    value->name,
+                    strlen(value->name));
+            switch(value->type)
+            {
+                case OCREP_PROP_NULL:
+                    err = err || cbor_encode_null(&repMap);
+                    break;
+                case OCREP_PROP_INT:
+                    err = err || cbor_encode_int(&repMap,
+                            value->i);
+                    break;
+                case OCREP_PROP_DOUBLE:
+                    err = err || cbor_encode_double(&repMap,
+                            value->d);
+                    break;
+                case OCREP_PROP_BOOL:
+                    err = err || cbor_encode_boolean(&repMap,
+                            value->b);
+                    break;
+                case OCREP_PROP_STRING:
+                    err = err || cbor_encode_text_string(&repMap,
+                            value->str, strlen(value->str));
+                    break;
+                case OCREP_PROP_OBJECT:
+                    err = err || OCConvertSingleRepPayload(&repMap, value->obj);
+                    break;
+                case OCREP_PROP_ARRAY:
+                    err = err || OCConvertArray(&repMap, &value->arr);
+                    break;
+                default:
+                    OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d",
+                            value->type);
+                    break;
+            }
+            value = value->next;
+        }
+
+        err = err || cbor_encoder_close_container(&map, &repMap);
+    }
+
+    // Close Map
+    err = err || cbor_encoder_close_container(parent, &map);
+
+    return err;
+}
+
+static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION);
+
+    while(payload != NULL && !err)
+    {
+        err = err || OCConvertSingleRepPayload(&rootArray, payload);
+        payload = payload->next;
+    }
+
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload,
+        uint8_t** outPayload, size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE);
+
+
+    CborEncoder map;
+    err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+    // Sequence Number
+    err = err || cbor_encode_text_string(&map,
+            OC_RSRVD_NONCE,
+            sizeof(OC_RSRVD_NONCE) - 1);
+    err = err || cbor_encode_uint(&map, payload->sequenceNumber);
+
+    // Max Age
+    err = err || cbor_encode_text_string(&map,
+            OC_RSRVD_TTL,
+            sizeof(OC_RSRVD_TTL) - 1);
+    err = err || cbor_encode_uint(&map, payload->maxAge);
+
+    // Trigger
+    const char* triggerStr = convertTriggerEnumToString(payload->trigger);
+    err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1,
+            triggerStr);
+
+    // Resource type name
+    if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
+    {
+        err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
+                sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType);
+    }
+
+    // Close Map
+    err = err || cbor_encoder_close_container(&rootArray, &map);
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Presence Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+
+    return OC_STACK_OK;
+}
+
+bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value)
+{
+    return cbor_encode_text_string(map, key, keylen) ||
+           cbor_encode_text_string(map, value, strlen(value));
+}
+
+bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value)
+{
+    return value ? AddTextStringToMap(map, key, keylen, value) : false;
+}
diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c
new file mode 100644 (file)
index 0000000..203986f
--- /dev/null
@@ -0,0 +1,869 @@
+//******************************************************************
+//
+// 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 "ocpayloadcbor.h"
+#include <stdlib.h>
+#include "logger.h"
+#include "oic_malloc.h"
+#include "ocstackinternal.h"
+#include "ocpayload.h"
+#include "cbor.h"
+
+#define TAG PCF("OCPayloadParse")
+
+static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
+static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
+static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
+
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize)
+{
+    CborParser parser;
+    CborValue rootValue;
+    bool err = false;
+
+    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
+    if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
+    {
+        OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    if(!cbor_value_is_array(&rootValue))
+    {
+        OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+
+    CborValue arrayValue;
+    // enter the array
+    err = err || cbor_value_enter_container(&rootValue, &arrayValue);
+
+    int payloadType;
+    err = err || cbor_value_get_int(&arrayValue, &payloadType);
+    err = err || cbor_value_advance_fixed(&arrayValue);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+
+    OCStackResult result = OC_STACK_ERROR;
+    switch(payloadType)
+    {
+        case PAYLOAD_TYPE_DISCOVERY:
+            result = OCParseDiscoveryPayload(outPayload, &arrayValue);
+            break;
+        case PAYLOAD_TYPE_DEVICE:
+            result = OCParseDevicePayload(outPayload, &arrayValue);
+            break;
+        case PAYLOAD_TYPE_PLATFORM:
+            result = OCParsePlatformPayload(outPayload, &arrayValue);
+            break;
+        case PAYLOAD_TYPE_REPRESENTATION:
+            result = OCParseRepPayload(outPayload, &arrayValue);
+            break;
+        case PAYLOAD_TYPE_PRESENCE:
+            result = OCParsePresencePayload(outPayload, &arrayValue);
+            break;
+        case PAYLOAD_TYPE_SECURITY:
+            result = OCParseSecurityPayload(outPayload, &arrayValue);
+            break;
+        default:
+            OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
+            result = OC_STACK_ERROR;
+            break;
+    }
+
+    if(result == OC_STACK_OK)
+    {
+        err = err || cbor_value_leave_container(&rootValue, &arrayValue);
+        if(err != CborNoError)
+        {
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
+    }
+
+    return result;
+}
+
+void OCFreeOCStringLL(OCStringLL* ll);
+
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+    char * securityData = NULL;
+
+    if(cbor_value_is_map(arrayVal))
+    {
+        CborValue curVal;
+        err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+        if(cbor_value_is_valid(&curVal))
+        {
+            size_t len;
+            err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
+        }
+    }
+    else
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Cbor main value not a map"));
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+
+    err = err || cbor_value_advance(arrayVal);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Cbor in error condition");
+        OICFree(securityData);
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+
+    *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
+    OICFree(securityData);
+
+    return OC_STACK_OK;
+
+}
+
+static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+
+    OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
+
+    if(!out)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    size_t resourceCount = 0;
+    while(!err &&
+            cbor_value_is_map(arrayVal))
+    {
+        OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
+        if(!resource)
+        {
+            OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+            return OC_STACK_NO_MEMORY;
+        }
+        CborValue curVal;
+
+        // Uri
+        err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+        size_t len;
+        err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+
+        // SID
+        err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
+        err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
+
+        // Prop Tag
+        {
+             err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
+            // ResourceTypes
+            CborValue rtArray;
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
+
+            CborValue rtVal;
+             err = err || cbor_value_enter_container(&rtArray, &rtVal);
+
+            OCStringLL* llPtr = NULL;
+            while(!err && cbor_value_is_text_string(&rtVal))
+            {
+                if(resource->types == NULL)
+                {
+                    resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                    llPtr = resource->types;
+                    if(!llPtr)
+                    {
+                        OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+                        OICFree(resource->uri);
+                        OICFree(resource->sid);
+                        OICFree(resource);
+                        return OC_STACK_NO_MEMORY;
+                    }
+                }
+                else
+                {
+                    llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                    llPtr = llPtr->next;
+                    if(!llPtr)
+                    {
+                        OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+                        OICFree(resource->uri);
+                        OICFree(resource->sid);
+                        OCFreeOCStringLL(resource->types);
+                        OICFree(resource);
+                        return OC_STACK_NO_MEMORY;
+                    }
+
+                }
+
+                 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
+                 err = err || cbor_value_advance(&rtVal);
+            }
+
+             err = err || cbor_value_leave_container(&rtArray, &rtVal);
+            //
+            // Interface Types
+            CborValue ifArray;
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
+            CborValue ifVal;
+             err = err || cbor_value_enter_container(&ifArray, &ifVal);
+
+            llPtr = NULL;
+            while(!err && cbor_value_is_text_string(&ifVal))
+            {
+                if(resource->interfaces == NULL)
+                {
+                    resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                    llPtr = resource->interfaces;
+                    if(!llPtr)
+                    {
+                        OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+                        OICFree(resource->uri);
+                        OICFree(resource->sid);
+                        OCFreeOCStringLL(resource->types);
+                        OICFree(resource);
+                        return OC_STACK_NO_MEMORY;
+                    }
+                }
+                else
+                {
+                    llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                    llPtr = llPtr->next;
+                    if(!llPtr)
+                    {
+                        OC_LOG_V(ERROR, TAG, "Memory allocation failed");
+                        OICFree(resource->uri);
+                        OICFree(resource->sid);
+                        OCFreeOCStringLL(resource->types);
+                        OCFreeOCStringLL(resource->interfaces);
+                        OICFree(resource);
+                        return OC_STACK_NO_MEMORY;
+                    }
+                }
+
+                 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
+                 err = err || cbor_value_advance(&ifVal);
+            }
+             err = err || cbor_value_leave_container(&ifArray, &ifVal);
+
+            // Policy
+            {
+                CborValue policyMap;
+                err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
+
+                // Bitmap
+                CborValue val;
+                err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
+                uint64_t temp = 0;
+                err = err || cbor_value_get_uint64(&val, &temp);
+                resource->bitmap = (uint8_t)temp;
+                // Secure Flag
+                err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
+                if(cbor_value_is_valid(&val))
+                {
+                    err = err || cbor_value_get_boolean(&val, &(resource->secure));
+                    // Port
+                    CborValue port;
+                    err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
+                                    &port);
+                    if(cbor_value_is_valid(&port))
+                    {
+                        err = err || cbor_value_get_uint64(&port, &temp);
+                        resource->port = (uint16_t)temp;
+                    }
+                }
+            }
+        }
+
+         err = err || cbor_value_advance(arrayVal);
+        if(err)
+        {
+            OICFree(resource->uri);
+            OICFree(resource->sid);
+            OCFreeOCStringLL(resource->types);
+            OCFreeOCStringLL(resource->interfaces);
+            OICFree(resource);
+            OCDiscoveryPayloadDestroy(out);
+            OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+        ++resourceCount;
+        OCDiscoveryPayloadAddNewResource(out, resource);
+    }
+
+    *outPayload = (OCPayload*)out;
+
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+
+    if(cbor_value_is_map(arrayVal))
+    {
+        char* uri = NULL;
+        uint8_t* sid = NULL;
+        char* dname = NULL;
+        char* specVer = NULL;
+        char* dmVer = NULL;
+        CborValue curVal;
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+        size_t len;
+         err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
+
+        // Representation
+        {
+             err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+            CborValue repVal;
+            // Device ID
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
+             err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
+            // Device Name
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
+             err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
+            // Device Spec Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
+             err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
+            // Data Model Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
+             err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
+
+        }
+
+         err = err || cbor_value_advance(arrayVal);
+
+        if(err)
+        {
+            OICFree(uri);
+            OICFree(sid);
+            OICFree(dname);
+            OICFree(specVer);
+            OICFree(dmVer);
+            OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+
+        *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
+
+        OICFree(uri);
+        OICFree(sid);
+        OICFree(dname);
+        OICFree(specVer);
+        OICFree(dmVer);
+        if(!*outPayload)
+        {
+            return OC_STACK_NO_MEMORY;
+        }
+
+        return OC_STACK_OK;
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+
+}
+
+static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+
+    if(cbor_value_is_map(arrayVal))
+    {
+        char* uri = NULL;
+        OCPlatformInfo info = {};
+        CborValue curVal;
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+        size_t len;
+         err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
+
+        // Representation
+        {
+             err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
+
+            CborValue repVal;
+            // Platform ID
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
+             err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
+
+            // MFG Name
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
+             err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
+
+            // MFG URL
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
+            }
+
+            // Model Num
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
+            }
+
+            // Date of Mfg
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
+                        NULL);
+            }
+
+            // Platform Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
+                        NULL);
+            }
+
+            // OS Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
+                        &len, NULL);
+            }
+
+            // Hardware Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
+                        NULL);
+            }
+
+            // Firmware Version
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
+                        NULL);
+            }
+
+            // Support URL
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
+            }
+
+            // System Time
+             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
+            if(cbor_value_is_valid(&repVal))
+            {
+                 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
+            }
+        }
+
+         err = err || cbor_value_advance(arrayVal);
+
+        if(err)
+        {
+            OICFree(info.dateOfManufacture);
+            OICFree(info.firmwareVersion);
+            OICFree(info.hardwareVersion);
+            OICFree(info.manufacturerName);
+            OICFree(info.manufacturerUrl);
+            OICFree(info.modelNumber);
+            OICFree(info.operatingSystemVersion);
+            OICFree(info.platformID);
+            OICFree(info.platformVersion);
+            OICFree(info.supportUrl);
+            OICFree(info.systemTime);
+            OC_LOG(ERROR, TAG, PCF("CBOR error In ParsePlatformPayload"));
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+
+        *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
+
+        if(!*outPayload)
+        {
+            return OC_STACK_NO_MEMORY;
+        }
+
+        return OC_STACK_OK;
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+}
+
+static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
+{
+    CborValue insideArray;
+    bool err = false;
+    uint64_t tempInt = 0;
+    OCRepPayloadPropType type;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH];
+    err = err || cbor_value_enter_container(container, &insideArray);
+
+    err = err || cbor_value_get_uint64(&insideArray, &tempInt);
+    err = err || cbor_value_advance_fixed(&insideArray);
+    type = (OCRepPayloadPropType)tempInt;
+
+    for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++ i)
+    {
+         err = err || cbor_value_get_uint64(&insideArray, &tempInt);
+         err = err || cbor_value_advance_fixed(&insideArray);
+        dimensions[i] = tempInt;
+    }
+
+    size_t dimTotal = calcDimTotal(dimensions);
+
+    void* arr = NULL;
+    char* tempStr;
+    size_t len;
+    OCRepPayload* pl;
+    switch(type)
+    {
+        case OCREP_PROP_INT:
+            arr = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+            for(size_t i = 0; i < dimTotal && !err; ++i)
+            {
+                 err = err || cbor_value_get_int64(&insideArray, &(((int64_t*)arr)[i]));
+                 err = err || cbor_value_advance_fixed(&insideArray);
+            }
+            if(!err &&
+                OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
+            {}
+            else
+            {
+                err = CborUnknownError;
+            }
+            break;
+        case OCREP_PROP_DOUBLE:
+            arr = (double*)OICMalloc(dimTotal * sizeof(double));
+            for(size_t i = 0; i < dimTotal && !err; ++i)
+            {
+                 err = err || cbor_value_get_double(&insideArray, &(((double*)arr)[i]));
+                 err = err || cbor_value_advance_fixed(&insideArray);
+            }
+            if(!err &&
+                OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
+            {}
+            else
+            {
+                err = CborUnknownError;
+            }
+            break;
+        case OCREP_PROP_BOOL:
+            arr = (bool*)OICMalloc(dimTotal * sizeof(bool));
+            for(size_t i = 0; i < dimTotal && !err; ++i)
+            {
+                 err = err || cbor_value_get_boolean(&insideArray, &(((bool*)arr)[i]));
+                 err = err || cbor_value_advance_fixed(&insideArray);
+            }
+            if(!err &&
+                OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
+            {}
+            else
+            {
+                err = CborUnknownError;
+            }
+            break;
+        case OCREP_PROP_STRING:
+            arr = (char**)OICMalloc(dimTotal * sizeof(char*));
+            for(size_t i = 0; i < dimTotal && !err; ++i)
+            {
+                err = err || cbor_value_dup_text_string(&insideArray, &tempStr, &len, NULL);
+                ((char**) arr)[i] = tempStr;
+                err = err || cbor_value_advance(&insideArray);
+            }
+            if(!err &&
+                OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
+            {}
+            else
+            {
+                err = CborUnknownError;
+            }
+            break;
+        case OCREP_PROP_OBJECT:
+            arr = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            for(size_t i = 0; i < dimTotal && !err; ++i)
+            {
+                pl = NULL;
+                 err = err || OCParseSingleRepPayload(&pl, &insideArray);
+                ((OCRepPayload**)arr)[i] = pl;
+                 err = err || cbor_value_advance(&insideArray);
+            }
+            if(!err &&
+                OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
+            {}
+            else
+            {
+                err = CborUnknownError;
+            }
+            break;
+        default:
+            OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
+            err = CborUnknownError;
+            break;
+    }
+
+    return err;
+}
+
+static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
+{
+    *outPayload = OCRepPayloadCreate();
+    OCRepPayload* curPayload = *outPayload;
+    bool err = false;
+    if(!*outPayload)
+    {
+        return CborErrorOutOfMemory;
+    }
+
+    size_t len;
+    CborValue curVal;
+    err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
+    if(cbor_value_is_valid(&curVal))
+    {
+        err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
+            NULL);
+    }
+
+    err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
+    if(cbor_value_is_valid(&curVal))
+    {
+        CborValue insidePropArray;
+        err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
+                &insidePropArray);
+
+        if(cbor_value_is_array(&insidePropArray))
+        {
+            CborValue rtArray;
+            err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
+
+            while(!err && cbor_value_is_valid(&rtArray))
+            {
+                char* curRt;
+                err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
+                err = err || cbor_value_advance(&rtArray);
+                OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
+            }
+
+            err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
+        }
+
+        err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
+
+        if(cbor_value_is_array(&insidePropArray))
+        {
+            CborValue ifArray;
+            err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
+
+            while(!err && cbor_value_is_valid(&ifArray))
+            {
+                char* curIf;
+                err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
+                err = err || cbor_value_advance(&ifArray);
+                OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
+            }
+
+            err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
+        }
+    }
+    err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
+    if(cbor_value_is_map(&curVal))
+    {
+        CborValue repMap;
+        err = err || cbor_value_enter_container(&curVal, &repMap);
+
+        while(!err && cbor_value_is_valid(&repMap))
+        {
+            char* name;
+             err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
+
+             err = err || cbor_value_advance(&repMap);
+
+            int64_t intval = 0;
+            bool boolval = false;
+            char* strval = NULL;
+            double doubleval = 0;
+            OCRepPayload* pl;
+
+            switch(cbor_value_get_type(&repMap))
+            {
+                case CborNullType:
+                    OCRepPayloadSetNull(curPayload, name);
+                    break;
+                case CborIntegerType:
+                    err = err || cbor_value_get_int64(&repMap, &intval);
+                    OCRepPayloadSetPropInt(curPayload, name, intval);
+                    break;
+                case CborDoubleType:
+                    err = err || cbor_value_get_double(&repMap, &doubleval);
+                    OCRepPayloadSetPropDouble(curPayload, name, doubleval);
+                    break;
+                case CborBooleanType:
+                    err = err || cbor_value_get_boolean(&repMap, &boolval);
+                    OCRepPayloadSetPropBool(curPayload, name, boolval);
+                    break;
+                case CborTextStringType:
+                    err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
+                    OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
+                    break;
+                case CborMapType:
+                    err = err || OCParseSingleRepPayload(&pl, &repMap);
+                    OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
+                    break;
+                case CborArrayType:
+                    err = err || OCParseArray(curPayload, name, &repMap);
+                    break;
+                default:
+                    OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
+                    err = true;
+            }
+
+             err = err || cbor_value_advance(&repMap);
+            OICFree(name);
+        }
+        err = err || cbor_value_leave_container(&curVal, &repMap);
+    }
+
+    if(err)
+    {
+        OCRepPayloadDestroy(*outPayload);
+        *outPayload = NULL;
+    }
+
+    return err;
+}
+static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+
+    OCRepPayload* rootPayload = NULL;
+    OCRepPayload* curPayload = NULL;
+    OCRepPayload* temp = NULL;
+    while(!err && cbor_value_is_map(arrayVal))
+    {
+         err = err || OCParseSingleRepPayload(&temp, arrayVal);
+
+        if(rootPayload == NULL)
+        {
+            rootPayload = temp;
+            curPayload = temp;
+        }
+        else
+        {
+            curPayload->next = temp;
+            curPayload = curPayload->next;
+        }
+
+
+         err = err || cbor_value_advance(arrayVal);
+        if(err)
+        {
+            OCRepPayloadDestroy(rootPayload);
+            OC_LOG_V(ERROR, TAG, PCF("CBOR error in ParseRepPayload"));
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+    }
+
+    *outPayload = (OCPayload*)rootPayload;
+
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
+{
+    bool err = false;
+    if(cbor_value_is_map(arrayVal))
+    {
+        uint64_t seqNum = 0;
+        uint64_t maxAge = 0;
+        OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
+        char* tempStr = NULL;
+        size_t len = 0;
+
+        CborValue curVal;
+        // Sequence Number
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
+         err = err || cbor_value_get_uint64(&curVal, &seqNum);
+
+        // Max Age
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
+         err = err || cbor_value_get_uint64(&curVal, &maxAge);
+
+        // Trigger
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
+         err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
+        trigger = convertTriggerStringToEnum(tempStr);
+        OICFree(tempStr);
+        tempStr = NULL;
+
+        // Resource type name
+         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
+        if(cbor_value_is_valid(&curVal))
+        {
+             err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
+        }
+
+        err = err || cbor_value_advance(arrayVal);
+
+        if(!err)
+        {
+            *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
+        }
+        OICFree(tempStr);
+
+        if(err)
+        {
+            OCPayloadDestroy(*outPayload);
+            OC_LOG_V(ERROR, TAG, PCF("CBOR error Parse Presence Payload"));
+            return OC_STACK_MALFORMED_RESPONSE;
+        }
+
+        if(!*outPayload)
+        {
+            return OC_STACK_NO_MEMORY;
+        }
+
+        return OC_STACK_OK;
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, PCF("Root presence node was not a map"));
+        return OC_STACK_MALFORMED_RESPONSE;
+    }
+}
index a5fa040..5f64f10 100644 (file)
 #include "ocresourcehandler.h"
 #include "ocobserve.h"
 #include "occollection.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
 #include "logger.h"
 #include "cJSON.h"
+#include "ocpayload.h"
 
 #include "cacommon.h"
 #include "cainterface.h"
 
 extern OCResource *headResource;
 static OCPlatformInfo savedPlatformInfo = {};
-static cJSON *savedDeviceInfo = NULL;
-static const char * VIRTUAL_RSRCS[] =
-{
-       "/oc/core",
-       "/oc/core/d",
-       "/oic/p",
-       "/oc/core/types/d",
-       #ifdef WITH_PRESENCE
-       "/oic/ad"
-       #endif
-};
+static OCDeviceInfo savedDeviceInfo = {};
 
 //-----------------------------------------------------------------------------
 // Default resource entity handler function
 //-----------------------------------------------------------------------------
 OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest * request)
+        OCEntityHandlerRequest * request, void* callbackParam)
 {
     //TODO ("Implement me!!!!");
     // TODO:  remove silence unused param warnings
     (void) flag;
     (void) request;
+    (void) callbackParam;
     return  OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
 }
 
 /* This method will retrieve the port at which the secure resource is hosted */
-static OCStackResult GetSecurePortInfo(CATransportType_t connType, uint16_t *port)
+static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
 {
-    CALocalConnectivity_t* info = NULL;
-    uint32_t size = 0;
-    OCStackResult ret = OC_STACK_ERROR;
+    uint16_t p = 0;
 
-    CAResult_t caResult = CAGetNetworkInformation(&info, &size);
-    if ((caResult == CA_STATUS_OK) && info && size)
+    if (endpoint->adapter == OC_ADAPTER_IP)
     {
-        while (size--)
+        if (endpoint->flags & OC_IP_USE_V6)
         {
-            if (info[size].isSecured && info[size].type == connType)
-            {
-                if (info[size].type == CA_IPV4)
-                {
-                    *port = info[size].addressInfo.IP.port;
-                    ret = OC_STACK_OK;
-                    break;
-                }
-            }
+            p = caglobals.ip.u6s.port;
+        }
+        else if (endpoint->flags & OC_IP_USE_V4)
+        {
+            p = caglobals.ip.u4s.port;
         }
     }
 
-    OCFree(info);
-    return ret;
+    *port = p;
+    return OC_STACK_OK;
 }
 
-static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
+/*
+ * Function will extract 0, 1 or 2 filters from query.
+ * More than 2 filters or unsupported filters will result in error.
+ * If both filters are of the same supported type, the 2nd one will be picked.
+ * Resource and device filters in the SAME query are NOT validated
+ * and resources will likely not clear filters.
+ */
+static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char **filterTwo)
 {
-    cJSON *rootObj = cJSON_CreateObject();
 
-    if (!rootObj)
-    {
-        return NULL;
-    }
+    char *key = NULL;
+    char *value = NULL;
+    char *restOfQuery = NULL;
+    int numKeyValuePairsParsed = 0;
 
-    cJSON *repObj = NULL;
-    char *jsonEncodedInfo = NULL;
+    *filterOne = NULL;
+    *filterTwo = NULL;
 
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
-            cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
+    OC_LOG_V(INFO, TAG, "Extracting params from %s", query);
 
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
+    char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
 
-    cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID, cJSON_CreateString(info.platformID));
-    cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME, cJSON_CreateString(info.manufacturerName));
-    if (info.manufacturerUrl)
+    while(keyValuePair)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
-                cJSON_CreateString(info.manufacturerUrl));
-    }
+        if (numKeyValuePairsParsed >= 2)
+        {
+            OC_LOG(ERROR, TAG, PCF("More than 2 queries params in URI."));
+            return OC_STACK_INVALID_QUERY;
+        }
 
-    if (info.modelNumber)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
-                cJSON_CreateString(info.modelNumber));
-    }
+        key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
 
-    if (info.dateOfManufacture)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
-                cJSON_CreateString(info.dateOfManufacture));
-    }
+        if (!key || !value)
+        {
+            return OC_STACK_INVALID_QUERY;
+        }
+        else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
+        {
+            *filterOne = value;     // if
+        }
+        else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
+        {
+            *filterTwo = value;     // rt
+        }
+        else
+        {
+            OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
+            return OC_STACK_INVALID_QUERY;
+        }
+        ++numKeyValuePairsParsed;
 
-    if (info.platformVersion)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
-                cJSON_CreateString(info.platformVersion));
+        keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
     }
 
-    if (info.operatingSystemVersion)
+    OC_LOG_V(INFO, TAG, "Extracted params %s and %s.", *filterOne, *filterTwo);
+    return OC_STACK_OK;
+}
+
+static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
+{
+    if (strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_URI) == 0)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
-                cJSON_CreateString(info.operatingSystemVersion));
+        return OC_WELL_KNOWN_URI;
     }
-
-    if (info.hardwareVersion)
+    else if (strcmp(uriInRequest, OC_RSRVD_DEVICE_URI) == 0)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
-                cJSON_CreateString(info.hardwareVersion));
+        return OC_DEVICE_URI;
     }
-
-    if (info.firmwareVersion)
+    else if (strcmp(uriInRequest, OC_RSRVD_PLATFORM_URI) == 0)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
-                cJSON_CreateString(info.firmwareVersion));
+        return OC_PLATFORM_URI;
     }
-
-    if (info.supportUrl)
+    else if (strcmp(uriInRequest, OC_RSRVD_RESOURCE_TYPES_URI) == 0)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
-                cJSON_CreateString(info.supportUrl));
+        return OC_RESOURCE_TYPES_URI;
     }
-
-    if (info.systemTime)
+#ifdef WITH_PRESENCE
+    else if (strcmp(uriInRequest, OC_RSRVD_PRESENCE_URI) == 0)
     {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
-                cJSON_CreateString(info.systemTime));
+        return OC_PRESENCE;
     }
-
-    jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
-    cJSON_Delete(rootObj);
-
-    return jsonEncodedInfo;
+#endif //WITH_PRESENCE
+    return OC_UNKNOWN_URI;
 }
 
-static OCStackResult ValidateUrlQuery (char *url, char *query,
-                                uint8_t *filterOn, char **filterValue)
+static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *query,
+                                            char **filterOne, char **filterTwo)
 {
-    if(!filterOn || !filterValue)
+    if(!filterOne || !filterTwo)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    char *filterParam = NULL;
-
-    OC_LOG(INFO, TAG, PCF("Entering ValidateUrlQuery"));
-    if (!url)
-    {
-        return OC_STACK_INVALID_URI;
-    }
-
-    if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
-                strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
-                strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
-    {
-        *filterOn = STACK_RES_DISCOVERY_NOFILTER;
-        if (query && *query)
-        {
-            char* strTokPtr = NULL;
-            filterParam = strtok_r((char *)query, "=", &strTokPtr);
-            *filterValue = strtok_r(NULL, " ", &strTokPtr);
+    *filterOne = NULL;
+    *filterTwo = NULL;
 
-            if (!(*filterValue) || ! filterParam)
-            {
-                return OC_STACK_INVALID_QUERY;
-            }
-            else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0)
-            {
-                // Resource discovery with interface filter
-                *filterOn = STACK_RES_DISCOVERY_IF_FILTER;
-            }
-            else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0)
-            {
-                // Resource discovery with resource type filter
-                *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
-            }
-            else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0)
-            {
-                //Device ID filter
-                *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
-            }
-            else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0)
-            {
-                //Device Name filter
-                *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
-            }
-            else
-            {
-                // Other filter types not supported
-                return OC_STACK_INVALID_QUERY;
-            }
-        }
-    }
     #ifdef WITH_PRESENCE
-    else if (strcmp((char *)url, GetVirtualResourceUri(OC_PRESENCE)) == 0)
+    if (uri == OC_PRESENCE)
     {
         //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
-        OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request"));
-        *filterOn = STACK_RES_DISCOVERY_NOFILTER;
+        OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request for virtual resource."));
+        return OC_STACK_OK;
     }
     #endif
-    else
-    {
-        // Other URIs not yet supported
-        return OC_STACK_INVALID_URI;
-    }
-    OC_LOG(INFO, TAG, PCF("Exiting ValidateUrlQuery"));
-    return OC_STACK_OK;
-}
 
+    OCStackResult result = OC_STACK_OK;
 
-OCStackResult
-BuildVirtualResourceResponse(const OCResource *resourcePtr, uint8_t filterOn,
-                       const char *filterValue, char *out, uint16_t *remaining,
-                       CATransportType_t connType )
-{
-    if(!resourcePtr || !out  || !remaining)
+    if (query && *query)
     {
-        return OC_STACK_INVALID_PARAM;
+        result = ExtractFiltersFromQuery(query, filterOne, filterTwo);
     }
 
-    OCResourceType *resourceTypePtr = NULL;
-    OCResourceInterface *interfacePtr = NULL;
-    cJSON *resObj = NULL;
-    cJSON *propObj = NULL;
-    cJSON *rtArray = NULL;
-    char *jsonStr = NULL;
-    uint8_t encodeRes = 0;
-    OCStackResult ret = OC_STACK_OK;
-    uint16_t jsonLen = 0;
+    return result;
+}
 
-    OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponse"));
-    resObj = cJSON_CreateObject();
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+                    OCRepPayload** payload)
+{
+    OCRepPayload *tempPayload = OCRepPayloadCreate();
 
-    if (resourcePtr)
+    if (!resourcePtr)
     {
-        encodeRes = 0;
-        if ((filterOn == STACK_RES_DISCOVERY_RT_FILTER) && filterValue)
-        {
-            resourceTypePtr = resourcePtr->rsrcType;
-            while (resourceTypePtr)
-            {
-                if (strcmp (resourceTypePtr->resourcetypename, filterValue) == 0)
-                {
-                    encodeRes = 1;
-                    break;
-                }
-                resourceTypePtr = resourceTypePtr->next;
-            }
-        }
-        else if ((filterOn == STACK_RES_DISCOVERY_IF_FILTER) && filterValue)
-        {
-            interfacePtr = resourcePtr->rsrcInterface;
-            while (interfacePtr)
-            {
-                if (strcmp (interfacePtr->name, filterValue) == 0)
-                {
-                    encodeRes = 1;
-                    break;
-                }
-                interfacePtr = interfacePtr->next;
-            }
-        }
-        else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
-        {
-            encodeRes = 1;
-        }
-        else
-        {
-            //TODO: Unsupported query filter
-            return OC_STACK_INVALID_QUERY;
-        }
-
-        if (encodeRes)
-        {
-            // Add URIs
-            cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
-
-            // Add server instance id
-            cJSON_AddItemToObject (resObj,
-                                   OC_RSRVD_SERVER_INSTANCE_ID,
-                                   cJSON_CreateString(OCGetServerInstanceIDString()));
-
-            cJSON_AddItemToObject (resObj, OC_RSRVD_PROPERTY, propObj = cJSON_CreateObject());
-            // Add resource types
-            cJSON_AddItemToObject (propObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
-            resourceTypePtr = resourcePtr->rsrcType;
-            while (resourceTypePtr)
-            {
-                cJSON_AddItemToArray (rtArray,
-                                      cJSON_CreateString(resourceTypePtr->resourcetypename));
-                resourceTypePtr = resourceTypePtr->next;
-            }
-            // Add interface types
-            cJSON_AddItemToObject (propObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
-            interfacePtr = resourcePtr->rsrcInterface;
-            while (interfacePtr)
-            {
-                cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
-                interfacePtr = interfacePtr->next;
-            }
-            // If resource is observable, set observability flag.
-            // Resources that are not observable will not have the flag.
-            if (resourcePtr->resourceProperties & OC_OBSERVABLE)
-            {
-                cJSON_AddItemToObject (propObj, OC_RSRVD_OBSERVABLE,
-                                       cJSON_CreateNumber(OC_RESOURCE_OBSERVABLE));
-            }
-            // Set secure flag for secure resources
-            if (resourcePtr->resourceProperties & OC_SECURE)
-            {
-                cJSON_AddNumberToObject (propObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
-                //Set the IP port also as secure resources are hosted on a different port
-                uint16_t port = 0;
-                if (GetSecurePortInfo (connType, &port) == OC_STACK_OK)
-                {
-                    cJSON_AddNumberToObject (propObj, OC_RSRVD_HOSTING_PORT, port);
-                }
-            }
-
-        }
+        OCRepPayloadDestroy(tempPayload);
+        return OC_STACK_INVALID_PARAM;
     }
-    jsonStr = cJSON_PrintUnformatted (resObj);
 
-    if(!jsonStr)
+    if(!tempPayload)
     {
-        cJSON_Delete(resObj);
         return OC_STACK_NO_MEMORY;
     }
 
-    jsonLen = strlen(jsonStr);
-    if (jsonLen < *remaining)
+    OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
+
+    OCResourceType *resType = resourcePtr->rsrcType;
+    while(resType)
     {
-        strcpy(out, jsonStr);
-        *remaining = *remaining - jsonLen;
+        OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename);
+        resType = resType->next;
     }
-    else
+
+    OCResourceInterface *resInterface = resourcePtr->rsrcInterface;
+    while(resInterface)
     {
-        ret = OC_STACK_ERROR;
+        OCRepPayloadAddInterface(tempPayload, resInterface->name);
+        resInterface = resInterface->next;
     }
-    cJSON_Delete (resObj);
-    OCFree (jsonStr);
-
-    OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponse"));
-    return ret;
-}
 
-OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
-                                                    char *out, uint16_t *remaining)
-{
-    if(!out || !remaining)
+    OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
+    while(resAttrib)
     {
-        return OC_STACK_INVALID_PARAM;
+        OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
+                                resAttrib->attrValue);
+        resAttrib = resAttrib->next;
     }
 
-    OCStackResult ret = OC_STACK_ERROR;
-
-    if (savedDeviceInfo != NULL)
+    if(!*payload)
     {
-        char *jsonStr = NULL;
-        uint16_t jsonLen = 0;
-        cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, OC_RSRVD_REPRESENTATION);
-
-        OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
-
-        if ((filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER) && filterValue)
-        {
-            if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID) != NULL) &&
-                    strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_ID)->valuestring, filterValue)
-                    == 0)
-            {
-                ret = OC_STACK_OK;
-            }
-        }
-        else if ((filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER) && filterValue)
-        {
-            if((cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME) != NULL) &&
-                    strcmp(cJSON_GetObjectItem(repObj,OC_RSRVD_DEVICE_NAME)->valuestring,
-                        filterValue) == 0)
-            {
-                ret = OC_STACK_OK;
-            }
-        }
-        else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
-        {
-            ret = OC_STACK_OK;
-        }
-        else
-        {
-            ret = OC_STACK_INVALID_QUERY;
-        }
-
-        if (ret == OC_STACK_OK)
-        {
-            jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
-
-            if(jsonStr)
-            {
-                jsonLen = strlen(jsonStr);
-
-                if (jsonLen < *remaining)
-                {
-                    strncpy(out, jsonStr, (jsonLen + 1));
-                    *remaining = *remaining - jsonLen;
-                    ret = OC_STACK_OK;
-                }
-                else
-                {
-                    ret = OC_STACK_ERROR;
-                }
-
-                OCFree(jsonStr);
-            }
-            else
-            {
-                ret = OC_STACK_ERROR;
-            }
-        }
-        else
-        {
-            ret = OC_STACK_INVALID_DEVICE_INFO;
-        }
+        *payload = tempPayload;
     }
     else
     {
-        OC_LOG(ERROR, TAG, PCF("No device info found."));
-        //error so that stack won't respond with empty payload
-        ret = OC_STACK_INVALID_DEVICE_INFO;
+        OCRepPayloadAppend(*payload, tempPayload);
     }
 
-    OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
-    return ret;
+    return OC_STACK_OK;
 }
 
-OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+                        OCDiscoveryPayload *payload, OCDevAddr *devAddr)
 {
-    OCStackResult ret = OC_STACK_OK;
-
-    char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
-
-    if(jsonStr)
-    {
-        size_t jsonLen = strlen(jsonStr);
-
-        if (jsonLen < *remaining)
-        {
-            strncpy(out, jsonStr, (jsonLen + 1));
-            *remaining = *remaining - jsonLen;
-            ret = OC_STACK_OK;
-        }
-        else
-        {
-            OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
-            ret = OC_STACK_ERROR;
-        }
-        OCFree(jsonStr);
-    }
-    else
+    if (!resourcePtr || !payload)
     {
-        OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
-        ret = OC_STACK_ERROR;
+        return OC_STACK_INVALID_PARAM;
     }
-
-
-    return ret;
-
-}
-const char * GetVirtualResourceUri( OCVirtualResources resource)
-{
-    if (resource < OC_MAX_VIRTUAL_RESOURCES)
+    uint16_t port = 0;
+    if (resourcePtr->resourceProperties & OC_SECURE)
     {
-        return VIRTUAL_RSRCS[resource];
+       if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
+       {
+           port = 0;
+       }
     }
 
-    return NULL;
+    OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+    return OC_STACK_OK;
 }
 
-bool IsVirtualResource(const char* resourceUri)
-{
-    if(!resourceUri)
-    {
-        return false;
-    }
-
-    for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
-    {
-        if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
-        {
-            return true;
-        }
-    }
-    return false;
-}
 
 uint8_t IsCollectionResource (OCResource *resource)
 {
@@ -573,7 +308,7 @@ OCResource *FindResourceByUri(const char* resourceUri)
         }
         pointer = pointer->next;
     }
-    OC_LOG(INFO, TAG, PCF("Resource not found"));
+    OC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
     return NULL;
 }
 
@@ -587,16 +322,17 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
         return OC_STACK_INVALID_PARAM;
     }
 
-    OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
+    OC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
 
     // Check if virtual resource
-    if (IsVirtualResource((const char*)request->resourceUrl))
+    if (GetTypeOfVirtualURI(request->resourceUrl) != OC_UNKNOWN_URI)
     {
+        OC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
         *handling = OC_RESOURCE_VIRTUAL;
         *resource = headResource;
         return OC_STACK_OK;
     }
-    if (NULL == request->resourceUrl || (strlen((const char*)(request->resourceUrl)) == 0))
+    if (strlen((const char*)(request->resourceUrl)) == 0)
     {
         // Resource URL not specified
         *handling = OC_RESOURCE_NOT_SPECIFIED;
@@ -621,13 +357,6 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
             return OC_STACK_NO_RESOURCE;
         }
 
-        // secure resource will entertain only authorized requests
-        if ((resourcePtr->resourceProperties & OC_SECURE) && (request->secured == 0))
-        {
-            OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
-            return OC_STACK_RESOURCE_ERROR;
-        }
-
         if (IsCollectionResource (resourcePtr))
         {
             // Collection resource
@@ -693,149 +422,248 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
     return result;
 }
 
-static OCStackResult
-HandleVirtualResource (OCServerRequest *request, OCResource* resource)
+static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilter)
 {
-    if(!request || !resource)
+    if (!resource)
     {
-        return OC_STACK_INVALID_PARAM;
+        return false;
     }
 
-    OCStackResult result = OC_STACK_ERROR;
-    char *filterValue = NULL;
-    uint8_t filterOn = 0;
-    uint16_t remaining = 0;
-    char * ptr = NULL;
-    uint8_t firstLoopDone = 0;
-    char discoveryResBuf[MAX_RESPONSE_LENGTH] = {};
-
-    OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
+    // Null or empty is analogous to no filter.
+    if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+    {
+        return true;
+    }
 
-    result = ValidateUrlQuery (request->resourceUrl,
-            request->query, &filterOn,
-            &filterValue);
+    OCResourceType *resourceTypePtr = resource->rsrcType;
 
-    if (result == OC_STACK_OK)
+    while (resourceTypePtr)
     {
-        if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
+        if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
         {
-            ptr = discoveryResBuf;
-            remaining = MAX_RESPONSE_LENGTH;
+            return true;
+        }
+        resourceTypePtr = resourceTypePtr->next;
+    }
 
-            // Check if valid resource and enough space in buffer for atleast
-            // the null character.
-            while(resource && (remaining > 1))
-            {
-                if((resource->resourceProperties & OC_ACTIVE)
-                        && (resource->resourceProperties & OC_DISCOVERABLE))
-                {
-                    // if there is data on the buffer, we have already added a response,
-                    // so we need to add a comma before we do anything
-                    if(firstLoopDone
-                            && remaining >= (sizeof(OC_JSON_SEPARATOR)+1))
-                    {
-                        *ptr = OC_JSON_SEPARATOR;
-                        ptr++;
-                        remaining--;
-                    }
-                    firstLoopDone = 1;
-                    result = BuildVirtualResourceResponse(resource, filterOn, filterValue,
-                            (char*)ptr, &remaining, request->connectivityType );
+    OC_LOG_V(INFO, TAG, PCF("%s does not contain rt=%s."), resource->uri, resourceTypeFilter);
+    return false;
+}
 
-                    if (result != OC_STACK_OK)
-                    {
-                        // if this failed, we need to remove the comma added above.
-                        if(!firstLoopDone)
-                        {
-                            ptr--;
-                            *ptr = '\0';
-                            remaining++;
-                        }
-                        break;
-                    }
-                    ptr += strlen((char *)ptr);
-                }
-                resource = resource->next;
-            }
+static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
+{
+    if (!resource)
+    {
+        return false;
+    }
 
-            if(strlen((const char *)discoveryResBuf) > 0)
-            {
-                OCEntityHandlerResponse response = {};
+    // Null or empty is analogous to no filter.
+    if (interfaceFilter == NULL || *interfaceFilter == 0)
+    {
+        return true;
+    }
 
-                response.ehResult = OC_EH_OK;
-                response.payload = discoveryResBuf;
-                response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
-                response.persistentBufferFlag = 0;
-                response.requestHandle = (OCRequestHandle) request;
-                response.resourceHandle = (OCResourceHandle) resource;
+    OCResourceInterface *interfacePtr = resource->rsrcInterface;
 
-                result = OCDoResponse(&response);
-            }
+    while (interfacePtr)
+    {
+        if (strcmp (interfacePtr->name, interfaceFilter) == 0)
+        {
+            return true;
         }
-        else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+        interfacePtr = interfacePtr->next;
+    }
+
+    OC_LOG_V(INFO, TAG, PCF("%s does not contain if=%s."), resource->uri, interfaceFilter);
+    return false;
+}
+
+/*
+ * If the filters are null, they will be assumed to NOT be present
+ * and the resource will not be matched against them.
+ * Function will return true if all non null AND non empty filters passed in find a match.
+ */
+static bool includeThisResourceInResponse(OCResource *resource,
+                                                 char *interfaceFilter,
+                                                 char *resourceTypeFilter)
+{
+    if (!resource)
+    {
+        OC_LOG(ERROR, TAG, PCF("Invalid resource"));
+        return false;
+    }
+
+    if ( resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+    {
+        /*
+         * At least one valid filter should be available to
+         * include the resource in discovery response
+         */
+        if (!((interfaceFilter && *interfaceFilter ) ||
+              (resourceTypeFilter && *resourceTypeFilter)))
         {
-            remaining = MAX_RESPONSE_LENGTH;
-            ptr = discoveryResBuf;
+            OC_LOG_V(INFO, TAG, PCF("%s no query string for EXPLICIT_DISCOVERABLE \
+                resource"), resource->uri);
+            return false;
+        }
+    }
+    else if ( !(resource->resourceProperties & OC_ACTIVE) ||
+         !(resource->resourceProperties & OC_DISCOVERABLE))
+    {
+        OC_LOG_V(INFO, TAG, PCF("%s not ACTIVE or DISCOVERABLE"), resource->uri);
+        return false;
+    }
 
-            result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
-                    (char*)ptr, &remaining);
+    return resourceMatchesIFFilter(resource, interfaceFilter) &&
+           resourceMatchesRTFilter(resource, resourceTypeFilter);
 
-            if(result == OC_STACK_OK)
-            {
-                ptr += strlen((char*)ptr);
-            }
+}
 
-            if(remaining < MAX_RESPONSE_LENGTH)
-            {
-                OCEntityHandlerResponse response = {0};
+OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
+                                OCPayload *discoveryPayload, OCEntityHandlerResult ehResult)
+{
+    OCEntityHandlerResponse response = {};
 
-                response.ehResult = OC_EH_OK;
-                response.payload = discoveryResBuf;
-                response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
-                response.persistentBufferFlag = 0;
-                response.requestHandle = (OCRequestHandle) request;
-                response.resourceHandle = (OCResourceHandle) resource;
+    response.ehResult = ehResult;
+    response.payload = discoveryPayload;
+    response.persistentBufferFlag = 0;
+    response.requestHandle = (OCRequestHandle) request;
+    response.resourceHandle = (OCResourceHandle) resource;
 
-                result = OCDoResponse(&response);
-            }
-        }
-        else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
-        {
-            remaining = MAX_RESPONSE_LENGTH;
-            ptr = discoveryResBuf;
+    return OCDoResponse(&response);
+}
+
+static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
+{
+    if (!request || !resource)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
 
-            result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
+    OCStackResult discoveryResult = OC_STACK_ERROR;
+
+    bool bMulticast    = false;     // Was the discovery request a multicast request?
+    OCPayload* payload = NULL;
+
+    OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
 
-            if(result == OC_STACK_OK)
+    OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
+
+    // Step 1: Generate the response to discovery request
+    if (virtualUriInRequest == OC_WELL_KNOWN_URI)
+    {
+        char *filterOne = NULL;
+        char *filterTwo = NULL;
+
+        discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+                &filterOne, &filterTwo);
+
+        if (discoveryResult == OC_STACK_OK)
+        {
+            payload = (OCPayload*)OCDiscoveryPayloadCreate();
+
+            if(payload)
             {
-                ptr += strlen((char*)ptr);
+                for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+                {
+                    if(includeThisResourceInResponse(resource, filterOne, filterTwo))
+                    {
+                        discoveryResult = BuildVirtualResourceResponse(resource,
+                                (OCDiscoveryPayload*)payload,
+                                &request->devAddr);
+                    }
+                }
+                // Set discoveryResult appropriately if no 'valid' resources are available.
+                if (((OCDiscoveryPayload*)payload)->resources == NULL)
+                {
+                    discoveryResult = OC_STACK_NO_RESOURCE;
+                }
             }
-
-            if(remaining < MAX_RESPONSE_LENGTH)
+            else
             {
-                OCEntityHandlerResponse response = {0};
+                discoveryResult = OC_STACK_NO_MEMORY;
+            }
+        }
+        else
+        {
+            OC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
+        }
+    }
+    else if (virtualUriInRequest == OC_DEVICE_URI)
+    {
+        payload = (OCPayload*)OCDevicePayloadCreate(OC_RSRVD_DEVICE_URI,
+                OCGetServerInstanceID(), savedDeviceInfo.deviceName,
+                OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
+        if (!payload)
+        {
+            discoveryResult = OC_STACK_NO_MEMORY;
+        }
+        else
+        {
+            discoveryResult = OC_STACK_OK;
+        }
+    }
+    else if (virtualUriInRequest == OC_PLATFORM_URI)
+    {
+        payload = (OCPayload*)OCPlatformPayloadCreate(
+                OC_RSRVD_PLATFORM_URI,
+                &savedPlatformInfo);
+        if (!payload)
+        {
+            discoveryResult = OC_STACK_NO_MEMORY;
+        }
+        else
+        {
+            discoveryResult = OC_STACK_OK;
+        }
+    }
 
-                response.ehResult = OC_EH_OK;
-                response.payload = discoveryResBuf;
-                response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
-                response.persistentBufferFlag = 0;
-                response.requestHandle = (OCRequestHandle) request;
-                response.resourceHandle = (OCResourceHandle) resource;
+    /**
+     * Step 2: Send the discovery response
+     *
+     * Iotivity should respond to discovery requests in below manner:
+     * 1)If query filter matching fails and discovery request is multicast,
+     *   it should NOT send any response.
+     * 2)If query filter matching fails and discovery request is unicast,
+     *   it should send an error(RESOURCE_NOT_FOUND - 404) response.
+     * 3)If Server does not have any 'DISCOVERABLE' resources and discovery
+     *   request is multicast, it should NOT send any response.
+     * 4)If Server does not have any 'DISCOVERABLE' resources and discovery
+     *   request is unicast, it should send an error(RESOURCE_NOT_FOUND - 404) response.
+     */
 
-                result = OCDoResponse(&response);
-            }
+    #ifdef WITH_PRESENCE
+    if ((virtualUriInRequest == OC_PRESENCE) &&
+        (resource->resourceProperties & OC_ACTIVE))
+    {
+        // Presence uses observer notification api to respond via SendPresenceNotification.
+        SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
+    }
+    else
+    #endif
+    {
+        if(discoveryResult == OC_STACK_OK)
+        {
+            SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
+        }
+        else if(bMulticast == false)
+        {
+            OC_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);
         }
-        #ifdef WITH_PRESENCE
         else
         {
-            if(resource->resourceProperties & OC_ACTIVE){
-                SendPresenceNotification(NULL);
-            }
+            // Ignoring the discovery request as per RFC 7252, Section #8.2
+            OC_LOG_V(INFO, TAG, "Silently ignoring the request since device does not have \
+                any useful data to send");
         }
-        #endif
     }
-    result = OC_STACK_OK;
-    return result;
+
+    OCPayloadDestroy(payload);
+
+    return OC_STACK_OK;
 }
 
 static OCStackResult
@@ -851,16 +679,22 @@ HandleDefaultDeviceEntityHandler (OCServerRequest *request)
     OCEntityHandlerRequest ehRequest = {};
 
     OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) NULL, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, (OCObservationId)0);
+    result = FormOCEntityHandlerRequest(&ehRequest,
+                                        (OCRequestHandle) request,
+                                        request->method,
+                                        &request->devAddr,
+                                        (OCResourceHandle) NULL, request->query,
+                                        request->payload,
+                                        request->payloadSize,
+                                        request->numRcvdVendorSpecificHeaderOptions,
+                                        request->rcvdVendorSpecificHeaderOptions,
+                                        (OCObserveAction)request->observationOption,
+                                        (OCObservationId)0);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
     // At this point we know for sure that defaultDeviceHandler exists
     ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
-                                  (char*) request->resourceUrl);
+                                  (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
     if(ehResult == OC_EH_SLOW)
     {
         OC_LOG(INFO, TAG, PCF("This is a slow resource"));
@@ -893,11 +727,19 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     OCEntityHandlerRequest ehRequest = {};
 
     OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) resource, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, 0);
+
+    result = FormOCEntityHandlerRequest(&ehRequest,
+                                        (OCRequestHandle)request,
+                                        request->method,
+                                        &request->devAddr,
+                                        (OCResourceHandle)resource,
+                                        request->query,
+                                        request->payload,
+                                        request->payloadSize,
+                                        request->numRcvdVendorSpecificHeaderOptions,
+                                        request->rcvdVendorSpecificHeaderOptions,
+                                        (OCObserveAction)request->observationOption,
+                                        0);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
     if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
@@ -905,10 +747,10 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         OC_LOG(INFO, TAG, PCF("No observation requested"));
         ehFlag = OC_REQUEST_FLAG;
     }
-    else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER &&
-            !collectionResource)
+    else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER && !collectionResource)
     {
-        OC_LOG(INFO, TAG, PCF("Registering observation requested"));
+        OC_LOG(INFO, TAG, PCF("Observation registration requested"));
+
         result = GenerateObserverId(&ehRequest.obsInfo.obsId);
         VERIFY_SUCCESS(result, OC_STACK_OK);
 
@@ -916,7 +758,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
                 (const char *)(request->query),
                 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
                 resource, request->qos,
-                &request->addressInfo, request->connectivityType);
+                &request->devAddr);
 
         if(result == OC_STACK_OK)
         {
@@ -927,9 +769,9 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         else
         {
             result = OC_STACK_OK;
-            // The error in observeResult for the request will be
-            // used when responding to this request by omitting
-            // the observation option/sequence number.
+
+            // The error in observeResult for the request will be used when responding to this
+            // request by omitting the observation option/sequence number.
             request->observeResult = OC_STACK_ERROR;
             OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
             ehFlag = OC_REQUEST_FLAG;
@@ -973,7 +815,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         goto exit;
     }
 
-    ehResult = resource->entityHandler(ehFlag, &ehRequest);
+    ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
     if(ehResult == OC_EH_SLOW)
     {
         OC_LOG(INFO, TAG, PCF("This is a slow resource"));
@@ -1000,11 +842,18 @@ HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
     OCStackResult result = OC_STACK_ERROR;
     OCEntityHandlerRequest ehRequest = {};
 
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) resource, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, (OCObservationId) 0);
+    result = FormOCEntityHandlerRequest(&ehRequest,
+                                        (OCRequestHandle)request,
+                                        request->method,
+                                        &request->devAddr,
+                                        (OCResourceHandle)resource,
+                                        request->query,
+                                        request->payload,
+                                        request->payloadSize,
+                                        request->numRcvdVendorSpecificHeaderOptions,
+                                        request->rcvdVendorSpecificHeaderOptions,
+                                        (OCObserveAction)request->observationOption,
+                                        (OCObservationId)0);
     if(result != OC_STACK_OK)
     {
         return result;
@@ -1064,127 +913,139 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
     return ret;
 }
 
-void DeleteDeviceInfo()
-{
-    if(savedDeviceInfo)
-    {
-        cJSON_Delete(savedDeviceInfo);
-    }
-}
-
 void DeletePlatformInfo()
 {
     OC_LOG(INFO, TAG, PCF("Deleting platform info."));
 
-    OCFree(savedPlatformInfo.platformID);
+    OICFree(savedPlatformInfo.platformID);
     savedPlatformInfo.platformID = NULL;
 
-    OCFree(savedPlatformInfo.manufacturerName);
+    OICFree(savedPlatformInfo.manufacturerName);
     savedPlatformInfo.manufacturerName = NULL;
 
-    OCFree(savedPlatformInfo.manufacturerUrl);
+    OICFree(savedPlatformInfo.manufacturerUrl);
     savedPlatformInfo.manufacturerUrl = NULL;
 
-    OCFree(savedPlatformInfo.modelNumber);
+    OICFree(savedPlatformInfo.modelNumber);
     savedPlatformInfo.modelNumber = NULL;
 
-    OCFree(savedPlatformInfo.dateOfManufacture);
+    OICFree(savedPlatformInfo.dateOfManufacture);
     savedPlatformInfo.dateOfManufacture = NULL;
 
-    OCFree(savedPlatformInfo.platformVersion);
+    OICFree(savedPlatformInfo.platformVersion);
     savedPlatformInfo.platformVersion = NULL;
 
-    OCFree(savedPlatformInfo.operatingSystemVersion);
+    OICFree(savedPlatformInfo.operatingSystemVersion);
     savedPlatformInfo.operatingSystemVersion = NULL;
 
-    OCFree(savedPlatformInfo.hardwareVersion);
+    OICFree(savedPlatformInfo.hardwareVersion);
     savedPlatformInfo.hardwareVersion = NULL;
 
-    OCFree(savedPlatformInfo.firmwareVersion);
+    OICFree(savedPlatformInfo.firmwareVersion);
     savedPlatformInfo.firmwareVersion = NULL;
 
-    OCFree(savedPlatformInfo.supportUrl);
+    OICFree(savedPlatformInfo.supportUrl);
     savedPlatformInfo.supportUrl = NULL;
 
-    OCFree(savedPlatformInfo.systemTime);
+    OICFree(savedPlatformInfo.systemTime);
     savedPlatformInfo.systemTime = NULL;
 }
 
-static OCStackResult CloneStringIfNonNull(char **dest, char *src)
+static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
 {
-    if (src)
-    {
-        *dest = (char*) OCMalloc(strlen(src) + 1);
-        if (!*dest)
-        {
-            return OC_STACK_NO_MEMORY;
-        }
-        strcpy(*dest, src);
-    }
-    else
+    savedPlatformInfo.platformID = OICStrdup(info.platformID);
+    savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
+    savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
+    savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
+    savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
+    savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
+    savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
+    savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
+    savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
+    savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
+    savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
+
+    if ((!savedPlatformInfo.platformID && info.platformID)||
+        (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
+        (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
+        (!savedPlatformInfo.modelNumber && info.modelNumber)||
+        (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
+        (!savedPlatformInfo.platformVersion && info.platformVersion)||
+        (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
+        (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
+        (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
+        (!savedPlatformInfo.supportUrl && info.supportUrl)||
+        (!savedPlatformInfo.systemTime && info.systemTime))
     {
-        *dest = NULL;
+        DeletePlatformInfo();
+        return OC_STACK_INVALID_PARAM;
     }
+
     return OC_STACK_OK;
+
 }
-static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
+
+OCStackResult SavePlatformInfo(OCPlatformInfo info)
 {
     DeletePlatformInfo();
 
-    OCStackResult ret = OC_STACK_OK;
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.platformID), info.platformID);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
-
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerName), info.manufacturerName);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
-
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerUrl), info.manufacturerUrl);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
-
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.modelNumber), info.modelNumber);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
-
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.dateOfManufacture), info.dateOfManufacture);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+    OCStackResult res = DeepCopyPlatFormInfo(info);
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.platformVersion), info.platformVersion);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+    if (res != OC_STACK_OK)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, PCF("Platform info saved."));
+    }
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.operatingSystemVersion), info.operatingSystemVersion);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+    return res;
+}
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.hardwareVersion), info.hardwareVersion);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+void DeleteDeviceInfo()
+{
+    OC_LOG(INFO, TAG, PCF("Deleting device info."));
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.firmwareVersion), info.firmwareVersion);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+    OICFree(savedDeviceInfo.deviceName);
+    savedDeviceInfo.deviceName = NULL;
+}
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.supportUrl), info.supportUrl);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
+{
+    savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
 
-    ret = CloneStringIfNonNull(&(savedPlatformInfo.systemTime), info.systemTime);
-    VERIFY_SUCCESS(ret, OC_STACK_OK);
+    if(!savedDeviceInfo.deviceName && info.deviceName)
+    {
+        DeleteDeviceInfo();
+        return OC_STACK_NO_MEMORY;
+    }
 
     return OC_STACK_OK;
-
-    exit:
-        DeletePlatformInfo();
-        return ret;
-
 }
 
-OCStackResult SavePlatformInfo(OCPlatformInfo info)
+OCStackResult SaveDeviceInfo(OCDeviceInfo info)
 {
-    OCStackResult res = DeepCopyPlatFormInfo(info);
+    OCStackResult res = OC_STACK_OK;
 
-    if (res != OC_STACK_OK)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
-    }
-    else
+    DeleteDeviceInfo();
+
+    res = DeepCopyDeviceInfo(info);
+
+    VERIFY_SUCCESS(res, OC_STACK_OK);
+
+    if(OCGetServerInstanceID() == NULL)
     {
-        OC_LOG(ERROR, TAG, PCF("Platform info saved."));
+        OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
+        res =  OC_STACK_ERROR;
+        goto exit;
     }
 
-    return res;
+    OC_LOG(INFO, TAG, PCF("Device initialized successfully."));
+    return OC_STACK_OK;
+
+    exit:
+        DeleteDeviceInfo();
+        return res;
+
 }
index 8448b87..9f8b0dc 100644 (file)
 #include "ocstack.h"
 #include "ocserverrequest.h"
 #include "ocresourcehandler.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
 
 #include "cacommon.h"
 #include "cainterface.h"
@@ -55,13 +58,11 @@ static OCStackResult AddServerResponse (OCServerResponse ** response, OCRequestH
 {
     OCServerResponse * serverResponse = NULL;
 
-    serverResponse = (OCServerResponse *) OCCalloc(1, sizeof(OCServerResponse));
+    serverResponse = (OCServerResponse *) OICCalloc(1, sizeof(OCServerResponse));
     VERIFY_NON_NULL(serverResponse);
 
-    serverResponse->payload = (char *) OCCalloc(1, MAX_RESPONSE_LENGTH);
-    VERIFY_NON_NULL(serverResponse->payload);
+    serverResponse->payload = NULL;
 
-    serverResponse->remainingPayloadSize = MAX_RESPONSE_LENGTH;
     serverResponse->requestHandle = requestHandle;
 
     *response = serverResponse;
@@ -72,7 +73,7 @@ static OCStackResult AddServerResponse (OCServerResponse ** response, OCRequestH
 exit:
     if (serverResponse)
     {
-        OCFree(serverResponse);
+        OICFree(serverResponse);
         serverResponse = NULL;
     }
     *response = NULL;
@@ -89,8 +90,8 @@ static void DeleteServerRequest(OCServerRequest * serverRequest)
     if(serverRequest)
     {
         LL_DELETE(serverRequestList, serverRequest);
-        OCFree(serverRequest->requestToken);
-        OCFree(serverRequest);
+        OICFree(serverRequest->requestToken);
+        OICFree(serverRequest);
         serverRequest = NULL;
         OC_LOG(INFO, TAG, PCF("Server Request Removed!!"));
     }
@@ -106,8 +107,8 @@ static void DeleteServerResponse(OCServerResponse * serverResponse)
     if(serverResponse)
     {
         LL_DELETE(serverResponseList, serverResponse);
-        OCFree(serverResponse->payload);
-        OCFree(serverResponse);
+        OICFree(serverResponse->payload);
+        OICFree(serverResponse);
         OC_LOG(INFO, TAG, PCF("Server Response Removed!!"));
     }
 }
@@ -155,10 +156,12 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok
     }
 
     OCServerRequest * out = NULL;
+    OC_LOG(INFO, TAG,PCF("Get server request with token"));
+    OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+
+    OC_LOG(INFO, TAG,PCF("Found token"));
     LL_FOREACH (serverRequestList, out)
     {
-        OC_LOG(INFO, TAG,PCF("comparing tokens"));
-        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->requestToken, tokenLength);
         if(memcmp(out->requestToken, token, tokenLength) == 0)
         {
@@ -212,53 +215,23 @@ OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
     return NULL;
 }
 
-/**
- * Add a server request to the server request list
- *
- * @param request - initialized server request that is created by this function
- * @param coapID - ID of CoAP pdu
- * @param delayedResNeeded - delayed response required 0=no 1=yes
- * @param secured - secure endpoint 0=no 1=yes
- * @param notificationFlag - //TODO: remove - does not appear to be used any longer
- * @param method - RESTful method
- * @param numRcvdVendorSpecificHeaderOptions - number of received vendor specific header options
- * @param observationOption - value of observation option
- * @param qos - request QOS
- * @param query - request query
- * @param rcvdVendorSpecificHeaderOptions - received vendor specific header options
- * @param reqJSONPayload - request JSON payload
- * @param requestToken - request token
- * @param tokenLength - request token length
- * @param resourceUrl - URL of resource
- * @param reqTotalSize - total size of the request
- * @param addressInfo - CA Address
- * @param connectivityType - connection type
- *
- * @return
- *     OCStackResult
- */
 OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
-        uint8_t delayedResNeeded, uint8_t secured, uint8_t notificationFlag, OCMethod method,
+        uint8_t delayedResNeeded, uint8_t notificationFlag, OCMethod method,
         uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
         OCQualityOfService qos, char * query,
         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
-        char * reqJSONPayload, CAToken_t requestToken,
-        uint8_t tokenLength,
-        char * resourceUrl, size_t reqTotalSize,
-        CAAddress_t *addressInfo, CATransportType_t connectivityType)
+        uint8_t * payload, CAToken_t requestToken, uint8_t tokenLength,
+        char * resourceUrl, size_t reqTotalSize, const OCDevAddr *devAddr)
 {
     OCServerRequest * serverRequest = NULL;
 
-    //Note: OCServerRequest includes 1 byte for the JSON Payload.  payloadSize is calculated
-    //as the required length of the string, so this will result in enough room for the
-    //null terminator as well.
-    serverRequest = (OCServerRequest *) OCCalloc(1, sizeof(OCServerRequest) +
+    serverRequest = (OCServerRequest *) OICCalloc(1, sizeof(OCServerRequest) +
         (reqTotalSize ? reqTotalSize : 1) - 1);
+    VERIFY_NON_NULL(devAddr);
     VERIFY_NON_NULL(serverRequest);
 
     serverRequest->coapID = coapID;
     serverRequest->delayedResNeeded = delayedResNeeded;
-    serverRequest->secured = secured;
     serverRequest->notificationFlag = notificationFlag;
 
     serverRequest->method = method;
@@ -271,8 +244,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
 
     if(query)
     {
-        strncpy((char*)serverRequest->query,
-                (const char*)query, sizeof(serverRequest->query) - 1);
+        OICStrcpy(serverRequest->query, sizeof(serverRequest->query), query);
     }
 
     if(rcvdVendorSpecificHeaderOptions)
@@ -280,13 +252,14 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
         memcpy(serverRequest->rcvdVendorSpecificHeaderOptions, rcvdVendorSpecificHeaderOptions,
             MAX_HEADER_OPTIONS * sizeof(OCHeaderOption));
     }
-    if(reqJSONPayload && reqTotalSize)
+    if(payload && reqTotalSize)
     {
-        // destination is at least 1 greater than the source, so a NULL always exists in the
+       // destination is at least 1 greater than the source, so a NULL always exists in the
         // last character
-        strncpy((char*)serverRequest->reqJSONPayload,
-                (const char*)reqJSONPayload, reqTotalSize - 1);
+        memcpy(serverRequest->payload, payload, reqTotalSize);
+        serverRequest->payloadSize = reqTotalSize;
     }
+
     serverRequest->requestComplete = 0;
     if(requestToken)
     {
@@ -294,7 +267,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
         // particular library implementation (it may or may not be a null pointer).
         if (tokenLength)
         {
-            serverRequest->requestToken = (CAToken_t) OCMalloc(tokenLength);
+            serverRequest->requestToken = (CAToken_t) OICMalloc(tokenLength);
             VERIFY_NON_NULL(serverRequest->requestToken);
             memcpy(serverRequest->requestToken, requestToken, tokenLength);
         }
@@ -304,15 +277,11 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
 
     if(resourceUrl)
     {
-        strncpy((char*)serverRequest->resourceUrl,
-                (const char*)resourceUrl, sizeof(serverRequest->resourceUrl) - 1);
+        OICStrcpy(serverRequest->resourceUrl, sizeof(serverRequest->resourceUrl),
+            resourceUrl);
     }
 
-    if (addressInfo)
-    {
-        serverRequest->addressInfo = *addressInfo;
-    }
-    serverRequest->connectivityType = connectivityType;
+    serverRequest->devAddr = *devAddr;
 
     *request = serverRequest;
     OC_LOG(INFO, TAG, PCF("Server Request Added!!"));
@@ -322,37 +291,22 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
 exit:
     if (serverRequest)
     {
-        OCFree(serverRequest);
+        OICFree(serverRequest);
         serverRequest = NULL;
     }
     *request = NULL;
     return OC_STACK_NO_MEMORY;
 }
 
-/**
- * Form the OCEntityHandlerRequest struct that is passed to a resource's entity handler
- *
- * @param entityHandlerRequest - pointer to the OCEntityHandlerRequest struct that is created
- * @param request          - request handle
- * @param method           - RESTful method
- * @param resource         - resource handle
- * @param queryBuf         - resource query of request
- * @param bufReqPayload    - JSON payload of request
- * @param numVendorOptions - number of vendor options
- * @param vendorOptions    - vendor options
- * @param observeAction    - observe action flag
- * @param observeID        - observe ID
- *
- * @return
- *     OCStackResult
- */
 OCStackResult FormOCEntityHandlerRequest(
         OCEntityHandlerRequest * entityHandlerRequest,
         OCRequestHandle request,
         OCMethod method,
+        OCDevAddr *endpoint,
         OCResourceHandle resource,
         char * queryBuf,
-        char * bufReqPayload,
+        uint8_t * payload,
+        size_t payloadSize,
         uint8_t numVendorOptions,
         OCHeaderOption * vendorOptions,
         OCObserveAction observeAction,
@@ -360,17 +314,29 @@ OCStackResult FormOCEntityHandlerRequest(
 {
     if (entityHandlerRequest)
     {
-        memset(entityHandlerRequest, 0, sizeof(OCEntityHandlerRequest));
+        entityHandlerRequest->resource = (OCResourceHandle) resource;
         entityHandlerRequest->requestHandle = request;
         entityHandlerRequest->method = method;
-        entityHandlerRequest->resource = (OCResourceHandle) resource;
+        entityHandlerRequest->devAddr = *endpoint;
         entityHandlerRequest->query = queryBuf;
-        entityHandlerRequest->reqJSONPayload = bufReqPayload;
+        entityHandlerRequest->obsInfo.action = observeAction;
+        entityHandlerRequest->obsInfo.obsId = observeID;
+
+        if(payload && payloadSize)
+        {
+            if(OCParsePayload(&entityHandlerRequest->payload, payload, payloadSize) != OC_STACK_OK)
+            {
+                return OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            entityHandlerRequest->payload = NULL;
+        }
+
         entityHandlerRequest->numRcvdVendorSpecificHeaderOptions = numVendorOptions;
         entityHandlerRequest->rcvdVendorSpecificHeaderOptions = vendorOptions;
 
-        entityHandlerRequest->obsInfo.action = observeAction;
-        entityHandlerRequest->obsInfo.obsId = observeID;
         return OC_STACK_OK;
     }
 
@@ -420,7 +386,7 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result)
             caResult = CA_SUCCESS;
             break;
         case OC_EH_FORBIDDEN:
-            caResult = CA_BAD_REQ;
+            caResult = CA_UNAUTHORIZED_REQ;
             break;
         case OC_EH_RESOURCE_NOT_FOUND:
             caResult = CA_NOT_FOUND;
@@ -445,32 +411,20 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result)
 OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
 {
     OCStackResult result = OC_STACK_ERROR;
-    CARemoteEndpoint_t responseEndpoint = {};
+    CAEndpoint_t responseEndpoint = {};
     CAResponseInfo_t responseInfo = {};
     CAHeaderOption_t* optionsPointer = NULL;
 
-    OC_LOG_V(INFO, TAG, "Inside HandleSingleResponse: %s", ehResponse->payload);
-
     if(!ehResponse || !ehResponse->requestHandle)
     {
         return OC_STACK_ERROR;
     }
 
-    if(ehResponse->payloadSize >= (MAX_RESPONSE_LENGTH))// - OC_JSON_PREFIX_LEN - OC_JSON_SUFFIX_LEN))
-    {
-        OC_LOG_V(ERROR, TAG, "Response payload size was too large.  Max is %hu, payload size was %hu",
-                (MAX_RESPONSE_LENGTH - OC_JSON_PREFIX_LEN - OC_JSON_SUFFIX_LEN), ehResponse->payloadSize);
-        return OC_STACK_INVALID_PARAM;
-    }
-
     OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
 
-    // Copy the address
-    responseEndpoint.resourceUri      = (CAURI_t) serverRequest->resourceUrl;
-    responseEndpoint.addressInfo      = serverRequest->addressInfo;
-    responseEndpoint.transportType    = serverRequest->connectivityType;
-    responseEndpoint.isSecured        = serverRequest->secured;
+    CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint);
 
+    responseInfo.info.resourceUri = serverRequest->resourceUrl;
     responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult);
 
     if(serverRequest->notificationFlag && serverRequest->qos == OC_HIGH_QOS)
@@ -496,13 +450,9 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
         responseInfo.info.type = CA_MSG_NONCONFIRM;
     }
 
+    char rspToken[CA_MAX_TOKEN_LEN + 1] = {};
     responseInfo.info.messageId = serverRequest->coapID;
-    responseInfo.info.token = (CAToken_t)OCMalloc(CA_MAX_TOKEN_LEN+1);
-    if (!responseInfo.info.token)
-    {
-        OC_LOG(FATAL, TAG, "Response Info Token is NULL");
-        return result;
-    }
+    responseInfo.info.token = (CAToken_t)rspToken;
 
     memcpy(responseInfo.info.token, serverRequest->requestToken, serverRequest->tokenLength);
     responseInfo.info.tokenLength = serverRequest->tokenLength;
@@ -519,13 +469,12 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     if(responseInfo.info.numOptions > 0)
     {
         responseInfo.info.options = (CAHeaderOption_t *)
-                                      OCCalloc(responseInfo.info.numOptions,
+                                      OICCalloc(responseInfo.info.numOptions,
                                               sizeof(CAHeaderOption_t));
 
         if(!responseInfo.info.options)
         {
-            OC_LOG(FATAL, TAG, PCF("options is NULL"));
-            OCFree(responseInfo.info.token);
+            OC_LOG(FATAL, TAG, PCF("Memory alloc for options failed"));
             return OC_STACK_NO_MEMORY;
         }
 
@@ -557,44 +506,90 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
         responseInfo.info.options = NULL;
     }
 
-    char payload[MAX_RESPONSE_LENGTH + OC_JSON_PREFIX_LEN + OC_JSON_SUFFIX_LEN] = {};
-
     // Put the JSON prefix and suffix around the payload
-    strcpy(payload, (const char *)OC_JSON_PREFIX);
-    strncat(payload, (const char *)ehResponse->payload, ehResponse->payloadSize);
-    strcat(payload, (const char *)OC_JSON_SUFFIX);
-    responseInfo.info.payload = (CAPayload_t)payload;
+    if(ehResponse->payload)
+    {
+        OCStackResult result;
+        if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload,
+                    &responseInfo.info.payloadSize))
+                != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "Error converting payload");
+            return result;
+        }
+
+        if(responseInfo.info.payloadSize > MAX_RESPONSE_LENGTH)
+        {
+            OICFree(responseInfo.info.payload);
+            OC_LOG(ERROR, TAG, "Payload too long!");
+            return OC_STACK_INVALID_PARAM;
+        }
+    }
+    else
+    {
+        responseInfo.info.payload = NULL;
+        responseInfo.info.payloadSize = 0;
+    }
 
     #ifdef WITH_PRESENCE
-    //TODO: Add other connectivity types to CAConnTypes[] when enabled
-    CATransportType_t CAConnTypes[] = {CA_IPV4};
-    const char * connTypes[] = {"ip transport"};
-    int size = sizeof(CAConnTypes)/ sizeof(CATransportType_t);
-    CATransportType_t connType = responseEndpoint.transportType;
+    CATransportAdapter_t CAConnTypes[] = {
+                            CA_ADAPTER_IP,
+                            CA_ADAPTER_GATT_BTLE,
+                            CA_ADAPTER_RFCOMM_BTEDR
+
+                            #ifdef RA_ADAPTER
+                            , CA_ADAPTER_REMOTE_ACCESS
+                            #endif
+                        };
+    const char * connTypes[] = {"ip" , "ble",  "edr"
+                                #ifdef RA_ADAPTER
+                                , "ra"
+                                #endif
+                            };
+    int size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t);
+
+    CATransportAdapter_t adapter = responseEndpoint.adapter;
     CAResult_t caResult = CA_STATUS_FAILED;
     result = OC_STACK_OK;
 
-    //Sending response on all n/w interfaces
+    // Default adapter, try to send response out on all adapters.
+    if (adapter == CA_DEFAULT_ADAPTER)
+    {
+        adapter =
+            (CATransportAdapter_t)(
+                CA_ADAPTER_IP           |
+                CA_ADAPTER_GATT_BTLE    |
+                CA_ADAPTER_RFCOMM_BTEDR
+
+                #ifdef RA_ADAP
+                | CA_ADAPTER_REMOTE_ACCESS
+                #endif
+            );
+    }
+
     for(int i = 0; i < size; i++ )
     {
-        responseEndpoint.transportType = (CATransportType_t)(connType & CAConnTypes[i]);
-        if(responseEndpoint.transportType)
+        responseEndpoint.adapter = (CATransportAdapter_t)(adapter & CAConnTypes[i]);
+        if(responseEndpoint.adapter)
         {
             //The result is set to OC_STACK_OK only if CASendResponse succeeds in sending the
             //response on all the n/w interfaces else it is set to OC_STACK_ERROR
             caResult = CASendResponse(&responseEndpoint, &responseInfo);
             if(caResult != CA_STATUS_OK)
             {
-                OC_LOG_V(ERROR, TAG, "CASendResponse failed on %s", connTypes[i]);
+                OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", caResult);
                 result = CAResultToOCResult(caResult);
             }
-            else
-            {
-                OC_LOG_V(INFO, TAG, "CASendResponse succeeded on %s", connTypes[i]);
-            }
         }
     }
     #else
+
+    OC_LOG(INFO, TAG, PCF("Calling CASendResponse with:"));
+    OC_LOG_V(INFO, TAG, "\tEndpoint address: %s", responseEndpoint.addr);
+    OC_LOG_V(INFO, TAG, "\tEndpoint adapter: %s", responseEndpoint.adapter);
+    OC_LOG_V(INFO, TAG, "\tResponse result : %s", responseInfo.result);
+    OC_LOG_V(INFO, TAG, "\tResponse for uri: %s", responseInfo.info.resourceUri);
+
     CAResult_t caResult = CASendResponse(&responseEndpoint, &responseInfo);
     if(caResult != CA_STATUS_OK)
     {
@@ -607,8 +602,8 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     }
     #endif
 
-    OCFree(responseInfo.info.token);
-    OCFree(responseInfo.info.options);
+    OICFree(responseInfo.info.payload);
+    OICFree(responseInfo.info.options);
     //Delete the request
     FindAndDeleteServerRequest(serverRequest);
     return result;
@@ -631,7 +626,6 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
     OCStackResult stackRet = OC_STACK_ERROR;
     OCServerRequest * serverRequest = NULL;
     OCServerResponse * serverResponse = NULL;
-    uint16_t bufferNeeded = 0;
 
     if(!ehResponse || !ehResponse->payload)
     {
@@ -639,7 +633,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
         return OC_STACK_INVALID_PARAM;
     }
 
-    OC_LOG_V(INFO, TAG, "Inside HandleAggregateResponse: %s", ehResponse->payload);
+    OC_LOG(INFO, TAG, "Inside HandleAggregateResponse");
 
     serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
     serverResponse = GetServerResponseUsingHandle((OCServerRequest *)ehResponse->requestHandle);
@@ -656,54 +650,42 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
                 return stackRet;
             }
             VERIFY_NON_NULL(serverResponse);
-            VERIFY_NON_NULL(serverResponse->payload);
         }
 
-        // If there is more than 1 response, then we need to allow for a null-termination
-        // in the server response payload buffer AND the JSON response separator
-        bufferNeeded = ehResponse->payloadSize + 1;
-        if (serverRequest->numResponses > 1)
+        if(ehResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
         {
-            bufferNeeded += strlen(OC_JSON_SEPARATOR_STR);
+            stackRet = OC_STACK_ERROR;
+            OC_LOG(ERROR, TAG, PCF("Error adding payload, as it was the incorrect type"));
+            goto exit;
         }
-        if(serverResponse->remainingPayloadSize >= bufferNeeded)
+
+        if(!serverResponse->payload)
         {
-            OC_LOG(ERROR, TAG, PCF("There is room in response buffer"));
-            // append
-            strncat((char *)serverResponse->payload,
-                    (char *)ehResponse->payload,
-                    serverResponse->remainingPayloadSize);
-            OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
-            serverResponse->remainingPayloadSize -= strlen((char *)ehResponse->payload);
-            (serverRequest->numResponses)--;
-            if(serverRequest->numResponses == 0)
-            {
-                OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
-                ehResponse->payload = serverResponse->payload;
-                ehResponse->payloadSize = strlen((char *) serverResponse->payload) + 1;
-                stackRet = HandleSingleResponse(ehResponse);
-                //Delete the request and response
-                FindAndDeleteServerRequest(serverRequest);
-                FindAndDeleteServerResponse(serverResponse);
-            }
-            else
-            {
-                OC_LOG(INFO, TAG, PCF("More response fragments to come"));
-                strncat((char *)serverResponse->payload,
-                        OC_JSON_SEPARATOR_STR,
-                        serverResponse->remainingPayloadSize);
-                OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
-                serverResponse->remainingPayloadSize -= strlen(OC_JSON_SEPARATOR_STR);
-                stackRet = OC_STACK_OK;
-            }
+            serverResponse->payload = (OCPayload*)OCRepPayloadCreate();
+            serverResponse->payload = ehResponse->payload;
         }
         else
         {
-            OC_LOG(ERROR, TAG, PCF("No room in response buffer"));
+            OCRepPayloadAppend((OCRepPayload*)serverResponse->payload,
+                    (OCRepPayload*)ehResponse->payload);
+        }
+
+
+        (serverRequest->numResponses)--;
+
+        if(serverRequest->numResponses == 0)
+        {
+            OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
+            ehResponse->payload = serverResponse->payload;
+            stackRet = HandleSingleResponse(ehResponse);
             //Delete the request and response
             FindAndDeleteServerRequest(serverRequest);
             FindAndDeleteServerResponse(serverResponse);
-            stackRet = OC_STACK_NO_MEMORY;
+        }
+        else
+        {
+            OC_LOG(INFO, TAG, PCF("More response fragments to come"));
+            stackRet = OC_STACK_OK;
         }
     }
 exit:
index 2ccd77a..be6fa96 100644 (file)
 #include "occlientcb.h"
 #include "ocobserve.h"
 #include "ocrandom.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
 #include "ocserverrequest.h"
-#include "ocsecurityinternal.h"
-
+#include "secureresourcemanager.h"
 #include "cacommon.h"
 #include "cainterface.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
 
 #ifdef WITH_ARDUINO
 #include "Time.h"
@@ -96,8 +98,12 @@ static uint32_t PresenceTimeOut[] = {50, 75, 85, 95, 100};
 #endif
 
 static OCMode myStackMode;
+#ifdef RA_ADAPTER
+//TODO: revisit this design
+static bool gRASetInfo = false;
+#endif
 OCDeviceEntityHandler defaultDeviceHandler;
-
+void* defaultDeviceHandlerCallbackParameter = NULL;
 
 //-----------------------------------------------------------------------------
 // Macros
@@ -107,6 +113,8 @@ OCDeviceEntityHandler defaultDeviceHandler;
             {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
              TAG, PCF(#arg " is NULL")); return (retVal); } }
+#define VERIFY_NON_NULL_NR(arg, logLevel) { if (!(arg)) { OC_LOG((logLevel), \
+             TAG, PCF(#arg " is NULL")); return; } }
 #define VERIFY_NON_NULL_V(arg) { if (!arg) {OC_LOG_V(FATAL, TAG, "%s is NULL", #arg);\
     goto exit;} }
 
@@ -114,21 +122,6 @@ OCDeviceEntityHandler defaultDeviceHandler;
 #define MAX_OBSERVE_AGE (0x2FFFFUL)
 
 #define MILLISECONDS_PER_SECOND   (1000)
-/**
- * Parse the presence payload and extract various parameters.
- * Note: Caller should invoke OCFree after done with resType pointer.
- *
- * @param payload Presence payload.
- * @param seqNum Sequence number.
- * @param maxAge Time To Live (in seconds).
- * @param resType Resource type.
- */
-// TODO: Not sure if I agree with this.  I think it should be static but it is called in
-// stack/test/stacktests.cpp, not included via a header file.  If we intend to allow it
-// to be called externally, we should change the name to OCParsePresencePayload and make
-// it part of the official public API.  But can't change now due to current API freeze.
-// Another option might be to make non-API utility functions for doing stuff like this.
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType);
 
 //-----------------------------------------------------------------------------
 // Private internal function prototypes
@@ -264,36 +257,6 @@ static void incrementSequenceNumber(OCResource * resPtr);
 static OCStackResult verifyUriQueryLength(const char * inputUri,
         uint16_t uriLen);
 
-/**
- * Determine if a request/response must be sent in a block transfer because it is too large to be
- * sent in a single PDU.  This function can be used for either a request or a response.
- * Note:  Either the request or response parameter should be non-NULL (i.e. only one, not both).
- *
- * @param request  NULL or pointer to request.
- * @param response NULL or pointer to response.
- * @param size     0 or size of the request/response.  If 0, strlen is used for determining
- *                 the length of the request/response.
- *
- * @return
- *    false - packet transfer NOT required (i.e. normal request/response).
- *    true  - packet transfer required (i.e. block transfer needed).
- */
-static bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size);
-
-/**
- * Retrieves a resource type based upon a query contains only just one
- * resource attribute (and that has to be of type "rt").
- *
- * @remark This API malloc's memory for the resource type. Do not malloc resourceType
- * before passing in.
- *
- * @param query The query part of the URI.
- * @param resourceType The resource type to be populated; pass by reference.
- *
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult getResourceType(const char * query, char** resourceType);
-
 /*
  * Attempts to initialize every network interface that the CA Layer might have compiled in.
  *
@@ -314,22 +277,6 @@ static CAResult_t OCSelectNetwork();
 static uint32_t GetTicks(uint32_t afterMilliSeconds);
 
 /**
- * This method is used to create the IPv4 dev_addr structure.
- * Builds a socket interface address using IP address and port number.
- * TODO: Remove in future. Temporary helper function.
- *
- * @param a IPv4 octet 0.
- * @param b IPv4 octet 1.
- * @param c IPv4 octet 2.
- * @param d IPv4 octet 3.
- * @param port Port number.
- * @param ipAddr - IPv4 address.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult OCBuildIPv4Address(uint8_t a, uint8_t b, uint8_t c, uint8_t d,
-        uint16_t port, OCDevAddr *ipAddr);
-
-/**
  * Convert CAResponseResult_t to OCStackResult.
  *
  * @param caCode CAResponseResult_t code.
@@ -346,33 +293,20 @@ static OCStackResult CAToOCStackResult(CAResponseResult_t caCode);
 static CAResponseResult_t OCToCAStackResult(OCStackResult ocCode);
 
 /**
- * Convert OCConnectivityType to CATransportType_t.
+ * Convert OCTransportFlags_t to CATransportModifiers_t.
  *
- * @param ocConType OCConnectivityType input.
- * @param caConType CATransportType_t output.
- * @return  ::OC_STACK_OK on success, some other value upon failure.
+ * @param ocConType OCTransportFlags_t input.
+ * @return CATransportFlags
  */
-static OCStackResult OCToCATransportType(OCConnectivityType ocConType,
-        CATransportType_t* caConType);
+static CATransportFlags_t OCToCATransportFlags(OCTransportFlags ocConType);
 
 /**
- * Convert CATransportType_t to OCConnectivityType.
+ * Convert CATransportFlags_t to OCTransportModifiers_t.
  *
- * @param caConType CATransportType_t input.
- * @param ocConType OCConnectivityType output.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult CAToOCConnectivityType(CATransportType_t caConType,
-        OCConnectivityType *ocConType);
-
-/**
- * Update response.addr appropriately from endPoint.addressInfo.
- *
- * @param address OCDevAddr output.
- * @param endPoint CARemoteEndpoint_t input.
- * @return ::OC_STACK_OK on success, some other value upon failure.
+ * @param caConType CATransportFlags_t input.
+ * @return OCTransportFlags
  */
-static OCStackResult UpdateResponseAddr(OCDevAddr *address, const CARemoteEndpoint_t* endPoint);
+static OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caConType);
 
 /**
  * Handle response from presence request.
@@ -381,8 +315,8 @@ static OCStackResult UpdateResponseAddr(OCDevAddr *address, const CARemoteEndpoi
  * @param responseInfo CA response info.
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
-        const CAResponseInfo_tresponseInfo);
+static OCStackResult HandlePresenceResponse(const CAEndpoint_t *endPoint,
+        const CAResponseInfo_t *responseInfo);
 
 /**
  * This function will be called back by CA layer when a response is received.
@@ -390,7 +324,7 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
  * @param endPoint CA remote endpoint.
  * @param responseInfo CA response info.
  */
-static void HandleCAResponses(const CARemoteEndpoint_t* endPoint,
+static void HandleCAResponses(const CAEndpoint_t* endPoint,
         const CAResponseInfo_t* responseInfo);
 
 /**
@@ -399,7 +333,7 @@ static void HandleCAResponses(const CARemoteEndpoint_t* endPoint,
  * @param endPoint CA remote endpoint.
  * @param requestInfo CA request info.
  */
-static void HandleCARequests(const CARemoteEndpoint_t* endPoint,
+static void HandleCARequests(const CAEndpoint_t* endPoint,
         const CARequestInfo_t* requestInfo);
 
 /**
@@ -456,25 +390,68 @@ uint32_t GetTicks(uint32_t afterMilliSeconds)
     }
 }
 
-OCStackResult OCBuildIPv4Address(uint8_t a, uint8_t b, uint8_t c, uint8_t d,
-        uint16_t port, OCDevAddr *ipAddr)
+void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out)
+{
+    VERIFY_NON_NULL_NR(in, FATAL);
+    VERIFY_NON_NULL_NR(out, FATAL);
+
+    out->adapter = (OCTransportAdapter)in->adapter;
+    out->flags = CAToOCTransportFlags(in->flags);
+    strncpy(out->addr, in->addr, MAX_ADDR_STR_SIZE);
+    out->addr[MAX_ADDR_STR_SIZE - 1] = '\0';
+    out->port = in->port;
+}
+
+void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out)
+{
+    VERIFY_NON_NULL_NR(in, FATAL);
+    VERIFY_NON_NULL_NR(out, FATAL);
+
+    out->adapter = (CATransportAdapter_t)in->adapter;
+    out->flags = OCToCATransportFlags(in->flags);
+    strncpy(out->addr, in->addr, MAX_ADDR_STR_SIZE);
+    out->port = in->port;
+}
+
+static OCStackResult OCCreateEndpoint(OCDevAddr *devAddr, CAEndpoint_t **endpoint)
 {
-    if (!ipAddr )
+    VERIFY_NON_NULL(devAddr, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
+
+    CAEndpoint_t *ep = (CAEndpoint_t *)OICMalloc(sizeof (CAEndpoint_t));
+    if (!ep)
     {
-        OC_LOG(FATAL, TAG, PCF("Invalid argument"));
-        return OC_STACK_INVALID_PARAM;
+        return OC_STACK_NO_MEMORY;
+    }
+
+    ep->adapter = (CATransportAdapter_t)devAddr->adapter;
+    if (!ep->adapter)
+    {
+        ep->adapter = CA_ADAPTER_IP;
     }
+    ep->flags = OCToCATransportFlags(devAddr->flags);
+    strncpy(ep->addr, devAddr->addr, MAX_ADDR_STR_SIZE_CA);
+    ep->port = devAddr->port;
 
-    ipAddr->addr[0] = a;
-    ipAddr->addr[1] = b;
-    ipAddr->addr[2] = c;
-    ipAddr->addr[3] = d;
-    ipAddr->addr[4] = (uint8_t)port;
-    ipAddr->addr[5] = (uint8_t)(port >> 8);
+    *endpoint = ep;
 
     return OC_STACK_OK;
 }
 
+static void OCDestroyEndpoint(CAEndpoint_t *endpoint)
+{
+    free(endpoint);
+}
+
+void FixUpClientResponse(OCClientResponse *cr)
+{
+    VERIFY_NON_NULL_NR(cr, FATAL);
+
+    cr->addr = &cr->devAddr;
+    cr->connType = (OCConnectivityType)
+        ((cr->devAddr.adapter << CT_ADAPTER_SHIFT) | (cr->devAddr.flags & CT_MASK_FLAGS));
+}
+
 //-----------------------------------------------------------------------------
 // Internal API function
 //-----------------------------------------------------------------------------
@@ -490,20 +467,26 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
     switch(status)
     {
     case OC_OBSERVER_NOT_INTERESTED:
-        OC_LOG(DEBUG, TAG, PCF("observer is not interested in our notifications anymore"));
+        OC_LOG(DEBUG, TAG, PCF("observer not interested in our notifications"));
         observer = GetObserverUsingToken (token, tokenLength);
         if(observer)
         {
-            result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
-                    OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
-                    NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
+            result = FormOCEntityHandlerRequest(&ehRequest,
+                                                (OCRequestHandle)NULL,
+                                                OC_REST_NOMETHOD,
+                                                &observer->devAddr,
+                                                (OCResourceHandle)NULL,
+                                                NULL, NULL, 0, 0, NULL,
+                                                OC_OBSERVE_DEREGISTER,
+                                                observer->observeId);
             if(result != OC_STACK_OK)
             {
                 return result;
             }
-            observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest);
+            observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
+                            observer->resource->entityHandlerCallbackParam);
         }
-        //observer is not observing anymore
+
         result = DeleteObserverUsingToken (token, tokenLength);
         if(result == OC_STACK_OK)
         {
@@ -515,10 +498,9 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
             OC_LOG(DEBUG, TAG, PCF("Observer Removal failed"));
         }
         break;
+
     case OC_OBSERVER_STILL_INTERESTED:
-        //observer is still interested
-        OC_LOG(DEBUG, TAG, PCF("observer is interested in our \
-                notifications, reset the failedCount"));
+        OC_LOG(DEBUG, TAG, PCF("observer still interested, reset the failedCount"));
         observer = GetObserverUsingToken (token, tokenLength);
         if(observer)
         {
@@ -531,23 +513,29 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
             result = OC_STACK_OBSERVER_NOT_FOUND;
         }
         break;
+
     case OC_OBSERVER_FAILED_COMM:
-        //observer is not reachable
         OC_LOG(DEBUG, TAG, PCF("observer is unreachable"));
         observer = GetObserverUsingToken (token, tokenLength);
         if(observer)
         {
             if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
             {
-                result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
-                        OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
-                        NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
+                result = FormOCEntityHandlerRequest(&ehRequest,
+                                                    (OCRequestHandle)NULL,
+                                                    OC_REST_NOMETHOD,
+                                                    &observer->devAddr,
+                                                    (OCResourceHandle)NULL,
+                                                    NULL, NULL, 0, 0, NULL,
+                                                    OC_OBSERVE_DEREGISTER,
+                                                    observer->observeId);
                 if(result != OC_STACK_OK)
                 {
                     return OC_STACK_ERROR;
                 }
-                observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest);
-                //observer is unreachable
+                observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
+                                    observer->resource->entityHandlerCallbackParam);
+
                 result = DeleteObserverUsingToken (token, tokenLength);
                 if(result == OC_STACK_OK)
                 {
@@ -593,6 +581,9 @@ OCStackResult CAToOCStackResult(CAResponseResult_t caCode)
         case CA_BAD_REQ:
             ret = OC_STACK_INVALID_QUERY;
             break;
+        case CA_UNAUTHORIZED_REQ:
+            ret = OC_STACK_UNAUTHORIZED_REQ;
+            break;
         case CA_BAD_OPT:
             ret = OC_STACK_INVALID_OPTION;
             break;
@@ -635,100 +626,34 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode)
         case OC_STACK_COMM_ERROR:
             ret = CA_RETRANSMIT_TIMEOUT;
             break;
+        case OC_STACK_UNAUTHORIZED_REQ:
+            ret = CA_UNAUTHORIZED_REQ;
+            break;
         default:
             break;
     }
     return ret;
 }
 
-OCStackResult OCToCATransportType(OCConnectivityType ocConType, CATransportType_t* caConType)
+CATransportFlags_t OCToCATransportFlags(OCTransportFlags ocFlags)
 {
-    OCStackResult ret = OC_STACK_OK;
+    CATransportFlags_t caFlags = (CATransportFlags_t)ocFlags;
 
-    switch(ocConType)
+    // supply default behavior.
+    if ((caFlags & (CA_IPV6|CA_IPV4)) == 0)
     {
-        case OC_IPV4:
-            *caConType = CA_IPV4;
-            break;
-        case OC_IPV6:
-            *caConType = CA_IPV6;
-            break;
-        case OC_EDR:
-            *caConType = CA_EDR;
-            break;
-        case OC_LE:
-            *caConType = CA_LE;
-            break;
-        case OC_ALL:
-            // Currently OC_ALL represents IPv4
-            // Add other connectivity types as they are enabled in future
-            *caConType = (CATransportType_t) (CA_IPV4);
-            break;
-        default:
-            ret = OC_STACK_INVALID_PARAM;
-            break;
+        caFlags = (CATransportFlags_t)(caFlags|CA_IPV6|CA_IPV4);
     }
-    return ret;
-}
-
-OCStackResult CAToOCConnectivityType(CATransportType_t caConType, OCConnectivityType *ocConType)
-{
-    OCStackResult ret = OC_STACK_OK;
-
-    switch(caConType)
+    if ((caFlags & OC_MASK_SCOPE) == 0)
     {
-        case CA_IPV4:
-            *ocConType = OC_IPV4;
-            break;
-        case CA_IPV6:
-            *ocConType = OC_IPV6;
-            break;
-        case CA_EDR:
-            *ocConType = OC_EDR;
-            break;
-        case CA_LE:
-            *ocConType = OC_LE;
-            break;
-        default:
-            ret = OC_STACK_INVALID_PARAM;
-            break;
+        caFlags = (CATransportFlags_t)(caFlags|OC_SCOPE_LINK);
     }
-    return ret;
+    return caFlags;
 }
 
-OCStackResult UpdateResponseAddr(OCDevAddr *address, const CARemoteEndpoint_t* endPoint)
+OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caFlags)
 {
-    OCStackResult ret = OC_STACK_ERROR;
-    char * tok = NULL;
-    char * savePtr = NULL;
-    char * cpAddress = (char *) OCMalloc(strlen(endPoint->addressInfo.IP.ipAddress) + 1);
-    if(!cpAddress)
-    {
-        ret = OC_STACK_NO_MEMORY;
-        goto exit;
-    }
-    memcpy(cpAddress, endPoint->addressInfo.IP.ipAddress,
-            strlen(endPoint->addressInfo.IP.ipAddress) + 1);
-
-    // Grabs the first three numbers from the IPv4 address and replaces dots
-    for(int i=0; i<4; i++)
-    {
-        tok = strtok_r(i==0 ? cpAddress : NULL, ".", &savePtr);
-
-        if(!tok)
-        {
-            ret = OC_STACK_ERROR;
-            goto exit;
-        }
-        address->addr[i] = atoi(tok);
-    }
-
-    memcpy(&address->addr[4], &endPoint->addressInfo.IP.port, sizeof(uint16_t));
-    ret = OC_STACK_OK;
-
-exit:
-    OCFree(cpAddress);
-    return ret;
+    return (OCTransportFlags)caFlags;
 }
 
 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds)
@@ -785,74 +710,103 @@ static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds)
     return OC_STACK_OK;
 }
 
-void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType)
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger)
 {
-    char * tok = NULL;
-    char * savePtr = NULL;
-    // The format of the payload is {"oc":[%u:%u:%s]}
-    // %u : sequence number,
-    // %u : max age
-    // %s : Resource Type (Optional)
-
-    if (!payload || !seqNum || !maxAge || !resType)
+    if (trigger == OC_PRESENCE_TRIGGER_CREATE)
     {
-        return;
+        return OC_RSRVD_TRIGGER_CREATE;
     }
-    tok = strtok_r(payload, "[:]}", &savePtr);
-    payload[strlen(payload)] = ':';
-
-    //Retrieve sequence number
-    tok = strtok_r(NULL, "[:]}", &savePtr);
-    if(tok == NULL)
+    else if (trigger == OC_PRESENCE_TRIGGER_CHANGE)
     {
-        return;
+        return OC_RSRVD_TRIGGER_CHANGE;
     }
-    payload[strlen((char *)payload)] = ':';
-    *seqNum = (uint32_t) atoi(tok);
-
-    //Retrieve MaxAge
-    tok = strtok_r(NULL, "[:]}", &savePtr);
-    if(tok == NULL)
+    else
     {
-        return;
+        return OC_RSRVD_TRIGGER_DELETE;
     }
-    *maxAge = (uint32_t) atoi(tok);
+}
 
-    //Retrieve ResourceType
-    tok = strtok_r(NULL, "[:]}",&savePtr);
-    if(tok == NULL)
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
+{
+    if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CREATE) == 0)
     {
-        return;
+        return OC_PRESENCE_TRIGGER_CREATE;
     }
+    else if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CHANGE) == 0)
+    {
+        return OC_PRESENCE_TRIGGER_CHANGE;
+    }
+    else
+    {
+        return OC_PRESENCE_TRIGGER_DELETE;
+    }
+}
+
+/**
+ * The cononical presence allows constructed URIs to be string compared.
+ *
+ * requestUri must be a char array of size CA_MAX_URI_LENGTH
+ */
+static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri,
+        char *presenceUri)
+{
+    VERIFY_NON_NULL(endpoint   , FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(resourceUri, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(presenceUri, FATAL, OC_STACK_INVALID_PARAM);
+
+    const char *format;
+    CAEndpoint_t *ep = (CAEndpoint_t *)endpoint;
 
-    *resType = (char *)OCMalloc(strlen(tok) + 1);
-    if(!*resType)
+    if (ep->adapter == CA_ADAPTER_IP)
     {
-        return;
+        if ((ep->flags & CA_IPV6) && !(ep->flags & CA_IPV4))
+        {
+            if ('\0' == ep->addr[0])  // multicast
+            {
+                return snprintf(presenceUri, CA_MAX_URI_LENGTH, OC_RSRVD_PRESENCE_URI);
+            }
+            else
+            {
+                format = "coap://[%s]:%u%s";
+            }
+        }
+        else
+        {
+            if ('\0' == ep->addr[0])  // multicast
+            {
+                OICStrcpy(ep->addr, sizeof(ep->addr), OC_MULTICAST_IP);
+                ep->port = OC_MULTICAST_PORT;
+            }
+            format = "coap://%s:%u%s";
+        }
+        return snprintf(presenceUri, CA_MAX_URI_LENGTH, format, ep->addr,
+                        ep->port, OC_RSRVD_PRESENCE_URI);
     }
-    payload[strlen((char *)payload)] = ':';
-    strcpy(*resType, tok);
-    OC_LOG_V(DEBUG, TAG, "resourceTypeName %s", *resType);
 
-    payload[strlen((char *)payload)] = ']';
+    // might work for other adapters (untested, but better than nothing)
+    format = "coap://%s%s";
+    return snprintf(presenceUri, CA_MAX_URI_LENGTH, format, ep->addr,
+                    OC_RSRVD_PRESENCE_URI);
 }
 
-static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
-                            const CAResponseInfo_t* responseInfo)
+
+OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
+                            const CAResponseInfo_t *responseInfo)
 {
+    VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(responseInfo, FATAL, OC_STACK_INVALID_PARAM);
+
     OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
     ClientCB * cbNode = NULL;
     char *resourceTypeName = NULL;
-    OCClientResponse response = {};
-    OCDevAddr address = {};
+    OCClientResponse response;
     OCStackResult result = OC_STACK_ERROR;
     uint32_t maxAge = 0;
+    int uriLen;
+    char presenceUri[CA_MAX_URI_LENGTH];
 
-    char *fullUri = NULL;
-    char *ipAddress = NULL;
     int presenceSubscribe = 0;
     int multicastPresenceSubscribe = 0;
-    size_t addressLen = 0;
 
     if (responseInfo->result != CA_SUCCESS)
     {
@@ -860,111 +814,77 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
         return OC_STACK_ERROR;
     }
 
-    fullUri = (char *) OCMalloc(MAX_URI_LENGTH);
-
-    if(!fullUri)
-    {
-        OC_LOG(ERROR, TAG, PCF("Memory could not be allocated for fullUri"));
-        result = OC_STACK_NO_MEMORY;
-        goto exit;
-    }
-
-    addressLen = strlen(endPoint->addressInfo.IP.ipAddress);
-    ipAddress = (char *) OCMalloc(addressLen + 1);
-
-    if(!ipAddress)
+    // check for unicast presence
+    uriLen = FormCanonicalPresenceUri(endpoint, OC_RSRVD_PRESENCE_URI, presenceUri);
+    if (uriLen < 0 || uriLen >= sizeof (presenceUri))
     {
-        OC_LOG(ERROR, TAG, PCF("Memory could not be allocated for ipAddress"));
-        result = OC_STACK_NO_MEMORY;
-        goto exit;
+        return OC_STACK_INVALID_URI;
     }
 
-    strncpy(ipAddress, endPoint->addressInfo.IP.ipAddress, addressLen);
-    ipAddress[addressLen] = '\0';
-
-    snprintf(fullUri, MAX_URI_LENGTH, "coap://%s:%u%s", ipAddress, endPoint->addressInfo.IP.port,
-                OC_PRESENCE_URI);
-
-    cbNode = GetClientCB(NULL, 0, NULL, fullUri);
-
-    if(cbNode)
+    cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
+    if (cbNode)
     {
         presenceSubscribe = 1;
     }
     else
     {
-        snprintf(fullUri, MAX_URI_LENGTH, "coap://%s:%u%s", OC_MULTICAST_IP, OC_MULTICAST_PORT,
-                                                endPoint->resourceUri);
-        cbNode = GetClientCB(NULL, 0, NULL, fullUri);
-        if(cbNode)
+        // check for multiicast presence
+        CAEndpoint_t ep = { endpoint->adapter, endpoint->flags };
+        OICStrcpy(ep.addr, sizeof(ep.addr), OC_MULTICAST_IP);
+        ep.port = OC_MULTICAST_PORT;
+
+        uriLen = FormCanonicalPresenceUri(&ep, OC_RSRVD_PRESENCE_URI, presenceUri);
+
+        cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
+        if (cbNode)
         {
             multicastPresenceSubscribe = 1;
         }
     }
 
-    if(!presenceSubscribe && !multicastPresenceSubscribe)
+    if (!presenceSubscribe && !multicastPresenceSubscribe)
     {
         OC_LOG(ERROR, TAG, PCF("Received a presence notification, but no callback, ignoring"));
         goto exit;
     }
 
-    // No payload to the application in case of presence
-    response.resJSONPayload = NULL;
+    response.payload = NULL;
     response.result = OC_STACK_OK;
 
-    result = UpdateResponseAddr(&address, endPoint);
-    if(result != OC_STACK_OK)
-    {
-        goto exit;
-    }
-
-    response.addr = &address;
+    CopyEndpointToDevAddr(endpoint, &response.devAddr);
+    FixUpClientResponse(&response);
 
-    result = CAToOCConnectivityType(endPoint->transportType, &(response.connType));
-    if(result != OC_STACK_OK)
+    if (responseInfo->info.payload)
     {
-        OC_LOG(ERROR, TAG, PCF("Invalid connectivity type in endpoint"));
-        goto exit;
-    }
+        result = OCParsePayload(&response.payload,  responseInfo->info.payload,
+                responseInfo->info.payloadSize);
 
-    if(responseInfo->info.payload)
-    {
-        parsePresencePayload(responseInfo->info.payload,
-                                &(response.sequenceNumber),
-                                &maxAge,
-                                &resourceTypeName);
+        if(result != OC_STACK_OK || response.payload->type != PAYLOAD_TYPE_PRESENCE)
+        {
+            OC_LOG(ERROR, TAG, PCF("Presence parse failed"));
+            goto exit;
+        }
+        response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber;
+        resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType;
+        maxAge = ((OCPresencePayload*)response.payload)->maxAge;
     }
 
-    if(presenceSubscribe)
+    if (presenceSubscribe)
     {
         if(cbNode->sequenceNumber == response.sequenceNumber)
         {
-            if (cbNode->presence)
-            {
-                OC_LOG(INFO, TAG, PCF("No presence change. Updating TTL."));
-
-                result = ResetPresenceTTL(cbNode, maxAge);
-
-                if (result != OC_STACK_OK)
-                {
-                    OC_LOG_V(ERROR, TAG, "ResetPresenceTTL failed with error: %u", result);
-                }
-            }
-            else
-            {
-                OC_LOG(INFO, TAG, PCF("Not subscribed to presence."));
-            }
-
+            OC_LOG(INFO, TAG, PCF("No presence change"));
             goto exit;
         }
+
         if(maxAge == 0)
         {
             OC_LOG(INFO, TAG, PCF("Stopping presence"));
             response.result = OC_STACK_PRESENCE_STOPPED;
             if(cbNode->presence)
             {
-                OCFree(cbNode->presence->timeOut);
-                OCFree(cbNode->presence);
+                OICFree(cbNode->presence->timeOut);
+                OICFree(cbNode->presence);
                 cbNode->presence = NULL;
             }
         }
@@ -972,7 +892,8 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
         {
             if(!cbNode->presence)
             {
-                cbNode->presence = (OCPresence *) OCMalloc(sizeof(OCPresence));
+                cbNode->presence = (OCPresence *)OICMalloc(sizeof (OCPresence));
+
                 if(!(cbNode->presence))
                 {
                     OC_LOG(ERROR, TAG, PCF("Could not allocate memory for cbNode->presence"));
@@ -983,11 +904,11 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
                 VERIFY_NON_NULL_V(cbNode->presence);
                 cbNode->presence->timeOut = NULL;
                 cbNode->presence->timeOut = (uint32_t *)
-                        OCMalloc(PresenceTimeOutSize * sizeof(uint32_t));
+                        OICMalloc(PresenceTimeOutSize * sizeof(uint32_t));
                 if(!(cbNode->presence->timeOut)){
                     OC_LOG(ERROR, TAG,
                                   PCF("Could not allocate memory for cbNode->presence->timeOut"));
-                    OCFree(cbNode->presence);
+                    OICFree(cbNode->presence);
                     result = OC_STACK_NO_MEMORY;
                     goto exit;
                 }
@@ -995,11 +916,10 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
 
             ResetPresenceTTL(cbNode, maxAge);
 
-            OC_LOG(INFO, TAG, PCF("Presence changed, calling up the stack"));
             cbNode->sequenceNumber = response.sequenceNumber;
 
             // Ensure that a filter is actually applied.
-            if(resourceTypeName && cbNode->filterResourceType)
+            if( resourceTypeName && cbNode->filterResourceType)
             {
                 if(!findResourceType(cbNode->filterResourceType, resourceTypeName))
                 {
@@ -1011,9 +931,8 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
     else
     {
         // This is the multicast case
-
         OCMulticastNode* mcNode = NULL;
-        mcNode = GetMCPresenceNode(fullUri);
+        mcNode = GetMCPresenceNode(presenceUri);
 
         if(mcNode != NULL)
         {
@@ -1032,27 +951,24 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
         }
         else
         {
-            uint32_t uriLen = strlen(fullUri);
-            char* uri = (char *) OCMalloc(uriLen + 1);
-            if(uri)
+            char* uri = OICStrdup(presenceUri);
+            if (!uri)
             {
-                memcpy(uri, fullUri, (uriLen + 1));
-            }
-            else
-            {
-                OC_LOG(ERROR, TAG,
+                OC_LOG(INFO, TAG,
                     PCF("No Memory for URI to store in the presence node"));
                 result = OC_STACK_NO_MEMORY;
                 goto exit;
             }
+
             result = AddMCPresenceNode(&mcNode, uri, response.sequenceNumber);
-            if(result != OC_STACK_OK)
+            if(result == OC_STACK_NO_MEMORY)
             {
-                OC_LOG(ERROR, TAG,
-                    PCF("Unable to add Multicast Presence Node"));
-                OCFree(uri);
+                OC_LOG(INFO, TAG,
+                    PCF("No Memory for Multicast Presence Node"));
+                OICFree(uri);
                 goto exit;
             }
+            // presence node now owns uri
         }
 
         // Ensure that a filter is actually applied.
@@ -1073,29 +989,19 @@ static OCStackResult HandlePresenceResponse(const CARemoteEndpoint_t* endPoint,
     }
 
 exit:
-OCFree(fullUri);
-OCFree(ipAddress);
-OCFree(resourceTypeName);
-return result;
+    OICFree(resourceTypeName);
+    return result;
 }
 
-void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
+void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
 {
-    OC_LOG(INFO, TAG, PCF("Enter HandleCAResponses"));
-
-    if(NULL == endPoint)
-    {
-        OC_LOG(ERROR, TAG, PCF("endPoint is NULL"));
-        return;
-    }
+    VERIFY_NON_NULL_NR(endPoint, FATAL);
+    VERIFY_NON_NULL_NR(responseInfo, FATAL);
 
-    if(NULL == responseInfo)
-    {
-        OC_LOG(ERROR, TAG, PCF("responseInfo is NULL"));
-        return;
-    }
+    OC_LOG(INFO, TAG, PCF("Enter HandleCAResponses"));
 
-    if(strcmp(endPoint->resourceUri, OC_PRESENCE_URI) == 0)
+    if(responseInfo->info.resourceUri &&
+        strcmp(responseInfo->info.resourceUri, OC_RSRVD_PRESENCE_URI) == 0)
     {
         HandlePresenceResponse(endPoint, responseInfo);
         return;
@@ -1103,7 +1009,7 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
 
     ClientCB *cbNode = GetClientCB(responseInfo->info.token,
             responseInfo->info.tokenLength, NULL, NULL);
-    OC_LOG_V(DEBUG, TAG, "Response has the token %s", responseInfo->info.token);
+
     ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token,
             responseInfo->info.tokenLength);
 
@@ -1126,22 +1032,11 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
         {
             OC_LOG(INFO, TAG, PCF("Receiving A Timeout for this token"));
             OC_LOG(INFO, TAG, PCF("Calling into application address space"));
-            OCClientResponse response = {};
-            OCDevAddr address = {};
-            OCStackResult result = UpdateResponseAddr(&address, endPoint);
-            if(result != OC_STACK_OK)
-            {
-                OC_LOG(ERROR, TAG, PCF("Error parsing IP address in UpdateResponseAddr"));
-                return;
-            }
 
-            result = UpdateResponseAddr(&address, endPoint);
-            if(result != OC_STACK_OK)
-            {
-                OC_LOG(ERROR, TAG, PCF("Invalid connectivity type in endpoint"));
-                return;
-            }
-            response.addr = &address;
+            OCClientResponse response = {};
+            CopyEndpointToDevAddr(endPoint, &response.devAddr);
+            FixUpClientResponse(&response);
+            response.resourceUri = responseInfo->info.resourceUri;
 
             response.result = CAToOCStackResult(responseInfo->result);
             cbNode->callBack(cbNode->context,
@@ -1152,29 +1047,23 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
         {
             OC_LOG(INFO, TAG, PCF("This is a regular response, A client call back is found"));
             OC_LOG(INFO, TAG, PCF("Calling into application address space"));
+
             OCClientResponse response = {};
-            OCDevAddr address = {};
+            response.sequenceNumber = OC_OBSERVE_NO_OPTION;
+            CopyEndpointToDevAddr(endPoint, &response.devAddr);
+            FixUpClientResponse(&response);
+            response.resourceUri = responseInfo->info.resourceUri;
 
-            OCStackResult result = UpdateResponseAddr(&address, endPoint);
-            if(result != OC_STACK_OK)
-            {
-                OC_LOG(ERROR, TAG, PCF("Error parsing IP address in UpdateResponseAddr"));
-                return;
-            }
-            response.addr = &address;
-            // Populate the connectivity type. If this is a discovery response,
-            // the resource that will be constructed from this response will make
-            // further API calls from this interface.
-            result = CAToOCConnectivityType(endPoint->transportType,
-                                    &(response.connType));
-            if(result != OC_STACK_OK)
+            response.result = CAToOCStackResult(responseInfo->result);
+            if(responseInfo->info.payload &&
+               responseInfo->info.payloadSize &&
+               OC_STACK_OK != OCParsePayload(&response.payload, responseInfo->info.payload,
+                                           responseInfo->info.payloadSize))
             {
-                OC_LOG(ERROR, TAG, PCF("Invalid connectivity type in endpoint"));
+                OC_LOG(ERROR, TAG, PCF("Error converting payload"));
                 return;
             }
 
-            response.result = CAToOCStackResult(responseInfo->result);
-            response.resJSONPayload = (const char*)responseInfo->info.payload;
             response.numRcvdVendorSpecificHeaderOptions = 0;
             if(responseInfo->info.numOptions > 0)
             {
@@ -1229,6 +1118,7 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
                     cbNode->TTL = GetTicks(MAX_CB_TIMEOUT_SECONDS *
                                             MILLISECONDS_PER_SECOND);
                 }
+                OCPayloadDestroy(response.payload);
             }
 
             //Need to send ACK when the response is CON
@@ -1280,8 +1170,7 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
             }
             else
             {
-                OC_LOG(INFO, TAG, PCF("Received a response or notification,\
-                        but I do not have callback. Sending RESET"));
+                OC_LOG(INFO, TAG, PCF("Received a message without callbacks. Sending RESET"));
                 SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
                         CA_MSG_RESET, 0, NULL, NULL, 0);
             }
@@ -1304,16 +1193,37 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
         return;
     }
 
-    OC_LOG_V(INFO, TAG, PCF("Received payload: %s\n"), (char*)responseInfo->info.payload);
     OC_LOG(INFO, TAG, PCF("Exit HandleCAResponses"));
 }
 
 /*
+ * This function handles error response from CA
+ * code shall be added to handle the errors
+ */
+void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errrorInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Enter HandleCAErrorResponse"));
+
+    if(NULL == endPoint)
+    {
+        OC_LOG(ERROR, TAG, PCF("endPoint is NULL"));
+        return;
+    }
+
+    if(NULL == errrorInfo)
+    {
+        OC_LOG(ERROR, TAG, PCF("errrorInfo is NULL"));
+        return;
+    }
+    OC_LOG(INFO, TAG, PCF("Exit HandleCAErrorResponse"));
+}
+
+/*
  * This function sends out Direct Stack Responses. These are responses that are not coming
  * from the application entity handler. These responses have no payload and are usually ACKs,
  * RESETs or some error conditions that were caught by the stack.
  */
-OCStackResult SendDirectStackResponse(const CARemoteEndpoint_t* endPoint, const uint16_t coapID,
+OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16_t coapID,
         const CAResponseResult_t responseResult, const CAMessageType_t type,
         const uint8_t numOptions, const CAHeaderOption_t *options,
         CAToken_t token, uint8_t tokenLength)
@@ -1338,7 +1248,7 @@ OCStackResult SendDirectStackResponse(const CARemoteEndpoint_t* endPoint, const
 }
 
 //This function will be called back by CA layer when a request is received
-void HandleCARequests(const CARemoteEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
+void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
 {
     OC_LOG(INFO, TAG, PCF("Enter HandleCARequests"));
     if(!endPoint)
@@ -1363,106 +1273,91 @@ void HandleCARequests(const CARemoteEndpoint_t* endPoint, const CARequestInfo_t*
 
     OCServerProtocolRequest serverRequest = {};
 
-    OC_LOG_V(INFO, TAG, PCF("Endpoint URI : %s\n"), (char*)endPoint->resourceUri);
+    OC_LOG_V(INFO, TAG, PCF("Endpoint URI : %s"), requestInfo->info.resourceUri);
 
-    char * newUri = NULL;
+    char * uriWithoutQuery = NULL;
     char * query  = NULL;
 
-    requestResult = getQueryFromUri(endPoint->resourceUri, &query, &newUri);
+    requestResult = getQueryFromUri(requestInfo->info.resourceUri, &query, &uriWithoutQuery);
 
     if (requestResult != OC_STACK_OK)
     {
         OC_LOG_V(ERROR, TAG, "getQueryFromUri() failed with OC error code %d\n", requestResult);
         return;
     }
-    OC_LOG_V(INFO, TAG, PCF("URI without query: %s\n"), newUri);
-    OC_LOG_V(INFO, TAG, PCF("Query : %s\n"), query);
+    OC_LOG_V(INFO, TAG, PCF("URI without query: %s"), uriWithoutQuery);
+    OC_LOG_V(INFO, TAG, PCF("Query : %s"), query);
 
-    if(strlen(newUri) < MAX_URI_LENGTH)
+    if(strlen(uriWithoutQuery) < MAX_URI_LENGTH)
     {
-        //copy URI
-        memcpy (&(serverRequest.resourceUrl), newUri, strlen(newUri));
-        OCFree(newUri);
+        OICStrcpy(serverRequest.resourceUrl, sizeof(serverRequest.resourceUrl), uriWithoutQuery);
+        OICFree(uriWithoutQuery);
     }
     else
     {
         OC_LOG(ERROR, TAG, PCF("URI length exceeds MAX_URI_LENGTH."));
-        OCFree(newUri);
-        OCFree(query);
+        OICFree(uriWithoutQuery);
+        OICFree(query);
         return;
     }
-    //copy query
+
     if(query)
     {
         if(strlen(query) < MAX_QUERY_LENGTH)
         {
-            memcpy (&(serverRequest.query), query, strlen(query));
-            OCFree(query);
+            OICStrcpy(serverRequest.query, sizeof(serverRequest.query), query);
+            OICFree(query);
         }
         else
         {
             OC_LOG(ERROR, TAG, PCF("Query length exceeds MAX_QUERY_LENGTH."));
-            OCFree(query);
+            OICFree(query);
             return;
         }
     }
-    //copy request payload
+
     if (requestInfo->info.payload)
     {
-        size_t payloadLen = strlen(requestInfo->info.payload);
-        serverRequest.reqTotalSize = payloadLen + 1;
-        memcpy (&(serverRequest.reqJSONPayload), requestInfo->info.payload,
-                payloadLen);
+        serverRequest.reqTotalSize = requestInfo->info.payloadSize;
+        memcpy (&(serverRequest.payload), requestInfo->info.payload,
+                requestInfo->info.payloadSize);
     }
     else
     {
-        serverRequest.reqTotalSize = 1;
-        serverRequest.reqJSONPayload[0] = '\0';
+        serverRequest.reqTotalSize = 0;
     }
 
     switch (requestInfo->method)
     {
         case CA_GET:
-            {
-                serverRequest.method = OC_REST_GET;
-                break;
-            }
+            serverRequest.method = OC_REST_GET;
+            break;
         case CA_PUT:
-            {
-                serverRequest.method = OC_REST_PUT;
-                break;
-            }
+            serverRequest.method = OC_REST_PUT;
+            break;
         case CA_POST:
-            {
-                serverRequest.method = OC_REST_POST;
-                break;
-            }
+            serverRequest.method = OC_REST_POST;
+            break;
         case CA_DELETE:
-            {
-                serverRequest.method = OC_REST_DELETE;
-                break;
-            }
+            serverRequest.method = OC_REST_DELETE;
+            break;
         default:
-            {
-                OC_LOG(ERROR, TAG, PCF("Received CA method %d not supported"));
-                SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_REQ,
+            OC_LOG_V(ERROR, TAG, "Received CA method %d not supported", requestInfo->method);
+            SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_REQ,
                         requestInfo->info.type, requestInfo->info.numOptions,
                         requestInfo->info.options, requestInfo->info.token,
                         requestInfo->info.tokenLength);
-                return;
-            }
+            return;
     }
 
-    OC_LOG_V(INFO, TAG, "HandleCARequests: CA token length = %d",
-            requestInfo->info.tokenLength);
     OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)requestInfo->info.token,
             requestInfo->info.tokenLength);
-    serverRequest.requestToken = (CAToken_t)OCMalloc(requestInfo->info.tokenLength);
+    serverRequest.requestToken = (CAToken_t)OICMalloc(requestInfo->info.tokenLength);
     serverRequest.tokenLength = requestInfo->info.tokenLength;
-    // Module Name
+
     if (!serverRequest.requestToken)
     {
-        OC_LOG(FATAL, TAG, "Server Request Token is NULL");
+        OC_LOG(FATAL, TAG, "Allocation for token failed.");
         SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_INTERNAL_SERVER_ERROR,
                 requestInfo->info.type, requestInfo->info.numOptions,
                 requestInfo->info.options, requestInfo->info.token,
@@ -1479,16 +1374,13 @@ void HandleCARequests(const CARemoteEndpoint_t* endPoint, const CARequestInfo_t*
     {
         serverRequest.qos = OC_LOW_QOS;
     }
-    // CA does not need the following 2 fields
+    // CA does not need the following field
     // Are we sure CA does not need them? how is it responding to multicast
     serverRequest.delayedResNeeded = 0;
-    serverRequest.secured = endPoint->isSecured;
 
     serverRequest.coapID = requestInfo->info.messageId;
 
-    // copy the address
-    serverRequest.addressInfo      = endPoint->addressInfo;
-    serverRequest.connectivityType = endPoint->transportType;
+    CopyEndpointToDevAddr(endPoint, &serverRequest.devAddr);
 
     // copy vendor specific header options
     uint8_t tempNum = (requestInfo->info.numOptions);
@@ -1501,7 +1393,7 @@ void HandleCARequests(const CARemoteEndpoint_t* endPoint, const CARequestInfo_t*
                 requestInfo->info.type, requestInfo->info.numOptions,
                 requestInfo->info.options, requestInfo->info.token,
                 requestInfo->info.tokenLength);
-        OCFree(serverRequest.requestToken);
+        OICFree(serverRequest.requestToken);
         return;
     }
     serverRequest.numRcvdVendorSpecificHeaderOptions = tempNum;
@@ -1532,7 +1424,7 @@ void HandleCARequests(const CARemoteEndpoint_t* endPoint, const CARequestInfo_t*
     }
     // requestToken is fed to HandleStackRequests, which then goes to AddServerRequest.
     // The token is copied in there, and is thus still owned by this function.
-    OCFree(serverRequest.requestToken);
+    OICFree(serverRequest.requestToken);
     OC_LOG(INFO, TAG, PCF("Exit HandleCARequests"));
 }
 
@@ -1554,14 +1446,14 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
     {
         OC_LOG(INFO, TAG, PCF("This is a new Server Request"));
         result = AddServerRequest(&request, protocolRequest->coapID,
-                protocolRequest->delayedResNeeded, protocolRequest->secured, 0,
+                protocolRequest->delayedResNeeded, 0,
                 protocolRequest->method, protocolRequest->numRcvdVendorSpecificHeaderOptions,
                 protocolRequest->observationOption, protocolRequest->qos,
                 protocolRequest->query, protocolRequest->rcvdVendorSpecificHeaderOptions,
-                protocolRequest->reqJSONPayload, protocolRequest->requestToken,
+                protocolRequest->payload, protocolRequest->requestToken,
                 protocolRequest->tokenLength,
-                protocolRequest->resourceUrl,protocolRequest->reqTotalSize,
-                &protocolRequest->addressInfo, protocolRequest->connectivityType);
+                protocolRequest->resourceUrl, protocolRequest->reqTotalSize,
+                &protocolRequest->devAddr);
         if (OC_STACK_OK != result)
         {
             OC_LOG(ERROR, TAG, PCF("Error adding server request"));
@@ -1581,8 +1473,7 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
     }
     else
     {
-        OC_LOG(INFO, TAG,
-                PCF("This is either a repeated or blocked Server Request"));
+        OC_LOG(INFO, TAG, PCF("This is either a repeated or blocked Server Request"));
     }
 
     if(request->requestComplete)
@@ -1602,76 +1493,16 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
     return result;
 }
 
-bool ParseIPv4Address(char * ipAddrStr, uint8_t * ipAddr, uint16_t * port)
+bool validatePlatformInfo(OCPlatformInfo info)
 {
-    size_t index = 0;
-     char *itr, *coap;
-     uint8_t dotCount = 0;
 
-     ipAddr[index] = 0;
-     *port = 0;
-     /* search for scheme */
-     itr = ipAddrStr;
-    if (!isdigit((char) *ipAddrStr))
+    if (!info.platformID)
     {
-        coap = OC_COAP_SCHEME;
-        while (*coap && tolower(*itr) == *coap)
-        {
-            coap++;
-            itr++;
-        }
+        OC_LOG(ERROR, TAG, PCF("No platform ID found."));
+        return false;
     }
-    ipAddrStr = itr;
 
-    while (*ipAddrStr)
-    {
-        if (isdigit(*ipAddrStr))
-        {
-            ipAddr[index] *= 10;
-            ipAddr[index] += *ipAddrStr - '0';
-        }
-        else if (*ipAddrStr == '.')
-        {
-            index++;
-            dotCount++;
-            ipAddr[index] = 0;
-        }
-        else
-        {
-            break;
-        }
-        ipAddrStr++;
-    }
-    if(*ipAddrStr == ':')
-    {
-        ipAddrStr++;
-        while (*ipAddrStr){
-            if (isdigit(*ipAddrStr))
-            {
-                *port *= 10;
-                *port += *ipAddrStr - '0';
-            }
-            else
-            {
-                break;
-            }
-            ipAddrStr++;
-        }
-    }
-
-    return (3 == dotCount);
-}
-
-bool validatePlatformInfo(OCPlatformInfo info)
-{
-
-    if (!info.platformID)
-    {
-        OC_LOG(ERROR, TAG, PCF("No platform ID found."));
-        return false;
-    }
-
-    if (info.manufacturerName)
+    if (info.manufacturerName)
     {
         size_t lenManufacturerName = strlen(info.manufacturerName);
 
@@ -1697,12 +1528,44 @@ bool validatePlatformInfo(OCPlatformInfo info)
     }
     return true;
 }
+
 //-----------------------------------------------------------------------------
 // Public APIs
 //-----------------------------------------------------------------------------
+#ifdef RA_ADAPTER
+OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo)
+{
+    if (!raInfo           ||
+        !raInfo->username ||
+        !raInfo->hostname ||
+        !raInfo->xmpp_domain)
+    {
+
+        return OC_STACK_INVALID_PARAM;
+    }
+    OCStackResult result = CAResultToOCResult(CASetRAInfo((const CARAInfo_t *) raInfo));
+    gRASetInfo = (result == OC_STACK_OK)? true : false;
+
+    return result;
+}
+#endif
 
 OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
 {
+    (void) ipAddr;
+    (void) port;
+#ifdef RA_ADAPTER
+    if(!gRASetInfo)
+    {
+        OC_LOG(ERROR, TAG, PCF("Need to call OCSetRAInfo before calling OCInit"));
+        return OC_STACK_ERROR;
+    }
+#endif
+    return OCInit1(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS);
+}
+
+OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags)
+{
     if(stackState == OC_STACK_INITIALIZED)
     {
         OC_LOG(INFO, TAG, PCF("Subsequent calls to OCInit() without calling \
@@ -1710,8 +1573,6 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
         return OC_STACK_OK;
     }
 
-    (void) ipAddr;
-    (void) port;
     OCStackResult result = OC_STACK_ERROR;
     OC_LOG(INFO, TAG, PCF("Entering OCInit"));
 
@@ -1723,7 +1584,28 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
     }
     myStackMode = mode;
 
+    if (mode == OC_CLIENT || mode == OC_CLIENT_SERVER)
+    {
+        caglobals.client = true;
+    }
+    if (mode == OC_SERVER || mode == OC_CLIENT_SERVER)
+    {
+        caglobals.server = true;
+    }
+
+    caglobals.serverFlags = (CATransportFlags_t)serverFlags;
+    if (!(caglobals.serverFlags & CA_IPFAMILY_MASK))
+    {
+        caglobals.serverFlags = (CATransportFlags_t)(caglobals.serverFlags|CA_IPV4);
+    }
+    caglobals.clientFlags = (CATransportFlags_t)clientFlags;
+    if (!(caglobals.clientFlags & CA_IPFAMILY_MASK))
+    {
+        caglobals.clientFlags = (CATransportFlags_t)(caglobals.clientFlags|CA_IPV4);
+    }
+
     defaultDeviceHandler = NULL;
+    defaultDeviceHandlerCallbackParameter = NULL;
     OCSeedRandom();
 
     result = CAResultToOCResult(CAInitialize());
@@ -1732,18 +1614,20 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
     result = CAResultToOCResult(OCSelectNetwork());
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    CARegisterHandler(HandleCARequests, HandleCAResponses);
     switch (myStackMode)
     {
         case OC_CLIENT:
+                       CARegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
             result = CAResultToOCResult(CAStartDiscoveryServer());
             OC_LOG(INFO, TAG, PCF("Client mode: CAStartDiscoveryServer"));
             break;
         case OC_SERVER:
+                       SRMRegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
             result = CAResultToOCResult(CAStartListeningServer());
             OC_LOG(INFO, TAG, PCF("Server mode: CAStartListeningServer"));
             break;
         case OC_CLIENT_SERVER:
+                       SRMRegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
             result = CAResultToOCResult(CAStartListeningServer());
             if(result == OC_STACK_OK)
             {
@@ -1753,12 +1637,6 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
     }
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-#if defined(__WITH_DTLS__)
-    result = (CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials) == CA_STATUS_OK) ?
-        OC_STACK_OK : OC_STACK_ERROR;
-    VERIFY_SUCCESS(result, OC_STACK_OK);
-#endif // (__WITH_DTLS__)
-
 #ifdef WITH_PRESENCE
     PresenceTimeOutSize = sizeof(PresenceTimeOut)/sizeof(PresenceTimeOut[0]) - 1;
 #endif // WITH_PRESENCE
@@ -1772,6 +1650,13 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
         result = initResources();
     }
 
+    // Initialize the SRM Policy Engine
+    if(result == OC_STACK_OK)
+    {
+        result = SRMInitPolicyEngine();
+        // TODO after BeachHead delivery: consolidate into single SRMInit()
+    }
+
 exit:
     if(result != OC_STACK_OK)
     {
@@ -1815,8 +1700,12 @@ OCStackResult OCStop()
     DeleteObserverList();
     // Remove all the client callbacks
     DeleteClientCBList();
-    // Deinit security blob
-    DeinitOCSecurityInfo();
+
+       // De-init the SRM Policy Engine
+    // TODO after BeachHead delivery: consolidate into single SRMDeInit()
+    SRMDeInitPolicyEngine();
+
+
     stackState = OC_STACK_UNINITIALIZED;
     return OC_STACK_OK;
 }
@@ -1860,259 +1749,468 @@ OCStackResult verifyUriQueryLength(const char *inputUri, uint16_t uriLen)
     return OC_STACK_OK;
 }
 
-OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
-            const char *referenceUri, const char *request, OCConnectivityType conType,
-            OCQualityOfService qos, OCCallbackData *cbData,
-            OCHeaderOption * options, uint8_t numOptions)
+/**
+ *  A request uri consists of the following components in order:
+ *                              example
+ *  optional prefix             "coap://"
+ *  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 result = OC_STACK_ERROR;
-    ClientCB *clientCB = NULL;
-    char * requestUri = NULL;
-    char * resourceType = NULL;
-    char * query = NULL;
-    char * newUri = (char *)requiredUri;
-    (void) referenceUri;
-    CARemoteEndpoint_t* endpoint = NULL;
-    CAResult_t caResult;
-    CAToken_t token = NULL;
-    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-    OCDoHandle resHandle = NULL;
-    CAInfo_t requestData ={};
-    CARequestInfo_t requestInfo ={};
-    CAGroupEndpoint_t grpEnd = {};
+    VERIFY_NON_NULL(fullUri, FATAL, OC_STACK_INVALID_CALLBACK);
 
-    OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
+    OCStackResult result = OC_STACK_OK;
+    OCDevAddr *da = NULL;
+    char *colon = NULL;
+    char *end;
 
-    // Validate input parameters
-    VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
-    VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+    // provide defaults for all returned values
+    if (devAddr)
+    {
+        *devAddr = NULL;
+    }
+    if (resourceUri)
+    {
+        *resourceUri = NULL;
+    }
+    if (resourceType)
+    {
+        *resourceType = NULL;
+    }
 
-    //TODO ("Need to form the final query by concatenating require and reference URI's");
-    VERIFY_NON_NULL(requiredUri, FATAL, OC_STACK_INVALID_URI);
+    // delimit url prefix, if any
+    const char *start = fullUri;
+    char *slash2 = strstr(start, "//");
+    if (slash2)
+    {
+        start = slash2 + 2;
+    }
+    char *slash = strchr(start, '/');
+    if (!slash)
+    {
+        return OC_STACK_INVALID_URI;
+    }
 
-    uint16_t uriLen = strlen(requiredUri);
+    // processs url prefix, if any
+    size_t urlLen = slash - start;
+    // port
+    uint16_t port = 0;
+    size_t len = 0;
+    if (urlLen && devAddr)
+    {   // construct OCDevAddr
+        if (OC_ADAPTER_IP == adapter)
+        {
+            if (start[0] == '[')
+            {   // ipv6 address
+                char *close = strchr(++start, ']');
+                if (!close || close > slash)
+                {
+                    return OC_STACK_INVALID_URI;
+                }
+                end = close;
+                if (close[1] == ':')
+                {
+                    colon = close + 1;
+                }
+            }
+            else
+            {   // ipv4 address
+                end = slash;
+                colon = strchr(start, ':');
+                end = (colon && colon < slash) ? colon : slash;
+            }
+            len = end - start;
+            if (len >= sizeof(da->addr))
+            {
+                return OC_STACK_INVALID_URI;
+            }
+            // collect port, if any
+            if (colon && colon < slash)
+            {
+                for (colon++; colon < slash; colon++)
+                {
+                    char c = colon[0];
+                    if (c < '0' || c > '9')
+                    {
+                        return OC_STACK_INVALID_URI;
+                    }
+                    port = 10 * port + c - '0';
+                }
+            }
+        }
+        else
+        {
+            /**
+             * This is for Non-IP adapters(EDR and BLE).
+             * The address will be between "//" and "/" in the request URI.
+             * [Ex. coap://AB:BC:CD:DE:EF:FG/resource_uri]
+             */
+            end = slash;
+        }
 
-    // ToDo: We should also check if the requiredUri has a mutlicast address,
-    // then qos has to be OC_Low_QOS
-    switch (method)
-    {
-        case OC_REST_GET:
-        case OC_REST_OBSERVE:
-        case OC_REST_OBSERVE_ALL:
-        case OC_REST_CANCEL_OBSERVE:
-            requestInfo.method = CA_GET;
-            break;
+        len = end - start;
+        if (len >= sizeof(da->addr))
+        {
+            return OC_STACK_INVALID_URI;
+        }
 
-        case OC_REST_PUT:
-            requestInfo.method = CA_PUT;
-            break;
+        da = (OCDevAddr *)OICCalloc(sizeof (OCDevAddr), 1);
+        if (!da)
+        {
+            return OC_STACK_NO_MEMORY;
+        }
+        OICStrcpyPartial(da->addr, sizeof(da->addr), start, len);
+        da->port = port;
+        da->adapter = adapter;
+        da->flags = flags;
+        if (!strncmp(fullUri, "coaps:", 6))
+        {
+            da->flags = (OCTransportFlags)(da->flags|CA_SECURE);
+        }
+        *devAddr = da;
+    }
 
-        case OC_REST_POST:
-            requestInfo.method = CA_POST;
-            break;
+    // process resource uri, if any
+    if (slash)
+    {   // request uri and query
+        size_t ulen = strlen(slash); // resource uri length
+        size_t tlen = 0;      // resource type length
+        char *type = NULL;
 
-        case OC_REST_DELETE:
-            requestInfo.method = CA_DELETE;
-            break;
+        static const char strPresence[] = "/oic/ad?rt=";
+        static const size_t lenPresence = sizeof(strPresence) - 1;
+        if (!strncmp(slash, strPresence, lenPresence))
+        {
+            type = slash + lenPresence;
+            tlen = ulen - lenPresence;
+        }
+        // resource uri
+        if (resourceUri)
+        {
+            *resourceUri = (char *)OICMalloc(ulen + 1);
+            if (!*resourceUri)
+            {
+                result = OC_STACK_NO_MEMORY;
+                goto error;
+            }
+            strcpy(*resourceUri, slash);
+        }
+        // resource type
+        if (type && resourceType)
+        {
+            *resourceType = (char *)OICMalloc(tlen + 1);
+            if (!*resourceType)
+            {
+                result = OC_STACK_NO_MEMORY;
+                goto error;
+            }
 
-        #ifdef WITH_PRESENCE
-        case OC_REST_PRESENCE:
-            // Replacing method type with GET because "presence"
-            // is a stack layer only implementation.
-            requestInfo.method = CA_GET;
-            break;
-        #endif
+            OICStrcpy(*resourceType, (tlen+1), type);
+        }
+    }
 
-        default:
-            result = OC_STACK_INVALID_METHOD;
-            goto exit;
+    return OC_STACK_OK;
+
+error:
+    // free all returned values
+    if (devAddr)
+    {
+        OICFree(*devAddr);
+    }
+    if (resourceUri)
+    {
+        OICFree(*resourceUri);
     }
+    if (resourceType)
+    {
+        OICFree(*resourceType);
+    }
+    return result;
+}
 
-    if((result = verifyUriQueryLength(requiredUri, uriLen)) != OC_STACK_OK)
+static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint,
+                                        char *resourceUri, char **requestUri)
+{
+    char uri[CA_MAX_URI_LENGTH];
+
+    FormCanonicalPresenceUri(endpoint, resourceUri, uri);
+
+    *requestUri = (char *)OICMalloc(strlen(uri) + 1);
+    if (!*requestUri)
     {
-        goto exit;
+        return OC_STACK_NO_MEMORY;
     }
 
-    if((request) && (strlen(request) > MAX_REQUEST_LENGTH))
+    strcpy(*requestUri, uri);
+    return OC_STACK_OK;
+}
+
+/**
+ * Discover or Perform requests on a specified resource
+ */
+OCStackResult OCDoResource(OCDoHandle *handle,
+                            OCMethod method,
+                            const char *requestUri,
+                            const OCDevAddr *destination,
+                            OCPayload* payload,
+                            OCConnectivityType connectivityType,
+                            OCQualityOfService qos,
+                            OCCallbackData *cbData,
+                            OCHeaderOption *options,
+                            uint8_t numOptions)
+{
+    OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
+
+    // Validate input parameters
+    VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL(requestUri , FATAL, OC_STACK_INVALID_URI);
+
+    OCStackResult result = OC_STACK_ERROR;
+    CAResult_t caResult;
+    CAToken_t token = NULL;
+    uint8_t tokenLength = CA_MAX_TOKEN_LEN;
+    ClientCB *clientCB = NULL;
+    OCDoHandle resHandle = NULL;
+    CAEndpoint_t *endpoint = NULL;
+    OCDevAddr tmpDevAddr = { OC_DEFAULT_ADAPTER };
+    uint32_t ttl = 0;
+    OCTransportAdapter adapter;
+    OCTransportFlags flags;
+    // the request contents are put here
+    CARequestInfo_t requestInfo = { CA_GET };
+    // requestUri  will be parsed into the following three variables
+    OCDevAddr *devAddr = NULL;
+    char *resourceUri = NULL;
+    char *resourceType = NULL;
+
+    // To track if memory is allocated for additional header options
+    uint8_t hdrOptionMemAlloc = 0;
+
+    // This validation is broken, but doesn't cause harm
+    size_t uriLen = strlen(requestUri );
+    if ((result = verifyUriQueryLength(requestUri , uriLen)) != OC_STACK_OK)
     {
-        result = OC_STACK_INVALID_PARAM;
         goto exit;
     }
 
-#ifdef WITH_PRESENCE
-    if(method == OC_REST_PRESENCE)
+    /*
+     * Support original behavior with address on resourceUri argument.
+     */
+    adapter = (OCTransportAdapter)(connectivityType >> CT_ADAPTER_SHIFT);
+    flags = (OCTransportFlags)(connectivityType & CT_MASK_FLAGS);
+
+    result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType);
+
+    if (result != OC_STACK_OK)
     {
-        result = getQueryFromUri(requiredUri, &query, &newUri);
+        OC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri);
+        goto exit;
+    }
 
-        if(result != OC_STACK_OK)
+    switch (method)
+    {
+    case OC_REST_GET:
+    case OC_REST_OBSERVE:
+    case OC_REST_OBSERVE_ALL:
+    case OC_REST_CANCEL_OBSERVE:
+        requestInfo.method = CA_GET;
+        break;
+    case OC_REST_PUT:
+        requestInfo.method = CA_PUT;
+        break;
+    case OC_REST_POST:
+        requestInfo.method = CA_POST;
+        break;
+    case OC_REST_DELETE:
+        requestInfo.method = CA_DELETE;
+        break;
+    case OC_REST_DISCOVER:
+        qos = OC_LOW_QOS;
+        if (destination || devAddr)
         {
-            OC_LOG_V(ERROR, TAG, "Invalid Param from getQueryFromUri: %d, URI is %s",
-                    result, requiredUri);
-            goto exit;
-        }
-
-        if(query)
-        {
-            result = getResourceType((char *) query, &resourceType);
-            OCFree(query);
-            if(resourceType)
-            {
-                OC_LOG_V(DEBUG, TAG, "Got Resource Type: %s", resourceType);
-            }
-            else
-            {
-                OC_LOG(DEBUG, TAG, PCF("Resource type is NULL."));
-            }
+            requestInfo.isMulticast = false;
         }
         else
         {
-            OC_LOG(DEBUG, TAG, PCF("Query string is NULL."));
-        }
-        if(result != OC_STACK_OK)
-        {
-            goto exit;
+            destination = &tmpDevAddr;
+            requestInfo.isMulticast = true;
         }
+        // CA_DISCOVER will become GET and isMulticast
+        requestInfo.method = CA_GET;
+        break;
+    #ifdef WITH_PRESENCE
+    case OC_REST_PRESENCE:
+        // Replacing method type with GET because "presence"
+        // is a stack layer only implementation.
+        requestInfo.method = CA_GET;
+        break;
+    #endif
+    default:
+        result = OC_STACK_INVALID_METHOD;
+        goto exit;
     }
-#endif // WITH_PRESENCE
 
-    requestUri = (char *) OCMalloc(uriLen + 1);
-    if(requestUri)
+    if (!devAddr && !destination)
     {
-        memcpy(requestUri, newUri, (uriLen + 1));
+        OC_LOG_V(DEBUG, TAG, "no devAddr and no destination");
+        result = OC_STACK_INVALID_PARAM;
+        goto exit;
     }
-    else
+
+    /* If not original behavior, use destination argument */
+    if (destination && !devAddr)
     {
-        result = OC_STACK_NO_MEMORY;
-        goto exit;
+        devAddr = (OCDevAddr *)OICMalloc(sizeof (OCDevAddr));
+        if (!devAddr)
+        {
+            result = OC_STACK_NO_MEMORY;
+            goto exit;
+        }
+        *devAddr = *destination;
     }
 
     resHandle = GenerateInvocationHandle();
-    if(!resHandle)
+    if (!resHandle)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
 
-    // create token
     caResult = CAGenerateToken(&token, tokenLength);
     if (caResult != CA_STATUS_OK)
     {
         OC_LOG(ERROR, TAG, PCF("CAGenerateToken error"));
-        CADestroyToken(token);
-        result = CAResultToOCResult (caResult);
         goto exit;
     }
 
-    requestData.type = qualityOfServiceToMessageType(qos);
-
-    requestData.token = token;
-    requestData.tokenLength = tokenLength;
+    // fill in request data
+    requestInfo.info.type = qualityOfServiceToMessageType(qos);
+    requestInfo.info.token = token;
+    requestInfo.info.tokenLength = tokenLength;
+    requestInfo.info.resourceUri = resourceUri;
 
     if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL))
     {
-        result = CreateObserveHeaderOption (&(requestData.options), options,
-                                    numOptions, OC_OBSERVE_REGISTER);
+        result = CreateObserveHeaderOption (&(requestInfo.info.options),
+                                    options, numOptions, OC_OBSERVE_REGISTER);
         if (result != OC_STACK_OK)
         {
-            CADestroyToken(token);
             goto exit;
         }
-        requestData.numOptions = numOptions + 1;
+        hdrOptionMemAlloc = 1;
+        requestInfo.info.numOptions = numOptions + 1;
     }
     else
     {
-        requestData.options = (CAHeaderOption_t*)options;
-        requestData.numOptions = numOptions;
+        requestInfo.info.options = (CAHeaderOption_t*)options;
+        requestInfo.info.numOptions = numOptions;
     }
 
-    requestData.payload = (char *)request;
+    // create remote endpoint
+    result = OCCreateEndpoint(devAddr, &endpoint);
+    if(payload)
+    {
+        if((result =
+            OCConvertPayload(payload, &requestInfo.info.payload, &requestInfo.info.payloadSize))
+                != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, PCF("Failed to create CBOR Payload"));
+            goto exit;
+        }
+    }
+    else
+    {
+        requestInfo.info.payload = NULL;
+        requestInfo.info.payloadSize = 0;
+    }
 
-    requestInfo.info = requestData;
 
-    CATransportType_t caConType;
 
-    result = OCToCATransportType((OCConnectivityType) conType, &caConType);
     if (result != OC_STACK_OK)
     {
-        OC_LOG(ERROR, TAG, PCF("Invalid Connectivity Type"));
+        OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
         goto exit;
     }
 
-    // send request
-    if(conType == OC_ALL)
-    {
-        grpEnd.transportType = caConType;
-
-        grpEnd.resourceUri = (CAURI_t) OCMalloc(uriLen + 1);
-        if(!grpEnd.resourceUri)
-        {
-            result = OC_STACK_NO_MEMORY;
-            CADestroyToken(token);
-            goto exit;
-        }
-        strncpy(grpEnd.resourceUri, requiredUri, (uriLen + 1));
-
-        caResult = CASendRequestToAll(&grpEnd, &requestInfo);
-    }
-    else
+    // prepare for response
+    #ifdef WITH_PRESENCE
+    if (method == OC_REST_PRESENCE)
     {
-        caResult = CACreateRemoteEndpoint(newUri, caConType, &endpoint);
-
-        if (caResult != CA_STATUS_OK)
+        char *presenceUri = NULL;
+        result = OCPreparePresence(endpoint, resourceUri, &presenceUri);
+        if (OC_STACK_OK != result)
         {
-            OC_LOG(ERROR, TAG, PCF("CACreateRemoteEndpoint error"));
-            result = CAResultToOCResult (caResult);
-            CADestroyToken(token);
             goto exit;
         }
 
-        caResult = CASendRequest(endpoint, &requestInfo);
+        // Assign full presence uri as coap://ip:port/oic/ad to add to callback list.
+        // Presence notification will form a canonical uri to
+        // look for callbacks into the application.
+        resourceUri = presenceUri;
     }
+    #endif
 
-    if (caResult != CA_STATUS_OK)
+    ttl = GetTicks(MAX_CB_TIMEOUT_SECONDS * MILLISECONDS_PER_SECOND);
+    result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle,
+                            method, devAddr, resourceUri, resourceType, ttl);
+    if (OC_STACK_OK != result)
     {
-        OC_LOG(ERROR, TAG, PCF("CASendRequest"));
-        result = CAResultToOCResult (caResult);
-        CADestroyToken(token);
         goto exit;
     }
 
-    result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle, method,
-                             requestUri, resourceType, conType,
-                             GetTicks(MAX_CB_TIMEOUT_SECONDS * MILLISECONDS_PER_SECOND));
-    if(result != OC_STACK_OK)
+    devAddr = NULL;       // Client CB list entry now owns it
+    resourceUri = NULL;   // Client CB list entry now owns it
+    resourceType = NULL;  // Client CB list entry now owns it
+
+    // send request
+    caResult = CASendRequest(endpoint, &requestInfo);
+    if (caResult != CA_STATUS_OK)
     {
-        result = OC_STACK_NO_MEMORY;
+        OC_LOG(ERROR, TAG, PCF("CASendRequest"));
+        result = OC_STACK_COMM_ERROR;
         goto exit;
     }
 
-    if(handle)
+    if (handle)
     {
         *handle = resHandle;
     }
 
 exit:
-    if(newUri != requiredUri)
-    {
-        OCFree(newUri);
-    }
     if (result != OC_STACK_OK)
     {
-        OC_LOG_V(ERROR, TAG, PCF("OCDoResource error no %d"), result);
+        OC_LOG(ERROR, TAG, PCF("OCDoResource error"));
         FindAndDeleteClientCB(clientCB);
-        OCFree(resHandle);
-        OCFree(requestUri);
-        OCFree(resourceType);
+        CADestroyToken(token);
+        if (handle)
+        {
+            *handle = NULL;
+        }
+        OICFree(resHandle);
     }
-    CADestroyRemoteEndpoint(endpoint);
-    OCFree(grpEnd.resourceUri);
 
-    if (requestData.options  && requestData.numOptions > 0)
+    // 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(endpoint);
+    if (hdrOptionMemAlloc)
     {
-        if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL))
-        {
-            OCFree(requestData.options);
-        }
+        OICFree(requestInfo.info.options);
     }
     return result;
 }
@@ -2138,7 +2236,7 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
      *      Remove the callback associated on client side.
      */
     OCStackResult ret = OC_STACK_OK;
-    CARemoteEndpoint_t* endpoint = NULL;
+    CAEndpoint_t* endpoint = NULL;
     CAResult_t caResult;
     CAInfo_t requestData = {};
     CARequestInfo_t requestInfo = {};
@@ -2148,201 +2246,216 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
         return OC_STACK_INVALID_PARAM;
     }
 
-    OC_LOG(INFO, TAG, PCF("Entering OCCancel"));
-
     ClientCB *clientCB = GetClientCB(NULL, 0, handle, NULL);
+    if (!clientCB)
+    {
+        OC_LOG(ERROR, TAG, PCF("Client callback not found. Called OCCancel twice?"));
+        goto Error;
+    }
 
-    if(clientCB)
+    switch (clientCB->method)
     {
-        switch (clientCB->method)
-        {
-            case OC_REST_OBSERVE:
-            case OC_REST_OBSERVE_ALL:
-                if(qos == OC_HIGH_QOS)
-                {
-                    requestData.type =  qualityOfServiceToMessageType(qos);
-                    requestData.token = clientCB->token;
-                    requestData.tokenLength = clientCB->tokenLength;
+        case OC_REST_OBSERVE:
+        case OC_REST_OBSERVE_ALL:
+            OC_LOG_V(INFO, TAG, "Canceling observation for resource %s",
+                                        clientCB->requestUri);
+            if (qos != OC_HIGH_QOS)
+            {
+                FindAndDeleteClientCB(clientCB);
+                break;
+            }
+            else
+            {
+                OC_LOG(INFO, TAG, PCF("Cancelling observation as CONFIRMABLE"));
+            }
 
-                    if (CreateObserveHeaderOption (&(requestData.options),
-                            options, numOptions, OC_OBSERVE_DEREGISTER) != OC_STACK_OK)
-                    {
-                        return OC_STACK_ERROR;
-                    }
-                    requestData.numOptions = numOptions + 1;
-                    requestInfo.method = CA_GET;
-                    requestInfo.info = requestData;
+            requestData.type = qualityOfServiceToMessageType(qos);
+            requestData.token = clientCB->token;
+            requestData.tokenLength = clientCB->tokenLength;
+            if (CreateObserveHeaderOption (&(requestData.options),
+                    options, numOptions, OC_OBSERVE_DEREGISTER) != OC_STACK_OK)
+            {
+                return OC_STACK_ERROR;
+            }
+            requestData.numOptions = numOptions + 1;
+            requestData.resourceUri = OICStrdup (clientCB->requestUri);
 
-                    CATransportType_t caConType;
-                    ret = OCToCATransportType(clientCB->conType, &caConType);
-                    if(ret != OC_STACK_OK)
-                    {
-                        goto Error;
-                    }
+            requestInfo.method = CA_GET;
+            requestInfo.info = requestData;
 
-                    caResult = CACreateRemoteEndpoint((char *)clientCB->requestUri,
-                            caConType, &endpoint);
-                    if (caResult != CA_STATUS_OK)
-                    {
-                        OC_LOG(ERROR, TAG, PCF("CACreateRemoteEndpoint error"));
-                        ret = OC_STACK_ERROR;
-                        goto Error;
-                    }
+            ret = OCCreateEndpoint(clientCB->devAddr, &endpoint);
+            if (ret != OC_STACK_OK)
+            {
+                OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
+                goto Error;
+            }
 
-                    // send request
-                    caResult = CASendRequest(endpoint, &requestInfo);
-                    if (caResult != CA_STATUS_OK)
-                    {
-                        OC_LOG(ERROR, TAG, PCF("CASendRequest error"));
-                        ret = OC_STACK_ERROR;
-                    }
-                    ret = CAResultToOCResult (caResult);
-                }
-                else
-                {
-                    FindAndDeleteClientCB(clientCB);
-                }
-                break;
+            // send request
+            caResult = CASendRequest(endpoint, &requestInfo);
+            if (caResult != CA_STATUS_OK)
+            {
+                OC_LOG(ERROR, TAG, PCF("CASendRequest error"));
+                ret = OC_STACK_ERROR;
+            }
+            ret = CAResultToOCResult (caResult);
+            break;
 
-            #ifdef WITH_PRESENCE
-            case OC_REST_PRESENCE:
-                FindAndDeleteClientCB(clientCB);
-                break;
-            #endif
-            default:
-                ret = OC_STACK_INVALID_METHOD;
-                break;
-        }
-    }
-    else
-    {
-        OC_LOG(ERROR, TAG, PCF("Client callback not found. Called OCCancel twice?"));
+        #ifdef WITH_PRESENCE
+        case OC_REST_PRESENCE:
+            FindAndDeleteClientCB(clientCB);
+            break;
+        #endif
+
+        default:
+            ret = OC_STACK_INVALID_METHOD;
+            break;
     }
 
-    Error:
-    CADestroyRemoteEndpoint(endpoint);
+Error:
+    OCDestroyEndpoint(endpoint);
     if (requestData.numOptions > 0)
     {
-        OCFree(requestData.options);
+        OICFree(requestData.options);
+    }
+    if (requestData.resourceUri)
+    {
+        OICFree (requestData.resourceUri);
     }
 
     return ret;
 }
 
+/**
+ * @brief   Register Persistent storage callback.
+ * @param   persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
+ * @return
+ *     OC_STACK_OK    - No errors; Success
+ *     OC_STACK_INVALID_PARAM - Invalid parameter
+ */
+OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
+{
+    OC_LOG(INFO, TAG, PCF("RegisterPersistentStorageHandler !!"));
+    if(!persistentStorageHandler)
+    {
+        OC_LOG(ERROR, TAG, PCF("The persistent storage handler is invalid"));
+        return OC_STACK_INVALID_PARAM;
+    }
+    else
+    {
+        if( !persistentStorageHandler->open ||
+                !persistentStorageHandler->close ||
+                !persistentStorageHandler->read ||
+                !persistentStorageHandler->unlink ||
+                !persistentStorageHandler->write)
+        {
+            OC_LOG(ERROR, TAG, PCF("The persistent storage handler is invalid"));
+            return OC_STACK_INVALID_PARAM;
+        }
+    }
+    return SRMRegisterPersistentStorageHandler(persistentStorageHandler);
+}
+
 #ifdef WITH_PRESENCE
+
 OCStackResult OCProcessPresence()
 {
     OCStackResult result = OC_STACK_OK;
-    uint8_t ipAddr[4] = { 0 };
-    uint16_t port = 0;
 
-    OC_LOG(INFO, TAG, PCF("Entering RequestPresence"));
+    // the following line floods the log with messages that are irrelevant
+    // to most purposes.  Uncomment as needed.
+    //OC_LOG(INFO, TAG, PCF("Entering RequestPresence"));
     ClientCB* cbNode = NULL;
-    OCDevAddr dst = {};
-    OCClientResponse clientResponse ={};
+    OCClientResponse clientResponse;
     OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
 
     LL_FOREACH(cbList, cbNode)
     {
-        if(OC_REST_PRESENCE == cbNode->method)
+        if (OC_REST_PRESENCE != cbNode->method || !cbNode->presence)
         {
-            if(cbNode->presence)
-            {
-                uint32_t now = GetTicks(0);
-                OC_LOG_V(DEBUG, TAG, "this TTL level %d",
-                                                        cbNode->presence->TTLlevel);
-                OC_LOG_V(DEBUG, TAG, "current ticks %d", now);
+            continue;
+        }
 
+        uint32_t now = GetTicks(0);
+        OC_LOG_V(DEBUG, TAG, "this TTL level %d",
+                                                cbNode->presence->TTLlevel);
+        OC_LOG_V(DEBUG, TAG, "current ticks %d", now);
 
-                if(cbNode->presence->TTLlevel >= (PresenceTimeOutSize + 1))
-                {
-                    goto exit;
-                }
+        if(cbNode->presence->TTLlevel >= (PresenceTimeOutSize + 1))
+        {
+            goto exit;
+        }
 
-                if(cbNode->presence->TTLlevel < PresenceTimeOutSize)
-                {
-                    OC_LOG_V(DEBUG, TAG, "timeout ticks %d",
-                            cbNode->presence->timeOut[cbNode->presence->TTLlevel]);
-                }
+        if (cbNode->presence->TTLlevel < PresenceTimeOutSize)
+        {
+            OC_LOG_V(DEBUG, TAG, "timeout ticks %d",
+                    cbNode->presence->timeOut[cbNode->presence->TTLlevel]);
+        }
 
-                if(cbNode->presence->TTLlevel >= PresenceTimeOutSize)
-                {
-                    OC_LOG(DEBUG, TAG, PCF("No more timeout ticks"));
-                    if (ParseIPv4Address(cbNode->requestUri, ipAddr, &port))
-                    {
-                        OCBuildIPv4Address(ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3], port,
-                                &dst);
-
-                        clientResponse.sequenceNumber = 0;
-                        clientResponse.result = OC_STACK_PRESENCE_TIMEOUT;
-                        clientResponse.addr = (OCDevAddr *) &dst;
-                        clientResponse.resJSONPayload = NULL;
-
-                        // Increment the TTLLevel (going to a next state), so we don't keep
-                        // sending presence notification to client.
-                        cbNode->presence->TTLlevel++;
-                        OC_LOG_V(DEBUG, TAG, "moving to TTL level %d",
-                                                cbNode->presence->TTLlevel);
-                    }
-                    else
-                    {
-                        result = OC_STACK_INVALID_IP;
-                        goto exit;
-                    }
+        if (cbNode->presence->TTLlevel >= PresenceTimeOutSize)
+        {
+            OC_LOG(DEBUG, TAG, PCF("No more timeout ticks"));
 
-                    cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &clientResponse);
-                    if (cbResult == OC_STACK_DELETE_TRANSACTION)
-                    {
-                        FindAndDeleteClientCB(cbNode);
-                    }
-                }
+            clientResponse.sequenceNumber = 0;
+            clientResponse.result = OC_STACK_PRESENCE_TIMEOUT;
+            clientResponse.devAddr = *cbNode->devAddr;
+            FixUpClientResponse(&clientResponse);
+            clientResponse.payload = NULL;
 
-                if(now >= cbNode->presence->timeOut[cbNode->presence->TTLlevel])
-                {
-                    CAResult_t caResult = CA_STATUS_OK;
-                    CARemoteEndpoint_t* endpoint = NULL;
-                    CAInfo_t requestData ={};
-                    CARequestInfo_t requestInfo = {};
+            // Increment the TTLLevel (going to a next state), so we don't keep
+            // sending presence notification to client.
+            cbNode->presence->TTLlevel++;
+            OC_LOG_V(DEBUG, TAG, "moving to TTL level %d",
+                                        cbNode->presence->TTLlevel);
 
-                    OC_LOG(DEBUG, TAG, PCF("time to test server presence"));
+            cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &clientResponse);
+            if (cbResult == OC_STACK_DELETE_TRANSACTION)
+            {
+                FindAndDeleteClientCB(cbNode);
+            }
+        }
 
+        if (now < cbNode->presence->timeOut[cbNode->presence->TTLlevel])
+        {
+            continue;
+        }
 
-                    CATransportType_t caConType;
-                    result = OCToCATransportType(cbNode->conType, &caConType);
-                    caResult = CACreateRemoteEndpoint((char *)cbNode->requestUri, caConType,
-                                                        &endpoint);
-                    if (caResult != CA_STATUS_OK || result != OC_STACK_OK)
-                    {
-                        OC_LOG(ERROR, TAG, PCF("CACreateRemoteEndpoint error"));
-                        goto exit;
-                    }
+        CAResult_t caResult = CA_STATUS_OK;
+        CAEndpoint_t* endpoint = NULL;
+        CAInfo_t requestData ={};
+        CARequestInfo_t requestInfo = {};
 
-                    requestData.type = CA_MSG_NONCONFIRM;
-                    requestData.token = cbNode->token;
-                    requestData.tokenLength = cbNode->tokenLength;
-                    requestInfo.method = CA_GET;
-                    requestInfo.info = requestData;
+        OC_LOG(DEBUG, TAG, PCF("time to test server presence"));
 
-                    caResult = CASendRequest(endpoint, &requestInfo);
-                    CADestroyRemoteEndpoint(endpoint);
+        result = OCCreateEndpoint(cbNode->devAddr, &endpoint);
+        if (result != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
+            goto exit;
+        }
 
-                    if (caResult != CA_STATUS_OK)
-                    {
-                        OC_LOG(ERROR, TAG, PCF("CASendRequest error"));
-                        goto exit;
-                    }
+        requestData.type = CA_MSG_NONCONFIRM;
+        requestData.token = cbNode->token;
+        requestData.tokenLength = cbNode->tokenLength;
+        requestData.resourceUri = OC_RSRVD_PRESENCE_URI;
+        requestInfo.method = CA_GET;
+        requestInfo.info = requestData;
 
-                    cbNode->presence->TTLlevel++;
-                    OC_LOG_V(DEBUG, TAG, "moving to TTL level %d",
-                                                            cbNode->presence->TTLlevel);
-                }
-            }
+        caResult = CASendRequest(endpoint, &requestInfo);
+        OCDestroyEndpoint(endpoint);
+
+        if (caResult != CA_STATUS_OK)
+        {
+            OC_LOG(ERROR, TAG, PCF("CASendRequest error"));
+            goto exit;
         }
+
+        cbNode->presence->TTLlevel++;
+        OC_LOG_V(DEBUG, TAG, "moving to TTL level %d", cbNode->presence->TTLlevel);
     }
 exit:
     if (result != OC_STACK_OK)
     {
-        OC_LOG_V(ERROR, TAG, PCF("OCProcessPresence error no %d"), result);
+        OC_LOG(ERROR, TAG, PCF("OCProcessPresence error"));
     }
     return result;
 }
@@ -2386,9 +2499,9 @@ OCStackResult OCStartPresence(const uint32_t ttl)
     {
         presenceState = OC_PRESENCE_INITIALIZED;
 
-        CAAddress_t addressInfo;
-        strncpy(addressInfo.IP.ipAddress, OC_MULTICAST_IP, CA_IPADDR_SIZE);
-        addressInfo.IP.port = OC_MULTICAST_PORT;
+        OCDevAddr devAddr = { OC_DEFAULT_ADAPTER };
+        OICStrcpy(devAddr.addr, sizeof(devAddr.addr), OC_MULTICAST_IP);
+        devAddr.port = OC_MULTICAST_PORT;
 
         CAToken_t caToken = NULL;
         CAResult_t caResult = CAGenerateToken(&caToken, tokenLength);
@@ -2399,11 +2512,8 @@ OCStackResult OCStartPresence(const uint32_t ttl)
             return OC_STACK_ERROR;
         }
 
-        CATransportType_t connType;
-        OCToCATransportType(OC_ALL, &connType );
-        AddObserver(OC_PRESENCE_URI, NULL, 0, caToken, tokenLength,
-                (OCResource *)presenceResource.handle, OC_LOW_QOS,
-                &addressInfo, connType);
+        AddObserver(OC_RSRVD_PRESENCE_URI, NULL, 0, caToken, tokenLength,
+                (OCResource *)presenceResource.handle, OC_LOW_QOS, &devAddr);
         CADestroyToken(caToken);
     }
 
@@ -2411,7 +2521,8 @@ OCStackResult OCStartPresence(const uint32_t ttl)
     // a different random 32-bit integer number is used
     ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
 
-    return SendPresenceNotification(NULL);
+    return SendPresenceNotification(((OCResource *)presenceResource.handle)->rsrcType,
+            OC_PRESENCE_TRIGGER_CREATE);
 }
 
 OCStackResult OCStopPresence()
@@ -2421,12 +2532,12 @@ OCStackResult OCStopPresence()
     if(presenceResource.handle)
     {
         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-    }
 
     // make resource inactive
     result = OCChangeResourceProperty(
             &(((OCResource *) presenceResource.handle)->resourceProperties),
             OC_ACTIVE, 0);
+    }
 
     if(result != OC_STACK_OK)
     {
@@ -2439,9 +2550,11 @@ OCStackResult OCStopPresence()
 }
 #endif
 
-OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler)
+OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler,
+                                            void* callbackParameter)
 {
     defaultDeviceHandler = entityHandler;
+    defaultDeviceHandlerCallbackParameter = callbackParameter;
 
     return OC_STACK_OK;
 }
@@ -2469,23 +2582,27 @@ OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo)
 
 OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
 {
-    // TODO: Implement this.
-    OC_LOG(ERROR, TAG, "Implement OCSetDeviceInfo !!");
+    OC_LOG(INFO, TAG, PCF("Entering OCSetDeviceInfo"));
 
-    // Returning ok to make samples work.
-    return OC_STACK_OK;
+    if (!deviceInfo.deviceName || deviceInfo.deviceName[0] == '\0')
+    {
+        OC_LOG(ERROR, TAG, PCF("Null or empty device name."));
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    return SaveDeviceInfo(deviceInfo);
 }
 
 OCStackResult OCCreateResource(OCResourceHandle *handle,
         const char *resourceTypeName,
         const char *resourceInterfaceName,
         const char *uri, OCEntityHandler entityHandler,
+        void* callbackParam,
         uint8_t resourceProperties)
 {
 
     OCResource *pointer = NULL;
     char *str = NULL;
-    size_t size = 0;
     OCStackResult result = OC_STACK_ERROR;
 
     OC_LOG(INFO, TAG, PCF("Entering OCCreateResource"));
@@ -2497,11 +2614,11 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
     // Validate parameters
     if(!uri || uri[0]=='\0' || strlen(uri)>=MAX_URI_LENGTH )
     {
-        OC_LOG(ERROR, TAG, PCF("URI is invalid"));
+        OC_LOG(ERROR, TAG, PCF("URI is empty or too long"));
         return OC_STACK_INVALID_URI;
     }
     // Is it presented during resource discovery?
-    if (!handle || !resourceTypeName)
+    if (!handle || !resourceTypeName || resourceTypeName[0] == '\0' )
     {
         OC_LOG(ERROR, TAG, PCF("Input parameter is NULL"));
         return OC_STACK_INVALID_PARAM;
@@ -2514,7 +2631,8 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
 
     // Make sure resourceProperties bitmask has allowed properties specified
     if (resourceProperties
-            > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE))
+            > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE |
+               OC_EXPLICIT_DISCOVERABLE))
     {
         OC_LOG(ERROR, TAG, PCF("Invalid property"));
         return OC_STACK_INVALID_PARAM;
@@ -2530,14 +2648,14 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         {
             if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0)
             {
-                OC_LOG(ERROR, TAG, PCF("URI already in use"));
+                OC_LOG_V(ERROR, TAG, "Resource %s already exists", uri);
                 return OC_STACK_INVALID_PARAM;
             }
             pointer = pointer->next;
         }
     }
     // Create the pointer and insert it into the resource list
-    pointer = (OCResource *) OCCalloc(1, sizeof(OCResource));
+    pointer = (OCResource *) OICCalloc(1, sizeof(OCResource));
     if (!pointer)
     {
         result = OC_STACK_NO_MEMORY;
@@ -2548,14 +2666,12 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
     insertResource(pointer);
 
     // Set the uri
-    size = strlen(uri) + 1;
-    str = (char *) OCMalloc(size);
+    str = OICStrdup(uri);
     if (!str)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
-    strncpy(str, uri, size);
     pointer->uri = str;
 
     // Set properties.  Set OC_ACTIVE
@@ -2583,10 +2699,12 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
     if (entityHandler)
     {
         pointer->entityHandler = entityHandler;
+        pointer->entityHandlerCallbackParam = callbackParam;
     }
     else
     {
         pointer->entityHandler = defaultResourceEHandler;
+        pointer->entityHandlerCallbackParam = NULL;
     }
 
     *handle = pointer;
@@ -2596,7 +2714,7 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
     if(presenceResource.handle)
     {
         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-        SendPresenceNotification(pointer->rsrcType);
+        SendPresenceNotification(pointer->rsrcType, OC_PRESENCE_TRIGGER_CREATE);
     }
     #endif
 exit:
@@ -2604,51 +2722,11 @@ exit:
     {
         // Deep delete of resource and other dynamic elements that it contains
         deleteResource(pointer);
-        OCFree(str);
+        OICFree(str);
     }
     return result;
 }
 
-OCStackResult OCCreateResourceWithHost(OCResourceHandle *handle,
-        const char *resourceTypeName,
-        const char *resourceInterfaceName,
-        const char *host,
-        const char *uri,
-        OCEntityHandler entityHandler,
-        uint8_t resourceProperties)
-{
-    OC_LOG(INFO, TAG, PCF("Entering OCCreateResourceWithHost"));
-    char *str = NULL;
-    size_t size = 0;
-
-    if(!host)
-    {
-        OC_LOG(ERROR, TAG, PCF("Added resource host is NULL."));
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    OCStackResult result = OC_STACK_ERROR;
-
-    result = OCCreateResource(handle, resourceTypeName, resourceInterfaceName,
-                                uri, entityHandler, resourceProperties);
-
-    if (result == OC_STACK_OK)
-    {
-        // Set the uri
-        size = strlen(host) + 1;
-        str = (char *) OCMalloc(size);
-        if (!str)
-        {
-            OC_LOG(ERROR, TAG, PCF("Memory could not be allocated."));
-            return OC_STACK_NO_MEMORY;
-        }
-        strncpy(str, host, size);
-
-        ((OCResource *) *handle)->host = str;
-    }
-
-    return result;
-}
 
 OCStackResult OCBindResource(
         OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
@@ -2689,7 +2767,8 @@ OCStackResult OCBindResource(
             if(presenceResource.handle)
             {
                 ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-                SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType);
+                SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
+                        OC_PRESENCE_TRIGGER_CHANGE);
             }
             #endif
             return OC_STACK_OK;
@@ -2741,7 +2820,8 @@ OCStackResult OCUnBindResource(
             if(presenceResource.handle)
             {
                 ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-                SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType);
+                SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
+                        OC_PRESENCE_TRIGGER_CHANGE);
             }
             #endif
             return OC_STACK_OK;
@@ -2759,33 +2839,23 @@ OCStackResult BindResourceTypeToResource(OCResource* resource,
 {
     OCResourceType *pointer = NULL;
     char *str = NULL;
-    size_t size = 0;
     OCStackResult result = OC_STACK_ERROR;
 
-    OC_LOG(INFO, TAG, PCF("Entering BindResourceTypeToResource"));
-
-    // Validate parameters
     VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
-    // TODO:  Does resource attribute representation really have to be maintained in stack?
-    // Is it presented during resource discovery?
 
-    // Create the resourcetype and insert it into the resource list
-    pointer = (OCResourceType *) OCCalloc(1, sizeof(OCResourceType));
+    pointer = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
     if (!pointer)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
 
-    // Set the resourceTypeName
-    size = strlen(resourceTypeName) + 1;
-    str = (char *) OCMalloc(size);
+    str = OICStrdup(resourceTypeName);
     if (!str)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
-    strncpy(str, resourceTypeName, size);
     pointer->resourcetypename = str;
 
     insertResourceType(resource, pointer);
@@ -2794,8 +2864,8 @@ OCStackResult BindResourceTypeToResource(OCResource* resource,
     exit:
     if (result != OC_STACK_OK)
     {
-        OCFree(pointer);
-        OCFree(str);
+        OICFree(pointer);
+        OICFree(str);
     }
 
     return result;
@@ -2806,33 +2876,25 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource,
 {
     OCResourceInterface *pointer = NULL;
     char *str = NULL;
-    size_t size = 0;
     OCStackResult result = OC_STACK_ERROR;
 
-    OC_LOG(INFO, TAG, PCF("Entering BindResourceInterfaceToResource"));
-
-    // Validate parameters
     VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
 
-    //TODO ("Make sure that the resourceinterface name doesn't already exist in the resource");
+    OC_LOG_V(INFO, TAG, "Binding %s interface to %s", resourceInterfaceName, resource->uri);
 
-    // Create the resourceinterface and insert it into the resource list
-    pointer = (OCResourceInterface *) OCCalloc(1, sizeof(OCResourceInterface));
+    pointer = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
     if (!pointer)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
 
-    // Set the resourceinterface name
-    size = strlen(resourceInterfaceName) + 1;
-    str = (char *) OCMalloc(size);
+    str = OICStrdup(resourceInterfaceName);
     if (!str)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
-    strncpy(str, resourceInterfaceName, size);
     pointer->name = str;
 
     // Bind the resourceinterface to the resource
@@ -2843,8 +2905,8 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource,
     exit:
     if (result != OC_STACK_OK)
     {
-        OCFree(pointer);
-        OCFree(str);
+        OICFree(pointer);
+        OICFree(str);
     }
 
     return result;
@@ -2857,7 +2919,6 @@ OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
     OCStackResult result = OC_STACK_ERROR;
     OCResource *resource = NULL;
 
-    // Make sure resource exists
     resource = findResource((OCResource *) handle);
     if (!resource)
     {
@@ -2865,14 +2926,13 @@ OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
         return OC_STACK_ERROR;
     }
 
-    // call internal function
     result = BindResourceTypeToResource(resource, resourceTypeName);
 
     #ifdef WITH_PRESENCE
     if(presenceResource.handle)
     {
         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-        SendPresenceNotification(resource->rsrcType);
+        SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
     }
     #endif
 
@@ -2886,7 +2946,6 @@ OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
     OCStackResult result = OC_STACK_ERROR;
     OCResource *resource = NULL;
 
-    // Make sure resource exists
     resource = findResource((OCResource *) handle);
     if (!resource)
     {
@@ -2894,14 +2953,13 @@ OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
         return OC_STACK_ERROR;
     }
 
-    // call internal function
     result = BindResourceInterfaceToResource(resource, resourceInterfaceName);
 
     #ifdef WITH_PRESENCE
     if(presenceResource.handle)
     {
         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-        SendPresenceNotification(resource->rsrcType);
+        SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
     }
     #endif
 
@@ -2912,7 +2970,6 @@ OCStackResult OCGetNumberOfResources(uint8_t *numResources)
 {
     OCResource *pointer = headResource;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResources"));
     VERIFY_NON_NULL(numResources, ERROR, OC_STACK_INVALID_PARAM);
     *numResources = 0;
     while (pointer)
@@ -2927,9 +2984,6 @@ OCResourceHandle OCGetResourceHandle(uint8_t index)
 {
     OCResource *pointer = headResource;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandle"));
-
-    // Iterate through the list
     for( uint8_t i = 0; i < index && pointer; ++i)
     {
         pointer = pointer->next;
@@ -2939,11 +2993,9 @@ OCResourceHandle OCGetResourceHandle(uint8_t index)
 
 OCStackResult OCDeleteResource(OCResourceHandle handle)
 {
-    OC_LOG(INFO, TAG, PCF("Entering OCDeleteResource"));
-
     if (!handle)
     {
-        OC_LOG(ERROR, TAG, PCF("Invalid param"));
+        OC_LOG(ERROR, TAG, PCF("Invalid handle for deletion"));
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -2966,7 +3018,6 @@ OCStackResult OCDeleteResource(OCResourceHandle handle)
 const char *OCGetResourceUri(OCResourceHandle handle)
 {
     OCResource *resource = NULL;
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceUri"));
 
     resource = findResource((OCResource *) handle);
     if (resource)
@@ -2979,7 +3030,6 @@ const char *OCGetResourceUri(OCResourceHandle handle)
 OCResourceProperty OCGetResourceProperties(OCResourceHandle handle)
 {
     OCResource *resource = NULL;
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceProperties"));
 
     resource = findResource((OCResource *) handle);
     if (resource)
@@ -2995,7 +3045,6 @@ OCStackResult OCGetNumberOfResourceTypes(OCResourceHandle handle,
     OCResource *resource = NULL;
     OCResourceType *pointer = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceTypes"));
     VERIFY_NON_NULL(numResourceTypes, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
 
@@ -3018,8 +3067,6 @@ const char *OCGetResourceTypeName(OCResourceHandle handle, uint8_t index)
 {
     OCResourceType *resourceType = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceTypeName"));
-
     resourceType = findResourceTypeAtIndex(handle, index);
     if (resourceType)
     {
@@ -3034,8 +3081,6 @@ OCStackResult OCGetNumberOfResourceInterfaces(OCResourceHandle handle,
     OCResourceInterface *pointer = NULL;
     OCResource *resource = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceInterfaces"));
-
     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(numResourceInterfaces, ERROR, OC_STACK_INVALID_PARAM);
 
@@ -3057,8 +3102,6 @@ const char *OCGetResourceInterfaceName(OCResourceHandle handle, uint8_t index)
 {
     OCResourceInterface *resourceInterface = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceInterfaceName"));
-
     resourceInterface = findResourceInterfaceAtIndex(handle, index);
     if (resourceInterface)
     {
@@ -3072,8 +3115,6 @@ OCResourceHandle OCGetResourceHandleFromCollection(OCResourceHandle collectionHa
 {
     OCResource *resource = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetContainedResource"));
-
     if (index >= MAX_CONTAINED_RESOURCES)
     {
         return NULL;
@@ -3089,12 +3130,11 @@ OCResourceHandle OCGetResourceHandleFromCollection(OCResourceHandle collectionHa
 }
 
 OCStackResult OCBindResourceHandler(OCResourceHandle handle,
-        OCEntityHandler entityHandler)
+        OCEntityHandler entityHandler,
+        void* callbackParam)
 {
     OCResource *resource = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCBindResourceHandler"));
-
     // Validate parameters
     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
 
@@ -3108,12 +3148,13 @@ OCStackResult OCBindResourceHandler(OCResourceHandle handle,
 
     // Bind the handler
     resource->entityHandler = entityHandler;
+    resource->entityHandlerCallbackParam = callbackParam;
 
     #ifdef WITH_PRESENCE
     if(presenceResource.handle)
     {
         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-        SendPresenceNotification(resource->rsrcType);
+        SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
     }
     #endif
 
@@ -3124,9 +3165,6 @@ OCEntityHandler OCGetResourceHandler(OCResourceHandle handle)
 {
     OCResource *resource = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandler"));
-
-    // Use the handle to find the resource in the resource linked list
     resource = findResource((OCResource *)handle);
     if (!resource)
     {
@@ -3150,7 +3188,8 @@ void incrementSequenceNumber(OCResource * resPtr)
 }
 
 #ifdef WITH_PRESENCE
-OCStackResult SendPresenceNotification(OCResourceType *resourceType)
+OCStackResult SendPresenceNotification(OCResourceType *resourceType,
+        OCPresenceTrigger trigger)
 {
     OCResource *resPtr = NULL;
     OCStackResult result = OC_STACK_ERROR;
@@ -3166,7 +3205,8 @@ OCStackResult SendPresenceNotification(OCResourceType *resourceType)
     {
         maxAge = presenceResource.presenceTTL;
 
-        result = SendAllObserverNotification(method, resPtr, maxAge, resourceType, OC_LOW_QOS);
+        result = SendAllObserverNotification(method, resPtr, maxAge,
+                trigger, resourceType, OC_LOW_QOS);
     }
 
     return result;
@@ -3184,7 +3224,8 @@ OCStackResult SendStopNotification()
     }
 
     // maxAge is 0. ResourceType is NULL.
-    result = SendAllObserverNotification(method, resPtr, 0, NULL, OC_LOW_QOS);
+    result = SendAllObserverNotification(method, resPtr, 0, OC_PRESENCE_TRIGGER_DELETE,
+            NULL, OC_LOW_QOS);
 
     return result;
 }
@@ -3192,15 +3233,12 @@ OCStackResult SendStopNotification()
 #endif // WITH_PRESENCE
 OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService qos)
 {
-
-    OC_LOG(INFO, TAG, PCF("Entering OCNotifyAllObservers"));
-
     OCResource *resPtr = NULL;
     OCStackResult result = OC_STACK_ERROR;
     OCMethod method = OC_REST_NOMETHOD;
     uint32_t maxAge = 0;
 
-    OC_LOG(INFO, TAG, PCF("Entering OCNotifyAllObservers"));
+    OC_LOG(INFO, TAG, PCF("Notifying all observers"));
     #ifdef WITH_PRESENCE
     if(handle == presenceResource.handle)
     {
@@ -3222,7 +3260,8 @@ OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService q
         method = OC_REST_OBSERVE;
         maxAge = MAX_OBSERVE_AGE;
         #ifdef WITH_PRESENCE
-        result = SendAllObserverNotification (method, resPtr, maxAge, NULL, qos);
+        result = SendAllObserverNotification (method, resPtr, maxAge,
+                OC_PRESENCE_TRIGGER_DELETE, NULL, qos);
         #else
         result = SendAllObserverNotification (method, resPtr, maxAge, qos);
         #endif
@@ -3234,7 +3273,7 @@ OCStackResult
 OCNotifyListOfObservers (OCResourceHandle handle,
                          OCObservationId  *obsIdList,
                          uint8_t          numberOfIds,
-                         const char       *notificationJSONPayload,
+                         const OCRepPayload       *payload,
                          OCQualityOfService qos)
 {
     OC_LOG(INFO, TAG, PCF("Entering OCNotifyListOfObservers"));
@@ -3245,9 +3284,8 @@ OCNotifyListOfObservers (OCResourceHandle handle,
 
     VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
     VERIFY_NON_NULL(obsIdList, ERROR, OC_STACK_ERROR);
-    VERIFY_NON_NULL(notificationJSONPayload, ERROR, OC_STACK_ERROR);
+    VERIFY_NON_NULL(payload, ERROR, OC_STACK_ERROR);
 
-    // Verify that the resource exists
     resPtr = findResource ((OCResource *) handle);
     if (NULL == resPtr || myStackMode == OC_CLIENT)
     {
@@ -3258,7 +3296,7 @@ OCNotifyListOfObservers (OCResourceHandle handle,
         incrementSequenceNumber(resPtr);
     }
     return (SendListObserverNotification(resPtr, obsIdList, numberOfIds,
-            notificationJSONPayload, maxAge, qos));
+            payload, maxAge, qos));
 }
 
 OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
@@ -3272,35 +3310,15 @@ OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
     VERIFY_NON_NULL(ehResponse, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(ehResponse->requestHandle, ERROR, OC_STACK_INVALID_PARAM);
 
-    // TODO: Placeholder for creating a response entry when implementing
-    // block transfer feature
-
-    // If a response payload is present, check if block transfer is required
-    if (ehResponse->payload && OCIsPacketTransferRequired(NULL,
-            (const char *)ehResponse->payload, ehResponse->payloadSize))
+    // Normal response
+    // Get pointer to request info
+    serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
+    if(serverRequest)
     {
-        OC_LOG(INFO, TAG, PCF("Block transfer required"));
-
-        // Persistent response buffer is needed for block transfer
-        if (!ehResponse->persistentBufferFlag)
-        {
-            OC_LOG(WARNING, TAG, PCF("Persistent response buffer required"));
-            return OC_STACK_PERSISTENT_BUFFER_REQUIRED;
-        }
-        // TODO: Placeholder for block transfer handling
-        // TODO: Placeholder for setting the the response handle in the OCServerResponse struct
-            // when implementing the block transfer feature
-    }
-    else
-    {
-        // Normal response
-        // Get pointer to request info
-        serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
-        if(serverRequest)
-        {
-            result = serverRequest->ehResponseHandler(ehResponse);
-        }
+        // response handler in ocserverrequest.c. Usually HandleSingleResponse.
+        result = serverRequest->ehResponseHandler(ehResponse);
     }
+
     return result;
 }
 
@@ -3311,7 +3329,7 @@ static OCDoHandle GenerateInvocationHandle()
 {
     OCDoHandle handle = NULL;
     // Generate token here, it will be deleted when the transaction is deleted
-    handle = (OCDoHandle) OCMalloc(sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
+    handle = (OCDoHandle) OICMalloc(sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
     if (handle)
     {
         OCFillRandomMem((uint8_t*)handle, sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
@@ -3349,17 +3367,18 @@ OCStackResult OCChangeResourceProperty(OCResourceProperty * inputProperty,
 OCStackResult initResources()
 {
     OCStackResult result = OC_STACK_OK;
-    // Init application resource vars
+
     headResource = NULL;
     tailResource = NULL;
     // Init Virtual Resources
     #ifdef WITH_PRESENCE
     presenceResource.presenceTTL = OC_DEFAULT_PRESENCE_TTL_SECONDS;
-    //presenceResource.token = OCGenerateCoAPToken();
+
     result = OCCreateResource(&presenceResource.handle,
             OC_RSRVD_RESOURCE_TYPE_PRESENCE,
             "core.r",
-            OC_PRESENCE_URI,
+            OC_RSRVD_PRESENCE_URI,
+            NULL,
             NULL,
             OC_OBSERVABLE);
     //make resource inactive
@@ -3367,6 +3386,12 @@ OCStackResult initResources()
             &(((OCResource *) presenceResource.handle)->resourceProperties),
             OC_ACTIVE, 0);
     #endif
+
+    if (result == OC_STACK_OK)
+    {
+        result = SRMInitSecureResources();
+    }
+
     return result;
 }
 
@@ -3419,6 +3444,8 @@ void deleteAllResources()
         pointer = temp;
     }
 
+    SRMDeInitSecureResources();
+
     #ifdef WITH_PRESENCE
     // Ensure that the last resource to be deleted is the presence resource. This allows for all
     // presence notification attributed to their deletion to be processed.
@@ -3430,6 +3457,13 @@ OCStackResult deleteResource(OCResource *resource)
 {
     OCResource *prev = NULL;
     OCResource *temp = NULL;
+    if(!resource)
+    {
+        OC_LOG_V(DEBUG,TAG,"resource is NULL");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OC_LOG_V (INFO, TAG, "Deleting resource %s", resource->uri);
 
     temp = headResource;
     while (temp)
@@ -3449,14 +3483,7 @@ OCStackResult deleteResource(OCResource *resource)
             if(presenceResource.handle)
             {
                 ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-                if(resource != (OCResource *) presenceResource.handle)
-                {
-                    SendPresenceNotification(resource->rsrcType);
-                }
-                else
-                {
-                    SendPresenceNotification(NULL);
-                }
+                SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_DELETE);
             }
             #endif
             // Only resource in list.
@@ -3482,7 +3509,7 @@ OCStackResult deleteResource(OCResource *resource)
             }
 
             deleteResourceElements(temp);
-            OCFree(temp);
+            OICFree(temp);
             return OC_STACK_OK;
         }
         else
@@ -3502,13 +3529,8 @@ void deleteResourceElements(OCResource *resource)
         return;
     }
 
-    // remove URI
-    OCFree(resource->uri);
-
-    // Delete resourcetype linked list
+    OICFree(resource->uri);
     deleteResourceType(resource->rsrcType);
-
-    // Delete resourceinterface linked list
     deleteResourceInterface(resource->rsrcInterface);
 }
 
@@ -3520,8 +3542,8 @@ void deleteResourceType(OCResourceType *resourceType)
     while (pointer)
     {
         next = pointer->next;
-        OCFree(pointer->resourcetypename);
-        OCFree(pointer);
+        OICFree(pointer->resourcetypename);
+        OICFree(pointer);
         pointer = next;
     }
 }
@@ -3534,8 +3556,8 @@ void deleteResourceInterface(OCResourceInterface *resourceInterface)
     while (pointer)
     {
         next = pointer->next;
-        OCFree(pointer->name);
-        OCFree(pointer);
+        OICFree(pointer->name);
+        OICFree(pointer);
         pointer = next;
     }
 }
@@ -3559,11 +3581,11 @@ void insertResourceType(OCResource *resource, OCResourceType *resourceType)
 
         while (pointer)
         {
-            // resource type already exists. Free 2nd arg and return.
             if (!strcmp(resourceType->resourcetypename, pointer->resourcetypename))
             {
-                OCFree(resourceType->resourcetypename);
-                OCFree(resourceType);
+                OC_LOG_V(INFO, TAG, "Type %s already exists", resourceType->resourcetypename);
+                OICFree(resourceType->resourcetypename);
+                OICFree(resourceType);
                 return;
             }
             previous = pointer;
@@ -3572,6 +3594,8 @@ void insertResourceType(OCResource *resource, OCResourceType *resourceType)
         previous->next = resourceType;
     }
     resourceType->next = NULL;
+
+    OC_LOG_V(INFO, TAG, "Added type %s to %s", resourceType->resourcetypename, resource->uri);
 }
 
 OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle, uint8_t index)
@@ -3643,8 +3667,8 @@ void insertResourceInterface(OCResource *resource, OCResourceInterface *newInter
     {
         if (strcmp((*firstInterface)->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
         {
-            OCFree(newInterface->name);
-            OCFree(newInterface);
+            OICFree(newInterface->name);
+            OICFree(newInterface);
             return;
         }
         else
@@ -3660,8 +3684,8 @@ void insertResourceInterface(OCResource *resource, OCResourceInterface *newInter
         {
             if (strcmp(newInterface->name, pointer->name) == 0)
             {
-                OCFree(newInterface->name);
-                OCFree(newInterface);
+                OICFree(newInterface->name);
+                OICFree(newInterface);
                 return;
             }
             previous = pointer;
@@ -3700,58 +3724,6 @@ OCResourceInterface *findResourceInterfaceAtIndex(OCResourceHandle handle,
     return pointer;
 }
 
-bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size)
-{
-    bool result = false;
-
-    // Determine if we are checking a request or a response
-    if (request)
-    {
-        // If size is greater than 0, use it for the request size value, otherwise
-        // assume request is null terminated and use strlen for size value
-        if ((size > MAX_REQUEST_LENGTH) || (strlen(request) > MAX_REQUEST_LENGTH))
-        {
-            result = true;
-        }
-    }
-    else if (response)
-    {
-        // If size is greater than 0, use it for the response size value, otherwise
-        // assume response is null terminated and use strlen for size value
-        if ((size > MAX_RESPONSE_LENGTH) || (strlen(response) > MAX_RESPONSE_LENGTH))
-        {
-            result = true;
-        }
-    }
-    return result;
-}
-
-OCStackResult getResourceType(const char * query, char** resourceType)
-{
-    if(!query)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    OCStackResult result = OC_STACK_ERROR;
-
-    if(strncmp(query, "rt=", 3) == 0)
-    {
-        *resourceType = (char *) OCMalloc(strlen(query)-3 + 1);
-        if(!*resourceType)
-        {
-            result = OC_STACK_NO_MEMORY;
-        }
-        else
-        {
-            strcpy((char *)*resourceType, ((const char *)&query[3]));
-            result = OC_STACK_OK;
-        }
-    }
-
-    return result;
-}
-
 /*
  * This function splits the uri using the '?' delimiter.
  * "uriWithoutQuery" is the block of characters between the beginning
@@ -3790,28 +3762,23 @@ OCStackResult getQueryFromUri(const char * uri, char** query, char ** uriWithout
 
     if (uriWithoutQueryLen)
     {
-        *uriWithoutQuery =  (char *) OCCalloc(uriWithoutQueryLen + 1, 1);
+        *uriWithoutQuery =  (char *) OICCalloc(uriWithoutQueryLen + 1, 1);
         if (!*uriWithoutQuery)
         {
             goto exit;
         }
-        strncpy(*uriWithoutQuery, uri, uriWithoutQueryLen);
-    }
-    else
-    {
-        return OC_STACK_INVALID_PARAM;
+        OICStrcpy(*uriWithoutQuery, uriWithoutQueryLen +1, uri);
     }
-
     if (queryLen)
     {
-        *query = (char *) OCCalloc(queryLen + 1, 1);
+        *query = (char *) OICCalloc(queryLen + 1, 1);
         if (!*query)
         {
-            OCFree(*uriWithoutQuery);
+            OICFree(*uriWithoutQuery);
             *uriWithoutQuery = NULL;
             goto exit;
         }
-        strncpy(*query, pointerToDelimiter + 1, queryLen);
+        OICStrcpy(*query, queryLen + 1, pointerToDelimiter + 1);
     }
 
     return OC_STACK_OK;
@@ -3860,45 +3827,20 @@ const char* OCGetServerInstanceIDString(void)
     return sidStr;
 }
 
-int32_t OCDevAddrToIPv4Addr(OCDevAddr *ipAddr, uint8_t *a, uint8_t *b,
-        uint8_t *c, uint8_t *d )
-{
-    if ( !ipAddr || !a || !b || !c || !d )
-    {
-        OC_LOG(FATAL, TAG, PCF("Invalid argument"));
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    *a = ipAddr->addr[0];
-    *b = ipAddr->addr[1];
-    *c = ipAddr->addr[2];
-    *d = ipAddr->addr[3];
-
-    return OC_STACK_OK;
-}
-
-int32_t OCDevAddrToPort(OCDevAddr *ipAddr, uint16_t *port)
-{
-    if ( !ipAddr || !port )
-    {
-        OC_LOG(FATAL, TAG, PCF("Invalid argument"));
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    *port = (ipAddr->addr[5]<< 8) | ipAddr->addr[4];
-
-    return OC_STACK_OK;
-}
-
 CAResult_t OCSelectNetwork()
 {
     CAResult_t retResult = CA_STATUS_FAILED;
     CAResult_t caResult = CA_STATUS_OK;
 
-    CATransportType_t connTypes[] = {
-            CA_IPV4,
-            CA_EDR,
-            CA_LE};
+    CATransportAdapter_t connTypes[] = {
+            CA_ADAPTER_IP,
+            CA_ADAPTER_RFCOMM_BTEDR,
+            CA_ADAPTER_GATT_BTLE
+
+            #ifdef RA_ADAPTER
+            ,CA_ADAPTER_REMOTE_ACCESS
+            #endif
+        };
     int numConnTypes = sizeof(connTypes)/sizeof(connTypes[0]);
 
     for(int i = 0; i<numConnTypes; i++)
old mode 100644 (file)
new mode 100755 (executable)
index 47d34be..4068852
@@ -24,7 +24,7 @@
 
 #include "oicgroup.h"
 #include "cJSON.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
 #include "occollection.h"
 #include "logger.h"
 #include "timer.h"
@@ -46,7 +46,7 @@
 #define ACTIONSET               "ActionSet"
 #define DELETE_ACTIONSET        "DelActionSet"
 
-#define OIC_ACTION_PREFIX               "{\"oc\":[{\"rep\":{"
+#define OIC_ACTION_PREFIX               "{\"oic\":[{\"rep\":{"
 #define VARIFY_POINTER_NULL(pointer, result, toExit) \
     if(pointer == NULL) \
     {\
@@ -62,7 +62,7 @@
 
 #define OCFREE(pointer) \
     { \
-        OCFree(pointer); \
+        OICFree(pointer); \
         pointer = NULL; \
     }
 
@@ -539,7 +539,7 @@ OCStackResult ExtractKeyValueFromRequest(char *request, char **key,
     VARIFY_POINTER_NULL(iterToken, result, exit);
     length = strlen(iterToken) + 1;
 
-    *key = (char *) OCMalloc(length);
+    *key = (char *) OICMalloc(length);
     VARIFY_POINTER_NULL(*key, result, exit)
 
     strncpy(*key, iterToken + 1, length);
@@ -549,7 +549,7 @@ OCStackResult ExtractKeyValueFromRequest(char *request, char **key,
     VARIFY_POINTER_NULL(iterToken, result, exit);
     length = strlen(iterToken) + 1;
 
-    *value = (char *) OCMalloc(length);
+    *value = (char *) OICMalloc(length);
     VARIFY_POINTER_NULL(*value, result, exit)
 
     strncpy(*value, iterToken + 1, length);
@@ -572,7 +572,7 @@ OCStackResult ExtractActionSetNameAndDelaytime(char *pChar, char **setName,
     OCStackResult result = OC_STACK_OK;
 
     token = (char*) strtok_r(pChar, ACTION_DELIMITER, &tokenPtr);
-    *setName = (char *) OCMalloc(strlen(token) + 1);
+    *setName = (char *) OICMalloc(strlen(token) + 1);
     VARIFY_POINTER_NULL(*setName, result, exit)
     VARIFY_PARAM_NULL(token, result, exit)
     strncpy(*setName, token, strlen(token) + 1);
@@ -604,14 +604,14 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
 
     OC_LOG(INFO, TAG, PCF("Build ActionSet Instance."));
 
-    *set = (OCActionSet*) OCMalloc(sizeof(OCActionSet));
+    *set = (OCActionSet*) OICMalloc(sizeof(OCActionSet));
     VARIFY_POINTER_NULL(*set, result, exit)
 
     iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr);
 
     // ActionSet Name
     memset(*set, 0, sizeof(OCActionSet));
-    (*set)->actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
+    (*set)->actionsetName = (char *) OICMalloc(strlen(iterToken) + 1);
     VARIFY_POINTER_NULL((*set)->actionsetName, result, exit)
     VARIFY_PARAM_NULL(iterToken, result, exit)
     strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1);
@@ -631,7 +631,7 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
     iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr);
     while (iterToken)
     {
-        desc = (char *) OCMalloc(strlen(iterToken) + 1);
+        desc = (char *) OICMalloc(strlen(iterToken) + 1);
         VARIFY_POINTER_NULL(desc, result, exit)
         VARIFY_PARAM_NULL(desc, result, exit)
         strncpy(desc, iterToken, strlen(iterToken) + 1);
@@ -639,21 +639,21 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
                 &descIterTokenPtr);
         while (descIterToken)
         {
-            attr = (char *) OCMalloc(strlen(descIterToken) + 1);
+            attr = (char *) OICMalloc(strlen(descIterToken) + 1);
             VARIFY_POINTER_NULL(attr, result, exit)
             VARIFY_PARAM_NULL(descIterToken, result, exit)
             strncpy(attr, descIterToken, strlen(descIterToken) + 1);
 
             attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN,
                     &attrIterTokenPtr);
-            key = (char *) OCMalloc(strlen(attrIterToken) + 1);
+            key = (char *) OICMalloc(strlen(attrIterToken) + 1);
             VARIFY_POINTER_NULL(key, result, exit)
             VARIFY_PARAM_NULL(attrIterToken, result, exit)
             strncpy(key, attrIterToken, strlen(attrIterToken) + 1);
 
             attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN,
                     &attrIterTokenPtr);
-            value = (char *) OCMalloc(strlen(attrIterToken) + 1);
+            value = (char *) OICMalloc(strlen(attrIterToken) + 1);
             VARIFY_POINTER_NULL(value, result, exit)
             VARIFY_PARAM_NULL(attrIterToken, result, exit)
             strncpy(value, attrIterToken, strlen(attrIterToken) + 1);
@@ -662,10 +662,10 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
             {
                 OC_LOG(INFO, TAG, PCF("Build OCAction Instance."));
 
-                action = (OCAction*) OCMalloc(sizeof(OCAction));
+                action = (OCAction*) OICMalloc(sizeof(OCAction));
                 VARIFY_POINTER_NULL(action, result, exit)
                 memset(action, 0, sizeof(OCAction));
-                action->resourceUri = (char *) OCMalloc(strlen(value) + 1);
+                action->resourceUri = (char *) OICMalloc(strlen(value) + 1);
                 VARIFY_POINTER_NULL(action->resourceUri, result, exit)
                 VARIFY_PARAM_NULL(value, result, exit)
                 strncpy(action->resourceUri, value, strlen(value) + 1);
@@ -676,16 +676,16 @@ OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc)
                 {
                     OC_LOG(INFO, TAG, PCF("Build OCCapability Instance."));
 
-                    capa = (OCCapability*) OCMalloc(sizeof(OCCapability));
+                    capa = (OCCapability*) OICMalloc(sizeof(OCCapability));
                     VARIFY_POINTER_NULL(capa, result, exit)
                     memset(capa, 0, sizeof(OCCapability));
 
-                    capa->capability = (char *) OCMalloc(strlen(key) + 1);
+                    capa->capability = (char *) OICMalloc(strlen(key) + 1);
                     VARIFY_POINTER_NULL(capa->capability, result, exit)
                     VARIFY_PARAM_NULL(key, result, exit)
                     strncpy(capa->capability, key, strlen(key) + 1);
 
-                    capa->status = (char *) OCMalloc(strlen(value) + 1);
+                    capa->status = (char *) OICMalloc(strlen(value) + 1);
                     VARIFY_POINTER_NULL(capa->status, result, exit)
                     VARIFY_PARAM_NULL(value, result, exit)
                     strncpy(capa->status, value, strlen(value) + 1);
@@ -778,7 +778,7 @@ OCStackResult BuildStringFromActionSet(OCActionSet* actionset, char** desc)
         }
     }
 
-    *desc = (char *) OCMalloc(1024 - remaining);
+    *desc = (char *) OICMalloc(1024 - remaining);
     VARIFY_POINTER_NULL(*desc, res, exit);
     strcpy(*desc, temp);
 
@@ -801,26 +801,29 @@ OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
     {
         int idx;
 
-        unsigned char *responseJson;
-        responseJson = (unsigned char *) OCMalloc(
-                (unsigned int) (strlen((char *) clientResponse->resJSONPayload)
-                        + 1));
+        unsigned char *responseJson = NULL;
+        // TODO: Figure out what this does, change implementation
+        //responseJson = (unsigned char *) OICMalloc(
+        //        (unsigned int) (strlen((char *) clientResponse->resJSONPayload)
+        //                + 1));
 
         if( responseJson == NULL )
             return OC_STACK_DELETE_TRANSACTION;
 
         // We need the body of response.
         // Copy the body from the response
-        strcpy((char *) responseJson,
-                ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN));
-        idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN;
+        // TODO: Taken out
+        //strcpy((char *) responseJson,
+        //        ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN));
+        //idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN;
         // And insert NULL at the end of body.
         (responseJson[idx]) = 0;
 
         OCEntityHandlerResponse response = { 0 };
         response.ehResult = OC_EH_OK;
-        response.payload = (char*)responseJson;
-        response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
+        // TODO: Removing payload size, waht goes here?
+        // response.payload = (char*)responseJson;
+        //response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
         response.persistentBufferFlag = 0;
         response.requestHandle = (OCRequestHandle) info->ehRequest;
         response.resourceHandle = (OCResourceHandle) info->collResource;
@@ -900,17 +903,15 @@ unsigned int GetNumOfTargetResource(OCAction *actionset)
 OCStackResult SendAction(OCDoHandle *handle, const char *targetUri,
         const unsigned char *action)
 {
-    OCCallbackData cbdata = { 0 };
+    OCCallbackData cbdata;
     cbdata.cb = &ActionSetCB;
     cbdata.cd = NULL;
     cbdata.context = (void*)DEFAULT_CONTEXT_VALUE;
 
-// TODO: Selecting OC_IPV4.
-// It is temporary change as OC_ALL is not working currently. Remove this code and use OC_ALL
-// once it is functioning.
-
-    return OCDoResource(handle, OC_REST_PUT, targetUri,
-    NULL, (char *) action, OC_IPV4, OC_NA_QOS, &cbdata, NULL, 0);
+    // TODO: disabled since this is no longer compatible
+    return OC_STACK_NOTIMPL;
+    //return OCDoResource(handle, OC_REST_PUT, targetUri,
+    //        NULL, (char *) action, CT_ADAPTER_IP, OC_NA_QOS, &cbdata, NULL, 0);
 }
 
 OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
@@ -931,7 +932,7 @@ OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
         strncat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX,
                 strlen((const char *) OC_JSON_SUFFIX));
 
-        ClientRequestInfo *info = (ClientRequestInfo *) OCMalloc(
+        ClientRequestInfo *info = (ClientRequestInfo *) OICMalloc(
                 sizeof(ClientRequestInfo));
 
         if( info == NULL )
@@ -946,6 +947,7 @@ OCStackResult DoAction(OCResource* resource, OCActionSet* actionset,
                 actionDescPtr);
         if (result != OC_STACK_OK)
         {
+            OICFree(info);
             return result;
         }
 
@@ -993,7 +995,7 @@ void DoScheduledGroupAction()
     if (info->actionset->type == RECURSIVE)
     {
         ScheduledResourceInfo *schedule;
-        schedule = (ScheduledResourceInfo *) OCMalloc(
+        schedule = (ScheduledResourceInfo *) OICMalloc(
                 sizeof(ScheduledResourceInfo));
 
         if (schedule)
@@ -1052,8 +1054,10 @@ OCStackResult BuildCollectionGroupActionJSONResponse(
 
         char *jsonResponse;
 
-        stackRet = ExtractKeyValueFromRequest((char *) ehRequest->reqJSONPayload,
-                &doWhat, &details);
+        stackRet = OC_STACK_NOTIMPL;
+        // TODO: Fix?
+        //stackRet = ExtractKeyValueFromRequest((char *) ehRequest->reqJSONPayload,
+        //        &doWhat, &details);
 
         if(stackRet != OC_STACK_OK)
         {
@@ -1126,8 +1130,9 @@ OCStackResult BuildCollectionGroupActionJSONResponse(
                     response.ehResult = OC_EH_OK;
                 else
                     response.ehResult = OC_EH_ERROR;
-                response.payload = (char*)buffer;
-                response.payloadSize = bufferLength + 1;
+                // TODO: Fix
+                //response.payload = (char*)buffer;
+                //response.payloadSize = bufferLength + 1;
                 response.persistentBufferFlag = 0;
                 response.requestHandle =
                         (OCRequestHandle) ehRequest->requestHandle;
@@ -1204,7 +1209,7 @@ OCStackResult BuildCollectionGroupActionJSONResponse(
                                     (delay == -1 ? actionset->timesteps : delay);
 
                             ScheduledResourceInfo *schedule;
-                            schedule = (ScheduledResourceInfo *) OCMalloc(
+                            schedule = (ScheduledResourceInfo *) OICMalloc(
                                     sizeof(ScheduledResourceInfo));
 
                             if (schedule)
@@ -1274,7 +1279,7 @@ OCStackResult BuildCollectionGroupActionJSONResponse(
                     {
                         cJSON_AddStringToObject(format, ACTIONSET, plainText);
                     }
-                    OCFree(plainText);
+                    OICFree(plainText);
                     stackRet = OC_STACK_OK;
                 }
             }
@@ -1293,8 +1298,9 @@ OCStackResult BuildCollectionGroupActionJSONResponse(
                     response.ehResult = OC_EH_OK;
                 else
                     response.ehResult = OC_EH_ERROR;
-                response.payload = (char *)buffer;
-                response.payloadSize = bufferLength + 1;
+                // TODO: Implement
+                //response.payload = (char *)buffer;
+                //response.payloadSize = bufferLength + 1;
                 response.persistentBufferFlag = 0;
                 response.requestHandle =
                         (OCRequestHandle) ehRequest->requestHandle;
index a331fa3..ade8f3f 100644 (file)
@@ -29,13 +29,17 @@ src_dir = stacktest_env.get('SRC_DIR')
 # Build flags
 ######################################################################
 stacktest_env.PrependUnique(CPPPATH = [
+               '../../security/include',
                '../../ocsocket/include',
                '../../logger/include',
+               '../../ocrandom/include',
                '../../stack/include',
-               '../../ocmalloc/include',
+               '../../stack/include/internal',
+               '../../connectivity/api',
+               '../../connectivity/external/inc',
                '../../extlibs/cjson',
                '../../../oc_logger/include',
-               '../../../../extlibs/gtest/gtest-1.7.0/include'
+               '#extlibs/gtest/gtest-1.7.0/include'
                ])
 
 stacktest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
@@ -44,6 +48,7 @@ stacktest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 stacktest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
 stacktest_env.PrependUnique(LIBS = ['m',
                                     'octbstack',
+                                    'ocsrm',
                                     'connectivity_abstraction',
                                     'coap',
                                     'gtest',
@@ -71,12 +76,7 @@ env.AppendTarget('test')
 if env.get('TEST') == '1':
        target_os = env.get('TARGET_OS')
        if target_os == 'linux':
-               out_dir = env.get('BUILD_DIR')
-               result_dir = env.get('BUILD_DIR') + '/test_out/'
-               if not os.path.isdir(result_dir):
-                       os.makedirs(result_dir)
-               stacktest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
-               stacktest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
-               stacktest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
-               ut = stacktest_env.Command ('ut', None, 'valgrind -q --leak-check=full --xml=yes --xml-file=resource_csdk_stack_test.memcheck ' + out_dir + 'resource/csdk/stack/test/stacktests')
-               AlwaysBuild ('ut')
+                from tools.scons.RunTest import *
+                run_test(stacktest_env,
+                         'resource_csdk_stack_test.memcheck',
+                         'resource/csdk/stack/test/stacktests')
index 322b487..823adf5 100644 (file)
@@ -41,13 +41,11 @@ void handleSigInt(int signum) {
 // This is a function called back when a device is discovered
 OCStackApplicationResult applicationDiscoverCB(
         OCClientResponse * clientResponse) {
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNu;
     OC_LOG(INFO, TAG, "Entering applicationDiscoverCB (Application Layer CB)");
-    OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-            remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);
-    OC_LOG_V(INFO, TAG, "Device =============> Discovered %s @ %d.%d.%d.%d:%d",clientResponse->resJSONPayload,remoteIpAddr[0], remoteIpAddr[1], remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
+    OC_LOG_V(INFO, TAG, "Device =============> Discovered %s @ %s:%d",
+                                    clientResponse->resJSONPayload,
+                                    clientResponse->devAddr.addr,
+                                    clientResponse->devAddr.port);
     //return OC_STACK_DELETE_TRANSACTION;
     return OC_STACK_KEEP_TRANSACTION;
 }
index 19631d7..8ee757d 100644 (file)
@@ -22,8 +22,9 @@
 extern "C"
 {
     #include "ocstack.h"
+    #include "ocstackinternal.h"
     #include "logger.h"
-    #include "ocmalloc.h"
+    #include "oic_malloc.h"
 }
 
 #include "gtest/gtest.h"
@@ -78,7 +79,8 @@ extern "C"  OCStackApplicationResult asyncDoResourcesCallback(void* ctx, OCDoHan
 //-----------------------------------------------------------------------------
 // Entity handler
 //-----------------------------------------------------------------------------
-OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest)
+OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest,
+                                    void* callbackParam)
 {
     OC_LOG(INFO, TAG, "Entering entityHandler");
 
@@ -217,6 +219,19 @@ TEST(StackStart, SetPlatformInfoWithNoManufacturerName)
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
+TEST(StackStart, SetPlatformInfoWithZeroLengthManufacturerName)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_OK, OCInit("127.0.0.1", 5683, OC_SERVER));
+
+    OCPlatformInfo info = {};
+    info.platformID = (char *) "platform_id";
+    info.manufacturerName = (char *) "";
+
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSetPlatformInfo(info));
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
 TEST(StackStart, SetPlatformInfoWithTooLongManufacName)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
@@ -256,7 +271,7 @@ TEST(StackDiscovery, DISABLED_DoResourceDeviceDiscovery)
 
     /* Start a discovery query*/
     char szQueryUri[64] = { 0 };
-    strcpy(szQueryUri, OC_WELL_KNOWN_QUERY);
+    strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
@@ -265,7 +280,7 @@ TEST(StackDiscovery, DISABLED_DoResourceDeviceDiscovery)
                                         szQueryUri,
                                         0,
                                         0,
-                                        OC_IPV4,
+                                        CT_ADAPTER_IP,
                                         OC_LOW_QOS,
                                         &cbData,
                                         NULL,
@@ -276,6 +291,12 @@ TEST(StackDiscovery, DISABLED_DoResourceDeviceDiscovery)
 TEST(StackStop, StackStopWithoutInit)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_ERROR, OCStop());
+}
+
+TEST(StackStop, StackStopRepeated)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
     EXPECT_EQ(OC_STACK_OK, OCInit("127.0.0.1", 5683, OC_CLIENT));
     EXPECT_EQ(OC_STACK_OK, OCStop());
     EXPECT_EQ(OC_STACK_ERROR, OCStop());
@@ -292,7 +313,7 @@ TEST(StackResource, DISABLED_UpdateResourceNullURI)
 
     /* Start a discovery query*/
     char szQueryUri[64] = { 0 };
-    strcpy(szQueryUri, OC_WELL_KNOWN_QUERY);
+    strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
@@ -301,7 +322,7 @@ TEST(StackResource, DISABLED_UpdateResourceNullURI)
                                         szQueryUri,
                                         0,
                                         0,
-                                        OC_IPV4,
+                                        CT_ADAPTER_IP,
                                         OC_LOW_QOS,
                                         &cbData,
                                         NULL,
@@ -322,6 +343,7 @@ TEST(StackResource, CreateResourceBadParams)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_INVALID_PARAM, OCCreateResource(&handle,
@@ -329,6 +351,7 @@ TEST(StackResource, CreateResourceBadParams)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     // Property bitmask out of range
@@ -337,11 +360,48 @@ TEST(StackResource, CreateResourceBadParams)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             128));// invalid bitmask for OCResourceProperty
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
+TEST(StackResource, CreateResourceBadUri)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    OC_LOG(INFO, TAG, "Starting CreateResourceBadUri test");
+    InitStack(OC_SERVER);
+
+    const char *uri65 = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL";
+
+    OCResourceHandle handle;
+
+    EXPECT_EQ(OC_STACK_INVALID_URI, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            NULL, //"/a/led",
+                                            0,
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_INVALID_URI, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "", //"/a/led",
+                                            0,
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_INVALID_URI, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            uri65, //"/a/led",
+                                            0,
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
 
 TEST(StackResource, CreateResourceSuccess)
 {
@@ -355,6 +415,7 @@ TEST(StackResource, CreateResourceSuccess)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     const char *url = OCGetResourceUri(handle);
     EXPECT_STREQ("/a/led", url);
@@ -362,6 +423,46 @@ TEST(StackResource, CreateResourceSuccess)
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
+TEST(StackResource, CreateResourceSuccessWithResourcePolicyPropNone)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    OC_LOG(INFO, TAG, "Starting CreateResourceSuccessWithResourcePolicyPropNone test");
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    // the resource is non-discoverable & non-observable by the client.
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            NULL,
+                                            OC_RES_PROP_NONE));// the resource is non-discoverable &
+                                                // non-observable by the client.
+    const char* url = OCGetResourceUri(handle);
+    EXPECT_STREQ("/a/led", url);
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
+TEST(StackResource, CreateResourceWithClientStackMode)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    OC_LOG(INFO, TAG, "Starting CreateResourceSuccess test");
+    InitStack(OC_CLIENT);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
 TEST(StackResource, CreateResourceFailDuplicateUri)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
@@ -374,6 +475,7 @@ TEST(StackResource, CreateResourceFailDuplicateUri)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     const char *url = OCGetResourceUri(handle);
     EXPECT_STREQ("/a/led", url);
@@ -383,6 +485,7 @@ TEST(StackResource, CreateResourceFailDuplicateUri)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
@@ -400,6 +503,7 @@ TEST(StackResource, CreateResourceMultipleResources)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     OCResourceHandle handle2;
@@ -408,6 +512,7 @@ TEST(StackResource, CreateResourceMultipleResources)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     OCResourceHandle handle3;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle3,
@@ -415,6 +520,7 @@ TEST(StackResource, CreateResourceMultipleResources)
                                             "core.rw",
                                             "/a/led3",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     const char *url = OCGetResourceUri(handle1);
@@ -441,6 +547,16 @@ TEST(StackResource, CreateResourceBadResoureType)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    OCResourceHandle handle2;
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCCreateResource(&handle2,
+                                            "",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
@@ -458,6 +574,7 @@ TEST(StackResource, CreateResourceGoodResourceType)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
@@ -475,6 +592,7 @@ TEST(StackResource, ResourceTypeName)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceTypes;
@@ -505,6 +623,7 @@ TEST(StackResource, ResourceTypeAttrRepresentation)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceTypes;
@@ -526,6 +645,7 @@ TEST(StackResource, ResourceTypeInterface)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -558,6 +678,7 @@ TEST(StackResource, ResourceDefaultInterfaceAlwaysFirst)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
                                         OC_RSRVD_INTERFACE_DEFAULT));
@@ -588,6 +709,7 @@ TEST(StackResource, ResourceDuplicateDefaultInterfaces)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
@@ -619,6 +741,7 @@ TEST(StackResource, ResourceDuplicateNonDefaultInterfaces)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
@@ -645,6 +768,7 @@ TEST(StackResource, ResourceTypeInterfaceMethods)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -666,6 +790,7 @@ TEST(StackResource, GetResourceProperties)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_ACTIVE|OC_DISCOVERABLE|OC_OBSERVABLE, OCGetResourceProperties(handle));
@@ -679,6 +804,8 @@ TEST(StackResource, StackTestResourceDiscoverOneResourceBad)
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
     OC_LOG(INFO, TAG, "Starting StackTestResourceDiscoverOneResourceBad test");
     InitStack(OC_SERVER);
+    uint8_t numResources = 0;
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
 
     OCResourceHandle handle;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle,
@@ -686,16 +813,16 @@ TEST(StackResource, StackTestResourceDiscoverOneResourceBad)
                                             "core.rw",
                                             "/a1/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     const char *url = OCGetResourceUri(handle);
     EXPECT_STREQ("/a1/led", url);
 
     //EXPECT_EQ(OC_STACK_INVALID_URI, OCHandleServerRequest(&res, uri, query, req, rsp));
     EXPECT_EQ(OC_STACK_OK, OCDeleteResource(handle));
-    uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
+    uint8_t numExpectedResources = 0;
 
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
     EXPECT_EQ(numExpectedResources, numResources);
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
@@ -713,6 +840,7 @@ TEST(StackResource, StackTestResourceDiscoverOneResource)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     const char *url = OCGetResourceUri(handle);
     EXPECT_STREQ("/a/led", url);
@@ -735,6 +863,7 @@ TEST(StackResource, StackTestResourceDiscoverManyResources)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE));
     const char *url = OCGetResourceUri(handle1);
     EXPECT_STREQ("/a/led1", url);
@@ -745,6 +874,7 @@ TEST(StackResource, StackTestResourceDiscoverManyResources)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     url = OCGetResourceUri(handle2);
     EXPECT_STREQ("/a/led2", url);
@@ -758,6 +888,7 @@ TEST(StackResource, StackTestResourceDiscoverManyResources)
                                             "core.rw",
                                             "/a/led3",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     url = OCGetResourceUri(handle3);
     EXPECT_STREQ("/a/led3", url);
@@ -771,6 +902,7 @@ TEST(StackResource, StackTestResourceDiscoverManyResources)
                                             "core.rw",
                                             "/a/led4",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE));
     url = OCGetResourceUri(handle4);
     EXPECT_STREQ("/a/led4", url);
@@ -796,6 +928,7 @@ TEST(StackBind, BindResourceTypeNameBad)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceTypes;
@@ -821,6 +954,7 @@ TEST(StackBind, BindResourceTypeNameGood)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceTypes;
@@ -856,6 +990,7 @@ TEST(StackBind, BindResourceTypeAttribRepGood)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceTypes;
@@ -886,6 +1021,7 @@ TEST(StackBind, BindResourceInterfaceNameBad)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -911,6 +1047,7 @@ TEST(StackBind, BindResourceInterfaceNameGood)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -941,6 +1078,7 @@ TEST(StackBind, BindResourceInterfaceMethodsBad)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -964,6 +1102,7 @@ TEST(StackBind, BindResourceInterfaceMethodsGood)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     uint8_t numResourceInterfaces;
@@ -990,6 +1129,7 @@ TEST(StackBind, BindContainedResourceBad)
                                             "core.rw",
                                             "/a/kitchen",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     OCResourceHandle handle0;
@@ -998,6 +1138,7 @@ TEST(StackBind, BindContainedResourceBad)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     EXPECT_EQ(OC_STACK_INVALID_PARAM, OCBindResource(containerHandle, containerHandle));
@@ -1014,10 +1155,9 @@ TEST(StackBind, BindContainedResourceGood)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
+    uint8_t numExpectedResources = 0;
 
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
 
     OCResourceHandle containerHandle;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&containerHandle,
@@ -1025,6 +1165,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/kitchen",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1035,6 +1176,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1045,6 +1187,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1055,6 +1198,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1065,6 +1209,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led3",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1075,6 +1220,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led4",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1085,6 +1231,7 @@ TEST(StackBind, BindContainedResourceGood)
                                             "core.rw",
                                             "/a/led5",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1121,9 +1268,10 @@ TEST(StackBind, BindEntityHandlerBad)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
-    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCBindResourceHandler(NULL, NULL));
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCBindResourceHandler(NULL, NULL, NULL));
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
@@ -1140,11 +1288,12 @@ TEST(StackBind, BindEntityHandlerGood)
                                             "core.rw",
                                             "/a/led",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
 
     OCEntityHandler myHandler = entityHandler;
 
-    EXPECT_EQ(OC_STACK_OK, OCBindResourceHandler(handle, myHandler));
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceHandler(handle, myHandler, NULL));
 
     EXPECT_EQ(myHandler, OCGetResourceHandler(handle));
 
@@ -1158,18 +1307,18 @@ TEST(StackResourceAccess, GetResourceByIndex)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
-    uint8_t resourceIndex = InitResourceIndex();
-
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
-
+    uint8_t numExpectedResources = 0;
+    uint8_t resourceIndex = 0;
+    uint8_t prevResources = 0;
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
+    prevResources = numExpectedResources;
     OCResourceHandle containerHandle;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&containerHandle,
                                             "core.led",
                                             "core.rw",
                                             "/a/kitchen",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1180,6 +1329,7 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1190,6 +1340,7 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1200,6 +1351,7 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1210,6 +1362,7 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led3",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1220,6 +1373,7 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led4",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1230,10 +1384,11 @@ TEST(StackResourceAccess, GetResourceByIndex)
                                             "core.rw",
                                             "/a/led5",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
-
+    resourceIndex += prevResources;
     EXPECT_EQ(containerHandle, OCGetResourceHandle(resourceIndex));
     EXPECT_EQ(handle0, OCGetResourceHandle(++resourceIndex));
     EXPECT_EQ(handle1, OCGetResourceHandle(++resourceIndex));
@@ -1252,10 +1407,9 @@ TEST(StackResourceAccess, DeleteHeadResource)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
+    uint8_t numExpectedResources = 0;
 
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
 
     OCResourceHandle handle0;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle0,
@@ -1263,6 +1417,7 @@ TEST(StackResourceAccess, DeleteHeadResource)
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1281,18 +1436,16 @@ TEST(StackResourceAccess, DeleteHeadResource2)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
-    uint8_t resourceIndex = InitResourceIndex();
-
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
+    uint8_t numExpectedResources = 0;
 
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
     OCResourceHandle handle0;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle0,
                                             "core.led",
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1303,6 +1456,7 @@ TEST(StackResourceAccess, DeleteHeadResource2)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1311,7 +1465,7 @@ TEST(StackResourceAccess, DeleteHeadResource2)
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(--numExpectedResources, numResources);
 
-    EXPECT_EQ(handle1, OCGetResourceHandle(resourceIndex));
+    EXPECT_EQ(handle1, OCGetResourceHandle(numResources - 1));
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
@@ -1324,11 +1478,9 @@ TEST(StackResourceAccess, DeleteLastResource)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
-    uint8_t resourceIndex = InitResourceIndex();
+    uint8_t numExpectedResources = 0;
 
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
 
     OCResourceHandle handle0;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle0,
@@ -1336,6 +1488,7 @@ TEST(StackResourceAccess, DeleteLastResource)
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1346,6 +1499,7 @@ TEST(StackResourceAccess, DeleteLastResource)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1354,7 +1508,7 @@ TEST(StackResourceAccess, DeleteLastResource)
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(--numExpectedResources, numResources);
 
-    EXPECT_EQ(handle0, OCGetResourceHandle(resourceIndex));
+    EXPECT_EQ(handle0, OCGetResourceHandle(numResources - 1));
 
     OCResourceHandle handle2;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle2,
@@ -1362,6 +1516,7 @@ TEST(StackResourceAccess, DeleteLastResource)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1376,18 +1531,18 @@ TEST(StackResourceAccess, DeleteMiddleResource)
     InitStack(OC_SERVER);
 
     uint8_t numResources = 0;
-    uint8_t numExpectedResources = InitNumExpectedResources();
+    uint8_t numExpectedResources = 0;
     uint8_t resourceIndex = InitResourceIndex();
 
-    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
-    EXPECT_EQ(numExpectedResources, numResources);
-
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numExpectedResources));
+    resourceIndex = numExpectedResources;
     OCResourceHandle handle0;
     EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle0,
                                             "core.led",
                                             "core.rw",
                                             "/a/led0",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1398,6 +1553,7 @@ TEST(StackResourceAccess, DeleteMiddleResource)
                                             "core.rw",
                                             "/a/led1",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1408,6 +1564,7 @@ TEST(StackResourceAccess, DeleteMiddleResource)
                                             "core.rw",
                                             "/a/led2",
                                             0,
+                                            NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResources(&numResources));
     EXPECT_EQ(++numExpectedResources, numResources);
@@ -1429,75 +1586,12 @@ TEST(StackResourceAccess, DeleteMiddleResource)
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-    void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge, char** resType);
-#ifdef __cplusplus
+TEST(PODTests, OCHeaderOption)
+{
+    EXPECT_TRUE(std::is_pod<OCHeaderOption>::value);
 }
-#endif // __cplusplus
 
-TEST(StackPresence, ParsePresencePayload)
+TEST(PODTests, OCCallbackData)
 {
-    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
-    OC_LOG(INFO, TAG, "Starting ParsePresencePayload test");
-
-    char payload[100];
-    uint32_t seqNum = 0, maxAge = 0;
-    char * resType = NULL;
-
-    //Good Scenario
-    strncpy(payload, "{\"oc\":[100:99:presence]}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(100 == seqNum);
-    EXPECT_TRUE(99 == maxAge);
-    EXPECT_STREQ("presence", resType);
-    OCFree(resType);
-
-    //Bad Scenario -- should not result in Seg Fault
-    parsePresencePayload(payload, NULL, &maxAge, &resType);
-
-    //Bad Scenario
-    seqNum = 0; maxAge = 0; resType = NULL;
-    strncpy(payload, "{abracadabra}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(0 == seqNum);
-    EXPECT_TRUE(0 == maxAge);
-    EXPECT_EQ(NULL, resType);
-    OCFree(resType);
-
-    //Bad Scenario
-    seqNum = 0; maxAge = 0; resType = NULL;
-    strncpy(payload, "{\"oc\":[100]}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(100 == seqNum);
-    EXPECT_TRUE(0 == maxAge);
-    EXPECT_EQ(NULL, resType);
-    OCFree(resType);
-
-    //Bad Scenario
-    seqNum = 0; maxAge = 0; resType = NULL;
-    strncpy(payload, "{\"oc\":[]}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(0 == seqNum);
-    EXPECT_TRUE(0 == maxAge);
-    EXPECT_EQ(NULL, resType);
-    OCFree(resType);
-
-    //Bad Scenario
-    strncpy(payload, "{:]}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(0 == seqNum);
-    EXPECT_TRUE(0 == maxAge);
-    EXPECT_EQ(NULL, resType);
-    OCFree(resType);
-
-    //Bad Scenario
-    strncpy(payload, "{:[presence}", sizeof(payload));
-    parsePresencePayload(payload, &seqNum, &maxAge, &resType);
-    EXPECT_TRUE(0 == seqNum);
-    EXPECT_TRUE(0 == maxAge);
-    EXPECT_EQ(NULL, resType);
-    OCFree(resType);
+    EXPECT_TRUE(std::is_pod<OCHeaderOption>::value);
 }
index 8b5740a..77c863d 100644 (file)
@@ -648,7 +648,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # and error messages should be written. If left blank the output is written
 # to stderr.
 
-WARN_LOGFILE           =
+WARN_LOGFILE           = ./doxygen.log
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
@@ -666,13 +666,14 @@ INPUT                  = . \
                          ../include/OCResourceRequest.h \
                          ../include/OCResourceResponse.h \
                          ../include/OCResource.h \
-                         ../resource/csdk/stack/include/octypes.h \
-                         ../resource/csdk/stack/include/ocstackconfig.h \
+                         ../csdk/stack/include/octypes.h \
+                         ../csdk/stack/include/ocstackconfig.h \
                          guides \
                          ../../service/things-manager/sdk/inc \
                          ../../service/soft-sensor-manager/SDK/cpp/include \
                          ../../service/protocol-plugin/plugin-manager/src/PluginManager.h \
-                         ../../service/noification-manager/NotificationManager/include/hosting.h 
+                         ../../service/notification-manager/NotificationManager/include/hosting.h \
+                         ../../service/resource-encapsulation/include \
 
 # 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
index 4ab5086..8d38f28 100644 (file)
@@ -108,14 +108,16 @@ INPUT                  = devdox \
                          ../csdk/connectivity/src \
                          ../csdk/logger/include \
                          ../csdk/logger/src \
-                         ../csdk/ocmalloc/include \
-                         ../csdk/ocmalloc/src \
                          ../csdk/ocrandom/include \
                          ../csdk/ocrandom/src \
                          ../csdk/security/include \
                          ../csdk/security/src \
                          ../csdk/stack/include \
-                         ../csdk/stack/src
+                         ../csdk/stack/src \
+                         ../c_common/oic_malloc/include \
+                         ../c_common/oic_malloc/src \
+                         ../c_common/oic_string/include \
+                         ../c_common/oic_string/src
 
 INPUT_ENCODING         = UTF-8
 FILE_PATTERNS          =
index eee3d5b..05b7982 100644 (file)
@@ -139,7 +139,7 @@ digraph G {
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::startAdapter" tooltip="+startAdapter: CAAdapterStart">+startAdapter: CAAdapterStart</td></tr>
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::startListenServer" tooltip="+startListenServer: CAAdapterStartListeningServer">+startListenServer: CAAdapterStartListeningServer</td></tr>
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::startDiscoveryServer" tooltip="+startDiscoveryServer: CAAdapterStartDiscoveryServer">+startDiscoveryServer: CAAdapterStartDiscoveryServer</td></tr>
-                    <tr><td align="left" href="\ref CAConnectivityHandler_t::sendData" tooltip="+sendData: CAAdapterSendUnitcastData">+sendData: CAAdapterSendUnitcastData</td></tr>
+                    <tr><td align="left" href="\ref CAConnectivityHandler_t::sendData" tooltip="+sendData: CAAdapterSendUnicastData">+sendData: CAAdapterSendUnicastData</td></tr>
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::sendDataToAll" tooltip="+sendDataToAll: CAAdapterSendMulticastData">+sendDataToAll: CAAdapterSendMulticastData</td></tr>
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::GetnetInfo" tooltip="+GetnetInfo: CAAdapterGetNetworkInfo">+GetnetInfo: CAAdapterGetNetworkInfo</td></tr>
                     <tr><td align="left" href="\ref CAConnectivityHandler_t::readData" tooltip="+readData: CAAdapterReadData">+readData: CAAdapterReadData</td></tr>
index 914a5ee..731b203 100644 (file)
@@ -100,4 +100,10 @@ Alias("examples", [simpleserver, simpleclient,
      ])
 env.AppendTarget('examples')
 
-
+src_dir = examples_env.get('SRC_DIR')
+svr_db_src_dir = src_dir + '/resource/examples/'
+svr_db_build_dir = env.get('BUILD_DIR') +'/resource/examples/'
+examples_env.Alias("install", examples_env.Install( svr_db_build_dir,
+                svr_db_src_dir + 'oic_svr_db_client.json'))
+examples_env.Alias("install", examples_env.Install( svr_db_build_dir,
+                svr_db_src_dir + 'oic_svr_db_server.json'))
index 90d22d8..25250d3 100644 (file)
 
 using namespace OC;
 
+static void printUsage()
+{
+    std::cout << "Usage devicediscoveryclient <0|1>" << std::endl;
+    std::cout << "connectivityType: Default IP" << std::endl;
+    std::cout << "connectivityType 0: IP" << std::endl;
+}
 //Callback after device information is received
 void receivedPlatformInfo(const OCRepresentation& rep)
 {
     std::cout << "\nPlatform Information received ---->\n";
     std::string value;
-    std::string values[22] =
+    std::string values[] =
     {
         "pi",   "Platform ID                    ",
         "mnmn", "Manufacturer name              ",
@@ -52,7 +58,7 @@ void receivedPlatformInfo(const OCRepresentation& rep)
         "st",   "Manufacturer system time       "
     };
 
-    for (int i = 0; i < 22; i += 2)
+    for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]) ; i += 2)
     {
         if(rep.getValue(values[i], value))
         {
@@ -63,7 +69,23 @@ void receivedPlatformInfo(const OCRepresentation& rep)
 
 void receivedDeviceInfo(const OCRepresentation& rep)
 {
-    std::cout << "Implement me !" << std::endl;
+    std::cout << "\nDevice Information received ---->\n";
+    std::string value;
+    std::string values[] =
+    {
+        "di",   "Device ID        ",
+        "n",    "Device name      ",
+        "lcv",  "Spec version url ",
+        "dmv",  "Data Model Model ",
+    };
+
+    for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]) ; i += 2)
+    {
+        if(rep.getValue(values[i], value))
+        {
+            std::cout << values[i + 1] << " : "<< value << std::endl;
+        }
+    }
 }
 
 int main(int argc, char* argv[]) {
@@ -74,7 +96,8 @@ int main(int argc, char* argv[]) {
     std::string platformDiscoveryURI = "/oic/p";
     std::string deviceDiscoveryURI   = "/oic/d";
 
-    OCConnectivityType connectivityType = OC_IPV4;
+    //Default Connectivity type
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
 
     if(argc == 2)
     {
@@ -87,37 +110,29 @@ int main(int argc, char* argv[]) {
             {
                 if(optionSelected == 0)
                 {
-                    connectivityType = OC_IPV4;
-                }
-                else if(optionSelected == 1)
-                {
-                    // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                    //connectivityType = OC_IPV6;
-                    connectivityType = OC_IPV4;
-                    std::cout << "IPv6 not currently supported. Using default IPv4" << std::endl;
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
                 }
                 else
                 {
-                    std::cout << "Invalid connectivity type selected. Using default IPv4"
-                    << std::endl;
+                    std::cout << "Invalid connectivity type selected." << std::endl;
+                    printUsage();
+                    return -1;
                 }
             }
             else
             {
-                std::cout << "Invalid connectivity type selected. Using default IPv4" << std::endl;
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
             }
         }
         catch(std::exception&)
         {
-            std::cout << "Invalid input argument. Using IPv4 as connectivity type" << std::endl;
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
         }
     }
     else
     {
-        std::cout << "Usage devicediscoveryclient <connectivityType(0|1)>" << std::endl;
-        std::cout << "connectivityType: Default IPv4" << std::endl;
-        std::cout << "connectivityType 0: IPv4" << std::endl;
-        std::cout << "connectivityType 1: IPv6 (not currently supported)" << std::endl;
+        printUsage();
     }
     // Create PlatformConfig object
     PlatformConfig cfg {
@@ -150,23 +165,20 @@ int main(int argc, char* argv[]) {
             std::cout << "failed." << std::endl;
         }
 
-        bool is_oic_d_implemented = false;
-        if (is_oic_d_implemented)
-        {
-            std::cout<< "Querying for device information... ";
+        std::cout<< "Querying for device information... ";
 
-            ret = OCPlatform::getDeviceInfo("", deviceDiscoveryRequest.str(), connectivityType,
-                    &receivedDeviceInfo);
+        ret = OCPlatform::getDeviceInfo("", deviceDiscoveryRequest.str(), connectivityType,
+                &receivedDeviceInfo);
 
-            if (ret == OC_STACK_OK)
-            {
-                std::cout << "done." << std::endl;
-            }
-            else
-            {
-                std::cout << "failed." << std::endl;
-            }
+        if (ret == OC_STACK_OK)
+        {
+            std::cout << "done." << std::endl;
         }
+        else
+        {
+            std::cout << "failed." << std::endl;
+        }
+
         // A condition variable will free the mutex it is given, then do a non-
         // intensive block until 'notify' is called on it.  In this case, since we
         // don't ever call cv.notify, this should be a non-processor intensive version
index 3c09140..8f9ec9b 100644 (file)
@@ -19,8 +19,8 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 ///
-///This sample demonstrates the device discovery feature
-///The server sets the device related info. which can
+///This sample demonstrates platform and device discovery feature
+///The server sets the platform and device related info. which can
 ///be later retrieved by a client.
 ///
 
@@ -45,9 +45,15 @@ std::string platformVersion = "platformVersion";
 std::string supportUrl = "www.mysupporturl.com";
 std::string systemTime = "mySystemTime";
 
+//Set of strings for each of platform info fields
+std::string deviceName = "Bill's Battlestar";
+
 //OCPlatformInfo Contains all the platform info to be stored
 OCPlatformInfo platformInfo;
 
+//OCDeviceInfo Contains all the device info to be stored
+OCDeviceInfo deviceInfo;
+
 void DeletePlatformInfo()
 {
     delete[] platformInfo.platformID;
@@ -63,6 +69,12 @@ void DeletePlatformInfo()
     delete[] platformInfo.systemTime;
 }
 
+
+void DeleteDeviceInfo()
+{
+    delete[] deviceInfo.deviceName;
+}
+
 void DuplicateString(char ** targetString, std::string sourceString)
 {
     *targetString = new char[sourceString.length() + 1];
@@ -89,10 +101,15 @@ OCStackResult SetPlatformInfo(std::string platformID, std::string manufacturerNa
 }
 
 
+OCStackResult SetDeviceInfo(std::string deviceName)
+{
+    DuplicateString(&deviceInfo.deviceName, deviceName);
+    return OC_STACK_OK;
+}
+
 
 int main()
 {
-
     // Create PlatformConfig object
     PlatformConfig cfg {
         OC::ServiceType::InProc,
@@ -110,21 +127,27 @@ int main()
             modelNumber, dateOfManufacture, platformVersion,  operatingSystemVersion,
             hardwareVersion, firmwareVersion,  supportUrl, systemTime);
 
+    result = OCPlatform::registerPlatformInfo(platformInfo);
+
     if(result != OC_STACK_OK)
     {
         std::cout << "Platform Registration failed\n";
         return -1;
     }
 
-    result = OCPlatform::registerPlatformInfo(platformInfo);
+
+    result = SetDeviceInfo(deviceName);
+
+    result = OCPlatform::registerDeviceInfo(deviceInfo);
 
     if(result != OC_STACK_OK)
     {
-        std::cout << "Platform Registration failed\n";
+        std::cout << "Device Registration failed\n";
         return -1;
     }
 
     DeletePlatformInfo();
+    DeleteDeviceInfo();
 
     // A condition variable will free the mutex it is given, then do a non-
     // intensive block until 'notify' is called on it.  In this case, since we
index 501ad75..44ad16e 100644 (file)
@@ -38,6 +38,12 @@ namespace PH = std::placeholders;
 const uint16_t API_VERSION = 2048;
 const uint16_t TOKEN = 3000;
 
+static void printUsage()
+{
+    std::cout << "Usage: fridgeclient <0|1>" <<std::endl;
+    std::cout << "connectivityType: Default IP" << std::endl;
+    std::cout << "connectivityType 0: IP" << std::endl;
+}
 class ClientFridge
 {
     public:
@@ -45,11 +51,11 @@ class ClientFridge
         m_callsMade(0),m_connectivityType(ct)
     {
         std::ostringstream requestURI;
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=intel.fridge";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=intel.fridge";
         std::cout << "Fridge Client has started " <<std::endl;
         FindCallback f (std::bind(&ClientFridge::foundDevice, this, PH::_1));
         OCStackResult result = OCPlatform::findResource(
-                "", requestURI.str(), OC_ALL, f);
+                "", requestURI.str(), CT_DEFAULT, f);
 
         if(OC_STACK_OK != result)
         {
@@ -176,7 +182,7 @@ class ClientFridge
     // however be a better fit to wrap each call in an object so a fuller context (and additional
     // requests) can be easily made inside of a simple context
     void getResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
-                const OCRepresentation rep, const int eCode, OCResource::Ptr resource, int getId)
+                const OCRepresentation& rep, const int eCode, OCResource::Ptr resource, int getId)
     {
         std::cout << "Got a response from get from the " << resourceName << std::endl;
         std::cout << "Get ID is "<<getId<<" and resource URI is " << resource->uri() << std::endl;
@@ -267,7 +273,7 @@ class ClientFridge
 
 int main(int argc, char* argv[])
 {
-    OCConnectivityType connectivityType = OC_IPV4;
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
     if(argc == 2)
     {
         try
@@ -279,37 +285,29 @@ int main(int argc, char* argv[])
             {
                 if(optionSelected == 0)
                 {
-                    connectivityType = OC_IPV4;
-                }
-                else if(optionSelected == 1)
-                {
-                    // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                    //connectivityType = OC_IPV6;
-                    connectivityType = OC_IPV4;
-                    std::cout << "IPv6 not currently supported. Using default IPv4" << std::endl;
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
                 }
                 else
                 {
-                    std::cout << "Invalid connectivity type selected. Using default IPv4"
-                        << std::endl;
+                    std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
+                    printUsage();
                 }
             }
             else
             {
-                std::cout << "Invalid connectivity type selected. Using default IPv4" << std::endl;
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
             }
         }
         catch(std::exception&)
         {
-            std::cout << "Invalid input argument. Using IPv4 as connectivity type" << std::endl;
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
         }
     }
     else
     {
-        std::cout << "Usage: fridgeclient <ConnectivityType(0|1)>\n";
-        std::cout << "connectivityType: Default IPv4" << std::endl;
-        std::cout << "connectivityType 0: IPv4" << std::endl;
-        std::cout << "connectivityType 1: IPv6 (not currently supported)" << std::endl;
+        printUsage();
+        std::cout << "Default input argument. Using IP as connectivity type" << std::endl;
     }
 
     PlatformConfig cfg
index 45f626b..dbc91ea 100644 (file)
@@ -281,7 +281,7 @@ class LightResource : public Resource
         return m_rep;
     }
 
-    void put(OCRepresentation rep)
+    void put(const OCRepresentation& rep)
     {
         rep.getValue("on", m_isOn);
     }
@@ -376,7 +376,7 @@ class DoorResource : public Resource
         return m_rep;
     }
 
-    void put(OCRepresentation rep)
+    void put(const OCRepresentation& rep)
     {
         rep.getValue("open", m_isOpen);
         // Note, we won't let the user change the door side!
index c64528d..5a5af3f 100644 (file)
@@ -34,6 +34,13 @@ const int SUCCESS_RESPONSE = 0;
 std::shared_ptr<OCResource> curResource;
 std::mutex curResourceLock;
 
+static void printUsage()
+{
+    std::cout<<"Usage: garageclient <0|1> \n";
+    std::cout<<"ConnectivityType: Default IP\n";
+    std::cout<<"ConnectivityType 0: IP \n";
+}
+
 class Garage
 {
 public:
@@ -288,6 +295,44 @@ int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
 
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
+
+    if(argc == 2)
+    {
+        try
+        {
+            std::size_t inputValLen;
+            int optionSelected = std::stoi(argv[1], &inputValLen);
+
+            if(inputValLen == strlen(argv[1]))
+            {
+                if(optionSelected == 0)
+                {
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
+                }
+                else
+                {
+                    std::cout << "Invalid connectivity type selected. Using default IP"
+                        << std::endl;
+                }
+            }
+            else
+            {
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
+            }
+        }
+        catch(std::exception& e)
+        {
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
+        }
+    }
+    else
+    {
+        printUsage();
+        std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
+    }
+
     // Create PlatformConfig object
     PlatformConfig cfg {
         OC::ServiceType::InProc,
@@ -301,10 +346,10 @@ int main(int argc, char* argv[]) {
     try
     {
         // Find all resources
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.garage";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.garage";
 
         OCPlatform::findResource("", requestURI.str(),
-                OC_ALL, &foundResource);
+                connectivityType, &foundResource);
 
         std::cout<< "Finding Resource... " <<std::endl;
 
index 89c5a61..99c6f16 100644 (file)
@@ -171,7 +171,7 @@ bool isResourceReady()
 int main(int argc, char* argv[])
 {
     ostringstream requestURI;
-    requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=a.collection";
+    requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=a.collection";
 
     PlatformConfig config
     { OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos };
@@ -185,7 +185,7 @@ int main(int argc, char* argv[])
         string resourceTypeName = "a.collection";
 
         OCPlatform::findResource("", requestURI.str(),
-                                 OC_ALL, &foundResource);
+                                 CT_DEFAULT, &foundResource);
 
         //Non-intensive block until foundResource callback is called by OCPlatform
         //and onGet gets resource.
index c4b069d..fd32467 100644 (file)
@@ -33,6 +33,12 @@ namespace PH = std::placeholders;
 OCResourceHandle resourceHandle;
 std::vector< OCResourceHandle > resourceHandleVector;
 
+static void printUsage()
+{
+    std::cout<<"Usage: groupclient <0|1>\n";
+    std::cout<<"ConnectivityType: Default \n";
+    std::cout<<"ConnectivityType 0: IP\n";
+}
 void foundResource(std::shared_ptr< OCResource > resource)
 {
 
@@ -80,6 +86,43 @@ int main(int argc, char* argv[])
 {
     ostringstream requestURI;
 
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
+
+    if(argc == 2)
+    {
+        try
+        {
+            std::size_t inputValLen;
+            int optionSelected = stoi(argv[1], &inputValLen);
+
+            if(inputValLen == strlen(argv[1]))
+            {
+                if(optionSelected == 0)
+                {
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
+                }
+                else
+                {
+                    std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
+                }
+            }
+            else
+            {
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
+            }
+        }
+        catch(exception& e)
+        {
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
+        }
+    }
+    else
+    {
+        printUsage();
+
+    }
+
     PlatformConfig config
     { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
 
@@ -100,10 +143,10 @@ int main(int argc, char* argv[])
 
         cout << "registerResource is called." << endl;
 
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
 
         OCPlatform::findResource("", requestURI.str(),
-                                 OC_ALL, &foundResource);
+                                 connectivityType, &foundResource);
 
         OCPlatform::bindInterfaceToResource(resourceHandle, GROUP_INTERFACE);
         OCPlatform::bindInterfaceToResource(resourceHandle, DEFAULT_INTERFACE);
diff --git a/resource/examples/oic_svr_db_client.json b/resource/examples/oic_svr_db_client.json
new file mode 100755 (executable)
index 0000000..17dc43f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MjIyMjIyMjIyMjIyMjIyMg==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MTExMTExMTExMTExMTExMQ==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
diff --git a/resource/examples/oic_svr_db_server.json b/resource/examples/oic_svr_db_server.json
new file mode 100755 (executable)
index 0000000..0a8cebe
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        },
+        {
+            "sub": "Kg==",
+            "rsrc": ["/a/light"],
+            "perms": 6,
+            "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+        }
+       ],
+       "pstat":        {
+               "isop": true,
+               "deviceid":     "ZGV2aWNlaWQAAAAAABhanw==",
+               "ch": 0,
+               "cm":   0,
+               "tm":   0,
+               "om":   3,
+               "sm":   [3]
+       },
+       "doxm": {
+               "oxm":  [0],
+               "oxmsel": 0,
+               "owned": true,
+               "deviceid":     "MTExMTExMTExMTExMTExMQ==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index 305bfe5..3755b57 100644 (file)
@@ -35,7 +35,7 @@ std::shared_ptr<OCResource> curResource;
 std::mutex resourceLock;
 static int TEST_CASE = 0;
 
-static OCConnectivityType connectivityType = OC_IPV4;
+static OCConnectivityType connectivityType = CT_ADAPTER_IP;
 
 /**
  * List of methods that can be inititated from the client
@@ -63,9 +63,8 @@ void printUsage()
               << std::endl;
     std::cout << "-t 6 : Discover Resources and Initiate Multicast Presence with two Filters"
             << std::endl;
-    std::cout<<"ConnectivityType: Default IPv4" << std::endl;
-    std::cout << "-c 0 : Send message with IPv4" << std::endl;
-    std::cout << "-c 1 : Send message with IPv6" << std::endl;
+    std::cout<<"ConnectivityType: Default IP" << std::endl;
+    std::cout << "-c 0 : Send message with IP" << std::endl;
 }
 
 // Callback to presence
@@ -221,26 +220,18 @@ int main(int argc, char* argv[]) {
                     {
                         if(optionSelected == 0)
                         {
-                            connectivityType = OC_IPV4;
-                        }
-                        else if(optionSelected == 1)
-                        {
-                            // TODO: re-enable IPv4/IPv6 command line selection when IPv6
-                            // is supported
-                            //connectivityType = OC_IPV6;
-                            connectivityType = OC_IPV4;
-                            std::cout << "IPv6 not currently supported. Using default IPv4"
-                                    << std::endl;
+                            std::cout << "Using IP."<< std::endl;
+                            connectivityType = CT_ADAPTER_IP;
                         }
                         else
                         {
-                            std::cout << "Invalid connectivity type selected. Using default IPv4"
+                            std::cout << "Invalid connectivity type selected. Using default IP"
                                 << std::endl;
                         }
                     }
                     else
                     {
-                        std::cout << "Invalid connectivity type selected. Using default IPv4"
+                        std::cout << "Invalid connectivity type selected. Using default IP"
                             << std::endl;
                     }
                     break;
@@ -252,7 +243,7 @@ int main(int argc, char* argv[]) {
     }
     catch(std::exception& )
     {
-        std::cout << "Invalid input argument. Using IPv4 as connectivity type"
+        std::cout << "Invalid input argument. Using IP as connectivity type"
             << std::endl;
     }
 
@@ -340,10 +331,10 @@ int main(int argc, char* argv[]) {
         else
         {
             // Find all resources
-            requestURI << OC_MULTICAST_DISCOVERY_URI;
+            requestURI << OC_RSRVD_WELL_KNOWN_URI;
 
             result = OCPlatform::findResource("", requestURI.str(),
-                    OC_ALL, &foundResource);
+                    CT_DEFAULT, &foundResource);
             if(result == OC_STACK_OK)
             {
                 std::cout << "Finding Resource... " << std::endl;
index fdba60d..2765dfe 100644 (file)
@@ -41,6 +41,12 @@ int observe_count()
     return ++oc;
 }
 
+static void printUsage()
+{
+    std::cout << "Usage roomclient <0|1>" << std::endl;
+    std::cout<<"connectivityType: Default" << std::endl;
+    std::cout << "connectivityType 0: IP" << std::endl;
+}
 // Forward declaration
 void putRoomRepresentation(std::shared_ptr<OCResource> resource);
 void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
@@ -215,7 +221,6 @@ void foundResource(std::shared_ptr<OCResource> resource)
     }
     catch(std::exception& e)
     {
-        std::cerr << "Exception in foundResource: "<< e.what() <<std::endl;
         //log(e.what());
     }
 }
@@ -224,6 +229,41 @@ int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
 
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
+    if(argc == 2)
+    {
+        try
+        {
+            std::size_t inputValLen;
+            int optionSelected = std::stoi(argv[1], &inputValLen);
+
+            if(inputValLen == strlen(argv[1]))
+            {
+                if(optionSelected == 0)
+                {
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
+                }
+                else
+                {
+                    std::cout << "Invalid connectivity type selected. Using default IP"<< std::endl;
+                }
+            }
+            else
+            {
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
+            }
+        }
+        catch(std::exception& e)
+        {
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "Default input argument. Using IP as Default connectivity type" << std::endl;
+        printUsage();
+    }
 
     // Create PlatformConfig object
     PlatformConfig cfg {
@@ -239,9 +279,9 @@ int main(int argc, char* argv[]) {
     try
     {
         // Find all resources
-        requestURI << OC_MULTICAST_DISCOVERY_URI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI;
 
-        OCPlatform::findResource("", requestURI.str(), OC_ALL, &foundResource);
+        OCPlatform::findResource("", requestURI.str(), connectivityType, &foundResource);
         std::cout<< "Finding Resource... " <<std::endl;
 
         // A condition variable will free the mutex it is given, then do a non-
index e06d731..bb7620c 100644 (file)
@@ -412,16 +412,21 @@ void checkObserverValue(int value)
     }
 }
 
+static FILE* client_open(const char *path, const char *mode)
+{
+    return fopen("./oic_svr_db_client.json", mode);
+}
+
 int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
-
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
     try
     {
         printUsage();
         if (argc == 1)
         {
-            std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IPv4===>\n\n";
+            std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
         }
         else if (argc == 2)
         {
@@ -442,10 +447,11 @@ int main(int argc, char* argv[]) {
     // Create PlatformConfig object
     PlatformConfig cfg {
         OC::ServiceType::InProc,
-        OC::ModeType::Client,
+        OC::ModeType::Both,
         "0.0.0.0",
         0,
-        OC::QualityOfService::LowQos
+        OC::QualityOfService::LowQos,
+        &ps
     };
 
     OCPlatform::Configure(cfg);
@@ -454,17 +460,17 @@ int main(int argc, char* argv[]) {
         // makes it so that all boolean values are printed as 'true/false' in this stream
         std::cout.setf(std::ios::boolalpha);
         // Find all resources
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
 
         OCPlatform::findResource("", requestURI.str(),
-                OC_ALL, &foundResource);
+                CT_DEFAULT, &foundResource);
         std::cout<< "Finding Resource... " <<std::endl;
 
         // Find resource is done twice so that we discover the original resources a second time.
         // These resources will have the same uniqueidentifier (yet be different objects), so that
         // we can verify/show the duplicate-checking code in foundResource(above);
         OCPlatform::findResource("", requestURI.str(),
-                OC_ALL, &foundResource);
+                CT_DEFAULT, &foundResource);
         std::cout<< "Finding Resource for second time..." << std::endl;
 
         // A condition variable will free the mutex it is given, then do a non-
index af0bea4..e4d2f0b 100644 (file)
@@ -370,35 +370,57 @@ void foundResource(std::shared_ptr<OCResource> resource)
 void PrintUsage()
 {
     std::cout << std::endl;
-    std::cout << "Usage : simpleclientHQ <ObserveType>" << std::endl;
+    std::cout << "Usage : simpleclientHQ <ObserveType> <ConnectivityType>" << std::endl;
     std::cout << "   ObserveType : 1 - Observe" << std::endl;
     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
+    std::cout << "   ConnectivityType: Default IP" << std::endl;
+    std::cout << "   ConnectivityType : 0 - IP"<< std::endl;
 }
 
 int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
 
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
     try
     {
         if (argc == 1)
         {
             OBSERVE_TYPE_TO_USE = ObserveType::Observe;
         }
-        else if (argc == 2)
+        else if (argc ==2 || argc==3)
         {
             int value = std::stoi(argv[1]);
             if (value == 1)
-            {
                 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
-            }
             else if (value == 2)
-            {
                 OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
-            }
             else
-            {
                 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+
+            if(argc == 3)
+            {
+                std::size_t inputValLen;
+                int optionSelected = std::stoi(argv[2], &inputValLen);
+
+                if(inputValLen == strlen(argv[2]))
+                {
+                    if(optionSelected == 0)
+                    {
+                        std::cout << "Using IP."<< std::endl;
+                        connectivityType = CT_ADAPTER_IP;
+                    }
+                    else
+                    {
+                        std::cout << "Invalid connectivity type selected. Using default IP"
+                            << std::endl;
+                    }
+                }
+                else
+                {
+                    std::cout << "Invalid connectivity type selected. Using default IP"
+                            << std::endl;
+                }
             }
         }
         else
@@ -407,11 +429,14 @@ int main(int argc, char* argv[]) {
             return -1;
         }
     }
-    catch(std::exception&)
+    catch(std::exception& e)
     {
-        std::cout << "Invalid input argument. Using Observe as observe type" << std::endl;
+        std::cout << "Invalid input argument." << std::endl;
+        PrintUsage();
+        return -1;
     }
 
+
     // Create PlatformConfig object
     PlatformConfig cfg {
         OC::ServiceType::InProc,
@@ -426,17 +451,17 @@ int main(int argc, char* argv[]) {
     try
     {
         // Find all resources
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
 
         OCPlatform::findResource("", requestURI.str(),
-                OC_ALL, &foundResource, OC::QualityOfService::LowQos);
+                connectivityType, &foundResource, OC::QualityOfService::LowQos);
         std::cout<< "Finding Resource... " <<std::endl;
 
         // Find resource is done twice so that we discover the original resources a second time.
         // These resources will have the same uniqueidentifier (yet be different objects), so that
         // we can verify/show the duplicate-checking code in foundResource(above);
         OCPlatform::findResource("", requestURI.str(),
-                OC_ALL, &foundResource, OC::QualityOfService::LowQos);
+                connectivityType, &foundResource, OC::QualityOfService::LowQos);
         std::cout<< "Finding Resource for second time... " <<std::endl;
 
         // A condition variable will free the mutex it is given, then do a non-
index f4282a3..7ed7576 100644 (file)
 #include "OCApi.h"
 using namespace OC;
 
+static void printUsage()
+{
+    std::cout<< "    Usage simpleclientserver <0|1>" << std::endl;
+    std::cout<< "    ConnectivityType: Default IP" << std::endl;
+    std::cout << "   ConnectivityType : 0 - IP" << std::endl;
+}
 
 class ClientWorker
 {
@@ -147,12 +153,12 @@ public:
     void start()
     {
         std::ostringstream requestURI;
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.foo";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.foo";
 
         std::cout<<"Starting Client find:"<<std::endl;
         FindCallback f (std::bind(&ClientWorker::foundResource, this, std::placeholders::_1));
         std::cout<<"result:" <<
-        OCPlatform::findResource("", requestURI.str(), OC_ALL, f)
+        OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, f)
         << std::endl;
 
         std::cout<<"Finding Resource..."<<std::endl;
@@ -296,7 +302,7 @@ struct FooResource
 
 int main(int argc, char* argv[])
 {
-    OCConnectivityType connectivityType = OC_IPV4;
+    OCConnectivityType connectivityType = CT_ADAPTER_IP;
 
     if(argc == 2)
     {
@@ -309,37 +315,27 @@ int main(int argc, char* argv[])
             {
                 if(optionSelected == 0)
                 {
-                    connectivityType = OC_IPV4;
-                }
-                else if(optionSelected == 1)
-                {
-                    // TODO: re-enable IPv4/IPv6 command line selection when IPv6 is supported
-                    // connectivityType = OC_IPV6;
-                    connectivityType = OC_IPV4;
-                    std::cout << "IPv6 not currently supported. Using default IPv4" << std::endl;
+                    std::cout << "Using IP."<< std::endl;
+                    connectivityType = CT_ADAPTER_IP;
                 }
                 else
                 {
-                    std::cout << "Invalid connectivity type selected. Using default IPv4"
-                    << std::endl;
+                    std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
                 }
             }
             else
             {
-                std::cout << "Invalid connectivity type selected. Using default IPv4" << std::endl;
+                std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
             }
         }
         catch(std::exception& )
         {
-            std::cout << "Invalid input argument. Using IPv4 as connectivity type" << std::endl;
+            std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
         }
     }
     else
     {
-        std::cout<< "Usage simpleclientserver <ConnectivityType(0|1)>" << std::endl;
-        std::cout<< "    ConnectivityType: Default IPv4" << std::endl;
-        std::cout << "   ConnectivityType : 0 - IPv4" << std::endl;
-        std::cout << "   ConnectivityType : 1 - IPv6 (not currently supported)" << std::endl;
+        printUsage();
     }
 
     PlatformConfig cfg {
index f52588b..d89faf2 100644 (file)
@@ -482,10 +482,15 @@ void PrintUsage()
     std::cout << "    4 - Non-secure resource, GET slow response, notify all observers\n";
 }
 
+static FILE* client_open(const char *path, const char *mode)
+{
+    return fopen("./oic_svr_db_server.json", mode);
+}
 
 int main(int argc, char* argv[])
 {
     PrintUsage();
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
 
     if (argc == 1)
     {
@@ -527,7 +532,8 @@ int main(int argc, char* argv[])
         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
-        OC::QualityOfService::LowQos
+        OC::QualityOfService::LowQos,
+        &ps
     };
 
     OCPlatform::Configure(cfg);
index e1332c8..b43d418 100644 (file)
@@ -279,7 +279,7 @@ void client1()
 {
     std::cout << "in client1\n";
     std::cout<<"result1:" << OCPlatform::findResource("", requestURI.str(),
-            OC_ALL, foundResource1)<< std::endl;
+            CT_DEFAULT, foundResource1)<< std::endl;
 
     // A condition variable will free the mutex it is given, then do a non-
     // intensive block until 'notify' is called on it.  In this case, since we
@@ -296,7 +296,7 @@ void client2()
     std::cout << "in client2\n";
     std::cout<<"result2:" << OCPlatform::findResource("",
                 requestURI.str(),
-                OC_ALL, foundResource2)<< std::endl;
+                CT_DEFAULT, foundResource2)<< std::endl;
 
     // A condition variable will free the mutex it is given, then do a non-
     // intensive block until 'notify' is called on it.  In this case, since we
@@ -330,7 +330,7 @@ void server()
 int main(int argc, char* argv[])
 {
 
-    requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.foo";
+    requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.foo";
 
     PlatformConfig cfg {
         OC::ServiceType::InProc,
index 7c31bde..272cd44 100644 (file)
@@ -41,48 +41,63 @@ namespace OC
         {}
 
         virtual OCStackResult ListenForResource(const std::string& serviceUrl,
-                        const std::string& resourceType, OCConnectivityType connectivityType,
+                        const std::string& resourceType,
+                        OCConnectivityType connectivityType,
                         FindCallback& callback,
                         QualityOfService QoS) = 0;
 
         virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
-                        const std::string& deviceURI, OCConnectivityType connectivityType,
+                        const std::string& deviceURI,
+                        OCConnectivityType connectivityType,
                         FindDeviceCallback& callback,
                         QualityOfService QoS) = 0;
 
-        virtual OCStackResult GetResourceRepresentation(const std::string& host,
-                        const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult GetResourceRepresentation(
+                        const OCDevAddr& devAddr,
+                        const std::string& uri,
                         const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
                         GetCallback& callback, QualityOfService QoS)=0;
 
-        virtual OCStackResult PutResourceRepresentation(const std::string& host,
-                        const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PutResourceRepresentation(
+                        const OCDevAddr& devAddr,
+                        const std::string& uri,
                         const OCRepresentation& rep, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
                         PutCallback& callback, QualityOfService QoS) = 0;
 
-        virtual OCStackResult PostResourceRepresentation(const std::string& host,
-                        const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PostResourceRepresentation(
+                        const OCDevAddr& devAddr,
+                        const std::string& uri,
                         const OCRepresentation& rep, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
                         PostCallback& callback, QualityOfService QoS) = 0;
 
-        virtual OCStackResult DeleteResource(const std::string& host, const std::string& uri,
-                        OCConnectivityType connectivityType, const HeaderOptions& headerOptions,
+        virtual OCStackResult DeleteResource(
+                        const OCDevAddr& devAddr,
+                        const std::string& uri,
+                        const HeaderOptions& headerOptions,
                         DeleteCallback& callback, QualityOfService QoS) = 0;
 
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
-                        const std::string& host, const std::string& uri,
-                        OCConnectivityType connectivityType, const QueryParamsMap& queryParams,
+        virtual OCStackResult ObserveResource(
+                        ObserveType observeType, OCDoHandle* handle,
+                        const OCDevAddr& devAddr,
+                        const std::string& uri,
+                        const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions, ObserveCallback& callback,
                         QualityOfService QoS)=0;
 
-        virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
-            const std::string& uri, const HeaderOptions& headerOptions, QualityOfService QoS)=0;
+        virtual OCStackResult CancelObserveResource(
+                        OCDoHandle handle,
+                        const std::string& host,
+                        const std::string& uri,
+                        const HeaderOptions& headerOptions,
+                        QualityOfService QoS)=0;
 
-        virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
-                        const std::string& resourceType, OCConnectivityType connectivityType,
+        virtual OCStackResult SubscribePresence(OCDoHandle* handle,
+                        const std::string& host,
+                        const std::string& resourceType,
+                        OCConnectivityType connectivityType,
                         SubscribeCallback& presenceHandler)=0;
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle) =0;
index ef45485..66f2007 100644 (file)
@@ -57,15 +57,6 @@ namespace OC
         virtual OCStackResult registerPlatformInfo(
                     const OCPlatformInfo PlatformInfo) = 0;
 
-        virtual OCStackResult registerResourceWithHost(
-                    OCResourceHandle& resourceHandle,
-                    std::string& resourceHOST,
-                    std::string& resourceURI,
-                    const std::string& resourceTypeName,
-                    const std::string& resourceInterface,
-                    EntityHandler& entityHandler,
-                    uint8_t resourceProperty) = 0;
-
         virtual OCStackResult unregisterResource(
                     const OCResourceHandle& resourceHandle) = 0;
         virtual OCStackResult bindTypeToResource(
index 9b7b95c..f6b7764 100644 (file)
@@ -27,7 +27,6 @@
 #include <iostream>
 
 #include <OCApi.h>
-#include <ocstack.h>
 #include <IClientWrapper.h>
 #include <InitializeException.h>
 #include <ResourceInitException.h>
@@ -39,38 +38,48 @@ namespace OC
         struct GetContext
         {
             GetCallback callback;
+            GetContext(GetCallback cb) : callback(cb){}
         };
 
         struct SetContext
         {
             PutCallback callback;
+            SetContext(PutCallback cb) : callback(cb){}
         };
 
         struct ListenContext
         {
             FindCallback callback;
             std::weak_ptr<IClientWrapper> clientWrapper;
+
+            ListenContext(FindCallback cb, std::weak_ptr<IClientWrapper> cw)
+                : callback(cb), clientWrapper(cw){}
         };
 
         struct DeviceListenContext
         {
             FindDeviceCallback callback;
             IClientWrapper::Ptr clientWrapper;
+            DeviceListenContext(FindDeviceCallback cb, IClientWrapper::Ptr cw)
+                    : callback(cb), clientWrapper(cw){}
         };
 
         struct SubscribePresenceContext
         {
             SubscribeCallback callback;
+            SubscribePresenceContext(SubscribeCallback cb) : callback(cb){}
         };
 
         struct DeleteContext
         {
             DeleteCallback callback;
+            DeleteContext(DeleteCallback cb) : callback(cb){}
         };
 
         struct ObserveContext
         {
             ObserveCallback callback;
+            ObserveContext(ObserveCallback cb) : callback(cb){}
         };
     }
 
@@ -84,42 +93,55 @@ namespace OC
         virtual ~InProcClientWrapper();
 
         virtual OCStackResult ListenForResource(const std::string& serviceUrl,
-            const std::string& resourceType, OCConnectivityType connectivityType,
+            const std::string& resourceType, OCConnectivityType transportFlags,
             FindCallback& callback, QualityOfService QoS);
 
         virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
-            const std::string& deviceURI, OCConnectivityType connectivityType,
+            const std::string& deviceURI, OCConnectivityType transportFlags,
             FindDeviceCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult GetResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult GetResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
             GetCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult PutResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PutResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, PutCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult PostResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PostResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, PostCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult DeleteResource(const std::string& host, const std::string& uri,
-            OCConnectivityType connectivityType, const HeaderOptions& headerOptions,
+        virtual OCStackResult DeleteResource(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
+            const HeaderOptions& headerOptions,
             DeleteCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
-            const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult ObserveResource(
+            ObserveType observeType, OCDoHandle* handle,
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
             ObserveCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
-            const std::string& uri, const HeaderOptions& headerOptions, QualityOfService QoS);
-
-        virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
-            const std::string& resourceType, OCConnectivityType connectivityType,
+        virtual OCStackResult CancelObserveResource(
+            OCDoHandle handle,
+            const std::string& host,
+            const std::string& uri,
+            const HeaderOptions& headerOptions, QualityOfService QoS);
+
+        virtual OCStackResult SubscribePresence(
+            OCDoHandle *handle,
+            const std::string& host,
+            const std::string& resourceType,
+            OCConnectivityType transportFlags,
             SubscribeCallback& presenceHandler);
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle);
@@ -127,7 +149,7 @@ namespace OC
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
-        std::string assembleSetResourcePayload(const OCRepresentation& attributes);
+        OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes);
         OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[],
            const HeaderOptions& headerOptions);
         std::thread m_listeningThread;
index 1a9192a..8eb78e3 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <thread>
 #include <mutex>
-#include <ocstack.h>
 
 #include <IServerWrapper.h>
 
@@ -51,15 +50,6 @@ namespace OC
         virtual OCStackResult registerPlatformInfo(
                     const OCPlatformInfo PlatformInfo);
 
-        virtual OCStackResult registerResourceWithHost(
-                    OCResourceHandle& resourceHandle,
-                    std::string& resourceHOST,
-                    std::string& resourceURI,
-                    const std::string& resourceTypeName,
-                    const std::string& resourceInterface,
-                    EntityHandler& entityHandler,
-                    uint8_t resourceProperty);
-
         virtual OCStackResult unregisterResource(
                     const OCResourceHandle& resourceHandle);
 
index f87972f..bc5a3d2 100644 (file)
@@ -22,7 +22,6 @@
 #define _INITIALIZE_EXCEPTION_H_
 
 #include <stdexcept>
-#include <ocstack.h>
 #include "StringConstants.h"
 
 namespace OC
old mode 100644 (file)
new mode 100755 (executable)
index 8087a4e..d38eb47
@@ -109,40 +109,63 @@ namespace OC
     *  Data structure to provide the configuration.
     *  ServiceType: indicate InProc or OutOfProc
     *  ModeType   : indicate whether we want to do server, client or both
-    *  ipAddress  : ip address of server.
-    *               if you specify 0.0.0.0 : it listens on any interface.
-    *  port       : port of server.
-    *             : if you specify 0 : next available random port is used.
-    *             : if you specify 5683 : client discovery can work even if they don't specify port.
-    *  QoS        : Quality of Service : CONFIRMABLE or NON CONFIRMABLE.
+    *  ServerConnectivity : default flags for server
+    *  ClientConnectivity : default flags for client
+    *  QoS        : indicate Quality of Service : LowQos, MidQos,HighQos and NaQos(No quality Defined).
+    *  ps         : persistant storage Handler structure (open/read/write/close/unlink)
     */
     struct PlatformConfig
     {
         ServiceType                serviceType;
         ModeType                   mode;
-        std::string                ipAddress;
-        uint16_t                   port;
-
+        OCConnectivityType         serverConnectivity;
+        OCConnectivityType         clientConnectivity;
+        std::string                ipAddress;   // not used
+        uint16_t                   port;        // not used
         QualityOfService           QoS;
+        OCPersistentStorage        *ps;
 
         public:
             PlatformConfig()
                 : serviceType(ServiceType::InProc),
                 mode(ModeType::Both),
+                serverConnectivity(CT_DEFAULT),
+                clientConnectivity(CT_DEFAULT),
                 ipAddress("0.0.0.0"),
                 port(0),
-                QoS(QualityOfService::NaQos)
+                QoS(QualityOfService::NaQos),
+                ps(nullptr)
+        {}
+            PlatformConfig(const ServiceType serviceType_,
+            const ModeType mode_,
+            OCConnectivityType serverConnectivity_,
+            OCConnectivityType clientConnectivity_,
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr)
+                : serviceType(serviceType_),
+                mode(mode_),
+                serverConnectivity(serverConnectivity_),
+                clientConnectivity(clientConnectivity_),
+                ipAddress(""),
+                port(0),
+                QoS(QoS_),
+                ps(ps_)
         {}
+            // for backward compatibility
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             const std::string& ipAddress_,
             const uint16_t port_,
-            const QualityOfService QoS_)
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr)
                 : serviceType(serviceType_),
                 mode(mode_),
+                serverConnectivity(CT_DEFAULT),
+                clientConnectivity(CT_DEFAULT),
                 ipAddress(ipAddress_),
                 port(port_),
-                QoS(QoS_)
+                QoS(QoS_),
+                ps(ps_)
         {}
     };
 
@@ -194,7 +217,7 @@ namespace OC
     const std::string BATCH_INTERFACE = "oic.if.b";
 
     // Used in GET, PUT, POST methods on links to other remote resources of a group.
-    const std::string GROUP_INTERFACE = "oc.mi.grp";
+    const std::string GROUP_INTERFACE = "oic.mi.grp";
 
 
     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
index 2852202..849bacd 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <stdexcept>
 #include <string>
-#include <ocstack.h>
+#include <octypes.h>
 
 namespace OC {
 
index 53209b9..83622bb 100644 (file)
@@ -130,7 +130,7 @@ namespace OC
         *
         * @param host - Host IP Address. If null or empty, Multicast is performed.
         * @param deviceURI - Uri containing address to the virtual device in C Stack
-                                ("/oc/core/d")
+                                ("/oic/d")
         * @param connectivityType - @ref OCConnectivityType type of connectivity indicating the
         *                           interface. Example: OC_WIFI, OC_ETHERNET, OC_ALL
         * @param deviceInfoHandler - device discovery callback
@@ -182,7 +182,7 @@ namespace OC
         * Above relative URI will be prepended (by core) with a host IP + namespace "oc"
         * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
         * Example, a relative URI: 'a/light' will result in a fully qualified URI:
-        *   //192.168.1.1/oc/a/light"
+        *   //192.168.1.1/oic/a/light"
         * First parameter can take a relative URI and core will take care of preparing the fully
         * qualified URI OR
         * first parameter can take fully qualified URI and core will take that as is for further
@@ -470,7 +470,8 @@ namespace OC
         * @param interfaces - a collection of interfaces that the resource supports/implements
         * @return OCResource::Ptr - a shared pointer to the new resource object
         */
-        OCResource::Ptr constructResourceObject(const std::string& host, const std::string& uri,
+        OCResource::Ptr constructResourceObject(const std::string& host,
+                        const std::string& uri,
                         OCConnectivityType connectivityType, bool isObservable,
                         const std::vector<std::string>& resourceTypes,
                         const std::vector<std::string>& interfaces);
index 83c17bc..7b23a56 100644 (file)
@@ -98,7 +98,7 @@ namespace OC
          *
          * @param host - Host IP Address. If null or empty, Multicast is performed.
          * @param resourceURI - Uri containing address to the virtual device in C Stack
-         *                       ("/oc/core/d")
+         *                       ("/oic/d")
          *
          * @param QualityOfService the quality of communication
          *
@@ -143,7 +143,7 @@ namespace OC
         * Above relative URI will be prepended (by core) with a host IP + namespace "oc"
         * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
         * Example, a relative URI: 'a/light' will result in a fully qualified URI:
-        *   //192.168.1.1/oc/a/light"
+        *   //192.168.1.1/oic/a/light"
         * First parameter can take a relative URI and core will take care of preparing the fully
         * qualified URI OR
         * first parameter can take fully qualified URI and core will take that as is for further
index 534bb5a..b89b9fb 100644 (file)
 
 #include <OCException.h>
 
-namespace cereal
-{
-    class access;
-}
-
 namespace OC
 {
 
@@ -62,24 +57,18 @@ namespace OC
         DefaultChild
     };
 
-    // The consumer requires resource info to be printed in 2 different ways, both with the "oc":[]
-    // and without.  This enum is used to differentiate between the two situations.  When the
-    // serialize is called with Include OC, we encode OC, otherwise we skip it and return just the
-    // contents of the array.
-    enum class OCInfoFormat
-    {
-        IncludeOC,
-        ExcludeOC
-    };
-
     class MessageContainer
     {
         public:
-            void setJSONRepresentation(const std::string& payload);
+            void setPayload(const OCPayload* rep);
+
+            void setPayload(const OCDevicePayload* rep);
 
-            void setJSONRepresentation(const char* payload);
+            void setPayload(const OCPlatformPayload* rep);
 
-            std::string getJSONRepresentation(OCInfoFormat f) const;
+            void setPayload(const OCRepPayload* rep);
+
+            OCRepPayload* getPayload() const;
 
             const std::vector<OCRepresentation>& representations() const;
 
@@ -119,7 +108,7 @@ namespace OC
 
             virtual ~OCRepresentation(){}
 
-            std::string getJSONRepresentation() const;
+            OCRepPayload* getPayload() const;
 
             void addChild(const OCRepresentation&);
 
@@ -129,6 +118,8 @@ namespace OC
 
             void setChildren(const std::vector<OCRepresentation>& children);
 
+            void setUri(const char* uri);
+
             void setUri(const std::string& uri);
 
             std::string getUri() const;
@@ -137,10 +128,14 @@ namespace OC
 
             void setResourceTypes(const std::vector<std::string>& resourceTypes);
 
+            void addResourceType(const std::string& str);
+
             const std::vector<std::string>& getResourceInterfaces() const;
 
             void setResourceInterfaces(const std::vector<std::string>& resourceInterfaces);
 
+            void addResourceInterface(const std::string& str);
+
             bool emptyData() const;
 
             int numberOfAttributes() const;
@@ -389,8 +384,16 @@ namespace OC
             const AttributeItem operator[](const std::string& key) const;
         private:
             friend class OCResourceResponse;
-            friend class cereal::access;
-
+            friend class MessageContainer;
+
+            template<typename T>
+            void payload_array_helper(const OCRepPayloadValue* pl, size_t depth);
+            template<typename T>
+            T payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl);
+            void setPayload(const OCRepPayload* payload);
+            void setPayloadArray(const OCRepPayloadValue* pl);
+            void getPayloadArray(OCRepPayload* payload,
+                    const OCRepresentation::AttributeItem& item) const;
             // the root node has a slightly different JSON version
             // based on the interface type configured in ResourceResponse.
             // This allows ResourceResponse to set it, so that the save function
@@ -415,25 +418,9 @@ namespace OC
                     m_interfaces(interfaces)
                     {}*/
                 private:
-                    friend class cereal::access;
-                    template <class Archive>
-                    void save(Archive& ar) const;
-
-                    template<class Archive>
-                    void load(Archive& ar);
-
                     std::vector<std::string>& m_types;
                     std::vector<std::string>& m_interfaces;
             };
-            template<class Archive, class Val>
-            static void optional_load(Archive& ar, Val&& v);
-
-            template<class Archive>
-            void save(Archive& ar) const;
-
-            template<class Archive>
-            void load(Archive& ar);
-
         private:
             std::string m_uri;
             std::vector<OCRepresentation> m_children;
index bc0109c..a648000 100644 (file)
@@ -441,7 +441,7 @@ namespace OC
 
         /**
         * Function to get the connectivity type of this resource
-        * @return uint8_t connectivity type
+        * @return enum connectivity type (flags and adapter)
         */
         OCConnectivityType connectivityType() const;
 
@@ -504,11 +504,12 @@ 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;
-        std::string m_host;
-        OCConnectivityType m_connectivityType;
+        OCDevAddr m_devAddr;
+        bool m_useHostString;
         bool m_isObservable;
         bool m_isCollection;
         std::vector<std::string> m_resourceTypes;
@@ -518,11 +519,18 @@ namespace OC
         HeaderOptions m_headerOptions;
 
     private:
-        OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
-            const std::string& uri, const std::string& serverId,
-            OCConnectivityType m_connectivityType, bool observable,
-            const std::vector<std::string>& resourceTypes,
-            const std::vector<std::string>& interfaces);
+        OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                    const OCDevAddr& devAddr, const std::string& uri,
+                    const std::string& serverId, bool observable,
+                    const std::vector<std::string>& resourceTypes,
+                    const std::vector<std::string>& interfaces);
+
+        OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                    const std::string& host, const std::string& uri,
+                    const std::string& serverId,
+                    OCConnectivityType connectivityType, bool observable,
+                    const std::vector<std::string>& resourceTypes,
+                    const std::vector<std::string>& interfaces);
     };
 
 } // namespace OC
index f4b8f84..962ddb2 100644 (file)
@@ -174,7 +174,7 @@ namespace OC
             m_requestType = requestType;
         }
 
-        void setPayload(const std::string& requestPayload);
+        void setPayload(OCPayload* requestPayload);
 
         void setQueryParams(QueryParamsMap& queryParams)
         {
index c654834..ea863ac 100644 (file)
@@ -174,7 +174,7 @@ namespace OC
     private:
         friend class InProcServerWrapper;
 
-        std::string getPayload() const
+        OCRepPayload* getPayload() const
         {
             MessageContainer inf;
             OCRepresentation first(m_representation);
@@ -215,7 +215,7 @@ namespace OC
 
             }
 
-            return inf.getJSONRepresentation(OCInfoFormat::ExcludeOC);
+            return inf.getPayload();
         }
     public:
 
index 898fde7..23cccc2 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <cereal/cereal.hpp>
-#include <cereal/types/memory.hpp>
-#include <cereal/types/vector.hpp>
-#include <cereal/archives/json.hpp>
-
 #include <StringConstants.h>
+#include "ocpayload.h"
+#include "ocrandom.h"
 
 namespace OC
 {
     class ListenOCContainer
     {
         private:
-        enum class OCSecureType
-        {
-            IPv4Secure,
-            IPv4
-        };
+            static std::vector<std::string> StringLLToVector(OCStringLL* ll)
+            {
+                std::vector<std::string> strs;
+                while(ll)
+                {
+                    strs.push_back(ll->value);
+                    ll = ll->next;
+                }
+                return strs;
+            }
 
-        class ListenResourceContainer
-        {
-            class ListenResourcePropertiesContainer
+        public:
+            ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+                    OCDevAddr& devAddr, OCDiscoveryPayload* payload)
+                    : m_clientWrapper(cw), m_devAddr(devAddr)
             {
-                friend class cereal::access;
-                friend class ListenResourceContainer;
+                OCResourcePayload* res = payload->resources;
 
-                template<class Archive>
-                void serialize(Archive& ar)
+                while(res)
                 {
-                    try
+                    char uuidString[UUID_STRING_SIZE];
+                    if(OCConvertUuidToString(res->sid, uuidString) != RAND_UUID_OK)
                     {
-                        m_observable=false;
-                        int obsTemp;
-                        ar(cereal::make_nvp(OC::Key::OBSERVABLEKEY, obsTemp));
-                        m_observable = obsTemp != 0;
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        // we swallow this exception, since it means the key
-                        // doesn't exist, allowing these to be optional
-                        ar.setNextName(nullptr);
+                        uuidString[0]= '\0';
                     }
 
-                    try
+                    if (res->secure)
                     {
-                        m_secure = false;
-                        int secureTemp;
-                        ar(cereal::make_nvp(OC::Key::SECUREKEY, secureTemp));
-                        m_secure = secureTemp != 0;
-
-                        m_port = -1;
-                        ar(cereal::make_nvp(OC::Key::PORTKEY, m_port));
+                        m_devAddr.flags =
+                              (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
                     }
-                    catch(cereal::Exception&)
+                    if (res->port != 0)
                     {
-                        ar.setNextName(nullptr);
+                         m_devAddr.port = res->port;
                     }
 
-                    try
-                    {
-                        ar(cereal::make_nvp(OC::Key::RESOURCETYPESKEY,m_resourceTypes));
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        ar.setNextName(nullptr);
-                    }
-                    try
-                    {
-                        ar(cereal::make_nvp(OC::Key::INTERFACESKEY, m_interfaces));
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        ar.setNextName(nullptr);
-                    }
+                    m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                new OC::OCResource(m_clientWrapper, m_devAddr,
+                                    std::string(res->uri),
+                                    std::string(uuidString),
+                                    (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                    StringLLToVector(res->types),
+                                    StringLLToVector(res->interfaces)
+                                    )));
+                    res = res->next;
                 }
 
-                bool m_observable;
-                std::vector<std::string> m_resourceTypes;
-                std::vector<std::string> m_interfaces;
-                bool m_secure;
-                int m_port;
-            };
-
-            public:
-            ListenResourceContainer() : m_loaded(false)
-            {}
-
-            private:
-            friend class cereal::access;
-            friend class ListenOCContainer;
-
-            template <class Archive>
-            void serialize(Archive& ar)
-            {
-                try
-                {
-                    ar(cereal::make_nvp(OC::Key::URIKEY, m_uri));
-                    m_loaded=true;
-                }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-                try
-                {
-                    ar(cereal::make_nvp(OC::Key::SERVERIDKEY, m_serverId));
-                    m_loaded=true;
-                }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-                try
-                {
-                    ar(cereal::make_nvp(OC::Key::PROPERTYKEY, m_props));
-                    m_loaded=true;
-                }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-            }
-
-
-            std::string m_uri;
-            std::string m_serverId;
-            bool m_loaded;
-            ListenResourcePropertiesContainer m_props;
-
-            bool loaded() const
-            {
-                return m_loaded;
-            }
-
-            bool observable() const
-            {
-                return m_props.m_observable;
-            }
-
-            OCSecureType secureType() const
-            {
-                return m_props.m_secure?OCSecureType::IPv4Secure :OCSecureType::IPv4;
-            }
-
-            int port() const
-            {
-                return m_props.m_port;
-            }
-
-            std::vector<std::string> resourceTypes() const
-            {
-                return m_props.m_resourceTypes;
-            }
-
-            std::vector<std::string> interfaces() const
-            {
-                return m_props.m_interfaces;
-            }
-        };
-
-        private:
-            friend class cereal::access;
-            template <class Archive>
-            void serialize(Archive& ar)
-            {
-                std::vector<ListenResourceContainer> resources;
-                ar(resources);
-            }
-        public:
-            ListenOCContainer(std::weak_ptr<IClientWrapper> cw, const OCDevAddr& address,
-                    OCConnectivityType connectivityType, std::stringstream& json):
-                m_clientWrapper(cw), m_address(address), m_connectivityType(connectivityType)
-            {
-                LoadFromJson(json);
             }
 
             const std::vector<std::shared_ptr<OCResource>>& Resources() const
             {
                 return m_resources;
             }
-
         private:
-            std::string ConvertOCAddrToString(OCSecureType sec, int secureport)
-            {
-                uint16_t port;
-                std::ostringstream os;
-
-                if(sec== OCSecureType::IPv4)
-                {
-                    os<<"coap://";
-                }
-                else if(sec == OCSecureType::IPv4Secure)
-                {
-                    os<<"coaps://";
-                }
-                else
-                {
-                    oclog() << "ConvertOCAddrToString():  invalid SecureType"<<std::flush;
-                    throw ResourceInitException(false, false, false, false, false, true);
-                }
-
-                uint8_t a;
-                uint8_t b;
-                uint8_t c;
-                uint8_t d;
-                if(OCDevAddrToIPv4Addr(&m_address, &a, &b, &c, &d) != 0)
-                {
-                    oclog() << "ConvertOCAddrToString(): Invalid Ip"
-                            << std::flush;
-                    throw ResourceInitException(false, false, false, false, false, true);
-                }
-
-                os<<static_cast<int>(a)<<"."<<static_cast<int>(b)
-                        <<"."<<static_cast<int>(c)<<"."<<static_cast<int>(d);
-
-                if(sec == OCSecureType::IPv4Secure && secureport>0 && secureport<=65535)
-                {
-                    port = static_cast<uint16_t>(secureport);
-                }
-                else if(sec == OCSecureType::IPv4 && 0==OCDevAddrToPort(&m_address, &port))
-                {
-                    // nothing to do, this is a successful case
-                }
-                else
-                {
-                    oclog() << "ConvertOCAddrToString() : Invalid Port"
-                            <<std::flush;
-                    throw ResourceInitException(false, false, false, false, true, false);
-                }
-
-                os <<":"<< static_cast<int>(port);
-
-                return os.str();
-            }
-
-            void LoadFromJson(std::stringstream& json)
-            {
-                cereal::JSONInputArchive archive(json);
-
-                std::vector<ListenResourceContainer> resources;
-                archive(cereal::make_nvp(OC::Key::OCKEY, resources));
-
-                m_resources.clear();
-
-                for(const auto& res : resources)
-                {
-                    try
-                    {
-                        if(res.loaded())
-                        {
-                            m_resources.push_back(std::shared_ptr<OCResource>(
-                                new OCResource(m_clientWrapper,
-                                    ConvertOCAddrToString(res.secureType(),res.port()),
-                                    res.m_uri, res.m_serverId, m_connectivityType, res.observable(),
-                                    res.resourceTypes(), res.interfaces())));
-                        }
-
-                    }
-                    catch(ResourceInitException& e)
-                    {
-                        oclog() << "listenCallback(): failed to create resource: " << e.what()
-                                << std::flush;
-                    }
-                }
-            }
             std::vector<std::shared_ptr<OC::OCResource>> m_resources;
             std::weak_ptr<IClientWrapper> m_clientWrapper;
-            OCDevAddr m_address;
-            OCConnectivityType m_connectivityType;
+            OCDevAddr& m_devAddr;
     };
 }
-
diff --git a/resource/include/OicJsonSerializer.hpp b/resource/include/OicJsonSerializer.hpp
deleted file mode 100644 (file)
index 280ac28..0000000
+++ /dev/null
@@ -1,847 +0,0 @@
-/*! \file OicJsonSerializer.hpp
-    \brief JSON input and output archives.
-Note: this has been customized by Intel(R) for usage in the OIC project.
-Nearly the entire file is from Cereal (see copyright notice below) other than specified
-below
-Added:
-#include of AttributeValue Type
-JSONOutputArchive::saveValue() to add JSON null value
-loadAttributeValues to get attribute values out of a map (implemented in OCRepresentation)
-
-*/
-/*
-  Copyright (c) 2014, Randolph Voorhies, Shane Grant
-  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.
-      * Neither the name of cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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 CEREAL_ARCHIVES_JSON_HPP_
-#define CEREAL_ARCHIVES_JSON_HPP_
-
-#include <AttributeValue.h>
-#include <cereal/cereal.hpp>
-#include <cereal/details/util.hpp>
-namespace cereal
-{
-  //! An exception thrown when rapidjson fails an internal assertion
-  /*! @ingroup Utility */
-  struct RapidJSONException : Exception
-  { RapidJSONException( const char * what_ ) : Exception( what_ ) {} };
-}
-
-// Override rapidjson assertions to throw exceptions by default
-#ifndef RAPIDJSON_ASSERT
-#define RAPIDJSON_ASSERT(x) if(!(x)){ \
-  throw ::cereal::RapidJSONException("rapidjson internal assertion failure: " #x); }
-#endif // RAPIDJSON_ASSERT
-
-#include <cereal/external/rapidjson/writer.h>
-#include <cereal/external/rapidjson/genericstream.h>
-#include <cereal/external/rapidjson/reader.h>
-#include <cereal/external/rapidjson/document.h>
-#include <cereal/external/base64.hpp>
-
-#include <limits>
-#include <sstream>
-#include <stack>
-#include <vector>
-#include <string>
-
-namespace cereal
-{
-  // ######################################################################
-  //! An output archive designed to save data to JSON
-  /*! This archive uses RapidJSON to build serialized data to JSON.
-
-      JSON archives provides a human readable output but at decreased
-      performance (both in time and space) compared to binary archives.
-
-      JSON benefits greatly from name-value pairs, which if present, will
-      name the nodes in the output.  If these are not present, each level
-      of the output will be given an automatically generated delimited name.
-
-      The precision of the output archive controls the number of decimals output
-      for floating point numbers and should be sufficiently large (i.e. at least 20)
-      if there is a desire to have binary equality between the numbers output and
-      those read in.  In general you should expect a loss of precision when going
-      from floating point to text and back.
-
-      JSON archives do not output the size information for any dynamically sized structure
-      and instead infer it from the number of children for a node.  This means that data
-      can be hand edited for dynamic sized structures and will still be readable.  This
-      is accomplished through the cereal::SizeTag object, which will cause the archive
-      to output the data as a JSON array (e.g. marked by [] instead of {}), which indicates
-      that the container is variable sized and may be edited.
-
-      \ingroup Archives */
-  class JSONOutputArchive : public OutputArchive<JSONOutputArchive>
-  {
-    enum class NodeType { StartObject, InObject, StartArray, InArray };
-
-    typedef rapidjson::GenericWriteStream WriteStream;
-    typedef rapidjson::Writer<WriteStream> JSONWriter;
-
-    public:
-      /*! @name Common Functionality
-          Common use cases for directly interacting with an JSONOutputArchive */
-      //! @{
-
-      //! A class containing various advanced options for the JSON archive
-      class Options
-      {
-        public:
-          //! Default options
-          static Options Default(){ return Options(); }
-
-          //! Specify specific options for the JSONOutputArchive
-          /*! @param precision The precision used for floating point numbers*/
-          explicit Options( int precision = std::numeric_limits<double>::max_digits10) :
-            itsPrecision( precision ) { }
-
-        private:
-          friend class JSONOutputArchive;
-          int itsPrecision;
-      };
-
-      //! Construct, outputting to the provided stream
-      /*! @param stream The stream to output to.
-          @param options The JSON specific options to use.  See the Options struct
-                         for the values of default parameters */
-      JSONOutputArchive(std::ostream & stream, Options const & options = Options::Default() ) :
-        OutputArchive<JSONOutputArchive>(this),
-        itsWriteStream(stream),
-        itsWriter(itsWriteStream, options.itsPrecision),
-        itsNextName(nullptr)
-      {
-        itsNameCounter.push(0);
-        itsNodeStack.push(NodeType::StartObject);
-      }
-
-      //! Destructor, flushes the JSON
-      ~JSONOutputArchive()
-      {
-        itsWriter.EndObject();
-      }
-
-      //! Saves some binary data, encoded as a base64 string, with an optional name
-      /*! This will create a new node, optionally named, and insert a value that consists of
-          the data encoded as a base64 string */
-      void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
-      {
-        setNextName( name );
-        writeName();
-
-        auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
-        saveValue( base64string );
-      };
-
-      //! @}
-      /*! @name Internal Functionality
-          Functionality designed for use by those requiring control over the inner mechanisms of
-          the JSONOutputArchive */
-      //! @{
-
-      //! Starts a new node in the JSON output
-      /*! The node can optionally be given a name by calling setNextName prior
-          to creating the node
-
-          Nodes only need to be started for types that are themselves objects or arrays */
-      void startNode()
-      {
-        writeName();
-        itsNodeStack.push(NodeType::StartObject);
-        itsNameCounter.push(0);
-      }
-
-      //! Designates the most recently added node as finished
-      void finishNode()
-      {
-        // if we ended up serializing an empty object or array, writeName
-        // will never have been called - so start and then immediately end
-        // the object/array.
-        //
-        // We'll also end any object/arrays we happen to be in
-        switch(itsNodeStack.top())
-        {
-          case NodeType::StartArray:
-            itsWriter.StartArray();
-          case NodeType::InArray:
-            itsWriter.EndArray();
-            break;
-          case NodeType::StartObject:
-            itsWriter.StartObject();
-          case NodeType::InObject:
-            itsWriter.EndObject();
-            break;
-        }
-
-        itsNodeStack.pop();
-        itsNameCounter.pop();
-      }
-
-      //! Sets the name for the next node created with startNode
-      void setNextName( const char * name )
-      {
-        itsNextName = name;
-      }
-
-      //! Saves a null to the current node, added by Intel
-      void saveValue()                      { itsWriter.Null_();                                                         }
-      //! Saves a bool to the current node
-      void saveValue(bool b)                { itsWriter.Bool_(b);                                                         }
-      //! Saves an int to the current node
-      void saveValue(int i)                 { itsWriter.Int(i);                                                          }
-      //! Saves a uint to the current node
-      void saveValue(unsigned u)            { itsWriter.Uint(u);                                                         }
-      //! Saves an int64 to the current node
-      void saveValue(int64_t i64)           { itsWriter.Int64(i64);                                                      }
-      //! Saves a uint64 to the current node
-      void saveValue(uint64_t u64)          { itsWriter.Uint64(u64);                                                     }
-      //! Saves a double to the current node
-      void saveValue(double d)              { itsWriter.Double(d);                                                       }
-      //! Saves a string to the current node
-      void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast<rapidjson::SizeType>( s.size() )); }
-      //! Saves a const char * to the current node
-      void saveValue(char const * s)        { itsWriter.String(s);                                                       }
-
-    public:
-#ifdef _MSC_VER
-      //! MSVC only long overload to current node
-      void saveValue( unsigned long lu ){ saveLong( lu ); };
-#else // _MSC_VER
-      //! Serialize a long if it would not be caught otherwise
-      template <class T> inline
-      typename std::enable_if<std::is_same<T, long>::value &&
-                              !std::is_same<T, std::int32_t>::value &&
-                              !std::is_same<T, std::int64_t>::value, void>::type
-      saveValue( T t )
-      {
-          saveLong( t );
-          return t;
-      }
-
-      //! Serialize an unsigned long if it would not be caught otherwise
-      template <class T> inline
-      typename std::enable_if<std::is_same<T, unsigned long>::value &&
-                              !std::is_same<T, std::uint32_t>::value &&
-                              !std::is_same<T, std::uint64_t>::value, void>::type
-      saveValue( T t )
-      {
-          saveLong( t );
-          return t;
-      }
-#endif // _MSC_VER
-
-      //! Save exotic arithmetic as strings to current node
-      /*! Handles long long (if distinct from other types), unsigned long (if distinct), and long double */
-      template<class T> inline
-      typename std::enable_if<std::is_arithmetic<T>::value &&
-                              !std::is_same<T, long>::value &&
-                              !std::is_same<T, unsigned long>::value &&
-                              !std::is_same<T, std::int64_t>::value &&
-                              !std::is_same<T, std::uint64_t>::value &&
-                              (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type
-      saveValue(T const & t)
-      {
-        std::stringstream ss; ss.precision( std::numeric_limits<long double>::max_digits10 );
-        ss << t;
-        saveValue( ss.str() );
-        return t;
-      }
-
-      //! Write the name of the upcoming node and prepare object/array state
-      /*! Since writeName is called for every value that is output, regardless of
-          whether it has a name or not, it is the place where we will do a deferred
-          check of our node state and decide whether we are in an array or an object.
-
-          The general workflow of saving to the JSON archive is:
-
-            1. (optional) Set the name for the next node to be created, usually done by an NVP
-            2. Start the node
-            3. (if there is data to save) Write the name of the node (this function)
-            4. (if there is data to save) Save the data (with saveValue)
-            5. Finish the node
-          */
-      void writeName()
-      {
-        NodeType const & nodeType = itsNodeStack.top();
-
-        // Start up either an object or an array, depending on state
-        if(nodeType == NodeType::StartArray)
-        {
-          itsWriter.StartArray();
-          itsNodeStack.top() = NodeType::InArray;
-        }
-        else if(nodeType == NodeType::StartObject)
-        {
-          itsNodeStack.top() = NodeType::InObject;
-          itsWriter.StartObject();
-        }
-
-        // Array types do not output names
-        if(nodeType == NodeType::InArray) return;
-
-        if(itsNextName == nullptr)
-        {
-          std::string name = "value" + std::to_string( itsNameCounter.top()++ ) + "\0";
-          saveValue(name);
-        }
-        else
-        {
-          saveValue(itsNextName);
-          itsNextName = nullptr;
-        }
-      }
-
-      //! Designates that the current node should be output as an array, not an object
-      void makeArray()
-      {
-        itsNodeStack.top() = NodeType::StartArray;
-      }
-
-      //! @}
-
-    private:
-      WriteStream itsWriteStream;          //!< Rapidjson write stream
-      JSONWriter itsWriter;                //!< Rapidjson writer
-      char const * itsNextName;            //!< The next name
-      std::stack<uint32_t> itsNameCounter; //!< Counter for creating unique names for unnamed nodes
-      std::stack<NodeType> itsNodeStack;
-  }; // JSONOutputArchive
-
-  // ######################################################################
-  //! An input archive designed to load data from JSON
-  /*! This archive uses RapidJSON to read in a JSON archive.
-
-      Input JSON should have been produced by the JSONOutputArchive.  Data can
-      only be added to dynamically sized containers (marked by JSON arrays) -
-      the input archive will determine their size by looking at the number of child nodes.
-      Only JSON originating from a JSONOutputArchive is officially supported, but data
-      from other sources may work if properly formatted.
-
-      The JSONInputArchive does not require that nodes are loaded in the same
-      order they were saved by JSONOutputArchive.  Using name value pairs (NVPs),
-      it is possible to load in an out of order fashion or otherwise skip/select
-      specific nodes to load.
-
-      The default behavior of the input archive is to read sequentially starting
-      with the first node and exploring its children.  When a given NVP does
-      not match the read in name for a node, the archive will search for that
-      node at the current level and load it if it exists.  After loading an out of
-      order node, the archive will then proceed back to loading sequentially from
-      its new position.
-
-      Consider this simple example where loading of some data is skipped:
-
-      @code{cpp}
-      // imagine the input file has someData(1-9) saved in order at the top level node
-      ar( someData1, someData2, someData3 );        // XML loads in the order it sees in the file
-      ar( cereal::make_nvp( "hello", someData6 ) ); // NVP given does not
-                                                    // match expected NVP name, so we search
-                                                    // for the given NVP and load that value
-      ar( someData7, someData8, someData9 );        // with no NVP given, loading resumes at its
-                                                    // current location, proceeding sequentially
-      @endcode
-
-      \ingroup Archives */
-  class JSONInputArchive : public InputArchive<JSONInputArchive>
-  {
-    private:
-      typedef rapidjson::GenericReadStream ReadStream;
-      typedef rapidjson::GenericValue<rapidjson::UTF8<>> JSONValue;
-      typedef JSONValue::ConstMemberIterator MemberIterator;
-      typedef JSONValue::ConstValueIterator ValueIterator;
-      typedef rapidjson::Document::GenericValue GenericValue;
-
-    public:
-      /*! @name Common Functionality
-          Common use cases for directly interacting with an JSONInputArchive */
-      //! @{
-
-      //! Construct, reading from the provided stream
-      /*! @param stream The stream to read from */
-      JSONInputArchive(std::istream & stream) :
-        InputArchive<JSONInputArchive>(this),
-        itsNextName( nullptr ),
-        itsReadStream(stream)
-      {
-        itsDocument.ParseStream<0>(itsReadStream);
-        itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd());
-      }
-
-      //! Loads some binary data, encoded as a base64 string
-      /*! This will automatically start and finish a node to load the data, and can be called directly by
-          users.
-
-          Note that this follows the same ordering rules specified in the class description in regards
-          to loading in/out of order */
-      void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
-      {
-        itsNextName = name;
-
-        std::string encoded;
-        loadValue( encoded );
-        auto decoded = base64::decode( encoded );
-
-        if( size != decoded.size() )
-          throw Exception("Decoded binary data size does not match specified size");
-
-        std::memcpy( data, decoded.data(), decoded.size() );
-        itsNextName = nullptr;
-      };
-
-      // Intel Added this as a custom parsing hook for the AttributeValue map
-      void loadAttributeValues(std::map<std::string, OC::AttributeValue>& map);
-
-    private:
-      //! @}
-      /*! @name Internal Functionality
-          Functionality designed for use by those requiring control over the inner mechanisms of
-          the JSONInputArchive */
-      //! @{
-
-      //! An internal iterator that handles both array and object types
-      /*! This class is a variant and holds both types of iterators that
-          rapidJSON supports - one for arrays and one for objects. */
-      class Iterator
-      {
-        public:
-          friend class cereal::JSONInputArchive;
-          Iterator() : itsIndex( 0 ), itsType(Null_) {}
-
-          Iterator(MemberIterator begin, MemberIterator end) :
-            itsMemberItBegin(begin), itsMemberItEnd(end), itsIndex(0), itsType(Member)
-          { }
-
-          Iterator(ValueIterator begin, ValueIterator end) :
-            itsValueItBegin(begin), itsValueItEnd(end), itsIndex(0), itsType(Value)
-          { }
-
-          //! Advance to the next node
-          Iterator & operator++()
-          {
-            ++itsIndex;
-            return *this;
-          }
-
-          //! Get the value of the current node
-          GenericValue const & value()
-          {
-            switch(itsType)
-            {
-              case Value : return itsValueItBegin[itsIndex];
-              case Member: return itsMemberItBegin[itsIndex].value;
-              default: throw cereal::Exception("Invalid Iterator Type!");
-            }
-          }
-
-          //! Get the name of the current node, or nullptr if it has no name
-          const char * name() const
-          {
-            if( itsType == Member && (itsMemberItBegin + itsIndex) != itsMemberItEnd )
-              return itsMemberItBegin[itsIndex].name.GetString();
-            else
-              return nullptr;
-          }
-
-          //! Adjust our position such that we are at the node with the given name
-          /*! @throws Exception if no such named node exists */
-          inline void search( const char * searchName )
-          {
-            const auto len = std::strlen( searchName );
-            size_t index = 0;
-            for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
-              if( std::strncmp( searchName, it->name.GetString(), len ) == 0 )
-              {
-                itsIndex = index;
-                return;
-              }
-
-            throw Exception("JSON Parsing failed - provided NVP not found");
-          }
-
-        private:
-          MemberIterator itsMemberItBegin, itsMemberItEnd; //!< The member iterator (object)
-          ValueIterator itsValueItBegin, itsValueItEnd;    //!< The value iterator (array)
-          size_t itsIndex;                                 //!< The current index of this iterator
-          enum Type {Value, Member, Null_} itsType;    //!< Whether this holds values (array) or members (objects) or nothing
-      };
-
-      //! Searches for the expectedName node if it doesn't match the actualName
-      /*! This needs to be called before every load or node start occurs.  This function will
-          check to see if an NVP has been provided (with setNextName) and if so, see if that name matches the actual
-          next name given.  If the names do not match, it will search in the current level of the JSON for that name.
-          If the name is not found, an exception will be thrown.
-
-          Resets the NVP name after called.
-
-          @throws Exception if an expectedName is given and not found */
-      inline void search()
-      {
-        // The name an NVP provided with setNextName()
-        if( itsNextName )
-        {
-          // The actual name of the current node
-          auto const actualName = itsIteratorStack.back().name();
-
-          // Do a search if we don't see a name coming up, or if the names don't match
-          if( !actualName || std::strcmp( itsNextName, actualName ) != 0 )
-            itsIteratorStack.back().search( itsNextName );
-        }
-
-        itsNextName = nullptr;
-      }
-
-    public:
-      //! Starts a new node, going into its proper iterator
-      /*! This places an iterator for the next node to be parsed onto the iterator stack.  If the next
-          node is an array, this will be a value iterator, otherwise it will be a member iterator.
-
-          By default our strategy is to start with the document root node and then recursively iterate through
-          all children in the order they show up in the document.
-          We don't need to know NVPs to do this; we'll just blindly load in the order things appear in.
-
-          If we were given an NVP, we will search for it if it does not match our the name of the next node
-          that would normally be loaded.  This functionality is provided by search(). */
-      void startNode()
-      {
-        search();
-
-        if(itsIteratorStack.back().value().IsArray())
-          itsIteratorStack.emplace_back(itsIteratorStack.back().value().Begin(), itsIteratorStack.back().value().End());
-        else
-          itsIteratorStack.emplace_back(itsIteratorStack.back().value().MemberBegin(), itsIteratorStack.back().value().MemberEnd());
-      }
-
-      //! Finishes the most recently started node
-      void finishNode()
-      {
-        itsIteratorStack.pop_back();
-        ++itsIteratorStack.back();
-      }
-
-      //! Sets the name for the next node created with startNode
-      void setNextName( const char * name )
-      {
-        itsNextName = name;
-      }
-
-      //! Loads a value from the current node - small signed overload
-      template<class T> inline
-      typename std::enable_if<std::is_signed<T>::value && sizeof(T) < sizeof(int64_t), void>::type
-      loadValue(T & val)
-      {
-        search();
-
-        val = itsIteratorStack.back().value().GetInt();
-        ++itsIteratorStack.back();
-      }
-
-      //! Loads a value from the current node - small unsigned overload
-      template<class T> inline
-      typename std::enable_if<(std::is_unsigned<T>::value && sizeof(T) < sizeof(uint64_t)) &&
-                              !std::is_same<bool, T>::value, void>::type
-      loadValue(T & val)
-      {
-        search();
-
-        val = itsIteratorStack.back().value().GetUint();
-        ++itsIteratorStack.back();
-      }
-
-      //! Loads a value from the current node - bool overload
-      void loadValue(bool & val)        { search(); val = itsIteratorStack.back().value().GetBool_();   ++itsIteratorStack.back(); }
-      //! Loads a value from the current node - int64 overload
-      void loadValue(int64_t & val)     { search(); val = itsIteratorStack.back().value().GetInt64();  ++itsIteratorStack.back(); }
-      //! Loads a value from the current node - uint64 overload
-      void loadValue(uint64_t & val)    { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
-      //! Loads a value from the current node - float overload
-      void loadValue(float & val)       { search(); val = static_cast<float>(itsIteratorStack.back().value().GetDouble()); ++itsIteratorStack.back(); }
-      //! Loads a value from the current node - double overload
-      void loadValue(double & val)      { search(); val = itsIteratorStack.back().value().GetDouble(); ++itsIteratorStack.back(); }
-      //! Loads a value from the current node - string overload
-      void loadValue(std::string & val) { search(); val = itsIteratorStack.back().value().GetString(); ++itsIteratorStack.back(); }
-
-    private:
-      //! Convert a string to a long long
-      void stringToNumber( std::string const & str, long long & val ) { val = std::stoll( str ); }
-      //! Convert a string to an unsigned long long
-      void stringToNumber( std::string const & str, unsigned long long & val ) { val = std::stoull( str ); }
-      //! Convert a string to a long double
-      void stringToNumber( std::string const & str, long double & val ) { val = std::stold( str ); }
-
-    public:
-      //! Loads a value from the current node - long double and long long overloads
-      template<class T> inline
-      typename std::enable_if<std::is_arithmetic<T>::value &&
-                              !std::is_same<T, long>::value &&
-                              !std::is_same<T, unsigned long>::value &&
-                              !std::is_same<T, std::int64_t>::value &&
-                              !std::is_same<T, std::uint64_t>::value &&
-                              (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type
-      loadValue(T & val)
-      {
-        std::string encoded;
-        loadValue( encoded );
-        stringToNumber( encoded, val );
-      }
-
-      //! Loads the size for a SizeTag
-      void loadSize(size_type & size)
-      {
-        size = (itsIteratorStack.rbegin() + 1)->value().Size();
-      }
-
-      //! @}
-
-    private:
-      const char * itsNextName;               //!< Next name set by NVP
-      ReadStream itsReadStream;               //!< Rapidjson write stream
-      std::vector<Iterator> itsIteratorStack; //!< 'Stack' of rapidJSON iterators
-      rapidjson::Document itsDocument;        //!< Rapidjson document
-  };
-
-  // ######################################################################
-  // JSONArchive prologue and epilogue functions
-  // ######################################################################
-
-  // ######################################################################
-  //! Prologue for NVPs for JSON archives
-  /*! NVPs do not start or finish nodes - they just set up the names */
-  template <class T> inline
-  void prologue( JSONOutputArchive &, NameValuePair<T> const & )
-  { }
-
-  //! Prologue for NVPs for JSON archives
-  template <class T> inline
-  void prologue( JSONInputArchive &, NameValuePair<T> const & )
-  { }
-
-  // ######################################################################
-  //! Epilogue for NVPs for JSON archives
-  /*! NVPs do not start or finish nodes - they just set up the names */
-  template <class T> inline
-  void epilogue( JSONOutputArchive &, NameValuePair<T> const & )
-  { }
-
-  //! Epilogue for NVPs for JSON archives
-  /*! NVPs do not start or finish nodes - they just set up the names */
-  template <class T> inline
-  void epilogue( JSONInputArchive &, NameValuePair<T> const & )
-  { }
-
-  // ######################################################################
-  //! Prologue for SizeTags for JSON archives
-  /*! SizeTags are strictly ignored for JSON, they just indicate
-      that the current node should be made into an array */
-  template <class T> inline
-  void prologue( JSONOutputArchive & ar, SizeTag<T> const & )
-  {
-    ar.makeArray();
-  }
-
-  //! Prologue for SizeTags for JSON archives
-  template <class T> inline
-  void prologue( JSONInputArchive &, SizeTag<T> const & )
-  { }
-
-  // ######################################################################
-  //! Epilogue for SizeTags for JSON archives
-  /*! SizeTags are strictly ignored for JSON */
-  template <class T> inline
-  void epilogue( JSONOutputArchive &, SizeTag<T> const & )
-  { }
-
-  //! Epilogue for SizeTags for JSON archives
-  template <class T> inline
-  void epilogue( JSONInputArchive &, SizeTag<T> const & )
-  { }
-
-  // ######################################################################
-  //! Prologue for all other types for JSON archives (except minimal types)
-  /*! Starts a new node, named either automatically or by some NVP,
-      that may be given data by the type about to be archived
-
-      Minimal types do not start or finish nodes */
-  template <class T> inline
-  typename std::enable_if<!std::is_arithmetic<T>::value &&
-                          !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value, void>::type
-  prologue( JSONOutputArchive & ar, T const & )
-  {
-    ar.startNode();
-  }
-
-  //! Prologue for all other types for JSON archives
-  template <class T> inline
-  typename std::enable_if<!std::is_arithmetic<T>::value &&
-                          !traits::has_minimal_input_serialization<T, JSONOutputArchive>::value, void>::type
-  prologue( JSONInputArchive & ar, T const & )
-  {
-    ar.startNode();
-  }
-
-  // ######################################################################
-  //! Epilogue for all other types other for JSON archives (except minimal types
-  /*! Finishes the node created in the prologue
-
-      Minimal types do not start or finish nodes */
-  template <class T> inline
-  typename std::enable_if<!std::is_arithmetic<T>::value &&
-                          !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value, void>::type
-  epilogue( JSONOutputArchive & ar, T const & )
-  {
-    ar.finishNode();
-  }
-
-  //! Epilogue for all other types other for JSON archives
-  template <class T> inline
-  typename std::enable_if<!std::is_arithmetic<T>::value &&
-                          !traits::has_minimal_input_serialization<T, JSONOutputArchive>::value, void>::type
-  epilogue( JSONInputArchive & ar, T const & )
-  {
-    ar.finishNode();
-  }
-
-  // ######################################################################
-  //! Prologue for arithmetic types for JSON archives
-  template <class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  prologue( JSONOutputArchive & ar, T const & )
-  {
-    ar.writeName();
-  }
-
-  //! Prologue for arithmetic types for JSON archives
-  template <class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  prologue( JSONInputArchive &, T const & )
-  { }
-
-  // ######################################################################
-  //! Epilogue for arithmetic types for JSON archives
-  template <class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  epilogue( JSONOutputArchive &, T const & )
-  { }
-
-  //! Epilogue for arithmetic types for JSON archives
-  template <class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  epilogue( JSONInputArchive &, T const & )
-  { }
-
-  // ######################################################################
-  //! Prologue for strings for JSON archives
-  template<class CharT, class Traits, class Alloc> inline
-  void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const &)
-  {
-    ar.writeName();
-  }
-
-  //! Prologue for strings for JSON archives
-  template<class CharT, class Traits, class Alloc> inline
-  void prologue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
-  { }
-
-  // ######################################################################
-  //! Epilogue for strings for JSON archives
-  template<class CharT, class Traits, class Alloc> inline
-  void epilogue(JSONOutputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
-  { }
-
-  //! Epilogue for strings for JSON archives
-  template<class CharT, class Traits, class Alloc> inline
-  void epilogue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
-  { }
-
-  // ######################################################################
-  // Common JSONArchive serialization functions
-  // ######################################################################
-
-  //! Serializing NVP types to JSON
-  template <class T> inline
-  void save( JSONOutputArchive & ar, NameValuePair<T> const & t )
-  {
-    ar.setNextName( t.name );
-    ar( t.value );
-  }
-
-  template <class T> inline
-  void load( JSONInputArchive & ar, NameValuePair<T> & t )
-  {
-    ar.setNextName( t.name );
-    ar( t.value );
-  }
-
-  //! Saving for arithmetic to JSON
-  template<class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  save(JSONOutputArchive & ar, T const & t)
-  {
-    ar.saveValue( t );
-  }
-
-  //! Loading arithmetic from JSON
-  template<class T> inline
-  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
-  load(JSONInputArchive & ar, T & t)
-  {
-    ar.loadValue( t );
-  }
-
-  //! saving string to JSON
-  template<class CharT, class Traits, class Alloc> inline
-  void save(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
-  {
-    ar.saveValue( str );
-  }
-
-  //! loading string from JSON
-  template<class CharT, class Traits, class Alloc> inline
-  void load(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
-  {
-    ar.loadValue( str );
-  }
-
-  // ######################################################################
-  //! Saving SizeTags to JSON
-  template <class T> inline
-  void save( JSONOutputArchive &, SizeTag<T> const & )
-  {
-    // nothing to do here, we don't explicitly save the size
-  }
-
-  //! Loading SizeTags from JSON
-  template <class T> inline
-  void load( JSONInputArchive & ar, SizeTag<T> & st )
-  {
-    ar.loadSize( st.size );
-  }
-} // namespace cereal
-
-// register archives for polymorphic support
-CEREAL_REGISTER_ARCHIVE(cereal::JSONInputArchive)
-CEREAL_REGISTER_ARCHIVE(cereal::JSONOutputArchive)
-
-#endif // CEREAL_ARCHIVES_JSON_HPP_
index db00d40..e524dfa 100644 (file)
@@ -33,12 +33,14 @@ namespace OC
         {}
 
         virtual OCStackResult ListenForResource(const std::string& serviceUrl,
-            const std::string& resourceType, OCConnectivityType connectivityType,
+            const std::string& resourceType,
+            OCConnectivityType connectivityType,
             FindCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
-            const std::string& deviceURI, OCConnectivityType connectivityType,
+            const std::string& deviceURI,
+            OCConnectivityType connectivityType,
             FindDeviceCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
@@ -47,44 +49,63 @@ namespace OC
             QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult GetResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult GetResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
             GetCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult PutResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PutResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, PutCallback& callback,
             QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult PostResourceRepresentation(const std::string& host,
-            const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult PostResourceRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, PostCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult DeleteResource(const std::string& host, const std::string& uri,
-            OCConnectivityType connectivityType, const HeaderOptions& headerOptions,
+        virtual OCStackResult DeleteResource(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
+            const HeaderOptions& headerOptions,
             DeleteCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
-            const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
+        virtual OCStackResult ObserveResource(
+            ObserveType observeType, OCDoHandle* handle,
+            const OCDevAddr& devAddr,
+            const std::string& uri,
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
-            ObserveCallback& callback, QualityOfService QoS){return OC_STACK_NOTIMPL;}
-        virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
+            ObserveCallback& callback, QualityOfService QoS)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult CancelObserveResource(
+            OCDoHandle handle,
+            const std::string& host,
             const std::string& uri,
-            const HeaderOptions& headerOptions, QualityOfService QoS){return OC_STACK_NOTIMPL;}
-        virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
-            const std::string& resourceType, OCConnectivityType connectivityType,
+            const HeaderOptions& headerOptions, QualityOfService QoS)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult SubscribePresence(
+            OCDoHandle* handle,
+            const std::string& host,
+            const std::string& resourceType,
+            OCConnectivityType connectivityType,
             SubscribeCallback& presenceHandler)
-        {return OC_STACK_NOTIMPL;}
-        virtual OCStackResult UnsubscribePresence(OCDoHandle handle){return OC_STACK_NOTIMPL;}
+            {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult GetDefaultQos(QualityOfService& QoS){return OC_STACK_NOTIMPL;}
+        virtual OCStackResult UnsubscribePresence(OCDoHandle handle)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult GetDefaultQos(QualityOfService& QoS)
+            {return OC_STACK_NOTIMPL;}
     };
 }
 
index c045b6c..9794e42 100644 (file)
@@ -22,7 +22,6 @@
 #define _RESOURCE_INIT_EXCEPTION_H_
 
 #include <stdexcept>
-#include <ocstack.h>
 #include "StringConstants.h"
 
 namespace OC
index 4bb245b..b7b0a62 100644 (file)
@@ -80,6 +80,7 @@ namespace OC
         static const char NOT_FOUND[]                  = "Resource Not Found";
         static const char RESOURCE_ERROR[]             = "Resource Error";
         static const char SLOW_RESOURCE[]              = "Slow Resource";
+        static const char DUPLICATE_REQUEST[]          = "Duplicate Request";
         static const char NO_OBSERVERS[]               = "No Observers";
         static const char OBSV_NO_FOUND[]              = "Stack observer not found";
         static const char OBSV_NOT_ADDED[]             = "Stack observer not added";
@@ -103,6 +104,7 @@ namespace OC
         static const char INVALID_JSON_TYPE_TAG[]      = "Invalid JSON Type Tag";
         static const char INVALID_ATTRIBUTE[]          = "Invalid Attribute: ";
         static const char INVALID_DEVICE_INFO[]        = "Invalid Device Information";
+        static const char UNAUTHORIZED_REQUEST[]       = "Unauthorized Request";
 
     }
 
@@ -121,16 +123,19 @@ namespace OC
 
     namespace Key
     {
-        static const std::string OCKEY                      = "oc";
+        static const std::string OCKEY                      = "oic";
         static const std::string URIKEY                     = "href";
-        static const std::string OBSERVABLEKEY              = "obs";
+        static const std::string POLICYKEY                  = "p";
+        static const std::string BMKEY                      = "bm";
         static const std::string RESOURCETYPESKEY           = "rt";
         static const std::string INTERFACESKEY              = "if";
         static const std::string PROPERTYKEY                = "prop";
         static const std::string REPKEY                     = "rep";
         static const std::string SECUREKEY                  = "sec";
         static const std::string PORTKEY                    = "port";
-        static const std::string SERVERIDKEY                = "sid";
+        static const std::string DEVICEIDKEY                = "di";
+        static const std::string LINKS                      = "links";
+
     }
 
 }
index 8bd1edc..98318be 100644 (file)
@@ -50,6 +50,7 @@ liboc_logger = liboc_logger_env.SharedLibrary('oc_logger',
                ['c/oc_logger.c', 'c/oc_console_logger.c', 'cpp/oc_ostream_logger.cpp'])
 
 liboc_logger_env.InstallTarget([liboc_logger_core, liboc_logger], 'liboc_logger')
+liboc_logger_env.UserInstallTargetLib([liboc_logger_core, liboc_logger], 'liboc_logger')
 
 if target_os not in ['ios', 'android']:
        SConscript('examples/SConscript')
index 7b2db2b..77df219 100644 (file)
@@ -19,6 +19,7 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "oc_logger.h"
+#include "oic_string.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -149,7 +150,6 @@ size_t oc_log_write_level(oc_log_ctx_t *ctx, const oc_log_level loglevel, const
 int oc_log_set_module(oc_log_ctx_t *ctx, const char *module_name)
 {
  char *mn = NULL;
- size_t len = 0;
 
  if(!ctx || !module_name)
  {
@@ -157,17 +157,13 @@ int oc_log_set_module(oc_log_ctx_t *ctx, const char *module_name)
  }
 
  /* Swap pointers so that module data's not erased in the event of failure: */
- len = strlen(module_name);
-
- mn = (char *)malloc(1 + len);
+ mn = OICStrdup(module_name);
 
  if(!mn)
  {
      return 0;
  }
 
- memcpy(mn, module_name, 1 + len);
-
  if(!ctx->module_name)
  {
      free(ctx->module_name);
diff --git a/resource/patches/cereal_gcc46.patch b/resource/patches/cereal_gcc46.patch
deleted file mode 100644 (file)
index c4da84f..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-From 17300ee96e42f8848d27db6fc97f04de293662d8 Mon Sep 17 00:00:00 2001
-From: Erich Keane <erich.keane@intel.com>
-Date: Thu, 6 Nov 2014 14:37:00 -0800
-Subject: [PATCH] Get this to work on g++4.6.3
-
----
- include/cereal/cereal.hpp                  |  2 +-
- include/cereal/details/helpers.hpp         | 32 ++++++++--------
- include/cereal/details/traits.hpp          | 61 +++++++++++++++++-------------
- include/cereal/external/rapidjson/reader.h | 13 ++-----
- include/cereal/external/rapidjson/writer.h | 12 ++----
- include/cereal/types/common.hpp            | 19 +++++++---
- include/cereal/types/memory.hpp            | 10 ++---
- 7 files changed, 77 insertions(+), 72 deletions(-)
-
-diff --git a/include/cereal/cereal.hpp b/include/cereal/cereal.hpp
-index b2858af..a219729 100644
---- a/include/cereal/cereal.hpp
-+++ b/include/cereal/cereal.hpp
-@@ -856,7 +856,7 @@ namespace cereal
-           std::uint32_t version;
-           process( make_nvp<ArchiveType>("cereal_class_version", version) );
--          itsVersionedTypes.emplace_hint( lookupResult, hash, version );
-+          itsVersionedTypes.insert( lookupResult, std::pair<std::size_t, std::uint32_t>(hash, version) );
-           return version;
-         }
-diff --git a/include/cereal/details/helpers.hpp b/include/cereal/details/helpers.hpp
-index e792d44..60e13c8 100644
---- a/include/cereal/details/helpers.hpp
-+++ b/include/cereal/details/helpers.hpp
-@@ -55,7 +55,7 @@ namespace cereal
-   /*! To ensure compatability between 32, 64, etc bit machines, we need to use
-    * a fixed size type instead of size_t, which may vary from machine to
-    * machine. */
--  using size_type = uint64_t;
-+   typedef uint64_t size_type;
-   // forward decls
-   class BinaryOutputArchive;
-@@ -138,12 +138,12 @@ namespace cereal
-       // otherwise, we store a reference.  If we were passed an array, don't
-       // decay the type - keep it as an array, and then proceed as normal
-       // with the RValue business
--      using DT = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
-+      typedef typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
-                                            typename std::remove_cv<T>::type,
--                                           typename std::decay<T>::type>::type;
--      using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
-+                                           typename std::decay<T>::type>::type DT;
-+      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
-                                              DT,
--                                             typename std::add_lvalue_reference<DT>::type>::type;
-+                                             typename std::add_lvalue_reference<DT>::type>::type Type;
-       // prevent nested nvps
-       static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
-                      "Cannot pair a name to a NameValuePair" );
-@@ -207,9 +207,9 @@ namespace cereal
-   {
-     //! Internally store the pointer as a void *, keeping const if created with
-     //! a const pointer
--    using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
-+    typedef typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
-                                          const void *,
--                                         void *>::type;
-+                                         void *>::type PT;
-     BinaryData( T && d, uint64_t s ) : data(d), size(s) {}
-@@ -248,10 +248,10 @@ namespace cereal
-     private:
-       // If we get passed an RValue, we'll just make a local copy if it here
-       // otherwise, we store a reference
--      using DT = typename std::decay<T>::type;
--      using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
-+      typedef typename std::decay<T>::type DT;
-+      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
-                                              DT,
--                                             typename std::add_lvalue_reference<DT>::type>::type;
-+                                             typename std::add_lvalue_reference<DT>::type>::type Type;
-     public:
-       SizeTag( T && sz ) : size(const_cast<Type>(sz)) {}
-@@ -283,17 +283,17 @@ namespace cereal
-   template <class Key, class Value>
-   struct MapItem
-   {
--    using DecayKey = typename std::decay<Key>::type;
--    using KeyType = typename std::conditional<
-+    typedef typename std::decay<Key>::type DecayKey;
-+    typedef typename std::conditional<
-       std::is_rvalue_reference<Key>::value,
-       DecayKey,
--      typename std::add_lvalue_reference<DecayKey>::type>::type;
-+      typename std::add_lvalue_reference<DecayKey>::type>::type KeyType;
--    using DecayValue = typename std::decay<Value>::type;
--    using ValueType =  typename std::conditional<
-+    typedef typename std::decay<Value>::type DecayValue;
-+    typedef  typename std::conditional<
-       std::is_rvalue_reference<Value>::value,
-       DecayValue,
--      typename std::add_lvalue_reference<DecayValue>::type>::type;
-+      typename std::add_lvalue_reference<DecayValue>::type>::type ValueType;
-     //! Construct a MapItem from a key and a value
-     /*! @internal */
-diff --git a/include/cereal/details/traits.hpp b/include/cereal/details/traits.hpp
-index 871886f..011054b 100644
---- a/include/cereal/details/traits.hpp
-+++ b/include/cereal/details/traits.hpp
-@@ -411,12 +411,12 @@ namespace cereal
-       };
-       template <class T, class A, bool Valid>
--      struct get_member_save_minimal_type { using type = void; };
-+      struct get_member_save_minimal_type { typedef void type; };
-       template <class T, class A>
-       struct get_member_save_minimal_type<T, A, true>
-       {
--        using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>() ) );
-+        typedef decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>() ) ) type;
-       };
-     } // end namespace detail
-@@ -428,7 +428,7 @@ namespace cereal
-         "cereal detected a non-const member save_minimal.  "
-         "save_minimal member functions must always be const" );
--      using type = typename detail::get_member_save_minimal_type<T, A, check::value>::type;
-+      typedef typename detail::get_member_save_minimal_type<T, A, check::value>::type type;
-       static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
-         "cereal detected a member save_minimal with an invalid return type.  "
-         "return type must be arithmetic or string" );
-@@ -473,12 +473,12 @@ namespace cereal
-       };
-       template <class T, class A, bool Valid>
--      struct get_member_versioned_save_minimal_type { using type = void; };
-+      struct get_member_versioned_save_minimal_type { typedef void type; };
-       template <class T, class A>
-       struct get_member_versioned_save_minimal_type<T, A, true>
-       {
--        using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) );
-+        typedef decltype( cereal::access::member_save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) ) type;
-       };
-     } // end namespace detail
-@@ -490,7 +490,7 @@ namespace cereal
-         "cereal detected a versioned non-const member save_minimal.  "
-         "save_minimal member functions must always be const" );
--      using type = typename detail::get_member_versioned_save_minimal_type<T, A, check::value>::type;
-+      typedef typename detail::get_member_versioned_save_minimal_type<T, A, check::value>::type type;
-       static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
-         "cereal detected a versioned member save_minimal with an invalid return type.  "
-         "return type must be arithmetic or string" );
-@@ -519,12 +519,12 @@ namespace cereal
-       };
-       template <class T, class A, bool Valid>
--      struct get_non_member_save_minimal_type { using type = void; };
-+      struct get_non_member_save_minimal_type { typedef void type; };
-       template <class T, class A>
-       struct get_non_member_save_minimal_type <T, A, true>
-       {
--        using type = decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>() ) );
-+        typedef decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>() ) ) type;
-       };
-     } // end namespace detail
-@@ -536,7 +536,7 @@ namespace cereal
-         "cereal detected a non-const type parameter in non-member save_minimal.  "
-         "save_minimal non-member functions must always pass their types as const" );
--      using type = typename detail::get_non_member_save_minimal_type<T, A, check::value>::type;
-+      typedef typename detail::get_non_member_save_minimal_type<T, A, check::value>::type type;
-       static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
-         "cereal detected a non-member save_minimal with an invalid return type.  "
-         "return type must be arithmetic or string" );
-@@ -565,12 +565,12 @@ namespace cereal
-       };
-       template <class T, class A, bool Valid>
--      struct get_non_member_versioned_save_minimal_type { using type = void; };
-+      struct get_non_member_versioned_save_minimal_type { typedef void type; };
-       template <class T, class A>
-       struct get_non_member_versioned_save_minimal_type <T, A, true>
-       {
--        using type = decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) );
-+        typedef decltype( save_minimal( std::declval<A const &>(), std::declval<T const &>(), 0 ) ) type;
-       };
-     } // end namespace detail
-@@ -582,7 +582,7 @@ namespace cereal
-         "cereal detected a non-const type parameter in versioned non-member save_minimal.  "
-         "save_minimal non-member functions must always pass their types as const" );
--      using type = typename detail::get_non_member_versioned_save_minimal_type<T, A, check::value>::type;
-+      typedef typename detail::get_non_member_versioned_save_minimal_type<T, A, check::value>::type type;
-       static_assert( (check::value && is_minimal_type<type>::value) || !check::value,
-         "cereal detected a non-member versioned save_minimal with an invalid return type.  "
-         "return type must be arithmetic or string" );
-@@ -608,7 +608,7 @@ namespace cereal
-       template <class Source>
-       struct NoConvertConstRef : NoConvertBase
-       {
--        using type = Source; //!< Used to get underlying type easily
-+        typedef Source type; //!< Used to get underlying type easily
-         template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
-         operator Dest () = delete;
-@@ -626,7 +626,7 @@ namespace cereal
-       template <class Source>
-       struct NoConvertRef : NoConvertBase
-       {
--        using type = Source; //!< Used to get underlying type easily
-+        typedef Source type; //!< Used to get underlying type easily
-         template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
-         operator Dest () = delete;
-@@ -698,7 +698,7 @@ namespace cereal
-           "cereal detected member load_minimal but no valid member save_minimal.  "
-           "cannot evaluate correctness of load_minimal without valid save_minimal." );
--        using SaveType = typename detail::get_member_save_minimal_type<T, A, true>::type;
-+        typedef typename detail::get_member_save_minimal_type<T, A, true>::type SaveType;
-         const static bool value = has_member_load_minimal_impl<T, A>::value;
-         const static bool valid = has_member_load_minimal_type_impl<T, A, SaveType>::value;
-@@ -759,7 +759,7 @@ namespace cereal
-           "cereal detected member versioned load_minimal but no valid member versioned save_minimal.  "
-           "cannot evaluate correctness of load_minimal without valid save_minimal." );
--        using SaveType = typename detail::get_member_versioned_save_minimal_type<T, A, true>::type;
-+        typedef typename detail::get_member_versioned_save_minimal_type<T, A, true>::type SaveType;
-         const static bool value = has_member_versioned_load_minimal_impl<T, A>::value;
-         const static bool valid = has_member_versioned_load_minimal_type_impl<T, A, SaveType>::value;
-@@ -814,8 +814,8 @@ namespace cereal
-           "cereal detected non-member load_minimal but no valid non-member save_minimal.  "
-           "cannot evaluate correctness of load_minimal without valid save_minimal." );
--        using SaveType = typename detail::get_non_member_save_minimal_type<T, A, true>::type;
--        using check = has_non_member_load_minimal_impl<T, A, SaveType>;
-+        typedef typename detail::get_non_member_save_minimal_type<T, A, true>::type SaveType;
-+        typedef has_non_member_load_minimal_impl<T, A, SaveType> check;
-         static const bool value = check::exists;
-         static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member load_minimal and save_minimal functions.  "
-@@ -866,8 +866,8 @@ namespace cereal
-           "cereal detected non-member versioned load_minimal but no valid non-member versioned save_minimal.  "
-           "cannot evaluate correctness of load_minimal without valid save_minimal." );
--        using SaveType = typename detail::get_non_member_versioned_save_minimal_type<T, A, true>::type;
--        using check = has_non_member_versioned_load_minimal_impl<T, A, SaveType>;
-+        typedef typename detail::get_non_member_versioned_save_minimal_type<T, A, true>::type SaveType;
-+        typedef has_non_member_versioned_load_minimal_impl<T, A, SaveType> check;;
-         static const bool value = check::exists;
-         static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member versioned load_minimal and save_minimal functions.  "
-@@ -1182,9 +1182,16 @@ namespace cereal
-       };
-     }
-+    // works around the lack of decltype inheritance in GCC 4.6
-+    template<class T>
-+    struct shared_wrapper
-+    {
-+       typedef decltype(detail::shared_from_this_wrapper::check(std::declval<T>())) type;
-+
-+    };
-     //! Determine if T or any base class of T has inherited from std::enable_shared_from_this
-     template<class T>
--    struct has_shared_from_this : decltype(detail::shared_from_this_wrapper::check(std::declval<T>()))
-+    struct has_shared_from_this : shared_wrapper<T>::type
-     { };
-     //! Get the type of the base class of T which inherited from std::enable_shared_from_this
-@@ -1192,10 +1199,10 @@ namespace cereal
-     struct get_shared_from_this_base
-     {
-       private:
--        using PtrType = decltype(detail::shared_from_this_wrapper::get(std::declval<T>()));
-+        typedef decltype(detail::shared_from_this_wrapper::get(std::declval<T>())) PtrType;
-       public:
-         //! The type of the base of T that inherited from std::enable_shared_from_this
--        using type = typename std::decay<typename PtrType::element_type>::type;
-+        typedef typename std::decay<typename PtrType::element_type>::type type;
-     };
-     // ######################################################################
-@@ -1209,14 +1216,14 @@ namespace cereal
-     template <class T, bool IsCerealMinimalTrait = std::is_base_of<detail::NoConvertBase, T>::value>
-     struct strip_minimal
-     {
--      using type = T;
-+      typedef T type;
-     };
-     //! Specialization for types wrapped in a NoConvert
-     template <class T>
-     struct strip_minimal<T, true>
-     {
--      using type = typename T::type;
-+      typedef typename T::type type;
-     };
-   } // namespace traits
-@@ -1232,10 +1239,12 @@ namespace cereal
-       { return nullptr; }
-     };
-+    template<class T>
-+    struct is_default_constructible : std::is_constructible<T>{};
-     template <class T, class A>
-     struct Construct<T, A, false, false>
-     {
--      static_assert( std::is_default_constructible<T>::value,
-+      static_assert( is_default_constructible<T>::value,
-                      "Trying to serialize a an object with no default constructor. \n\n "
-                      "Types must either be default constructible or define either a member or non member Construct function. \n "
-                      "Construct functions generally have the signature: \n\n "
-diff --git a/include/cereal/external/rapidjson/reader.h b/include/cereal/external/rapidjson/reader.h
-index 7790907..3ee838c 100644
---- a/include/cereal/external/rapidjson/reader.h
-+++ b/include/cereal/external/rapidjson/reader.h
-@@ -402,20 +402,13 @@ private:
-       }
-   // cereal Temporary until constexpr support is added in RTM
--#ifdef _MSC_VER
-+//#ifdef _MSC_VER
-   template <class Ch>
-   bool characterOk( Ch c )
-   {
-     return c < 256;
-   }
--
--  template <>
--  bool characterOk<char>( Ch )
--  {
--    return true;
--  }
--
--#else
-+/*#else
-   // As part of a fix for GCC 4.7
-   template <class T>
-   static constexpr int to_int( T t ){ return t; }
-@@ -432,7 +425,7 @@ private:
-     characterOk(Ch c)
-   { return c < 256; }
- #endif
--
-+*/
-       // Parse string, handling the prefix and suffix double quotes and escaping.
-       template<unsigned parseFlags, typename Stream, typename Handler>
-       void ParseString(Stream& stream, Handler& handler) {
-diff --git a/include/cereal/external/rapidjson/writer.h b/include/cereal/external/rapidjson/writer.h
-index 0f87255..e02c27a 100644
---- a/include/cereal/external/rapidjson/writer.h
-+++ b/include/cereal/external/rapidjson/writer.h
-@@ -177,20 +177,14 @@ protected:
-       }
-   // cereal Temporary until constexpr support is added in RTM
--#ifdef _MSC_VER
-+//#ifdef _MSC_VER
-   template <class Ch>
-   bool characterOk( Ch c )
-   {
-     return c < 256;
-   }
--  template <>
--  bool characterOk<char>( Ch )
--  {
--    return true;
--  }
--
--#else
-+/*#else
-   // As part of a fix for GCC 4.7
-   template <class T>
-   static constexpr int to_int( T t ){ return t; }
-@@ -206,7 +200,7 @@ protected:
-   typename std::enable_if< to_int(std::numeric_limits<Ch>::max()) >= to_int(256), bool>::type
-     characterOk(Ch c)
-   { return c < 256; }
--#endif
-+#endif*/
-       //! \todo Optimization with custom double-to-string converter.
-       void WriteDouble(double d) {
-diff --git a/include/cereal/types/common.hpp b/include/cereal/types/common.hpp
-index abb8bfd..5c014cd 100644
---- a/include/cereal/types/common.hpp
-+++ b/include/cereal/types/common.hpp
-@@ -55,6 +55,15 @@ namespace cereal
-     namespace
-     {
-+      template<class en>
-+      struct underlying_type
-+      {
-+          typedef typename std::conditional<
-+                  en(-1)<en(0),
-+                  typename std::make_signed<en>::type,
-+                  typename std::make_unsigned<en>::type
-+                  > ::type type;
-+      };
-       //! Gets the underlying type of an enum
-       /*! @internal */
-       template <class T, bool IsEnum>
-@@ -64,7 +73,7 @@ namespace cereal
-       /*! Specialization for when we actually have an enum
-           @internal */
-       template <class T>
--      struct enum_underlying_type<T, true> { using type = typename std::underlying_type<T>::type; };
-+      struct enum_underlying_type<T, true> { typedef typename underlying_type<T>::type type; };
-     } // anon namespace
-     //! Checks if a type is an enum
-@@ -78,13 +87,13 @@ namespace cereal
-     class is_enum
-     {
-       private:
--        using DecayedT  = typename std::decay<T>::type;
--        using StrippedT = typename ::cereal::traits::strip_minimal<DecayedT>::type;
-+        typedef typename std::decay<T>::type DecayedT;
-+        typedef typename ::cereal::traits::strip_minimal<DecayedT>::type StrippedT;
-       public:
-         static const bool value = std::is_enum<StrippedT>::value;
--        using type = StrippedT;
--        using base_type = typename enum_underlying_type<StrippedT, value>::type;
-+        typedef StrippedT type;
-+        typedef typename enum_underlying_type<StrippedT, value>::type base_type;
-     };
-   }
-diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp
-index bf56c92..d2357ff 100644
---- a/include/cereal/types/memory.hpp
-+++ b/include/cereal/types/memory.hpp
-@@ -115,9 +115,9 @@ namespace cereal
-     class EnableSharedStateHelper
-     {
-       // typedefs for parent type and storage type
--      using BaseType = typename ::cereal::traits::get_shared_from_this_base<T>::type;
--      using ParentType = std::enable_shared_from_this<BaseType>;
--      using StorageType = typename std::aligned_storage<sizeof(ParentType)>::type;
-+      typedef typename ::cereal::traits::get_shared_from_this_base<T>::type BaseType;
-+      typedef std::enable_shared_from_this<BaseType> ParentType;
-+      typedef typename std::aligned_storage<sizeof(ParentType)>::type StorageType;
-       public:
-         //! Saves the state of some type inheriting from enable_shared_from_this
-@@ -257,7 +257,7 @@ namespace cereal
-     {
-       // Storage type for the pointer - since we can't default construct this type,
-       // we'll allocate it using std::aligned_storage and use a custom deleter
--      using ST = typename std::aligned_storage<sizeof(T)>::type;
-+      typedef typename std::aligned_storage<sizeof(T)>::type ST;
-       // Valid flag - set to true once construction finishes
-       //  This prevents us from calling the destructor on
-@@ -345,7 +345,7 @@ namespace cereal
-     {
-       // Storage type for the pointer - since we can't default construct this type,
-       // we'll allocate it using std::aligned_storage
--      using ST = typename std::aligned_storage<sizeof(T)>::type;
-+      typedef typename std::aligned_storage<sizeof(T)>::type ST;
-       // Allocate storage - note the ST type so that deleter is correct if
-       //                    an exception is thrown before we are initialized
--- 
-1.9.3
-
index 84a8f93..987c0f5 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "OCPlatform.h"
 #include "OCResource.h"
+#include "ocpayload.h"
 #include <OCSerialization.h>
 using namespace std;
 
@@ -38,7 +39,11 @@ namespace OC
 
         if(m_cfg.mode == ModeType::Client)
         {
-            OCStackResult result = OCInit(m_cfg.ipAddress.c_str(), m_cfg.port, OC_CLIENT);
+            OCTransportFlags serverFlags =
+                            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);
 
             if(OC_STACK_OK != result)
             {
@@ -94,28 +99,21 @@ namespace OC
 
     OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
     {
-        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
-        {
+        if(clientResponse->payload == nullptr ||
+                (
+                    clientResponse->payload->type != PAYLOAD_TYPE_DEVICE &&
+                    clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM &&
+                    clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
+                )
+          )
+        {
+            //OCPayloadDestroy(clientResponse->payload);
             return OCRepresentation();
         }
 
         MessageContainer oc;
-        try
-        {
-            oc.setJSONRepresentation(clientResponse->resJSONPayload);
-        }
-        catch (cereal::RapidJSONException& ex)
-        {
-            oclog() <<"RapidJSON Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
-                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
-            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
-        }
-        catch (cereal::Exception& ex)
-        {
-            oclog() <<"Cereal Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
-                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
-            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
-        }
+        oc.setPayload(clientResponse->payload);
+        //OCPayloadDestroy(clientResponse->payload);
 
         std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
         if(it == oc.representations().end())
@@ -149,6 +147,13 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
+        if(!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+        {
+            oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
+                << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         auto clientWrapper = context->clientWrapper.lock();
 
         if(!clientWrapper)
@@ -158,40 +163,24 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
-        std::stringstream requestStream;
-        requestStream << clientResponse->resJSONPayload;
-
-        try
+        ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+                                reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+        // loop to ensure valid construction of all resources
+        for(auto resource : container.Resources())
         {
-
-            ListenOCContainer container(clientWrapper, *clientResponse->addr,
-                    clientResponse->connType, requestStream);
-            // loop to ensure valid construction of all resources
-            for(auto resource : container.Resources())
-            {
-                std::thread exec(context->callback, resource);
-                exec.detach();
-            }
-
-        }
-        catch(const std::exception& e)
-        {
-            oclog() << "listenCallback failed to parse a malformed message: "
-                    << e.what()
-                    << std::endl
-                    << clientResponse->resJSONPayload
-                    << std::endl
-                    << clientResponse->result
-                    << std::flush;
-            return OC_STACK_KEEP_TRANSACTION;
+            std::thread exec(context->callback, resource);
+            exec.detach();
         }
 
+
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
-        const std::string& resourceType, OCConnectivityType connectivityType,
-        FindCallback& callback, QualityOfService QoS)
+    OCStackResult InProcClientWrapper::ListenForResource(
+            const std::string& serviceUrl,
+            const std::string& resourceType,
+            OCConnectivityType connectivityType,
+            FindCallback& callback, QualityOfService QoS)
     {
         if(!callback)
         {
@@ -199,23 +188,23 @@ namespace OC
         }
 
         OCStackResult result;
+        ostringstream resourceUri;
+        resourceUri << serviceUrl << resourceType;
 
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext();
-        context->callback = callback;
-        context->clientWrapper = shared_from_this();
-
-        cbdata.context =  static_cast<void*>(context);
-        cbdata.cb = listenCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);};
+        ClientCallbackContext::ListenContext* context =
+            new ClientCallbackContext::ListenContext(callback, shared_from_this());
+        OCCallbackData cbdata(
+                static_cast<void*>(context),
+                listenCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);}
+            );
 
         auto cLock = m_csdkLock.lock();
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDoResource(nullptr, OC_REST_GET,
-                                  resourceType.c_str(),
+            result = OCDoResource(nullptr, OC_REST_DISCOVER,
+                                  resourceUri.str().c_str(),
                                   nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
@@ -250,31 +239,35 @@ namespace OC
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
-        const std::string& deviceURI, OCConnectivityType connectivityType,
-        FindDeviceCallback& callback, QualityOfService QoS)
+    OCStackResult InProcClientWrapper::ListenForDevice(
+            const std::string& serviceUrl,
+            const std::string& deviceURI,
+            OCConnectivityType connectivityType,
+            FindDeviceCallback& callback,
+            QualityOfService QoS)
     {
         if(!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
+        ostringstream deviceUri;
+        deviceUri << serviceUrl << deviceURI;
 
-        OCCallbackData cbdata = {0};
         ClientCallbackContext::DeviceListenContext* context =
-            new ClientCallbackContext::DeviceListenContext();
-        context->callback = callback;
-        context->clientWrapper = shared_from_this();
-        cbdata.context =  static_cast<void*>(context);
-        cbdata.cb = listenDeviceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
+            new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
+        OCCallbackData cbdata(
+                static_cast<void*>(context),
+                listenDeviceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);}
+                );
 
         auto cLock = m_csdkLock.lock();
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDoResource(nullptr, OC_REST_GET,
-                                  deviceURI.c_str(),
+            result = OCDoResource(nullptr, OC_REST_DISCOVER,
+                                  deviceUri.str().c_str(),
                                   nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
@@ -341,8 +334,9 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType,
+    OCStackResult InProcClientWrapper::GetResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& resourceUri,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         GetCallback& callback, QualityOfService QoS)
     {
@@ -351,26 +345,28 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
+        ClientCallbackContext::GetContext* ctx =
+            new ClientCallbackContext::GetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                getResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);}
+                );
 
-        ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext();
-        ctx->callback = callback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cb = &getResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);};
+        std::string uri = assembleSetResourceUri(resourceUri, queryParams);
 
         auto cLock = m_csdkLock.lock();
 
         if(cLock)
         {
-            std::ostringstream os;
-            os << host << assembleSetResourceUri(uri, queryParams).c_str();
-
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            result = OCDoResource(nullptr, OC_REST_GET, os.str().c_str(),
-                                  nullptr, nullptr, connectivityType,
+            result = OCDoResource(
+                                  nullptr, OC_REST_GET,
+                                  uri.c_str(),
+                                  &devAddr, nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -430,11 +426,11 @@ namespace OC
 
         for(auto& param : queryParams)
         {
-            paramsList << param.first <<'='<<param.second<<'&';
+            paramsList << param.first <<'='<<param.second<<';';
         }
 
         std::string queryString = paramsList.str();
-        if(queryString.back() == '&')
+        if(queryString.back() == ';')
         {
             queryString.resize(queryString.size() - 1);
         }
@@ -443,15 +439,17 @@ namespace OC
         return ret;
     }
 
-    std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
+    OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
     {
         MessageContainer ocInfo;
         ocInfo.addRepresentation(rep);
-        return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
+        return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
     }
 
-    OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
+    OCStackResult InProcClientWrapper::PostResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
+        const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PostCallback& callback, QualityOfService QoS)
     {
@@ -460,18 +458,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
-        ctx->callback = callback;
-        cbdata.cb = &setResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
+        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                setResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);}
+                );
 
-        // TODO: in the future the cstack should be combining these two strings!
-        ostringstream os;
-        os << host << assembleSetResourceUri(uri, queryParams).c_str();
-        // TODO: end of above
+        std::string url = assembleSetResourceUri(uri, queryParams);
 
         auto cLock = m_csdkLock.lock();
 
@@ -481,8 +475,9 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(nullptr, OC_REST_POST,
-                                  os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  url.c_str(), &devAddr,
+                                  assembleSetResourcePayload(rep),
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -497,8 +492,10 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
+    OCStackResult InProcClientWrapper::PutResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
+        const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PutCallback& callback, QualityOfService QoS)
     {
@@ -507,18 +504,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
+        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                setResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);}
+                );
 
-        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
-        ctx->callback = callback;
-        cbdata.cb = &setResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
-
-        // TODO: in the future the cstack should be combining these two strings!
-        ostringstream os;
-        os << host << assembleSetResourceUri(uri, queryParams).c_str();
-        // TODO: end of above
+        std::string url = assembleSetResourceUri(uri, queryParams).c_str();
 
         auto cLock = m_csdkLock.lock();
 
@@ -529,8 +522,9 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(&handle, OC_REST_PUT,
-                                  os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  url.c_str(), &devAddr,
+                                  assembleSetResourcePayload(rep),
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -561,8 +555,9 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType,
+    OCStackResult InProcClientWrapper::DeleteResource(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
         const HeaderOptions& headerOptions, DeleteCallback& callback, QualityOfService QoS)
     {
         if(!callback)
@@ -570,16 +565,13 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext();
-        ctx->callback = callback;
-        cbdata.cb = &deleteResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
-
-        ostringstream os;
-        os << host << uri;
+        ClientCallbackContext::DeleteContext* ctx =
+            new ClientCallbackContext::DeleteContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                deleteResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);}
+                );
 
         auto cLock = m_csdkLock.lock();
 
@@ -590,8 +582,9 @@ namespace OC
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
             result = OCDoResource(nullptr, OC_REST_DELETE,
-                                  os.str().c_str(), nullptr,
-                                  nullptr, connectivityType,
+                                  uri.c_str(), &devAddr,
+                                  nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -638,7 +631,8 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
-        const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
+        const OCDevAddr& devAddr,
+        const std::string& uri,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         ObserveCallback& callback, QualityOfService QoS)
     {
@@ -647,13 +641,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
 
-        ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext();
-        ctx->callback = callback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cb = &observeResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);};
+        ClientCallbackContext::ObserveContext* ctx =
+            new ClientCallbackContext::ObserveContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                observeResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);}
+                );
 
         OCMethod method;
         if (observeType == ObserveType::Observe)
@@ -669,19 +664,19 @@ namespace OC
             method = OC_REST_OBSERVE_ALL;
         }
 
+        std::string url = assembleSetResourceUri(uri, queryParams).c_str();
+
         auto cLock = m_csdkLock.lock();
 
         if(cLock)
         {
-            std::ostringstream os;
-            os << host << assembleSetResourceUri(uri, queryParams).c_str();
-
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(handle, method,
-                                  os.str().c_str(), nullptr,
-                                  nullptr, connectivityType,
+                                  url.c_str(), &devAddr,
+                                  nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -696,9 +691,12 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
-        const std::string& host, const std::string& uri, const HeaderOptions& headerOptions,
-        QualityOfService QoS)
+    OCStackResult InProcClientWrapper::CancelObserveResource(
+            OCDoHandle handle,
+            const std::string& host, // unused
+            const std::string& uri,  // unused
+            const HeaderOptions& headerOptions,
+            QualityOfService QoS)
     {
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
@@ -724,32 +722,19 @@ namespace OC
     OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
             OCClientResponse* clientResponse)
     {
-        ostringstream os;
-        uint16_t port;
-        uint8_t a;
-        uint8_t b;
-        uint8_t c;
-        uint8_t d;
+        ClientCallbackContext::SubscribePresenceContext* context =
+        static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
 
-        if(OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) == 0 &&
-                OCDevAddrToPort(clientResponse->addr, &port) == 0)
-        {
-            os<<static_cast<int>(a)<<"."<<static_cast<int>(b)<<"."<<static_cast<int>(c)
-                    <<"."<<static_cast<int>(d)<<":"<<static_cast<int>(port);
+        /*
+         * This a hack while we rethink presence subscription.
+         */
+        std::string url = clientResponse->devAddr.addr;
 
-            ClientCallbackContext::SubscribePresenceContext* context =
-                static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
+        std::thread exec(context->callback, clientResponse->result,
+                    clientResponse->sequenceNumber, url);
 
-            std::thread exec(context->callback, clientResponse->result,
-                    clientResponse->sequenceNumber, os.str());
+        exec.detach();
 
-            exec.detach();
-        }
-        else
-        {
-            oclog() << "subscribePresenceCallback(): OCDevAddrToIPv4Addr() or OCDevAddrToPort() "
-                    <<"failed"<< std::flush;
-        }
         return OC_STACK_KEEP_TRANSACTION;
     }
 
@@ -761,19 +746,20 @@ namespace OC
         {
             return OC_STACK_INVALID_PARAM;
         }
-        OCCallbackData cbdata = {0};
 
         ClientCallbackContext::SubscribePresenceContext* ctx =
-            new ClientCallbackContext::SubscribePresenceContext();
-        ctx->callback = presenceHandler;
-        cbdata.cb = &subscribePresenceCallback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cd = [](void* c)
-            {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);};
+            new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                subscribePresenceCallback,
+                [](void* c)
+                {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);}
+                );
+
         auto cLock = m_csdkLock.lock();
 
         std::ostringstream os;
-        os << host << OC_PRESENCE_URI;
+        os << host << OC_RSRVD_PRESENCE_URI;
 
         if(!resourceType.empty())
         {
@@ -786,8 +772,10 @@ namespace OC
             return OC_STACK_ERROR;
         }
 
-        return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
-                            connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
+        return OCDoResource(handle, OC_REST_PRESENCE,
+                            os.str().c_str(), nullptr,
+                            nullptr, connectivityType,
+                            OC_LOW_QOS, &cbdata, NULL, 0);
     }
 
     OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
@@ -826,11 +814,10 @@ namespace OC
 
         for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
         {
-            options[i].protocolID = OC_COAP_ID;
-            options[i].optionID = static_cast<uint16_t>(it->getOptionID());
-            options[i].optionLength = (it->getOptionData()).length() + 1;
-            memcpy(options[i].optionData, (it->getOptionData()).c_str(),
-                    (it->getOptionData()).length() + 1);
+            options[i] = OCHeaderOption(OC_COAP_ID,
+                    it->getOptionID(),
+                    it->getOptionData().length() + 1,
+                    reinterpret_cast<const uint8_t*>(it->getOptionData().c_str()));
             i++;
         }
 
index f42a18c..e37022b 100644 (file)
@@ -33,7 +33,7 @@
 #include <OCResourceResponse.h>
 #include <ocstack.h>
 #include <OCApi.h>
-#include <ocmalloc.h>
+#include <oic_malloc.h>
 #include <OCPlatform.h>
 #include <OCUtilities.h>
 
@@ -104,14 +104,12 @@ void formResourceRequest(OCEntityHandlerFlag flag,
             else if(OC_REST_PUT == entityHandlerRequest->method)
             {
                 pRequest->setRequestType(OC::PlatformCommands::PUT);
-                pRequest->setPayload(std::string(reinterpret_cast<const char*>
-                                            (entityHandlerRequest->reqJSONPayload)));
+                pRequest->setPayload(entityHandlerRequest->payload);
             }
             else if(OC_REST_POST == entityHandlerRequest->method)
             {
                 pRequest->setRequestType(OC::PlatformCommands::POST);
-                pRequest->setPayload(std::string(reinterpret_cast<const char*>
-                                            (entityHandlerRequest->reqJSONPayload)));
+                pRequest->setPayload(entityHandlerRequest->payload);
             }
             else if(OC_REST_DELETE == entityHandlerRequest->method)
             {
@@ -137,7 +135,8 @@ void formResourceRequest(OCEntityHandlerFlag flag,
 
 OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
                                                   OCEntityHandlerRequest * entityHandlerRequest,
-                                                  char* uri)
+                                                  char* uri,
+                                                  void * callbackParam)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
 
@@ -176,7 +175,8 @@ OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
 
 
 OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag,
-                                           OCEntityHandlerRequest * entityHandlerRequest)
+                                           OCEntityHandlerRequest * entityHandlerRequest,
+                                           void* callbackParam)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
 
@@ -260,10 +260,14 @@ namespace OC
         else
         {
             throw InitializeException(OC::InitException::NOT_CONFIGURED_AS_SERVER,
-                                      OC_STACK_INVALID_PARAM);
+                                         OC_STACK_INVALID_PARAM);
         }
 
-        OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, initType);
+        OCTransportFlags serverFlags =
+                            static_cast<OCTransportFlags>(cfg.serverConnectivity & CT_MASK_FLAGS);
+        OCTransportFlags clientFlags =
+                            static_cast<OCTransportFlags>(cfg.clientConnectivity & CT_MASK_FLAGS);
+        OCStackResult result = OCInit1(initType, serverFlags, clientFlags);
 
         if(OC_STACK_OK != result)
         {
@@ -344,6 +348,7 @@ namespace OC
                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
                             resourceURI.c_str(), // const char * uri
                             EntityHandlerWrapper, // OCEntityHandler entityHandler
+                            NULL,
                             resourceProperties // uint8_t resourceProperties
                             );
             }
@@ -354,6 +359,7 @@ namespace OC
                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
                             resourceURI.c_str(), // const char * uri
                             NULL, // OCEntityHandler entityHandler
+                            NULL,
                             resourceProperties // uint8_t resourceProperties
                             );
             }
@@ -377,65 +383,7 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcServerWrapper::registerResourceWithHost(
-                    OCResourceHandle& resourceHandle,
-                    std::string& resourceHOST,
-                    std::string& resourceURI,
-                    const std::string& resourceTypeName,
-                    const std::string& resourceInterface,
-                    EntityHandler& eHandler,
-                    uint8_t resourceProperties)
-
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        auto cLock = m_csdkLock.lock();
-
-        if (cLock)
-        {
-            std::lock_guard < std::recursive_mutex > lock(*cLock);
-
-            if (NULL != eHandler)
-            {
-                result = OCCreateResourceWithHost(&resourceHandle, // OCResourceHandle *handle
-                        resourceTypeName.c_str(), // const char * resourceTypeName
-                        resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
-                        resourceHOST.c_str(), // const char * host
-                        (resourceHOST + resourceURI).c_str(), // const char * uri
-                        EntityHandlerWrapper, // OCEntityHandler entityHandler
-                        resourceProperties // uint8_t resourceProperties
-                        );
-            }
-            else
-            {
-                result = OCCreateResourceWithHost(&resourceHandle, // OCResourceHandle *handle
-                        resourceTypeName.c_str(), // const char * resourceTypeName
-                        resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
-                        resourceHOST.c_str(), // const char * host
-                        (resourceHOST + resourceURI).c_str(), // const char * uri
-                        nullptr, // OCEntityHandler entityHandler
-                        resourceProperties // uint8_t resourceProperties
-                        );
-            }
 
-            if (result != OC_STACK_OK)
-            {
-                resourceHandle = nullptr;
-            }
-            else
-            {
-                std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
-                OC::details::entityHandlerMap[resourceHandle] = eHandler;
-                OC::details::resourceUriMap[resourceHandle] = resourceURI;
-            }
-        }
-        else
-        {
-            result = OC_STACK_ERROR;
-        }
-
-        return result;
-    }
 
     OCStackResult InProcServerWrapper::setDefaultDeviceEntityHandler
                                         (EntityHandler entityHandler)
@@ -449,12 +397,12 @@ namespace OC
 
         if(entityHandler)
         {
-            result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper);
+            result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper, NULL);
         }
         else
         {
             // If Null passed we unset
-            result = OCSetDefaultDeviceEntityHandler(NULL);
+            result = OCSetDefaultDeviceEntityHandler(NULL, NULL);
         }
 
         return result;
@@ -582,25 +530,15 @@ namespace OC
         else
         {
             OCEntityHandlerResponse response;
-            std::string payLoad;
-            HeaderOptions serverHeaderOptions;
-
-            payLoad = pResponse->getPayload();
-            serverHeaderOptions = pResponse->getHeaderOptions();
+//            OCRepPayload* payLoad = pResponse->getPayload();
+            HeaderOptions serverHeaderOptions = pResponse->getHeaderOptions();
 
             response.requestHandle = pResponse->getRequestHandle();
             response.resourceHandle = pResponse->getResourceHandle();
             response.ehResult = pResponse->getResponseResult();
 
-            response.payload = static_cast<char*>(OCMalloc(payLoad.length() + 1));
-            if(!response.payload)
-            {
-                result = OC_STACK_NO_MEMORY;
-                throw OCException(OC::Exception::NO_MEMORY, OC_STACK_NO_MEMORY);
-            }
+            response.payload = reinterpret_cast<OCPayload*>(pResponse->getPayload());
 
-            strncpy(response.payload, payLoad.c_str(), payLoad.length()+1);
-            response.payloadSize = payLoad.length() + 1;
             response.persistentBufferFlag = 0;
 
             response.numSendVendorSpecificHeaderOptions = serverHeaderOptions.size();
@@ -612,18 +550,20 @@ namespace OC
                     static_cast<uint16_t>(it->getOptionID());
                 response.sendVendorSpecificHeaderOptions[i].optionLength =
                     (it->getOptionData()).length() + 1;
-                memcpy(response.sendVendorSpecificHeaderOptions[i].optionData,
-                    (it->getOptionData()).c_str(),
-                    (it->getOptionData()).length() + 1);
+                std::string optionData = it->getOptionData();
+                std::copy(optionData.begin(),
+                         optionData.end(),
+                         response.sendVendorSpecificHeaderOptions[i].optionData);
+                response.sendVendorSpecificHeaderOptions[i].optionData[it->getOptionData().length()]
+                    = '\0';
                 i++;
             }
 
             if(OC_EH_RESOURCE_CREATED == response.ehResult)
             {
-                std::string createdUri = pResponse->getNewResourceUri();
-                strncpy(reinterpret_cast<char*>(response.resourceUri),
-                        createdUri.c_str(),
-                        createdUri.length() + 1);
+                pResponse->getNewResourceUri().copy(response.resourceUri,
+                        sizeof (response.resourceUri) - 1);
+                response.resourceUri[pResponse->getNewResourceUri().length()] = '\0';
             }
 
             if(cLock)
@@ -633,7 +573,7 @@ namespace OC
             }
             else
             {
-                OCFree(response.payload);
+                OICFree(response.payload);
                 result = OC_STACK_ERROR;
             }
 
index 64d1cfd..76893f1 100644 (file)
@@ -63,6 +63,8 @@ std::string OC::OCException::reason(const OCStackResult sr)
             return OC::Exception::RESOURCE_ERROR;
         case OC_STACK_SLOW_RESOURCE:
             return OC::Exception::SLOW_RESOURCE;
+        case OC_STACK_DUPLICATE_REQUEST:
+            return OC::Exception::DUPLICATE_REQUEST;
         case OC_STACK_NO_OBSERVERS:
             return OC::Exception::NO_OBSERVERS;
         case OC_STACK_OBSERVER_NOT_FOUND:
@@ -93,6 +95,8 @@ std::string OC::OCException::reason(const OCStackResult sr)
             return OC::Exception::INVALID_DEVICE_INFO;
         case OC_STACK_INVALID_JSON:
             return OC::Exception::INVALID_REPRESENTATION;
+        case OC_STACK_UNAUTHORIZED_REQ:
+            return OC::Exception::UNAUTHORIZED_REQUEST;
     }
 
     return OC::Exception::UNKNOWN_ERROR;
index 8093aa2..4a7bc49 100644 (file)
@@ -77,43 +77,45 @@ namespace OC
                                                 const std::vector<std::string>& resourceTypes,
                                                 const std::vector<std::string>& interfaces)
         {
-            return OCPlatform_impl::Instance().constructResourceObject(host, uri, connectivityType,
+            return OCPlatform_impl::Instance().constructResourceObject(host,
+                                                uri, connectivityType,
                                                 isObservable,
                                                 resourceTypes, interfaces);
         }
 
         OCStackResult findResource(const std::string& host,
-                                                const std::string& resourceName,
-                                                OCConnectivityType connectivityType,
-                                                FindCallback resourceHandler)
+                                            const std::string& resourceName,
+                                            OCConnectivityType connectivityType,
+                                            FindCallback resourceHandler)
         {
             return OCPlatform_impl::Instance().findResource(host, resourceName,
-                   connectivityType, resourceHandler);
+                                    connectivityType, resourceHandler);
         }
 
         OCStackResult findResource(const std::string& host,
-                                                const std::string& resourceName,
-                                                OCConnectivityType connectivityType,
-                                                FindCallback resourceHandler, QualityOfService QoS)
+                                            const std::string& resourceName,
+                                            OCConnectivityType connectivityType,
+                                            FindCallback resourceHandler,
+                                            QualityOfService QoS)
         {
-            return OCPlatform_impl::Instance().findResource(host, resourceName, connectivityType,
-                                                resourceHandler, QoS);
+            return OCPlatform_impl::Instance().findResource(host, resourceName,
+                                    connectivityType, resourceHandler, QoS);
         }
 
         OCStackResult getDeviceInfo(const std::string& host,
-                                                const std::string& deviceURI,
-                                                OCConnectivityType connectivityType,
-                                                FindDeviceCallback deviceInfoHandler)
+                                            const std::string& deviceURI,
+                                            OCConnectivityType connectivityType,
+                                            FindDeviceCallback deviceInfoHandler)
         {
             return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI,
                    connectivityType, deviceInfoHandler);
         }
 
         OCStackResult getDeviceInfo(const std::string& host,
-                                                const std::string& deviceURI,
-                                                OCConnectivityType connectivityType,
-                                                FindDeviceCallback deviceInfoHandler,
-                                                QualityOfService QoS)
+                                            const std::string& deviceURI,
+                                            OCConnectivityType connectivityType,
+                                            FindDeviceCallback deviceInfoHandler,
+                                            QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI, connectivityType,
                     deviceInfoHandler, QoS);
index e694bab..2a612a6 100644 (file)
@@ -42,6 +42,7 @@
 #include "OCApi.h"
 #include "OCException.h"
 #include "OCUtilities.h"
+#include "ocpayload.h"
 
 #include "oc_logger.hpp"
 
@@ -56,6 +57,7 @@ namespace OC
 
     void OCPlatform_impl::Configure(const PlatformConfig& config)
     {
+        OCRegisterPersistentStorageHandler(config.ps);
         globalConfig() = config;
     }
 
@@ -131,13 +133,14 @@ namespace OC
          return result_guard(OC_STACK_ERROR);
         }
 
-        std::string payload(pResponse->getResourceRepresentation().getJSONRepresentation());
-
-        return result_guard(
+        OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
+        OCStackResult result =
                    OCNotifyListOfObservers(resourceHandle,
                             &observationIds[0], observationIds.size(),
-                            payload.c_str(),
-                            static_cast<OCQualityOfService>(QoS)));
+                            pl,
+                            static_cast<OCQualityOfService>(QoS));
+        OCRepPayloadDestroy(pl);
+        return result_guard(result);
     }
 
     OCResource::Ptr OCPlatform_impl::constructResourceObject(const std::string& host,
@@ -171,9 +174,9 @@ namespace OC
     OCStackResult OCPlatform_impl::findResource(const std::string& host,
                                             const std::string& resourceName,
                                             OCConnectivityType connectivityType,
-                                            FindCallback resourceHandler, QualityOfService QoS)
+                                            FindCallback resourceHandler,
+                                            QualityOfService QoS)
     {
-
         return checked_guard(m_client, &IClientWrapper::ListenForResource,
                              host, resourceName, connectivityType, resourceHandler, QoS);
     }
@@ -244,8 +247,8 @@ namespace OC
         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
         std::vector<std::string> resourceTypes = resource->getResourceTypes();
 
-        return checked_guard(m_server, &IServerWrapper::registerResourceWithHost,
-                std::ref(resourceHandle), resource->host(), resource->uri(),
+        return checked_guard(m_server, &IServerWrapper::registerResource,
+                std::ref(resourceHandle), resource->host() + resource->uri(),
                 resourceTypes[0]/*"core.remote"*/, DEFAULT_INTERFACE,
                 (EntityHandler) nullptr, resourceProperty);
     }
index 6f73435..998bdbe 100644 (file)
 #include <OCRepresentation.h>
 
 #include <boost/lexical_cast.hpp>
-#include <cereal/cereal.hpp>
-#include <cereal/types/map.hpp>
-#include <cereal/types/vector.hpp>
-#include <cereal/types/utility.hpp>
-#include <OicJsonSerializer.hpp>
 #include <algorithm>
+#include "ocpayload.h"
+#include "ocrandom.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
 
-// code needed to serialize a string=>Attribute value map
 namespace OC
 {
-    namespace detail
+
+    void MessageContainer::setPayload(const OCPayload* rep)
     {
-        template<class Archive>
-        class WriteAttributeValue : public boost::static_visitor<>
+        switch(rep->type)
         {
-            public:
-                WriteAttributeValue(const std::string& name, Archive& ar)
-                    :m_name(name), m_archive(ar)
-                {}
-
-                template<class T>
-                void operator()(const T& value) const
-                {
-                    m_archive(cereal::make_nvp(m_name, value));
-                }
-            private:
-                std::string m_name;
-                Archive& m_archive;
-        };
+            case PAYLOAD_TYPE_REPRESENTATION:
+                setPayload(reinterpret_cast<const OCRepPayload*>(rep));
+                break;
+            case PAYLOAD_TYPE_DEVICE:
+                setPayload(reinterpret_cast<const OCDevicePayload*>(rep));
+                break;
+            case PAYLOAD_TYPE_PLATFORM:
+                setPayload(reinterpret_cast<const OCPlatformPayload*>(rep));
+                break;
+            default:
+                throw OC::OCException("Invalid Payload type in setPayload");
+                break;
+        }
     }
-}
-
-namespace cereal
-{
-    // take no action when serializing the null type, because the 'save' below
-    // doesn't use the visitor for this type.
-    template <class Archive>
-    void serialize(Archive&, OC::NullType t)
-    {}
 
-    template<class Archive>
-    void save(Archive& ar, const std::map<std::string, OC::AttributeValue>& vals)
+    void MessageContainer::setPayload(const OCDevicePayload* payload)
     {
-        for(const auto& kv : vals)
+        OCRepresentation rep;
+        rep.setUri(payload->uri);
+        char uuidString[UUID_STRING_SIZE];
+        if(payload->sid && RAND_UUID_OK == OCConvertUuidToString(payload->sid, uuidString))
         {
-            const auto& k = kv.first;
-            const auto& v = kv.second;
+            rep[OC_RSRVD_DEVICE_ID] = std::string(uuidString);
+        }
+        else
+        {
+            rep[OC_RSRVD_DEVICE_ID] = std::string();
+        }
+        rep[OC_RSRVD_DEVICE_NAME] = payload->deviceName ?
+            std::string(payload->deviceName) :
+            std::string();
+        rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ?
+            std::string(payload->specVersion) :
+            std::string();
+        rep[OC_RSRVD_DATA_MODEL_VERSION] = payload->dataModelVersion ?
+            std::string(payload->dataModelVersion) :
+            std::string();
+        m_reps.push_back(std::move(rep));
+    }
+
+    void MessageContainer::setPayload(const OCPlatformPayload* payload)
+    {
+        OCRepresentation rep;
+        rep.setUri(payload->uri);
+
+        rep[OC_RSRVD_PLATFORM_ID] = payload->info.platformID ?
+            std::string(payload->info.platformID) :
+            std::string();
+        rep[OC_RSRVD_MFG_NAME] = payload->info.manufacturerName ?
+            std::string(payload->info.manufacturerName) :
+            std::string();
+        rep[OC_RSRVD_MFG_URL] = payload->info.manufacturerUrl ?
+            std::string(payload->info.manufacturerUrl) :
+            std::string();
+        rep[OC_RSRVD_MODEL_NUM] = payload->info.modelNumber ?
+            std::string(payload->info.modelNumber) :
+            std::string();
+        rep[OC_RSRVD_MFG_DATE] = payload->info.dateOfManufacture ?
+            std::string(payload->info.dateOfManufacture) :
+            std::string();
+        rep[OC_RSRVD_PLATFORM_VERSION] = payload->info.platformVersion ?
+            std::string(payload->info.platformVersion) :
+            std::string();
+        rep[OC_RSRVD_OS_VERSION] = payload->info.operatingSystemVersion ?
+            std::string(payload->info.operatingSystemVersion) :
+            std::string();
+        rep[OC_RSRVD_HARDWARE_VERSION] = payload->info.hardwareVersion ?
+            std::string(payload->info.hardwareVersion) :
+            std::string();
+        rep[OC_RSRVD_FIRMWARE_VERSION] = payload->info.firmwareVersion ?
+            std::string(payload->info.firmwareVersion) :
+            std::string();
+        rep[OC_RSRVD_SUPPORT_URL] = payload->info.supportUrl ?
+            std::string(payload->info.supportUrl) :
+            std::string();
+        rep[OC_RSRVD_SYSTEM_TIME] = payload->info.systemTime ?
+            std::string(payload->info.systemTime) :
+            std::string();
+
+        m_reps.push_back(std::move(rep));
+    }
+
+    void MessageContainer::setPayload(const OCRepPayload* payload)
+    {
+        const OCRepPayload* pl = payload;
+        while(pl)
+        {
+            OCRepresentation cur;
+            cur.setPayload(pl);
+
+            pl = pl->next;
+            this->addRepresentation(cur);
+        }
+    }
 
-            if(v.which() != OC::AttributeValueNullIndex)
+    OCRepPayload* MessageContainer::getPayload() const
+    {
+        OCRepPayload* root = nullptr;
+        for(const auto& r : representations())
+        {
+            if(!root)
             {
-                OC::detail::WriteAttributeValue<Archive> writer(k,ar);
-                boost::apply_visitor(writer, v);
+                root = r.getPayload();
             }
             else
             {
-                ar.setNextName(k.c_str());
-                ar.writeName();
-                ar.saveValue();
+                OCRepPayloadAppend(root, r.getPayload());
             }
         }
+
+        return root;
     }
 
-    template<class Archive>
-    void load(Archive& ar, std::map<std::string, OC::AttributeValue>& vals)
+    const std::vector<OCRepresentation>& MessageContainer::representations() const
     {
-        ar.loadAttributeValues(vals);
+        return m_reps;
+    }
+
+    void MessageContainer::addRepresentation(const OCRepresentation& rep)
+    {
+        m_reps.push_back(rep);
     }
 }
 
 namespace OC
 {
-    typedef cereal::JSONOutputArchive OutputArchiveType;
-    typedef cereal::JSONInputArchive InputArchiveType;
+    struct get_payload_array: boost::static_visitor<>
+    {
+        template<typename T>
+        void operator()(T& arr)
+        {
+            throw std::logic_error("Invalid calc_dimensions_visitor type");
+        }
+
+        template<typename T>
+        void operator()(std::vector<T>& arr)
+        {
+            root_size_calc<T>();
+            dimensions[0] = arr.size();
+            dimTotal = calcDimTotal(dimensions);
+
+            array = (void*)OICMalloc(dimTotal * root_size);
+
+            for(size_t i = 0; i < dimensions[0]; ++i)
+            {
+                copy_to_array(arr[i], array, i);
+            }
+
+        }
+        template<typename T>
+        void operator()(std::vector<std::vector<T>>& arr)
+        {
+            root_size_calc<T>();
+            dimensions[0] = arr.size();
+            for(size_t i = 0; i < arr.size(); ++i)
+            {
+                dimensions[1] = std::max(dimensions[1], arr[i].size());
+            }
+            dimTotal = calcDimTotal(dimensions);
+            array = (void*)OICCalloc(1, dimTotal * root_size);
+
+            for(size_t i = 0; i < dimensions[0]; ++i)
+            {
+                for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
+                {
+                    copy_to_array(arr[i][j], array, i*dimensions[1] + j);
+                }
+            }
+        }
+        template<typename T>
+        void operator()(std::vector<std::vector<std::vector<T>>>& arr)
+        {
+            root_size_calc<T>();
+            dimensions[0] = arr.size();
+            for(size_t i = 0; i < arr.size(); ++i)
+            {
+                dimensions[1] = std::max(dimensions[1], arr[i].size());
+
+                for(size_t j = 0; j < arr[i].size(); ++j)
+                {
+                    dimensions[2] = std::max(dimensions[2], arr[i][j].size());
+                }
+            }
+
+            dimTotal = calcDimTotal(dimensions);
+            array = (void*)OICCalloc(1, dimTotal * root_size);
+
+            for(size_t i = 0; i < dimensions[0]; ++i)
+            {
+                for(size_t j = 0; j < dimensions[1] && j < arr[i].size(); ++j)
+                {
+                    for(size_t k = 0; k < dimensions[2] && k < arr[i][j].size(); ++k)
+                    {
+                        copy_to_array(arr[i][j][k], array,
+                                dimensions[2] * j +
+                                dimensions[2] * dimensions[1] * i +
+                                k);
+                    }
+                }
+            }
+        }
+
+        template<typename T>
+        void root_size_calc()
+        {
+            root_size = sizeof(T);
+        }
+
+        template<typename T>
+        void copy_to_array(T item, void* array, size_t pos)
+        {
+            ((T*)array)[pos] = item;
+        }
 
-    void MessageContainer::setJSONRepresentation(const std::string& payload)
+        size_t dimensions[MAX_REP_ARRAY_DEPTH];
+        size_t root_size;
+        size_t dimTotal;
+        void* array;
+    };
+
+    template<>
+    void get_payload_array::root_size_calc<int>()
+    {
+        root_size = sizeof(int64_t);
+    }
+
+    template<>
+    void get_payload_array::root_size_calc<std::string>()
+    {
+        root_size = sizeof(char*);
+    }
+
+    template<>
+    void get_payload_array::root_size_calc<OC::OCRepresentation>()
+    {
+        root_size = sizeof(OCRepPayload*);
+    }
+
+    template<>
+    void get_payload_array::copy_to_array(int item, void* array, size_t pos)
+    {
+        ((int64_t*)array)[pos] = item;
+    }
+
+    template<>
+    void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos)
+    {
+        ((bool*)array)[pos] = static_cast<bool>(br);
+    }
+
+    template<>
+    void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
     {
-        std::stringstream os(payload);
+        ((char**)array)[pos] = OICStrdup(item.c_str());
+    }
+
+    template<>
+    void get_payload_array::copy_to_array(OC::OCRepresentation item, void* array, size_t pos)
+    {
+        ((OCRepPayload**)array)[pos] = item.getPayload();
+    }
+
+    void OCRepresentation::getPayloadArray(OCRepPayload* payload,
+                    const OCRepresentation::AttributeItem& item) const
+    {
+        get_payload_array vis{};
+        boost::apply_visitor(vis, m_values[item.attrname()]);
+
+
+        switch(item.base_type())
         {
-            InputArchiveType archive(os);
-            archive(cereal::make_nvp(OC::Key::OCKEY, m_reps));
+            case AttributeType::Integer:
+                OCRepPayloadSetIntArrayAsOwner(payload, item.attrname().c_str(),
+                        (int64_t*)vis.array,
+                        vis.dimensions);
+                break;
+            case AttributeType::Double:
+                OCRepPayloadSetDoubleArrayAsOwner(payload, item.attrname().c_str(),
+                        (double*)vis.array,
+                        vis.dimensions);
+                break;
+            case AttributeType::Boolean:
+                OCRepPayloadSetBoolArrayAsOwner(payload, item.attrname().c_str(),
+                        (bool*)vis.array,
+                        vis.dimensions);
+                break;
+            case AttributeType::String:
+                OCRepPayloadSetStringArrayAsOwner(payload, item.attrname().c_str(),
+                        (char**)vis.array,
+                        vis.dimensions);
+                break;
+            case AttributeType::OCRepresentation:
+                OCRepPayloadSetPropObjectArrayAsOwner(payload, item.attrname().c_str(),
+                        (OCRepPayload**)vis.array, vis.dimensions);
+                break;
+            default:
+                throw std::logic_error(std::string("GetPayloadArray: Not Implemented") +
+                        std::to_string((int)item.base_type()));
         }
     }
 
-    void MessageContainer::setJSONRepresentation(const char* payload)
+    OCRepPayload* OCRepresentation::getPayload() const
     {
-        setJSONRepresentation(std::string(payload));
+        OCRepPayload* root = OCRepPayloadCreate();
+        if(!root)
+        {
+            throw std::bad_alloc();
+        }
+
+        OCRepPayloadSetUri(root, getUri().c_str());
+
+        for(const std::string& type : getResourceTypes())
+        {
+            OCRepPayloadAddResourceType(root, type.c_str());
+        }
+
+        for(const std::string& iface : getResourceInterfaces())
+        {
+            OCRepPayloadAddInterface(root, iface.c_str());
+        }
+
+        for(auto& val : *this)
+        {
+            switch(val.type())
+            {
+                case AttributeType::Null:
+                    OCRepPayloadSetNull(root, val.attrname().c_str());
+                    break;
+                case AttributeType::Integer:
+                    OCRepPayloadSetPropInt(root, val.attrname().c_str(), static_cast<int>(val));
+                    break;
+                case AttributeType::Double:
+                    OCRepPayloadSetPropDouble(root, val.attrname().c_str(), val);
+                    break;
+                case AttributeType::Boolean:
+                    OCRepPayloadSetPropBool(root, val.attrname().c_str(), val);
+                    break;
+                case AttributeType::String:
+                    OCRepPayloadSetPropString(root, val.attrname().c_str(),
+                            static_cast<std::string>(val).c_str());
+                    break;
+                case AttributeType::OCRepresentation:
+                    OCRepPayloadSetPropObjectAsOwner(root, val.attrname().c_str(),
+                            static_cast<OCRepresentation>(val).getPayload());
+                    break;
+                case AttributeType::Vector:
+                    getPayloadArray(root, val);
+                    break;
+                default:
+                    throw std::logic_error(std::string("Getpayload: Not Implemented") +
+                            std::to_string((int)val.type()));
+                    break;
+            }
+        }
+
+        OCRepPayload* cur = root;
+        for(auto& child : this->getChildren())
+        {
+            cur->next = child.getPayload();
+            cur = cur->next;
+        }
+
+        return root;
     }
 
-    std::string MessageContainer::getJSONRepresentation(OCInfoFormat f) const
+    size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
     {
-        std::stringstream os;
+        if(dimensions[0] == 0)
+        {
+            throw std::logic_error("invalid calcArrayDepth");
+        }
+        else if(dimensions[1] == 0)
+        {
+            return 1;
+        }
+        else if (dimensions[2] == 0)
+        {
+            return 2;
+        }
+        else
+        {
+            return 3;
+        }
+    }
+
+    template<typename T>
+    T OCRepresentation::payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl)
+    {
+        throw std::logic_error("payload_array_helper_copy: unsupported type");
+    }
+    template<>
+    int OCRepresentation::payload_array_helper_copy<int>(size_t index, const OCRepPayloadValue* pl)
+    {
+        return pl->arr.iArray[index];
+    }
+    template<>
+    double OCRepresentation::payload_array_helper_copy<double>(size_t index, const OCRepPayloadValue* pl)
+    {
+        return pl->arr.dArray[index];
+    }
+    template<>
+    bool OCRepresentation::payload_array_helper_copy<bool>(size_t index, const OCRepPayloadValue* pl)
+    {
+        return pl->arr.bArray[index];
+    }
+    template<>
+    std::string OCRepresentation::payload_array_helper_copy<std::string>(
+            size_t index, const OCRepPayloadValue* pl)
+    {
+        return std::string(pl->arr.strArray[index]);
+    }
+    template<>
+    OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
+            size_t index, const OCRepPayloadValue* pl)
+    {
+        OCRepresentation r;
+        r.setPayload(pl->arr.objArray[index]);
+        return r;
+    }
 
-        // note: the block is required because cereal closes the JSON string
-        // upon destruction, so the archive needs to be destroyed before accessing
-        // the data
+    template<typename T>
+    void OCRepresentation::payload_array_helper(const OCRepPayloadValue* pl, size_t depth)
+    {
+        if(depth == 1)
         {
-            if(f == OCInfoFormat::IncludeOC)
+            std::vector<T> val(pl->arr.dimensions[0]);
+
+            for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
             {
-                OutputArchiveType archive(os);
-                archive(cereal::make_nvp(OC::Key::OCKEY, m_reps));
+                val[i] = payload_array_helper_copy<T>(i, pl);
             }
-            else if(f== OCInfoFormat::ExcludeOC)
+            this->setValue(std::string(pl->name), val);
+        }
+        else if (depth == 2)
+        {
+            std::vector<std::vector<T>> val(pl->arr.dimensions[0]);
+            for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
             {
-                bool firstPrinted = false;
-                for(std::vector<OCRepresentation>::size_type i = 0; i< m_reps.size();++i)
+                val[i].reserve(pl->arr.dimensions[1]);
+                for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
                 {
-                    if(!m_reps[i].emptyData())
+                    val[i][j] = payload_array_helper_copy<T>(
+                            i * pl->arr.dimensions[1] + j, pl);
+                }
+            }
+            this->setValue(std::string(pl->name), val);
+        }
+        else if (depth == 3)
+        {
+            std::vector<std::vector<std::vector<T>>> val;
+            for(size_t i = 0; i < pl->arr.dimensions[0]; ++i)
+            {
+                val[i].reserve(pl->arr.dimensions[1]);
+                for(size_t j = 0; j < pl->arr.dimensions[1]; ++j)
+                {
+                    val[i][j].reserve(pl->arr.dimensions[2]);
+                    for(size_t k = 0; k < pl->arr.dimensions[2]; ++k)
                     {
-                        if(firstPrinted)
-                        {
-                            os<<',';
-                        }
-                        firstPrinted=true;
-                        os << m_reps[i].getJSONRepresentation();
+                        val[i][j][k] = payload_array_helper_copy<T>(
+                                pl->arr.dimensions[2] * j +
+                                pl->arr.dimensions[2] * pl->arr.dimensions[1] * i +
+                                k,
+                                pl);
                     }
                 }
             }
+            this->setValue(std::string(pl->name), val);
+        }
+        else
+        {
+            throw std::logic_error("Invalid depth in payload_array_helper");
         }
-        return os.str();
     }
 
-    const std::vector<OCRepresentation>& MessageContainer::representations() const
+    void OCRepresentation::setPayloadArray(const OCRepPayloadValue* pl)
     {
-        return m_reps;
-    }
 
-    void MessageContainer::addRepresentation(const OCRepresentation& rep)
-    {
-        m_reps.push_back(rep);
+        switch(pl->arr.type)
+        {
+            case OCREP_PROP_INT:
+                payload_array_helper<int>(pl, calcArrayDepth(pl->arr.dimensions));
+                break;
+            case OCREP_PROP_DOUBLE:
+                payload_array_helper<double>(pl, calcArrayDepth(pl->arr.dimensions));
+                break;
+            case OCREP_PROP_BOOL:
+                payload_array_helper<bool>(pl, calcArrayDepth(pl->arr.dimensions));
+                break;
+            case OCREP_PROP_STRING:
+                payload_array_helper<std::string>(pl, calcArrayDepth(pl->arr.dimensions));
+                break;
+            case OCREP_PROP_OBJECT:
+                payload_array_helper<OCRepresentation>(pl, calcArrayDepth(pl->arr.dimensions));
+                break;
+            default:
+                throw std::logic_error("setPayload array invalid type");
+                break;
+        }
     }
-}
 
-namespace OC
-{
-    std::string OCRepresentation::getJSONRepresentation() const
+    void OCRepresentation::setPayload(const OCRepPayload* pl)
     {
-        if(emptyData())
+        setUri(pl->uri);
+
+        OCStringLL* ll = pl->types;
+        while(ll)
         {
-            return "{}";
+            addResourceType(ll->value);
+            ll = ll->next;
         }
 
-        std::stringstream os;
-
-        // note: the block is required because cereal closes the JSON string
-        // upon destruction, so the archive needs to be destroyed before accessing
-        // the data
+        ll = pl->interfaces;
+        while(ll)
         {
-            OutputArchiveType archive (os);
-            save(archive);
+            addResourceInterface(ll->value);
+            ll = ll->next;
         }
 
-        return os.str();
+        OCRepPayloadValue* val = pl->values;
+
+        while(val)
+        {
+            switch(val->type)
+            {
+                case OCREP_PROP_NULL:
+                    setNULL(val->name);
+                    break;
+                case OCREP_PROP_INT:
+                    setValue<int>(val->name, val->i);
+                    break;
+                case OCREP_PROP_DOUBLE:
+                    setValue<double>(val->name, val->d);
+                    break;
+                case OCREP_PROP_BOOL:
+                    setValue<bool>(val->name, val->b);
+                    break;
+                case OCREP_PROP_STRING:
+                    setValue<std::string>(val->name, val->str);
+                    break;
+                case OCREP_PROP_OBJECT:
+                    {
+                        OCRepresentation cur;
+                        cur.setPayload(val->obj);
+                        setValue<OCRepresentation>(val->name, cur);
+                    }
+                    break;
+                case OCREP_PROP_ARRAY:
+                    setPayloadArray(val);
+                    break;
+                default:
+                    throw std::logic_error(std::string("Not Implemented!") +
+                            std::to_string((int)val->type));
+                    break;
+            }
+            val = val->next;
+        }
     }
 
     void OCRepresentation::addChild(const OCRepresentation& rep)
@@ -202,6 +619,10 @@ namespace OC
     {
         m_children = children;
     }
+    void OCRepresentation::setUri(const char* uri)
+    {
+        m_uri = uri ? uri : "";
+    }
 
     void OCRepresentation::setUri(const std::string& uri)
     {
@@ -223,11 +644,21 @@ namespace OC
         m_resourceTypes = resourceTypes;
     }
 
+    void OCRepresentation::addResourceType(const std::string& str)
+    {
+        m_resourceTypes.push_back(str);
+    }
+
     const std::vector<std::string>& OCRepresentation::getResourceInterfaces() const
     {
         return m_interfaces;
     }
 
+    void OCRepresentation::addResourceInterface(const std::string& str)
+    {
+        m_interfaces.push_back(str);
+    }
+
     void OCRepresentation::setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
     {
         m_interfaces = resourceInterfaces;
@@ -305,355 +736,6 @@ namespace OC
 
 namespace OC
 {
-    template <class Archive, class Val>
-    void OCRepresentation::optional_load(Archive& ar, Val&& v)
-    {
-        try
-        {
-            ar(v);
-        }
-        catch(cereal::Exception&)
-        {
-            ar.setNextName(nullptr);
-            // Loading a key that doesn't exist results in an exception
-            // Since "Not Found" is a valid condition for us, we swallow
-            // this exception and the archive will not load anything
-        }
-    }
-
-    template<class Archive>
-    void OCRepresentation::save(Archive& ar) const
-    {
-        // printed for all interface types
-        if(!m_uri.empty())
-        {
-            ar(cereal::make_nvp(Key::URIKEY, m_uri));
-        }
-
-        if((m_interfaceType == InterfaceType::None
-                    || m_interfaceType==InterfaceType::DefaultChild
-                    || m_interfaceType==InterfaceType::LinkChild)
-                && (m_resourceTypes.size()>0 || m_interfaces.size()>0))
-        {
-            // The Prop object requires that it refer to non-const vectors
-            // so that it can alter them in the 'load' case.  In the save case
-            // (initiated here) it will not modify the object.  So, to keep the
-            // compiler happy, removing the 'const' context here is necessary.
-            const std::vector<std::string>& rt(m_resourceTypes);
-            const std::vector<std::string>& intf(m_interfaces);
-            Prop temp(const_cast<std::vector<std::string>&>(rt),
-                    const_cast<std::vector<std::string>&>(intf));
-            ar(cereal::make_nvp(Key::PROPERTYKEY, temp));
-        }
-
-        // printed only for BatchChildren and DefaultParent
-        if((m_interfaceType == InterfaceType::None
-                    || m_interfaceType == InterfaceType::BatchChild
-                    || m_interfaceType == InterfaceType::DefaultParent)
-                && m_values.size()>0)
-        {
-            ar(cereal::make_nvp(Key::REPKEY, m_values));
-        }
-    }
-
-    template<class Archive>
-    void OCRepresentation::load(Archive& ar)
-    {
-        optional_load(ar, cereal::make_nvp(Key::URIKEY, m_uri));
-        {
-            Prop temp(m_resourceTypes, m_interfaces);
-            optional_load(ar, cereal::make_nvp(Key::PROPERTYKEY, temp));
-        }
-        optional_load(ar, cereal::make_nvp(Key::REPKEY, m_values));
-    }
-
-    template<class Archive>
-    void OCRepresentation::Prop::save(Archive& ar) const
-    {
-        if(m_types.size() > 0)
-        {
-            ar(cereal::make_nvp(Key::RESOURCETYPESKEY, m_types));
-        }
-
-        if(m_interfaces.size()>0)
-        {
-            ar(cereal::make_nvp(Key::INTERFACESKEY, m_interfaces));
-        }
-    }
-
-    template<class Archive>
-    void OCRepresentation::Prop::load(Archive& ar)
-    {
-        optional_load(ar, cereal::make_nvp(Key::RESOURCETYPESKEY, m_types));
-        optional_load(ar, cereal::make_nvp(Key::INTERFACESKEY, m_interfaces));
-    }
-}
-
-// note: the below is used to load an AttributeValue map out of JSON
-namespace OC
-{
-    namespace detail
-    {
-        enum class typeTag:uint8_t
-        {
-            NOTHING = 0,
-            _string,
-            _int,
-            _double,
-            _bool,
-            _representation
-        };
-
-        typedef rapidjson::Document::GenericValue GenericValue;
-
-        AttributeValue parseAttributeValue(const GenericValue& v);
-        AttributeValue parseAttributeValue(const GenericValue& v,
-                const unsigned int curLevel, unsigned int& maxDepth, typeTag& t);
-        AttributeValue parseAttributeValueObject(const GenericValue& v, typeTag& t);
-        AttributeValue parseAttributeValueArray(const GenericValue& v,
-                const unsigned int curLevel, unsigned int& maxDepth, typeTag& t);
-        AttributeValue parseAttributeValuePrimitive(const GenericValue& v, typeTag& t);
-
-        AttributeValue parseAttributeValue(const GenericValue& v)
-        {
-            // base entrance, start everything at '0'
-            unsigned int max_depth {0};
-            typeTag t {typeTag::NOTHING};
-
-            return parseAttributeValue(v, 0, max_depth, t);
-        }
-
-        AttributeValue parseAttributeValue(const GenericValue& v,
-                const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
-        {
-            if(v.IsObject())
-            {
-                return parseAttributeValueObject(v, t);
-            }
-            else if(v.IsArray())
-            {
-                return parseAttributeValueArray(v, curLevel + 1, maxDepth, t);
-            }
-            else
-            {
-                return parseAttributeValuePrimitive(v,t);
-            }
-        }
-
-        AttributeValue parseAttributeValueObject(const GenericValue& v, typeTag& t)
-        {
-            typedef rapidjson::Value::ConstMemberIterator CMI;
-            t = typeTag::_representation;
-            OC::OCRepresentation rep;
-
-            for(CMI itr = v.MemberBegin(); itr!= v.MemberEnd(); ++itr)
-            {
-                std::string keyName = itr->name.GetString();
-
-                if(keyName == OC::Key::URIKEY)
-                {
-                    rep.setUri(boost::get<std::string>(parseAttributeValue(itr->value)));
-                }
-                else if (keyName == OC::Key::PROPERTYKEY)
-                {
-                    for(CMI itr2 = itr->value.MemberBegin();
-                            itr->value.MemberEnd()!=itr2;
-                            ++itr2)
-                    {
-                        if(keyName == OC::Key::RESOURCETYPESKEY)
-                        {
-                            rep.setResourceTypes(
-                                    boost::get<std::vector<std::string>>(
-                                        parseAttributeValue(itr->value)));
-                        }
-                        else if(keyName == OC::Key::PROPERTYKEY)
-                        {
-                            rep.setResourceInterfaces(
-                                    boost::get<std::vector<std::string>>(
-                                        parseAttributeValue(itr->value)));
-                        }
-                    }
-                }
-                else if (keyName == OC::Key::REPKEY)
-                {
-                    for(CMI itr2 = itr->value.MemberBegin();
-                            itr->value.MemberEnd()!=itr2;
-                            ++itr2)
-                    {
-                        rep.setValue(itr2->name.GetString(),
-                                parseAttributeValue(itr2->value));
-                    }
-                }
-            }
-
-            return rep;
-        }
-
-        AttributeValue parseAttributeValuePrimitive(const GenericValue& v, typeTag& t)
-        {
-            if(v.IsString())
-            {
-                t = typeTag::_string;
-                return std::string(v.GetString());
-            }
-            else if (v.IsNumber())
-            {
-                if(v.IsDouble())
-                {
-                    t = typeTag::_double;
-                    return double(v.GetDouble());
-                }
-                else if (v.IsInt())
-                {
-                    t = typeTag::_int;
-                    return int(v.GetInt());
-                }
-                else
-                {
-                    throw OC::OCException(OC::Exception::INVALID_JSON_NUMERIC
-                            + std::to_string(v.GetType()));
-                }
-            }
-            else if(v.IsBool_())
-            {
-                t=typeTag::_bool;
-                return bool(v.GetBool_());
-            }
-            else if(v.IsNull_())
-            {
-                return OC::NullType();
-            }
-            else
-            {
-                throw OC::OCException(OC::Exception::INVALID_JSON_TYPE
-                        + std::to_string(v.GetType()));
-            }
-        }
-
-        std::vector<AttributeValue> gatherArrayContents(const GenericValue& v,
-                const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
-        {
-            std::vector<AttributeValue> out;
-
-            std::transform(v.Begin(), v.End(), back_inserter(out),
-                    [curLevel, &maxDepth, &t](const GenericValue& x)
-                    {
-                        return parseAttributeValue(x, curLevel, maxDepth, t);
-                    });
-            return out;
-        }
-
-        template<class OutT>
-        struct valueToConcrete
-        {
-            OutT operator()(const AttributeValue& v)
-            {
-                return boost::get<OutT>(v);
-            }
-
-        };
-
-        template <class OutSeqT>
-        OutSeqT valuesToConcreteVectors(const std::vector<AttributeValue>& vs)
-        {
-            OutSeqT ret;
-
-            std::transform(begin(vs),end(vs), back_inserter(ret),
-                valueToConcrete<typename OutSeqT::value_type>());
-            return ret;
-        }
-
-        template<class valueType>
-        AttributeValue remapArrayDepth(const unsigned int curLevel,
-                const std::vector<OC::AttributeValue>& vs)
-        {
-            switch(curLevel)
-            {
-                default:
-                    throw OC::OCException(OC::Exception::INVALID_JSON_ARRAY_DEPTH);
-                    break;
-                case 1:
-                    return valuesToConcreteVectors<std::vector<valueType>>(vs);
-                    break;
-                case 2:
-                    return valuesToConcreteVectors<std::vector<std::vector<valueType>>>(vs);
-                    break;
-                case 3:
-                    return valuesToConcreteVectors
-                        <std::vector<std::vector<std::vector<valueType>>>>(vs);
-                    break;
-            }
-        }
-
-        AttributeValue convertArrayToConcretes(const typeTag t,
-                const unsigned int curLevel, const std::vector<OC::AttributeValue>& vs)
-        {
-            // This function converts a std::vector of AttributeValue to a std::vector
-            // of concrete types.  Since we don't use a recursive Variant, we need
-            // to get back to a 'base' primitive type
-            switch(t)
-            {
-                default:
-                case typeTag::NOTHING:
-                    throw OC::OCException(OC::Exception::INVALID_JSON_TYPE_TAG);
-                    break;
-                case typeTag::_string:
-                    return remapArrayDepth<std::string>(curLevel, vs);
-                    break;
-                case typeTag::_int:
-                    return remapArrayDepth<int>(curLevel, vs);
-                    break;
-                case typeTag::_double:
-                    return remapArrayDepth<double>(curLevel, vs);
-                    break;
-                case typeTag::_bool:
-                    return remapArrayDepth<bool>(curLevel, vs);
-                    break;
-                case typeTag::_representation:
-                    return remapArrayDepth<OCRepresentation>(curLevel, vs);
-                    break;
-            }
-        }
-
-        AttributeValue parseAttributeValueArray(const GenericValue& v,
-                const unsigned int curLevel, unsigned int& maxDepth, typeTag& t)
-        {
-            const unsigned int max_level = 3;
-
-            if(curLevel > max_level)
-            {
-                throw OC::OCException(OC::Exception::INVALID_JSON_ARRAY_DEPTH);
-            }
-
-            if(curLevel > maxDepth)
-            {
-                maxDepth = curLevel;
-            }
-
-            auto arrayItems = gatherArrayContents(v, curLevel, maxDepth, t);
-            const int remapLevel = maxDepth - (curLevel -1);
-            return convertArrayToConcretes(t, remapLevel, arrayItems);
-        }
-    }
-}
-
-namespace cereal
-{
-   void JSONInputArchive::loadAttributeValues(std::map<std::string, OC::AttributeValue>& map)
-   {
-       for(auto&b = itsIteratorStack.back();
-           b.Member && b.itsMemberItEnd != b.itsMemberItBegin+b.itsIndex;
-           ++b)
-       {
-           std::string key = b.itsMemberItBegin[b.itsIndex].name.GetString();
-           const GenericValue& v = itsIteratorStack.back().value();
-           map[key] = OC::detail::parseAttributeValue(v);
-       }
-   }
-}
-
-namespace OC
-{
     std::ostream& operator <<(std::ostream& os, const AttributeType at)
     {
         switch(at)
index 2ad836a..1d35ea2 100644 (file)
 #include "OCUtilities.h"
 
 #include <boost/lexical_cast.hpp>
+#include <sstream>
 
 namespace OC {
 
+static const char COAP[] = "coap://";
+static const char COAPS[] = "coaps://";
 using OC::nil_guard;
 using OC::result_guard;
 using OC::checked_guard;
 
-OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
-                       const std::string& uri, const std::string& serverId,
-                       OCConnectivityType connectivityType, bool observable,
-                       const std::vector<std::string>& resourceTypes,
-                       const std::vector<std::string>& interfaces)
- :  m_clientWrapper(clientWrapper), m_uri(uri), m_resourceId(serverId, m_uri),
-    m_host(host),
-    m_connectivityType(connectivityType),
-    m_isObservable(observable),
-    m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                        const OCDevAddr& devAddr, const std::string& uri,
+                        const std::string& serverId, bool observable,
+                        const std::vector<std::string>& resourceTypes,
+                        const std::vector<std::string>& interfaces)
+ :  m_clientWrapper(clientWrapper), m_uri(uri),
+    m_resourceId(serverId, m_uri), m_devAddr(devAddr),
+    m_isObservable(observable), m_isCollection(false),
+    m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
 {
     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
@@ -54,16 +56,124 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::s
     }
 }
 
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                        const std::string& host, const std::string& uri,
+                        const std::string& serverId,
+                        OCConnectivityType connectivityType, bool observable,
+                        const std::vector<std::string>& resourceTypes,
+                        const std::vector<std::string>& interfaces)
+ :  m_clientWrapper(clientWrapper), m_uri(uri),
+    m_resourceId(serverId, m_uri),
+    m_devAddr{ OC_DEFAULT_ADAPTER },
+    m_isObservable(observable), m_isCollection(false),
+    m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+    m_observeHandle(nullptr)
+{
+    m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+                        != m_interfaces.end();
+
+    if (m_uri.empty() ||
+        resourceTypes.empty() ||
+        interfaces.empty()||
+        m_clientWrapper.expired())
+    {
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    // construct the devAddr from the pieces we have
+    m_devAddr.adapter = static_cast<OCTransportAdapter>(connectivityType >> CT_ADAPTER_SHIFT);
+    m_devAddr.flags = static_cast<OCTransportFlags>(connectivityType & CT_MASK_FLAGS);
+    size_t len = host.length();
+    if (len >= MAX_ADDR_STR_SIZE)
+    {
+        throw std::length_error("host address is too long.");
+    }
+
+    this->setHost(host);
+}
+
 OCResource::~OCResource()
 {
 }
 
+void OCResource::setHost(const std::string& host)
+{
+    size_t prefix_len;
+
+    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;
+        m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_SECURE);
+    }
+    else
+    {
+        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    // removed coap:// or coaps://
+    std::string host_token = host.substr(prefix_len);
+
+    if(host_token[0] == '[')
+    {
+        m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_IP_USE_V6);
+
+        size_t found = host_token.find(']');
+
+        if(found == std::string::npos)
+        {
+            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        }
+        // extract the ipaddress
+        std::string ip6Addr = host_token.substr(1, found-1);
+        ip6Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
+        m_devAddr.addr[ip6Addr.length()] = '\0';
+        //skip ']' and ':' characters in host string
+        host_token = host_token.substr(found + 2);
+    }
+    else
+    {
+        size_t found = host_token.find(':');
+
+        if(found == std::string::npos)
+        {
+            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        }
+
+        std::string addrPart = host_token.substr(0, found);
+        addrPart.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
+        m_devAddr.addr[addrPart.length()] = '\0';
+        //skip ':' character in host string
+        host_token = host_token.substr(found + 1);
+    }
+
+    int port = std::stoi(host_token);
+
+    if( port < 0 || port > UINT16_MAX )
+    {
+        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    m_devAddr.port = static_cast<uint16_t>(port);
+
+}
+
 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
                               GetCallback attributeHandler, QualityOfService QoS)
 {
-    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
-                         m_host, m_uri, m_connectivityType, queryParametersMap, m_headerOptions,
-                         attributeHandler, QoS);
+    return checked_guard(m_clientWrapper.lock(),
+                            &IClientWrapper::GetResourceRepresentation,
+                            m_devAddr, m_uri,
+                            queryParametersMap, m_headerOptions,
+                            attributeHandler, QoS);
 }
 
 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
@@ -107,7 +217,7 @@ OCStackResult OCResource::put(const OCRepresentation& rep,
                               QualityOfService QoS)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
-                         m_host, m_uri, m_connectivityType, rep, queryParametersMap,
+                         m_devAddr, m_uri, rep, queryParametersMap,
                          m_headerOptions, attributeHandler, QoS);
 }
 
@@ -157,7 +267,7 @@ OCStackResult OCResource::post(const OCRepresentation& rep,
                                QualityOfService QoS)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
-                         m_host, m_uri, m_connectivityType, rep, queryParametersMap,
+                         m_devAddr, m_uri, rep, queryParametersMap,
                          m_headerOptions, attributeHandler, QoS);
 }
 
@@ -205,7 +315,7 @@ OCStackResult OCResource::post(const std::string& resourceType,
 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler, QualityOfService QoS)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
-                         m_host, m_uri, m_connectivityType, m_headerOptions, deleteHandler, QoS);
+                         m_devAddr, m_uri, m_headerOptions, deleteHandler, QoS);
 }
 
 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler)
@@ -226,8 +336,8 @@ OCStackResult OCResource::observe(ObserveType observeType,
     }
 
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
-                         observeType, &m_observeHandle, m_host,
-                         m_uri, m_connectivityType, queryParametersMap, m_headerOptions,
+                         observeType, &m_observeHandle, m_devAddr,
+                         m_uri, queryParametersMap, m_headerOptions,
                          observeHandler, QoS);
 }
 
@@ -256,7 +366,7 @@ OCStackResult OCResource::cancelObserve(QualityOfService QoS)
 
     OCStackResult result =  checked_guard(m_clientWrapper.lock(),
             &IClientWrapper::CancelObserveResource,
-            m_observeHandle, m_host, m_uri, m_headerOptions, QoS);
+            m_observeHandle, "", m_uri, m_headerOptions, QoS);
 
     if(result == OC_STACK_OK)
     {
@@ -268,7 +378,28 @@ OCStackResult OCResource::cancelObserve(QualityOfService QoS)
 
 std::string OCResource::host() const
 {
-    return m_host;
+    std::ostringstream ss;
+    if (m_devAddr.flags & OC_SECURE)
+    {
+        ss << COAPS;
+    }
+    else
+    {
+        ss << COAP;
+    }
+    if (m_devAddr.flags & OC_IP_USE_V6)
+    {
+        ss << '[' << m_devAddr.addr << ']';
+    }
+    else
+    {
+        ss << m_devAddr.addr;
+    }
+    if (m_devAddr.port)
+    {
+        ss << ':' << m_devAddr.port;
+    }
+    return ss.str();
 }
 
 std::string OCResource::uri() const
@@ -278,7 +409,8 @@ std::string OCResource::uri() const
 
 OCConnectivityType OCResource::connectivityType() const
 {
-    return m_connectivityType;
+    return static_cast<OCConnectivityType>(
+           (m_devAddr.adapter << CT_ADAPTER_SHIFT) | (m_devAddr.flags & CT_MASK_FLAGS));
 }
 
 bool OCResource::isObservable() const
@@ -286,7 +418,6 @@ bool OCResource::isObservable() const
     return m_isObservable;
 }
 
-
 OCResourceIdentifier OCResource::uniqueIdentifier() const
 {
     return m_resourceId;
@@ -335,7 +466,6 @@ OCResourceIdentifier::OCResourceIdentifier(const std::string& wireServerIdentifi
 
 std::ostream& operator <<(std::ostream& os, const OCResourceIdentifier& ri)
 {
-
     os << ri.m_representation<<ri.m_resourceUri;
 
     return os;
index 16abce1..d600017 100644 (file)
 
 #include <vector>
 #include <map>
-#include <cereal/cereal.hpp>
-#include <OicJsonSerializer.hpp>
+#include "ocpayload.h"
 
 using namespace OC;
-using namespace std;
 
-void OCResourceRequest::setPayload(const std::string& requestPayload)
+void OCResourceRequest::setPayload(OCPayload* payload)
 {
     MessageContainer info;
 
-    if(requestPayload.empty())
+    if(payload == nullptr)
     {
         return;
     }
-
-    try
-    {
-        info.setJSONRepresentation(requestPayload);
-    }
-    catch(cereal::RapidJSONException& ex)
+    if(payload->type != PAYLOAD_TYPE_REPRESENTATION)
     {
-        oclog() << "RapidJSON Exception in setPayload: "<<ex.what()<<std::endl<<
-            "Data was:"<<requestPayload<<std::flush;
-        return;
-    }
-    catch(cereal::Exception& ex)
-    {
-        oclog() << "Cereal Exception in setPayload: "<<ex.what()<<std::endl<<
-            "Data was:"<<requestPayload<<std::flush;
+        throw std::logic_error("Wrong payload type");
         return;
     }
 
+    info.setPayload(payload);
+
     const std::vector<OCRepresentation>& reps = info.representations();
     if(reps.size() >0)
     {
index 8fc0f03..f0e606e 100644 (file)
@@ -37,8 +37,7 @@ OC::Utilities::QueryParamsKeyVal OC::Utilities::getQueryParams(const std::string
     }
 
     std::vector<std::string> queryparams;
-    boost::split(queryparams, uri, [](const char c){return c=='&';},
-    boost::token_compress_on);
+    boost::split(queryparams, uri, boost::is_any_of(OC_QUERY_SEPARATOR), boost::token_compress_on);
 
     for(std::string& it: queryparams)
     {
index 2e2c94f..621e01c 100644 (file)
@@ -35,7 +35,6 @@ oclib_env.AppendUnique(CPPPATH = [
                '../include/',
                '../csdk/stack/include',
                '../csdk/ocrandom/include',
-               '../csdk/ocmalloc/include',
                '../csdk/logger/include',
                '../oc_logger/include',
                '../csdk/connectivity/lib/libcoap-4.1.1'
@@ -69,7 +68,7 @@ oclib_src = [
                'OCResourceRequest.cpp'
        ]
 
-oclib_env.AppendUnique(CPPPATH = [oclib_env.get('SRC_DIR') + '/extlibs/cereal/include'])
 oclib = oclib_env.SharedLibrary('oc', oclib_src)
 oclib_env.InstallTarget(oclib, 'liboc')
+oclib_env.UserInstallTargetLib(oclib, 'liboc')
 
index 41a10bc..14b13e2 100644 (file)
@@ -38,15 +38,26 @@ if target_os == 'linux':
        # get it and install it
        SConscript(src_dir + '/extlibs/hippomocks.scons')
 
+    # Build Common unit tests
+       SConscript('c_common/oic_string/test/SConscript')
+       SConscript('c_common/oic_malloc/test/SConscript')
+
        # Build C unit tests
        SConscript('csdk/stack/test/SConscript')
        SConscript('csdk/ocrandom/test/SConscript')
 
        SConscript('csdk/connectivity/test/SConscript')
 
+       # Build Security Resource Manager unit tests
+       SConscript('csdk/security/unittest/SConscript')
+
        # Build C++ unit tests
        SConscript('unittests/SConscript')
 
+       # Build Provisioning API unit test
+       if env.get('SECURED') == '1':
+               SConscript('csdk/security/provisioning/unittest/SConscript')
+
 elif target_os == 'darwin':
        # Verify that 'google unit test' library is installed.  If not,
        # get it and install it
@@ -56,3 +67,4 @@ elif target_os == 'darwin':
        SConscript('csdk/stack/test/SConscript')
        SConscript('csdk/connectivity/test/SConscript')
 
+
index 0e0d4a6..0c71f02 100644 (file)
@@ -53,6 +53,7 @@ namespace OC
                 OC_STACK_NO_RESOURCE,
                 OC_STACK_RESOURCE_ERROR,
                 OC_STACK_SLOW_RESOURCE,
+                OC_STACK_DUPLICATE_REQUEST,
                 OC_STACK_NO_OBSERVERS,
                 OC_STACK_OBSERVER_NOT_FOUND,
                 OC_STACK_VIRTUAL_DO_NOT_HANDLE,
@@ -62,6 +63,7 @@ namespace OC
                 OC_STACK_INVALID_REQUEST_HANDLE,
                 OC_STACK_INVALID_DEVICE_INFO,
                 OC_STACK_INVALID_JSON,
+                OC_STACK_UNAUTHORIZED_REQ,
                 OC_STACK_PRESENCE_STOPPED,
                 OC_STACK_PRESENCE_TIMEOUT,
                 OC_STACK_PRESENCE_DO_NOT_HANDLE,
@@ -90,6 +92,7 @@ namespace OC
                 OC::Exception::NOT_FOUND,
                 OC::Exception::RESOURCE_ERROR,
                 OC::Exception::SLOW_RESOURCE,
+                OC::Exception::DUPLICATE_REQUEST,
                 OC::Exception::NO_OBSERVERS,
                 OC::Exception::OBSV_NO_FOUND,
                 OC::Exception::VIRTUAL_DO_NOT_HANDLE,
@@ -99,6 +102,7 @@ namespace OC
                 OC::Exception::INVALID_REQUEST_HANDLE,
                 OC::Exception::INVALID_DEVICE_INFO,
                 OC::Exception::INVALID_REPRESENTATION,
+                OC::Exception::UNAUTHORIZED_REQUEST,
                 OC::Exception::PRESENCE_STOPPED,
                 OC::Exception::PRESENCE_TIMEOUT,
                 OC::Exception::PRESENCE_NOT_HANDLED,
index 2264e37..f526585 100644 (file)
@@ -31,7 +31,13 @@ namespace OCPlatformTest
     const std::string gResourceInterface = DEFAULT_INTERFACE;
     const uint8_t gResourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
     OCResourceHandle resourceHandle;
+  //OCPersistent Storage Handlers
 
+   static FILE* client_open(const char *path, const char *mode)
+   {
+       std::cout << "<===Opening SVR DB file = './oic_svr_db_client.json' with mode = '"<< mode<<"' "<<std::endl;
+               return fopen("./oic_svr_db_client.json", mode);
+   }
     // Callbacks
     OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
     {
@@ -54,18 +60,8 @@ namespace OCPlatformTest
     //Helper methods
     void DeleteDeviceInfo(OCDeviceInfo deviceInfo)
     {
-        delete[] deviceInfo.contentType;
-        delete[] deviceInfo.dateOfManufacture;
         delete[] deviceInfo.deviceName;
-        delete[] deviceInfo.deviceUUID;
-        delete[] deviceInfo.firmwareVersion;
-        delete[] deviceInfo.hostName;
-        delete[] deviceInfo.manufacturerName;
-        delete[] deviceInfo.manufacturerUrl;
-        delete[] deviceInfo.modelNumber;
-        delete[] deviceInfo.platformVersion;
-        delete[] deviceInfo.supportUrl;
-        delete[] deviceInfo.version;
+
     }
 
     void DuplicateString(char ** targetString, std::string sourceString)
@@ -224,6 +220,67 @@ namespace OCPlatformTest
                  resourceHandle, uri, type,
                  gResourceInterface, entityHandler, gResourceProperty));
     }
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureDefaultNULLPersistentStorage)
+    {
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureNULLPersistentStorage)
+    {
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             nullptr
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigurePersistentStorage)
+    {
+        OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             &ps
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureNULLHandlersPersistentStorage)
+    {
+        OCPersistentStorage ps {client_open, nullptr, nullptr, nullptr, nullptr };
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             &ps
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
 
     //RegisterResourceTest
     TEST(RegisterResourceTest, RegisterSingleResource)
@@ -476,87 +533,87 @@ namespace OCPlatformTest
     TEST(FindResourceTest, DISABLED_FindResourceValid)
     {
       std::ostringstream requestURI;
-      requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
       EXPECT_EQ(OC_STACK_OK, OCPlatform::findResource("", requestURI.str(),
-              OC_IPV4, &foundResource));
+              CT_DEFAULT, &foundResource));
     }
 
     TEST(FindResourceTest, FindResourceNullResourceURI)
     {
       EXPECT_ANY_THROW(OCPlatform::findResource("", nullptr,
-              OC_IPV4, &foundResource));
+              CT_DEFAULT, &foundResource));
     }
 
     TEST(FindResourceTest, FindResourceNullResourceURI1)
     {
       std::ostringstream requestURI;
-      requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
       EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
-              OC_IPV4, &foundResource));
+              CT_DEFAULT, &foundResource));
     }
 
     TEST(FindResourceTest, FindResourceNullHost)
     {
       std::ostringstream requestURI;
-      requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
       EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
-              OC_IPV4, &foundResource));
+              CT_DEFAULT, &foundResource));
     }
 
     TEST(FindResourceTest, FindResourceNullresourceHandler)
     {
       std::ostringstream requestURI;
-      requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
       EXPECT_THROW(OCPlatform::findResource("", requestURI.str(),
-              OC_IPV4, NULL), OC::OCException);
+              CT_DEFAULT, NULL), OC::OCException);
     }
 
     TEST(FindResourceTest, DISABLED_FindResourceWithLowQoS)
     {
         std::ostringstream requestURI;
-        requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::findResource("", requestURI.str(), OC_IPV4, &foundResource,
+                OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource,
                         OC::QualityOfService::LowQos));
     }
 
     TEST(FindResourceTest, DISABLED_FindResourceWithMidQos)
     {
         std::ostringstream requestURI;
-        requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::findResource("", requestURI.str(), OC_IPV4, &foundResource,
+                OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource,
                         OC::QualityOfService::MidQos));
     }
 
     TEST(FindResourceTest, DISABLED_FindResourceWithHighQos)
     {
         std::ostringstream requestURI;
-        requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::findResource("", requestURI.str(), OC_IPV4, &foundResource,
+                OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource,
                         OC::QualityOfService::HighQos));
     }
 
     TEST(FindResourceTest, DISABLED_FindResourceWithNaQos)
     {
         std::ostringstream requestURI;
-        requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.light";
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::findResource("", requestURI.str(), OC_IPV4, &foundResource,
+                OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource,
                         OC::QualityOfService::NaQos));
     }
 
     //GetDeviceInfo Test
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithValidParameters)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, &receivedDeviceInfo));
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, &receivedDeviceInfo));
     }
 
     TEST(GetDeviceInfoTest, GetDeviceInfoNullDeviceURI)
@@ -564,66 +621,66 @@ namespace OCPlatformTest
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         EXPECT_ANY_THROW(
-                OCPlatform::getDeviceInfo("", nullptr, OC_IPV4, &receivedDeviceInfo));
+                OCPlatform::getDeviceInfo("", nullptr, CT_DEFAULT, &receivedDeviceInfo));
     }
 
     TEST(GetDeviceInfoTest, GetDeviceInfoWithNullDeviceInfoHandler)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_THROW(
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, NULL),
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, NULL),
                 OC::OCException);
     }
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithLowQos)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, &receivedDeviceInfo,
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, &receivedDeviceInfo,
                         OC::QualityOfService::LowQos));
     }
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithMidQos)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, &receivedDeviceInfo,
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, &receivedDeviceInfo,
                         OC::QualityOfService::MidQos));
     }
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithHighQos)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, &receivedDeviceInfo,
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, &receivedDeviceInfo,
                         OC::QualityOfService::HighQos));
     }
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithNaQos)
     {
-        std::string deviceDiscoveryURI = "/oc/core/d";
+        std::string deviceDiscoveryURI = "/oic/d";
         PlatformConfig cfg;
         OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
-                OCPlatform::getDeviceInfo("", requestURI.str(), OC_IPV4, &receivedDeviceInfo,
+                OCPlatform::getDeviceInfo("", requestURI.str(), CT_DEFAULT, &receivedDeviceInfo,
                         OC::QualityOfService::NaQos));
     }
 
@@ -632,18 +689,7 @@ namespace OCPlatformTest
     {
         OCDeviceInfo deviceInfo;
 
-        DuplicateString(&deviceInfo.contentType, "myContentType");
-        DuplicateString(&deviceInfo.dateOfManufacture, "myDateOfManufacture");
         DuplicateString(&deviceInfo.deviceName, "myDeviceName");
-        DuplicateString(&deviceInfo.deviceUUID, "myDeviceUUID");
-        DuplicateString(&deviceInfo.firmwareVersion, "myFirmwareVersion");
-        DuplicateString(&deviceInfo.hostName, "myHostName");
-        DuplicateString(&deviceInfo.manufacturerName, "myManufacturerNa");
-        DuplicateString(&deviceInfo.manufacturerUrl, "myManufacturerUrl");
-        DuplicateString(&deviceInfo.modelNumber, "myModelNumber");
-        DuplicateString(&deviceInfo.platformVersion, "myPlatformVersion");
-        DuplicateString(&deviceInfo.supportUrl, "mySupportUrl");
-        DuplicateString(&deviceInfo.version, "myVersion");
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::registerDeviceInfo(deviceInfo));
         EXPECT_NO_THROW(DeleteDeviceInfo(deviceInfo));
@@ -652,7 +698,7 @@ namespace OCPlatformTest
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithEmptyObject)
     {
         OCDeviceInfo di = {};
-        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerDeviceInfo(di));
+        EXPECT_ANY_THROW(OCPlatform::registerDeviceInfo(di));
     }
 
     //SubscribePresence Test
@@ -662,7 +708,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle, hostAddress,
-                 OC_IPV4, &presenceHandler));
+                 CT_DEFAULT, &presenceHandler));
     }
 
     TEST(SubscribePresenceTest, SubscribePresenceWithNullHost)
@@ -670,7 +716,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle, nullptr,
-                 OC_IPV4, &presenceHandler));
+                 CT_DEFAULT, &presenceHandler));
     }
 
     TEST(SubscribePresenceTest, SubscribePresenceWithNullPresenceHandler)
@@ -678,7 +724,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle, nullptr,
-                 OC_IPV4, NULL));
+                 CT_DEFAULT, NULL));
     }
 
     TEST(SubscribePresenceTest, DISABLED_SubscribePresenceWithResourceType)
@@ -686,7 +732,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
-                OC_MULTICAST_IP, "core.light", OC_IPV4, &presenceHandler));
+                OC_MULTICAST_IP, "core.light", CT_DEFAULT, &presenceHandler));
     }
 
     TEST(SubscribePresenceTest, SubscribePresenceWithNullResourceType)
@@ -694,7 +740,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle,
-                OC_MULTICAST_IP, nullptr, OC_IPV4, &presenceHandler));
+                OC_MULTICAST_IP, nullptr, CT_DEFAULT, &presenceHandler));
     }
 
     TEST(SubscribePresenceTest, DISABLED_UnsubscribePresenceWithValidHandleAndRT)
@@ -702,7 +748,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
-                OC_MULTICAST_IP, "core.light", OC_IPV4, &presenceHandler));
+                OC_MULTICAST_IP, "core.light", CT_DEFAULT, &presenceHandler));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
     }
 
@@ -717,8 +763,7 @@ namespace OCPlatformTest
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
-                OC_MULTICAST_IP, OC_IPV4, &presenceHandler));
+                OC_MULTICAST_IP, CT_DEFAULT, &presenceHandler));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
     }
-
 }
index 0768836..3ea5826 100644 (file)
@@ -89,13 +89,13 @@ namespace OCResourceResponseTest
         OCServerRequest request;
         request.method = OC_REST_GET;
         strncpy(request.query, query, sizeof(query));
-        request.connectivityType = CA_IPV4;
-        strncpy(request.addressInfo.IP.ipAddress, address, sizeof(query));
-        request.addressInfo.IP.port = 5364;
-        request.qos =  OC_LOW_QOS;
+        request.devAddr.flags = OC_DEFAULT_FLAGS;
+        request.devAddr.adapter = OC_DEFAULT_ADAPTER;
+        strncpy(request.devAddr.addr, address, sizeof(query));
+        request.devAddr.port = 5364;
+        request.qos = OC_LOW_QOS;
         request.coapID = 0;
         request.delayedResNeeded = 0;
-        request.secured = 0;
 
         OCRequestHandle handle = static_cast<OCRequestHandle>(&request);
         EXPECT_EQ(NULL, response.getRequestHandle());
@@ -124,7 +124,7 @@ namespace OCResourceResponseTest
         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
 
         EXPECT_EQ(OC_STACK_OK, OCCreateResource(&resHandle, resourceURI.c_str(),
-                resourceTypeName.c_str(), resourceInterface.c_str(), nullptr,
+                resourceTypeName.c_str(), resourceInterface.c_str(), nullptr, nullptr,
                 resourceProperty));
         EXPECT_EQ(NULL, response.getResourceHandle());
         EXPECT_NO_THROW(response.setResourceHandle(resHandle));
index 501857d..bdc870f 100644 (file)
@@ -49,7 +49,7 @@ namespace OCResourceTest
     //Helper method
     OCResource::Ptr ConstructResourceObject(std::string host, std::string uri)
     {
-        OCConnectivityType connectivityType = OC_IPV4;
+        OCConnectivityType connectivityType = CT_DEFAULT;
         std::vector<std::string> types = {"intel.rpost"};
         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
 
@@ -450,7 +450,7 @@ namespace OCResourceTest
     {
         OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
         EXPECT_TRUE(resource != NULL);
-        EXPECT_TRUE(resource->connectivityType() == OC_IPV4);
+        EXPECT_TRUE(resource->connectivityType() == CT_DEFAULT);
     }
 
     //IsObservable Test
index cdb9ca7..4264736 100644 (file)
@@ -34,12 +34,13 @@ unittests_env.PrependUnique(CPPPATH = [
                '../csdk/security/include',
                '../csdk/stack/include/internal',
                '../csdk/connectivity/api',
+               '../csdk/connectivity/external/inc',
                '../csdk/ocsocket/include',
                '../csdk/ocrandom/include',
                '../csdk/logger/include',
-               '../../extlibs/gtest/gtest-1.7.0/include',
-               '../../extlibs/hippomocks-master/HippoMocks',
-               '../../extlibs/hippomocks-master/HippoMocksTest'
+               '#extlibs/gtest/gtest-1.7.0/include',
+               '#extlibs/hippomocks-master/HippoMocks',
+               '#extlibs/hippomocks-master/HippoMocksTest'
                ])
 
 unittests_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
@@ -79,13 +80,15 @@ env.AppendTarget('unittests')
 if env.get('TEST') == '1':
        target_os = env.get('TARGET_OS')
        if target_os == 'linux':
-               out_dir = env.get('BUILD_DIR')
-               result_dir = env.get('BUILD_DIR') + '/test_out/'
-               if not os.path.isdir(result_dir):
-                       os.makedirs(result_dir)
-               unittests_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir])
-               unittests_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir])
-               unittests_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
-               ut = unittests_env.Command ('ut', None,
-                [ 'valgrind --leak-check=full --xml=yes --xml-file=resource_unittests_unittests.memcheck ' + out_dir + 'resource/unittests/unittests'])
-               AlwaysBuild ('ut')
+                from tools.scons.RunTest import *
+                run_test(unittests_env,
+                         'resource_unittests_unittests.memcheck',
+                         'resource/unittests/unittests')
+
+src_dir = unittests_env.get('SRC_DIR')
+svr_db_src_dir = os.path.join(src_dir, 'resource/examples/')
+svr_db_build_dir = os.path.join(env.get('BUILD_DIR'), 'resource/unittests/')
+unittests_env.Alias("install",
+                    unittests_env.Install(svr_db_build_dir,
+                                          os.path.join(svr_db_src_dir,
+                                                       'oic_svr_db_client.json')))
index a3bd70e..5389725 100644 (file)
@@ -39,7 +39,12 @@ if target_os not in ['arduino','darwin','ios']:
                SConscript('protocol-plugin/SConscript')
 
        # Build notification manager project
-       SConscript('notification-manager/SConscript')
+       if target_os not in ['android', 'tizen']:
+               SConscript('notification-manager/SConscript')
+
+       # Build resource-encapsulation project
+       if target_os not in ['android', 'tizen']:
+               SConscript('resource-encapsulation/SConscript')
 #else:
 #      SConscript('notification-manager/SampleApp/arduino/SConscript')
 
@@ -1,10 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="gen"/>
        <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
        <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
        <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="src" path="gen"/>
-       <classpathentry exported="true" kind="lib" path="C:/Users/jay.sharma/Desktop/master_19_may/iotivity/android/android_api/base/build/intermediates/bundles/release/classes.jar"/>
        <classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git a/service/notification-manager/NotificationManager/android/resource_hosting/AndroidManifest.xml b/service/notification-manager/NotificationManager/android/resource_hosting/AndroidManifest.xml
new file mode 100755 (executable)
index 0000000..bb17c60
--- /dev/null
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.ResourceHosting"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="21" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+    </application>
+
+</manifest>
diff --git a/service/notification-manager/NotificationManager/android/resource_hosting/jni/Android.mk b/service/notification-manager/NotificationManager/android/resource_hosting/jni/Android.mk
new file mode 100755 (executable)
index 0000000..4bac6bd
--- /dev/null
@@ -0,0 +1,65 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ca
+LOCAL_SRC_FILES := ../libs/libconnectivity_abstraction.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ca_i
+LOCAL_SRC_FILES := ../libs/libca-interface.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := oc_logger_core
+LOCAL_SRC_FILES := ../libs/liboc_logger_core.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := oc_logger
+LOCAL_SRC_FILES := ../libs/liboc_logger.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := octbstack
+LOCAL_SRC_FILES := ../libs/liboctbstack.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := oc
+LOCAL_SRC_FILES := ../libs/liboc.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ocstack-jni
+LOCAL_SRC_FILES := ../libs/libocstack-jni.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := NotificationManager
+LOCAL_SRC_FILES := ../libs/libNotificationManager.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ResourceHosing_JNI
+LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions
+
+LOCAL_STATIC_LIBRARIES = ca_i
+LOCAL_STATIC_LIBRARIES += ca
+LOCAL_STATIC_LIBRARIES += oc_logger_core
+LOCAL_STATIC_LIBRARIES += oc_logger
+LOCAL_STATIC_LIBRARIES += octbstack
+LOCAL_STATIC_LIBRARIES += oc
+LOCAL_STATIC_LIBRARIES += ocstack-jni
+LOCAL_STATIC_LIBRARIES += NotificationManager
+
+LOCAL_C_INCLUDES := ../../../../../../resource/csdk/stack/include/
+LOCAL_C_INCLUDES += ../../../../../../resource/csdk/logger/include/
+LOCAL_C_INCLUDES += ../../../../../../resource/include/
+LOCAL_C_INCLUDES += ../../../../../../resource/oc_logger/include/
+LOCAL_C_INCLUDES += ../../../../../../extlibs/boost/boost_1_58_0/
+LOCAL_C_INCLUDES += ../../../../NotificationManager/include/
+
+
+LOCAL_SRC_FILES := ResourceHosing_JNI.cpp
+include $(BUILD_SHARED_LIBRARY)
@@ -1,3 +1,4 @@
+
 //******************************************************************
 //
 // Copyright 2015 Samsung Electronics All Rights Reserved.
@@ -21,8 +22,8 @@
 extern "C" {
 #include "hosting.h"
 }
-#include "resourceCoordinator_JNI.h"
-#include "android_cpp11_compat.h"
+#include "ResourceHosing_JNI.h"
+#include "OCAndroid.h"
 
 using namespace std;
 
@@ -38,54 +39,38 @@ void ocProcessFunc()
 
         if (OCProcess() != OC_STACK_OK)
         {
-            //OCProcess ERROR
+            return ;
         }
 
         sleep(2);
     }
 }
-/*
- * To callback log message from C++ to Java for android
- */
-void messageCallback(JNIEnv *env, jobject obj, const char *c_str)
-{
-      jstring jstr = (env)->NewStringUTF(c_str);
-      jclass cls = env->GetObjectClass(obj);
-      jmethodID cbMessage = env->GetMethodID(cls, "cbMessage", "(Ljava/lang/String;)V");
-      env->CallVoidMethod(obj,cbMessage, jstr);
-}
+
 /*
  *  for Hosting Device Side
  */
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_OICCoordinatorStart
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_OICCoordinatorStart
 (JNIEnv *env, jobject obj)
 {
     jint result = 0;
     if(threadRun==true)
     {
-
-        messageCallback(env,obj,"already execute OICCoordinatorStart");
         result = (jint)HOSTING_THREAD_ERROR;
         return result;
     }
     else
     {
-        messageCallback(env,obj,"OICCoordinatorStart");
         result = (jint)OICStartCoordinate();
-        string str = "OICStartCoordinate result : ";
-        string result_str = std::to_string(result);
-        str += result_str;
-        messageCallback(env,obj,str.c_str());
+
         threadRun = true;
         ocProcessThread = thread(ocProcessFunc);
         return result;
     }
 }
 
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_OICCoordinatorStop
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_OICCoordinatorStop
 (JNIEnv *env, jobject obj)
 {
-    messageCallback(env,obj,"OICCoordinatorStop");
     jint result = 0;
     //terminate Thread
     if (ocProcessThread.joinable())
@@ -95,22 +80,17 @@ JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting
     }
     else
     {
-            messageCallback(env,obj,"The thread may be not running.");
             result = (jint)HOSTING_THREAD_ERROR;
             return result;
     }
     result = (jint)OICStopCoordinate();
-    string str = "OICStopCoordinate result : ";
-    string result_str = std::to_string(result);
-    str += result_str;
-    messageCallback(env,obj,str.c_str());
+
     return result;
 }
 
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_ResourceHostingInit
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_ResourceHostingInit
 (JNIEnv *env, jobject obj,jstring j_addr)
 {
-    messageCallback(env,obj,"ResourceHostingInit");
     const char* addr = env->GetStringUTFChars(j_addr,NULL);
 
     if (NULL == j_addr)
@@ -118,7 +98,6 @@ JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting
 
     if(OCInit(addr,USE_RANDOM_PORT,OC_CLIENT_SERVER)!=OC_STACK_OK)
     {
-        messageCallback(env,obj,"OCStack init Error");
         return (jint)OCSTACK_ERROR;
     }
 
@@ -126,14 +105,11 @@ JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting
     return (jint)OCSTACK_OK;
 }
 
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_ResourceHostingTerminate
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_ResourceHostingTerminate
 (JNIEnv *env, jobject obj)
 {
-    messageCallback(env,obj,"ResourceHostingTerminate");
     if (OCStop() != OC_STACK_OK)
     {
-
-        messageCallback(env,obj,"OCStack stop error");
         return (jint)OCSTACK_ERROR;
     }
     //terminate Thread
@@ -144,7 +120,6 @@ JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting
     }
     else
     {
-        messageCallback(env,obj,"The thread may be not running.");
         return (jint)HOSTING_THREAD_ERROR;
     }
 
@@ -19,8 +19,8 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 
-#ifndef RESOURCECOORDINATOR_JNI_H_
-#define RESOURCECOORDINATOR_JNI_H_
+#ifndef RESOURCEHOSTING_JNI_H_
+#define RESOURCEHOSTING_JNI_H_
 
 #include <jni.h>
 #include <thread>
@@ -39,37 +39,37 @@ extern "C" {
 #endif
 
 /*
- * Class:     org_iotivity_service_resourcehostingsampleapp_ResourceHosting
+ * Class:     org_iotivity_service_resourcehosting_ResourceHosting
  * Method:    OICCoordinatorStart
  * Signature: ()V
  */
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_OICCoordinatorStart
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_OICCoordinatorStart
 (JNIEnv *, jobject);
 /*
- * @Class:     org_iotivity_service_resourcehostingsampleapp_ResourceHosting
+ * @Class:     org_iotivity_service_resourcehosting_ResourceHosting
  * @Method:    OICCoordinatorStop
  * @Signature: ()V
  */
 
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_OICCoordinatorStop
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_OICCoordinatorStop
 (JNIEnv *, jobject);
 /*
- * Class:     org_iotivity_service_resourcehostingsampleapp_ResourceHosting
+ * Class:     org_iotivity_service_resourcehosting_ResourceHosting
  * Method:    ResourceHostingInit
  * Signature: ()V
  */
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_ResourceHostingInit
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_ResourceHostingInit
 (JNIEnv *env, jobject obj,jstring j_addr);
 /*
- * Class:     org_iotivity_service_resourcehostingsampleapp_ResourceHosting
+ * Class:     org_iotivity_service_resourcehosting_ResourceHosting
  * Method:    ResourceHostingTerminate
  * Signature: (Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL Java_com_example_resourcehostingsampleapp_ResourceHosting_ResourceHostingTerminate
+JNIEXPORT jint JNICALL Java_org_iotivity_ResourceHosting_ResourceHosting_ResourceHostingTerminate
 (JNIEnv *env, jobject obj);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* RESOURCECOORDINATOR_JNI_H_ */
+#endif /* RESOURCEHOSTING_JNI_H_ */
diff --git a/service/notification-manager/NotificationManager/android/resource_hosting/project.properties b/service/notification-manager/NotificationManager/android/resource_hosting/project.properties
new file mode 100755 (executable)
index 0000000..00cf62b
--- /dev/null
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-22
diff --git a/service/notification-manager/NotificationManager/android/resource_hosting/src/org/iotivity/ResourceHosting/ResourceHosting.java b/service/notification-manager/NotificationManager/android/resource_hosting/src/org/iotivity/ResourceHosting/ResourceHosting.java
new file mode 100755 (executable)
index 0000000..451b773
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+package org.iotivity.ResourceHosting;
+import java.lang.System;
+import java.lang.String;;
+/**
+ * To execute resource hosting function for android sample application .
+ * 
+ * @author Copyright 2015 Samsung Electronics All Rights Reserved.
+ * @see className class : ResourceHosting</br>
+ *
+ */
+
+public class ResourceHosting {
+
+    /**
+     * jni function - OicCorrdinatorstart() method.
+     * 
+     * @see Class class :
+     *      org_iotivity_resourcehosting_ResourceHosting</br>
+     * @see Method method : OICCoordinatorStart</br>
+     * @see Signature signature : ()V</br>
+     */
+    public native int OICCoordinatorStart();
+
+    /**
+     * jni function - OICCoordinatorStop() method.
+     * 
+     * @see Class class :
+     *      org_iotivity_resourcehosting_ResourceHosting</br>
+     * @see Method method : OICCoordinatorStop</br>
+     * @see signature signature : ()V</br>
+     */
+    public native int OICCoordinatorStop();
+
+    /**
+     * jni function - ResourceHostingInit() method in order to execute
+     * OICCoordinatorStart() method.
+     * 
+     * @see Class class :
+     *      org_iotivity_resourcehosting_ResourceHosting</br>
+     * @see Method method : ResourceHostingInit</br>
+     * @param addr
+     *            ipAddress
+     * @see signature signature : (Ljava/lang/String;)V</br>
+     */
+    public native int ResourceHostingInit(String addr);
+
+    /**
+     * jni function - ResourceHostingTerminate() method in order to terminate
+     * resource hosting
+     * 
+     * @see Class class :
+     *      org_iotivity_resourcehosting_ResourceHosting</br>
+     * @see Method method : ResourceHostingTerminate</br>
+     * @see signature signature : ()V</br>
+     */
+    public native int ResourceHostingTerminate();
+
+    static {
+        System.loadLibrary("connectivity_abstraction");
+        System.loadLibrary("ca-interface");
+        System.loadLibrary("oc_logger_core");
+        System.loadLibrary("oc_logger");
+        System.loadLibrary("octbstack");
+        System.loadLibrary("oc");
+        System.loadLibrary("ocstack-jni");
+        System.loadLibrary("NotificationManager");
+       System.loadLibrary("ResourceHosing_JNI");
+    }
+}
index 5a18a0a..e4b7ed8 100644 (file)
@@ -30,8 +30,7 @@
 #include "ocstack.h"
 #include "logger.h"
 
-//#define OC_TRANSPORT OC_ALL
-#define OC_TRANSPORT OC_IPV4
+#define OC_TRANSPORT CT_ADAPTER_IP
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,16 +39,16 @@ extern "C" {
 #define HOSTING_TAG  PCF("Hosting")
 
 /**
- * Start resource coordinator.
- * This function will create mirrorResourceList and start to discover coordinatee candidate.
+ * Start resource hosting.
+ * This function will start the resource hosting and the discovery for remote resource which want to be hosted.
  *
  * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR is returned except the case that OC_STACK_SUCCESS is returned.
  */
 OCStackResult OICStartCoordinate();
 
 /**
- * Stop resource coordinator.
- * This function will stop the resource hosting and delete mirrorResourceList used.
+ * Stop resource hosting.
+ * This function will stop the resource hosting and delete all hosting resource.
  *
  * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR is returned except the case that OC_STACK_SUCCESS is returned.
  */
diff --git a/service/notification-manager/NotificationManager/src/HostingObject.cpp b/service/notification-manager/NotificationManager/src/HostingObject.cpp
new file mode 100644 (file)
index 0000000..6228e3b
--- /dev/null
@@ -0,0 +1,248 @@
+//******************************************************************
+//
+// 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 "HostingObject.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+void OIC_HOSTING_LOG(LogLevel level, const char * format, ...)
+{
+    if (!format)
+    {
+        return;
+    }
+    char buffer[MAX_LOG_V_BUFFER_SIZE] = {};
+    va_list args;
+    va_start(args, format);
+    vsnprintf(buffer, sizeof buffer - 1, format, args);
+    va_end(args);
+    OCLog(level, PCF("Hosting"), buffer);
+}
+
+HostingObject::HostingObject()
+: remoteObject(nullptr), mirroredServer(nullptr),
+  remoteState(ResourceState::NONE),
+  pStateChangedCB(nullptr), pDataUpdateCB(nullptr),
+  pDestroyCB(nullptr), pSetRequestHandler(nullptr)
+{
+}
+
+HostingObject::RemoteObjectPtr HostingObject::getRemoteResource() const
+{
+    return remoteObject;
+}
+
+void HostingObject::initializeHostingObject(RemoteObjectPtr rResource, DestroyedCallback destroyCB)
+{
+
+    remoteObject = rResource;
+
+    pStateChangedCB = std::bind(&HostingObject::stateChangedCB, this,
+            std::placeholders::_1, remoteObject);
+    pDataUpdateCB = std::bind(&HostingObject::dataChangedCB, this,
+            std::placeholders::_1, remoteObject);
+    pDestroyCB = destroyCB;
+
+    pSetRequestHandler = std::bind(&HostingObject::setRequestHandler, this,
+            std::placeholders::_1, std::placeholders::_2);
+
+    try
+    {
+        remoteObject->startMonitoring(pStateChangedCB);
+        remoteObject->startCaching(pDataUpdateCB);
+    }catch(...)
+    {
+        throw;
+    }
+}
+
+void HostingObject::destroyHostingObject()
+{
+    pDestroyCB();
+}
+
+void HostingObject::stateChangedCB(ResourceState state, RemoteObjectPtr rObject)
+{
+    remoteState = state;
+
+    switch (state)
+    {
+    case ResourceState::ALIVE:
+    {
+        if(rObject->isCaching() == false)
+        {
+            try
+            {
+                rObject->startCaching(pDataUpdateCB);
+            }catch(InvalidParameterException &e)
+            {
+                OIC_HOSTING_LOG(DEBUG,
+                        "[HostingObject::stateChangedCB]startCaching InvalidParameterException:%s",
+                        e.what());
+            }
+        }
+        break;
+    }
+    case ResourceState::LOST_SIGNAL:
+    case ResourceState::DESTROYED:
+    {
+        if(rObject->isCaching() == true)
+        {
+            try
+            {
+                rObject->stopCaching();
+            }catch(InvalidParameterException &e)
+            {
+                OIC_HOSTING_LOG(DEBUG,
+                        "[HostingObject::stateChangedCB]stopCaching InvalidParameterException:%s",
+                        e.what());
+            }
+        }
+        if(rObject->isMonitoring() == true)
+        {
+            try
+            {
+                rObject->stopMonitoring();
+            }catch(InvalidParameterException &e)
+            {
+                OIC_HOSTING_LOG(DEBUG,
+                        "[HostingObject::stateChangedCB]stopWatching InvalidParameterException:%s",
+                        e.what());
+            }
+        }
+        mirroredServer = nullptr;
+        destroyHostingObject();
+        break;
+    }
+    default:
+        // not support of state
+        break;
+    }
+}
+
+void HostingObject::dataChangedCB(const RCSResourceAttributes & attributes, RemoteObjectPtr rObject)
+{
+    if(attributes.empty())
+    {
+        return;
+    }
+
+    if(mirroredServer == nullptr)
+    {
+        try
+        {
+            mirroredServer = createMirroredServer(rObject);
+        }catch(PlatformException &e)
+        {
+            OIC_HOSTING_LOG(DEBUG,
+                        "[HostingObject::dataChangedCB]createMirroredServer PlatformException:%s",
+                        e.what());
+            mirroredServer = nullptr;
+            return;
+        }
+    }
+
+    RCSResourceAttributes rData;
+    {
+        RCSResourceObject::LockGuard guard(mirroredServer);
+        rData = mirroredServer->getAttributes();
+    }
+    if(rData.empty() || rData != attributes)
+    {
+        {
+            RCSResourceObject::LockGuard guard(mirroredServer);
+            for(auto it = rData.begin(); ; ++it)
+            {
+                if(it == rData.end())
+                {
+                    break;
+                }
+                mirroredServer->removeAttribute(it->key());
+            }
+
+            for(auto it = attributes.begin();; ++it)
+            {
+                if(it == attributes.end())
+                {
+                    break;
+                }
+                mirroredServer->setAttribute(it->key(), it->value());
+            }
+        }
+    }
+}
+
+HostingObject::ResourceObjectPtr HostingObject::createMirroredServer(RemoteObjectPtr rObject)
+{
+    ResourceObjectPtr retResource = nullptr;
+    if(rObject != nullptr)
+    {
+        std::string fulluri = rObject->getUri();
+        std::string uri = fulluri.substr(0, fulluri.size()-8);
+        std::vector<std::string> types = rObject->getTypes();
+        std::vector<std::string> interfaces = rObject->getInterfaces();
+        try
+        {
+            std::string type = types.begin()->c_str();
+            std::string interface = interfaces.begin()->c_str();
+            retResource = RCSResourceObject::Builder(uri, type, interface).
+                    setDiscoverable(true).setObservable(true).build();
+
+            // TODO need to bind types and interfaces
+            retResource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+            retResource->setSetRequestHandler(pSetRequestHandler);
+        }catch(...)
+        {
+            OIC_HOSTING_LOG(DEBUG, "[HostingObject::createMirroredServer] %s", "PlatformException");
+            throw;
+        }
+    }
+    else
+    {
+        throw PlatformException(OC_STACK_ERROR);
+    }
+
+    return retResource;
+}
+
+RCSSetResponse HostingObject::setRequestHandler(const RCSRequest & primitiveRequest,
+            RCSResourceAttributes & resourceAttibutes)
+{
+    try
+    {
+        RequestObject newRequest = { };
+        newRequest.invokeRequest(remoteObject, RequestObject::RequestMethod::Setter,
+                resourceAttibutes);
+    }catch(PlatformException &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[HostingObject::setRequestHandler] PlatformException:%s",
+                e.what());
+        throw;
+    }
+
+    return RCSSetResponse::create(resourceAttibutes);
+}
+
+} /* namespace Service */
+} /* namespace OIC */
diff --git a/service/notification-manager/NotificationManager/src/HostingObject.h b/service/notification-manager/NotificationManager/src/HostingObject.h
new file mode 100644 (file)
index 0000000..af05c30
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RH_HOSTINGOBJECT_H_
+#define RH_HOSTINGOBJECT_H_
+
+#include "RCSRemoteResourceObject.h"
+#include "RCSResourceObject.h"
+#include "RequestObject.h"
+#include "ResourceBroker.h"
+#include "ResourceCacheManager.h"
+#include "PrimitiveResource.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+void OIC_HOSTING_LOG(LogLevel level, const char * format, ...);
+
+class HostingObject
+{
+private:
+    typedef std::shared_ptr<RCSResourceObject> ResourceObjectPtr;
+    typedef std::shared_ptr<RCSRemoteResourceObject> RemoteObjectPtr;
+    typedef std::shared_ptr<RequestObject> RequestObjectPtr;
+    typedef std::shared_ptr<PrimitiveResource> PrimiteveResourcePtr;
+
+    typedef std::function<void(ResourceState)> BrokerCallback;
+    typedef std::function<void(const RCSResourceAttributes &)> CacheCallback;
+    typedef std::function<void()> DestroyedCallback;
+
+    typedef std::function<
+            RCSSetResponse(const RCSRequest&, RCSResourceAttributes&)> SetRequestHandler;
+
+public:
+    HostingObject();
+    ~HostingObject() = default;
+
+    void initializeHostingObject(RemoteObjectPtr rResource, DestroyedCallback destroyCB);
+
+    RemoteObjectPtr getRemoteResource() const;
+
+private:
+    RemoteObjectPtr remoteObject;
+    ResourceObjectPtr mirroredServer;
+
+    ResourceState remoteState;
+
+    BrokerCallback pStateChangedCB;
+    CacheCallback pDataUpdateCB;
+    DestroyedCallback pDestroyCB;
+
+    SetRequestHandler pSetRequestHandler;
+
+    ResourceObjectPtr createMirroredServer(RemoteObjectPtr rObject);
+
+    void stateChangedCB(ResourceState state, RemoteObjectPtr rObject);
+    void dataChangedCB(const RCSResourceAttributes & attributes, RemoteObjectPtr rObject);
+
+    RCSSetResponse setRequestHandler(
+            const RCSRequest & request, RCSResourceAttributes & attributes);
+
+    void destroyHostingObject();
+
+};
+
+} /* namespace Service */
+} /* namespace OIC */
+
+#endif /* RH_HOSTINGOBJECT_H_ */
diff --git a/service/notification-manager/NotificationManager/src/RequestObject.cpp b/service/notification-manager/NotificationManager/src/RequestObject.cpp
new file mode 100644 (file)
index 0000000..867cbdf
--- /dev/null
@@ -0,0 +1,62 @@
+//******************************************************************
+//
+// 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 "RequestObject.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+void RequestObject::invokeRequest(RemoteObjectPtr remoteObject, RequestMethod method,
+        RCSResourceAttributes & resourceAttibutes)
+{
+    try
+    {
+        switch (method)
+        {
+        case RequestMethod::Setter:
+            remoteObject->setRemoteAttributes(resourceAttibutes,
+                    std::bind(&RequestObject::setRequestCB, this,
+                            std::placeholders::_1, resourceAttibutes));
+            break;
+        case RequestMethod::Getter:
+        case RequestMethod::Delete:
+        default:
+            // unknown type of method.
+            break;
+        }
+    }catch(...)
+    {
+        throw;
+    }
+}
+
+void RequestObject::setRequestCB(const RCSResourceAttributes & returnedAttributes,
+        RCSResourceAttributes & putAttibutes)
+{
+    if(putAttibutes != returnedAttributes)
+    {
+        // TODO fail set attributes
+    }
+}
+
+} /* namespace Service */
+} /* namespace OIC */
diff --git a/service/notification-manager/NotificationManager/src/RequestObject.h b/service/notification-manager/NotificationManager/src/RequestObject.h
new file mode 100644 (file)
index 0000000..a4b040d
--- /dev/null
@@ -0,0 +1,58 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RH_REQUESTOBJECT_H_
+#define RH_REQUESTOBJECT_H_
+
+#include "RCSRemoteResourceObject.h"
+#include "RCSResourceObject.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+class RequestObject
+{
+public:
+    typedef std::shared_ptr<RCSRemoteResourceObject> RemoteObjectPtr;
+
+    enum class RequestMethod
+    {
+        Getter = 0,
+        Setter,
+        Delete
+    };
+
+    RequestObject() = default;
+    ~RequestObject() = default;
+
+    void invokeRequest(RemoteObjectPtr remoteObject, RequestMethod method,
+            RCSResourceAttributes & resourceAttibutes);
+
+private:
+    void setRequestCB(const RCSResourceAttributes & returnedAttributes,
+            RCSResourceAttributes & putAttibutes);
+};
+
+} /* namespace Service */
+} /* namespace OIC */
+
+#endif /* RH_REQUESTOBJECT_H_ */
diff --git a/service/notification-manager/NotificationManager/src/ResourceHosting.cpp b/service/notification-manager/NotificationManager/src/ResourceHosting.cpp
new file mode 100755 (executable)
index 0000000..b41bfe9
--- /dev/null
@@ -0,0 +1,254 @@
+//******************************************************************
+//
+// 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 "ResourceHosting.h"
+
+#include "PresenceSubscriber.h"
+#include "OCPlatform.h"
+#include "RCSDiscoveryManager.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+namespace
+{
+    std::string HOSTING_TAG = "/hosting";
+    size_t HOSTING_TAG_SIZE = (size_t)HOSTING_TAG.size();
+    std::string MULTICAST_PRESENCE_ADDRESS = std::string("coap://") + OC_MULTICAST_PREFIX;
+    std::string HOSTING_RESOURSE_TYPE = "Resource.Hosting";
+}
+
+ResourceHosting * ResourceHosting::s_instance(nullptr);
+std::mutex ResourceHosting::s_mutexForCreation;
+
+ResourceHosting::ResourceHosting()
+: hostingObjectList(),
+  discoveryManager(nullptr),
+  presenceHandle(),
+  pPresenceCB(nullptr), pDiscoveryCB(nullptr)
+{
+}
+
+ResourceHosting * ResourceHosting::getInstance()
+{
+    if (!s_instance)
+    {
+        s_mutexForCreation.lock();
+        if (!s_instance)
+        {
+            s_instance = new ResourceHosting();
+            s_instance->initializeResourceHosting();
+        }
+        s_mutexForCreation.unlock();
+    }
+    return s_instance;
+}
+
+void ResourceHosting::startHosting()
+{
+    try
+    {
+        requestMulticastPresence();
+        requestMulticastDiscovery();
+    }catch(PlatformException &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[ResourceHosting::startHosting]PlatformException:%s", e.what());
+        throw;
+    }catch(InvalidParameterException &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[ResourceHosting::startHosting]InvalidParameterException:%s", e.what());
+        throw;
+    }catch(std::exception &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[ResourceHosting::startHosting]std::exception:%s", e.what());
+        throw;
+    }
+}
+
+void ResourceHosting::stopHosting()
+{
+    // clear list hostingObjectList
+    if(presenceHandle.isSubscribing())
+    {
+        presenceHandle.unsubscribe();
+    }
+    for(auto it : hostingObjectList)
+    {
+        it.reset();
+    }
+}
+
+void ResourceHosting::initializeResourceHosting()
+{
+    pPresenceCB = std::bind(&ResourceHosting::presenceHandler, this,
+            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
+    pDiscoveryCB = std::bind(&ResourceHosting::discoverHandler, this,
+            std::placeholders::_1);
+
+    discoveryManager = RCSDiscoveryManager::getInstance();
+}
+
+void ResourceHosting::requestMulticastPresence()
+{
+    try
+    {
+        presenceHandle = PresenceSubscriber(MULTICAST_PRESENCE_ADDRESS,
+                OCConnectivityType::CT_DEFAULT, pPresenceCB);
+    }catch(...)
+    {
+        throw;
+    }
+}
+
+void ResourceHosting::presenceHandler(OCStackResult ret, const unsigned int /*seq*/,
+        const std::string & address)
+{
+    switch(ret)
+    {
+    case OC_STACK_OK:
+    case OC_STACK_CONTINUE:
+    case OC_STACK_RESOURCE_CREATED:
+    {
+        // TODO start discovery
+        requestDiscovery(address);
+        break;
+    }
+
+    case OC_STACK_RESOURCE_DELETED:
+    case OC_STACK_COMM_ERROR:
+    case OC_STACK_TIMEOUT:
+    case OC_STACK_PRESENCE_STOPPED:
+    case OC_STACK_PRESENCE_TIMEOUT:
+    case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+    case OC_STACK_ERROR:
+        // TODO presence error
+        break;
+
+    case OC_STACK_INVALID_URI:
+    case OC_STACK_INVALID_QUERY:
+    case OC_STACK_INVALID_IP:
+    case OC_STACK_INVALID_PORT:
+    case OC_STACK_INVALID_CALLBACK:
+    case OC_STACK_INVALID_METHOD:
+    case OC_STACK_INVALID_PARAM:
+    case OC_STACK_INVALID_OBSERVE_PARAM:
+    case OC_STACK_NO_MEMORY:
+    case OC_STACK_ADAPTER_NOT_ENABLED:
+    case OC_STACK_NOTIMPL:
+    case OC_STACK_NO_RESOURCE:
+    case OC_STACK_RESOURCE_ERROR:
+    case OC_STACK_SLOW_RESOURCE:
+    case OC_STACK_DUPLICATE_REQUEST:
+    case OC_STACK_NO_OBSERVERS:
+    case OC_STACK_OBSERVER_NOT_FOUND:
+    case OC_STACK_INVALID_OPTION:
+    case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
+    case OC_STACK_MALFORMED_RESPONSE:
+    case OC_STACK_PERSISTENT_BUFFER_REQUIRED:
+    case OC_STACK_INVALID_REQUEST_HANDLE:
+    case OC_STACK_INVALID_DEVICE_INFO:
+    case OC_STACK_INVALID_JSON:
+        break;
+    default:
+        // TODO unknown presence result
+        break;
+    }
+}
+
+void ResourceHosting::requestMulticastDiscovery()
+{
+    requestDiscovery();
+}
+void ResourceHosting::requestDiscovery(std::string address)
+{
+    std::string host = address;
+    std::string uri = OC_RSRVD_WELL_KNOWN_URI + std::string("?rt=") + HOSTING_RESOURSE_TYPE;
+    RCSAddress rcsAddress = RCSAddress::unicast(host);
+    discoveryManager->discoverResource(rcsAddress, uri, pDiscoveryCB);
+}
+
+void ResourceHosting::discoverHandler(RemoteObjectPtr remoteResource)
+{
+    std::string discoverdUri = remoteResource->getUri();
+    if(discoverdUri.compare(
+            discoverdUri.size()-HOSTING_TAG_SIZE, HOSTING_TAG_SIZE, HOSTING_TAG) != 0)
+    {
+        return;
+    }
+
+    HostingObjectPtr foundHostingObject = findRemoteResource(remoteResource);
+    if(foundHostingObject == nullptr)
+    {
+        try
+        {
+            foundHostingObject.reset(new HostingObject());
+            foundHostingObject->initializeHostingObject(remoteResource,
+                    std::bind(&ResourceHosting::destroyedHostingObject, this, foundHostingObject));
+            hostingObjectList.push_back(foundHostingObject);
+        }catch(InvalidParameterException &e)
+        {
+            OIC_HOSTING_LOG(DEBUG,
+                    "[ResourceHosting::discoverHandler]InvalidParameterException:%s", e.what());
+        }
+    }
+}
+
+ResourceHosting::HostingObjectPtr ResourceHosting::findRemoteResource(
+        RemoteObjectPtr remoteResource)
+{
+    HostingObjectPtr retObject = nullptr;
+
+    for(auto it : hostingObjectList)
+    {
+        RemoteObjectPtr inListPtr = it->getRemoteResource();
+        if(inListPtr != nullptr && isSameRemoteResource(inListPtr, remoteResource))
+        {
+            retObject = it;
+        }
+    }
+
+    return retObject;
+}
+
+bool ResourceHosting::isSameRemoteResource(
+        RemoteObjectPtr remoteResource_1, RemoteObjectPtr remoteResource_2)
+{
+    bool ret = false;
+    if(remoteResource_1->getAddress() == remoteResource_2->getAddress() &&
+//       remoteResource_1->getID() == remoteResource_2->getID() &&
+       remoteResource_1->getUri() == remoteResource_2->getUri())
+    {
+        ret = true;
+    }
+    return ret;
+}
+
+void ResourceHosting::destroyedHostingObject(HostingObjectPtr destroyedPtr)
+{
+    hostingObjectList.remove(destroyedPtr);
+}
+
+} /* namespace Service */
+} /* namespace OIC */
diff --git a/service/notification-manager/NotificationManager/src/ResourceHosting.h b/service/notification-manager/NotificationManager/src/ResourceHosting.h
new file mode 100644 (file)
index 0000000..f4f9ff6
--- /dev/null
@@ -0,0 +1,102 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RH_RESOURCEHOSTING_H_
+#define RH_RESOURCEHOSTING_H_
+
+#include <cstdbool>
+#include <iostream>
+#include <list>
+#include <memory>
+#include <functional>
+#include <string>
+#include <atomic>
+
+#include "octypes.h"
+#include "RCSAddress.h"
+#include "PresenceSubscriber.h"
+#include "HostingObject.h"
+#include "PrimitiveResource.h"
+
+namespace OIC
+{
+namespace Service
+{
+
+class RCSDiscoveryManager;
+class ResourceHosting
+{
+private:
+    typedef std::shared_ptr<HostingObject> HostingObjectPtr;
+    typedef std::shared_ptr<RCSRemoteResourceObject> RemoteObjectPtr;
+    typedef std::shared_ptr<PrimitiveResource> PrimiteveResourcePtr;
+
+    typedef std::function<
+            void(OCStackResult, const unsigned int, const std::string&)> SubscribeCallback;
+    typedef std::function<
+            void(std::shared_ptr<RCSRemoteResourceObject>)> DiscoveryCallback;
+    typedef std::function<void()> DestroyedCallback;
+
+public:
+    void startHosting();
+    void stopHosting();
+
+    static ResourceHosting * getInstance();
+
+private:
+    ResourceHosting();
+    ~ResourceHosting() = default;
+
+    ResourceHosting(const ResourceHosting&) = delete;
+    ResourceHosting(ResourceHosting&&) = delete;
+    ResourceHosting& operator=(const ResourceHosting&) const = delete;
+    ResourceHosting& operator=(ResourceHosting&&) const = delete;
+
+    static ResourceHosting * s_instance;
+    static std::mutex s_mutexForCreation;
+
+    std::list<HostingObjectPtr> hostingObjectList;
+
+    RCSDiscoveryManager * discoveryManager;
+    PresenceSubscriber presenceHandle;
+
+    SubscribeCallback pPresenceCB;
+    DiscoveryCallback pDiscoveryCB;
+
+    void initializeResourceHosting();
+
+    void requestMulticastPresence();
+    void requestMulticastDiscovery();
+    void requestDiscovery(std::string address = std::string());
+
+    void presenceHandler(OCStackResult ret, const unsigned int seq, const std::string & address);
+    void discoverHandler(RemoteObjectPtr remoteResource);
+
+    HostingObjectPtr findRemoteResource(RemoteObjectPtr remoteResource);
+    bool isSameRemoteResource(RemoteObjectPtr remoteResource_1, RemoteObjectPtr remoteResource_2);
+
+    void destroyedHostingObject(HostingObjectPtr destroyedPtr);
+
+};
+
+} /* namespace Service */
+} /* namespace OIC */
+
+#endif /* RH_RESOURCEHOSTING_H_ */
diff --git a/service/notification-manager/NotificationManager/src/hosting.c b/service/notification-manager/NotificationManager/src/hosting.c
deleted file mode 100644 (file)
index dc74925..0000000
+++ /dev/null
@@ -1,1550 +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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-// Hosting Header
-#include "hosting.h"
-#include "virtualResource.h"
-
-// External Lib
-#include "cJSON.h"
-
-/*
- * internal function & static variable
- */
-///////////////////////////////////////////////////////////////////////////////////////////////////
-static MirrorResourceList *s_mirrorResourceList = NULL;
-static RequestHandleList *s_requestHandleList = NULL;
-
-#define OIC_COORDINATING_FLAG "/hosting"
-#define OIC_STRING_MAX_VALUE 100
-
-#define OC_DEFAULT_ADDRESS               "224.0.1.187"
-#define OC_WELL_KNOWN_COORDINATING_QUERY "coap://224.0.1.187:5683/oc/core?rt=Resource.Hosting"
-#define OC_COORDINATING_QUERY            "/oc/core?rt=Resource.Hosting"
-#define DEFAULT_CONTEXT_VALUE 0x99
-
-/*
- * Presence Func for hosting
- */
-
-/**
- *
- * request presence for coordinating
- *
- * @param[in] originResourceAddr - pointer of address string of original resource
- *
- * @return
- *     OC_STACK_OK
- *     OC_STACK_ERROR
- */
-OCStackResult requestPresence(char *originResourceAddr);
-
-/**
- *
- * callback function that call when response of presence request received
- *
- * @param[in] originResourceAddr - pointer of address string of original resource
- *
- * @return
- *     OC_STACK_OK
- *     OC_STACK_ERROR
- */
-OCStackApplicationResult requestPresenceCB(void *context, OCDoHandle handle,
-        OCClientResponse *clientResponse);
-
-/**
- *
- * build mirror resource list by clientResponse
- *
- * @param[in] handle - not using...
- * @param[in] clientResponse - client response that mirror resources are stored
- *
- * @return
- *     pointer of result MirrorResourceList
- */
-MirrorResourceList *buildMirrorResourceList(OCDoHandle handle, OCClientResponse *clientResponse);
-
-/**
- *
- * build mirror resource by JSON payload
- *
- * @param[in] ocArray_sub - pointer of json payload string
- *
- * @return
- *     pointer of result MirrorResource
- */
-MirrorResource *buildMirrorResource(cJSON *ocArray_sub);
-
-/**
- *
- * This method is used when setting queryUri, registering callback function and starting OCDoResource() Function in order to find Coordinatee Candidate
- *
- * @brief discover coordinatee candidate
- *
- * @return
- *     OC_STACK_OK               - no errors
- *     OC_STACK_INVALID_CALLBACK - invalid callback function pointer
- *     OC_STACK_INVALID_METHOD   - invalid resource method
- *     OC_STACK_INVALID_URI      - invalid required or reference URI
- *     OC_STACK_INVALID_QUERY    - number of resource types specified for filtering presence
- *                                 notifications exceeds @ref MAX_PRESENCE_FILTERS.
- *     OC_STACK_ERROR            - otherwise error(initialized value)
- */
-int requestCoordinateeCandidateDiscovery(char *address);
-
-/**
- *
- * This method is used to add a coordinator resource callback method in mirrorResourceList when host resource discovered.
- *
- * @param[in] context
- *              Context for callback method
- * @param[in] handle
- *              Handle to an @ref OCDoResource invocation.
- * @param[in] clientResponse
- *              Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
- *
- * @brief callback for receiving response of discoverCoordinateeCandidate()
- *
- * @return
- *     PRINT("Callback Context for DISCOVER query recvd successfully")      - context is DEFAULT_CONTEXT_VALUE
- *     call the buildMirrorResource() method                                    - clientResponse is not NULL && clientResponse->result is OC_STACK_OK
- *     OC_STACK_KEEP_TRANSACTION                                                - otherwise case
- */
-OCStackApplicationResult requestCoordinateeCandidateDiscoveryCB(void *context, OCDoHandle handle,
-        OCClientResponse *clientResponse);
-
-/**
- *
- * This method is used when setting queryUri, registering callback function and starting OCDoResource() Function in order to request resource coordination
- *
- * @brief
- *
- * @param[in] mirrorResource
- *          mirrorResource for using in order to request resource coordination
- *
- * @return
- *     OC_STACK_OK               - no errors
- *     OC_STACK_INVALID_CALLBACK - invalid callback function pointer
- *     OC_STACK_INVALID_METHOD   - invalid resource method
- *     OC_STACK_INVALID_URI      - invalid required or reference URI
- *     OC_STACK_INVALID_QUERY    - number of resource types specified for filtering presence
- *                                 notifications exceeds @ref MAX_PRESENCE_FILTERS.
- *     OC_STACK_ERROR            - otherwise error(initialized value)
- */
-OCStackResult requestResourceObservation(MirrorResource *mirrorResource);
-
-/**
- *
- * This method is used to handle callback of requestCoordination method.
- *
- * @param[in] context
- *              Context for callback method
- * @param[in] handle
- *              Handle to update mirror resource and check errorResponse
- * @param[in] clientResponse
- *              Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
- *
- * @brief callback when receiving response of coordinating requestion.
- *
- * @todo diverge return value
- *
- * @return
- *
- *     OC_STACK_KEEP_TRANSACTION                                            - otherwise case
- */
-OCStackApplicationResult requestResourceObservationCB(void *context, OCDoHandle handle,
-        OCClientResponse *clientResponse);
-
-/**
- *
- * This method is used to check resource validation and delete resource if it is not exist(not alive).
- *
- * @brief check mirror resource is alive
- *
- * @param[in] requestHandle
- *              Handle to check mirror resource
- *
- * @return
- *
- *     OC_STACK_DELETE_TRANSACTION                                              - otherwise case
- */
-OCStackApplicationResult checkResourceValidation(OCDoHandle requestHandle);
-
-/**
- *
- * register Mirror resource in the base resource list
- *
- * @param[in] requestHandle
- *              Handle to check mirror resource
- *
- * @return
- *     OC_STACK_OK
- *     OC_STACK_ERROR
- */
-OCStackResult registerMirrorResource(MirrorResource *node);
-
-/**
- *
- * update resource
- *
- * @param[in] sourceHandle - handle of source resource
- * @param[in] payload - pointer of json payload string that update items stored
- *
- * @return
- *     pointer of mirror resource. return NULL if there is any error.
- */
-MirrorResource *updateMirrorResource(OCDoHandle sourceHandle, const char *payload);
-
-/**
- *
- * build response payload
- *
- * @param[in] ehRequest - pointer of handler of entity handler request that to be responded
- *
- * @return
- *     OC_STACK_OK
- *     OC_STACK_ERROR
- */
-char *buildResponsePayload (OCEntityHandlerRequest *ehRequest);
-
-/**
- *
- * handle "Get" request
- *
- * @param[in] ehRequest - pointer of handler of entity handler request
- * @param[out] payload - pointer of payload to be responded
- * @param[in] maxPayloadSize - size of payload
- *
- * @return
- *     OC_EH_OK - success to copy response payload
- *     OC_EH_ERROR - error to copy response payload
- */
-OCEntityHandlerResult handleGetRequest (OCEntityHandlerRequest *ehRequest,
-                                        char *payload, uint16_t maxPayloadSize);
-
-/**
- *
- * handle request for non-existing resource
- *
- * @param[in] ehRequest - pointer of handler of entity handler request
- * @param[out] payload - pointer of payload to be responded
- * @param[in] maxPayloadSize - size of payload
- *
- * @return
- *     OC_EH_RESOURCE_DELETED - resource deleted
- */
-OCEntityHandlerResult handleNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize);
-
-/**
- *
- * callback function that called when source resource changed
- *
- * @param[in] flag - entity handler flag
- * @param[in] entityHandlerRequest - pointer of entity handler request
- *
- * @return
- *     OC_EH_OK
- *     OC_EH_ERROR
- */
-OCEntityHandlerResult resourceEntityHandlerCB (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest);
-
-/**
- *
- * request that address is alive
- *
- * @param[in] address - pointer of address string
- *
- * @return
- *     OC_STACK_OK
- *     OC_STACK_ERROR
- */
-OCStackResult requestIsAlive(const char *address);
-
-/**
- *
- * get string value of OCStackResult code
- *
- * @param[in] result - OCStringResult code
- *
- * @return
- *     pointer of result string value
- */
-const char *getResultString(OCStackResult result);
-
-OCStackResult requestQuery(RequestHandle *request, OCMethod method,
-                           const char *queryAddress, const char *queryUri);
-OCStackApplicationResult requestQueryCB(void *context, OCDoHandle handle,
-                                        OCClientResponse *clientResponse);
-OCEntityHandlerResponse buildEntityHandlerResponse(OCEntityHandlerRequest *entityHandlerRequest,
-        const char *clientPayload);
-OCEntityHandlerResult handleRequestPayload (OCEntityHandlerRequest *entityHandlerRequest,
-        char *payload, uint16_t maxPayloadSize);
-
-/*
- * for Lite Device Side
- */
-
-/**
- *
- * register resource as coordinatable
- *
- * @param[in] handle - resource handle
- * @param[in] resourceTypeName - resource type name
- * @param[in] resourceInterfaceName - resource interface name
- * @param[in] resourceUri - resource URI
- * @param[in] entityHandler - entity handler
- * @param[in] resourceProperties - resource properties
- *
- * @return
- *     pointer of result string value
- */
-OCStackResult registerResourceAsCoordinatable(OCResourceHandle *handle,
-        const char *resourceTypeName, const char *resourceInterfaceName,
-        const char *resourceUri, OCEntityHandler entityHandler, uint8_t resourceProperties);
-
-OCStackResult registerResourceAsCoordinatable(OCResourceHandle *handle,
-        const char *resourceTypeName,
-        const char *resourceInterfaceName,
-        const char *resourceUri,
-        OCEntityHandler entityHandler,
-        uint8_t resourceProperties)
-{
-    OCStackResult ret = OC_STACK_OK;
-    size_t coordinateUriLen = sizeof(char) * (strlen(resourceUri) +
-            strlen(OIC_COORDINATING_FLAG) + 1);
-    char *coordinatingURI = (char *)malloc(coordinateUriLen);
-    if(coordinatingURI == NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : coordinatingURI");
-        return OC_STACK_NO_MEMORY;
-    }
-
-    snprintf(coordinatingURI, coordinateUriLen,"%s%s", resourceUri, OIC_COORDINATING_FLAG);
-
-    OC_LOG_V(DEBUG, HOSTING_TAG, "requiredUri+coordinatingFlag = %s", coordinatingURI);
-
-    ret = OCCreateResource(handle, resourceTypeName, resourceInterfaceName,
-            coordinatingURI, entityHandler, resourceProperties);
-    free(coordinatingURI);
-    return ret;
-}
-
-/*
- *  for Hosting Device Side
- */
-OCStackResult OICStartCoordinate()
-{
-    OCStackResult ret = OC_STACK_ERROR;
-    if (OCInit((char *) NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
-    {
-        OC_LOG(ERROR, HOSTING_TAG, PCF("OCStack init ERROR"));
-    }
-    else
-    {
-        s_mirrorResourceList = createMirrorResourceList();
-        s_requestHandleList = createRequestHandleList();
-        ret = requestPresence(OC_MULTICAST_PREFIX);
-    }
-
-    return ret;
-}
-
-OCStackResult OICStopCoordinate()
-{
-    OCStackResult result = OC_STACK_ERROR;
-
-    if (OCStop() == OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack Stop OK");
-    }
-
-    result = destroyMirrorResourceList(s_mirrorResourceList);
-    s_mirrorResourceList = NULL;
-    if(result != OC_STACK_OK)
-    {
-        return OC_STACK_ERROR;
-    }
-
-    return result;
-}
-
-int requestCoordinateeCandidateDiscovery(char *sourceResourceAddress)
-{
-    OCStackResult result;
-    OCCallbackData cbData;
-    OCDoHandle handle;
-
-    /* Start a discovery query*/
-    char queryUri[OIC_STRING_MAX_VALUE] = { '\0' };
-    if (sourceResourceAddress == NULL)
-    {
-        strncpy(queryUri, OC_WELL_KNOWN_COORDINATING_QUERY, sizeof(queryUri));
-    }
-    else
-    {
-        snprintf(queryUri, sizeof(queryUri), "coap://%s%s",
-                sourceResourceAddress , OC_COORDINATING_QUERY);
-    }
-
-    cbData.cb = requestCoordinateeCandidateDiscoveryCB;
-    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
-    cbData.cd = NULL;
-
-    result = OCDoResource(&handle, OC_REST_GET, queryUri, OIC_COORDINATING_FLAG, 0,
-            OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
-    if (result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack resource error");
-    }
-    else
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Host Resource Finding...");
-    }
-    return result;
-}
-
-OCStackResult requestPresence(char *sourceResourceAddress)
-{
-    OCStackResult result = OC_STACK_ERROR;
-    OCCallbackData cbData;
-    OCDoHandle handle;
-
-    if (sourceResourceAddress == NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "SourceResourceAddress is not available.");
-        return result;
-    }
-
-    cbData.cb = requestPresenceCB;
-    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
-    cbData.cd = NULL;
-
-    char queryUri[OIC_STRING_MAX_VALUE] = { '\0' };
-    snprintf(queryUri, sizeof(queryUri), "coap://%s%s", sourceResourceAddress , OC_PRESENCE_URI);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "initializePresenceForCoordinating Query : %s", queryUri);
-
-    result = OCDoResource(&handle, OC_REST_PRESENCE, queryUri, 0, 0,
-            OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
-
-    if (result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "initializePresenceForCoordinating error");
-        result = OC_STACK_ERROR;
-    }
-    else
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Success initializePresenceForCoordinating");
-    }
-
-    return result;
-}
-
-OCStackApplicationResult requestPresenceCB(void *context, OCDoHandle handle,
-        OCClientResponse *clientResponse)
-{
-    uint8_t remoteIpAddress[4];
-    uint16_t remotePortNumber;
-    char address[OIC_STRING_MAX_VALUE] = { '\0' };
-
-    if (context == (void *) DEFAULT_CONTEXT_VALUE)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "\tCallback Context for presence CB recv successfully");
-    }
-    if (clientResponse)
-    {
-        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddress,
-                            remoteIpAddress + 1, remoteIpAddress + 2, remoteIpAddress + 3);
-        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNumber);
-        OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %s",  getResultString(clientResponse->result));
-        OC_LOG_V(DEBUG, HOSTING_TAG, "\tStackResult: %d",  clientResponse->result);
-        OC_LOG_V(DEBUG, HOSTING_TAG,
-                 "\tPresence Device =============> Presence %s @ %d.%d.%d.%d:%d",
-                 clientResponse->resJSONPayload, remoteIpAddress[0], remoteIpAddress[1],
-                 remoteIpAddress[2], remoteIpAddress[3], remotePortNumber);
-
-        snprintf(address, sizeof(address), "%d.%d.%d.%d:%d", remoteIpAddress[0], remoteIpAddress[1],
-                remoteIpAddress[2], remoteIpAddress[3], remotePortNumber);
-        if (clientResponse->result == OC_STACK_OK)
-        {
-            requestCoordinateeCandidateDiscovery(address);
-        }
-        if (clientResponse->result == OC_STACK_PRESENCE_STOPPED
-            || clientResponse->result == OC_STACK_PRESENCE_TIMEOUT
-            || clientResponse->result == OC_STACK_PRESENCE_DO_NOT_HANDLE)
-        {
-            requestIsAlive(address);
-        }
-
-    }
-    return OC_STACK_KEEP_TRANSACTION;
-}
-
-OCStackApplicationResult requestCoordinateeCandidateDiscoveryCB(void *ctx, OCDoHandle handle,
-        OCClientResponse *clientResponse)
-{
-    OC_LOG(DEBUG, HOSTING_TAG, "Found Host Resource");
-    OCStackResult ret = OC_STACK_DELETE_TRANSACTION;
-
-    if (ctx == (void *) DEFAULT_CONTEXT_VALUE)
-    {
-        OC_LOG(DEBUG, HOSTING_TAG, "Callback Context for DISCOVER query recvd successfully");
-    }
-    if (clientResponse && clientResponse->result == OC_STACK_OK)
-    {
-        MirrorResourceList *vList = buildMirrorResourceList(handle, clientResponse);
-        if (vList != NULL)
-        {
-
-            if (vList->headerNode == NULL)
-            {
-                OC_LOG(DEBUG, HOSTING_TAG, "This Discover Response is empty");
-                destroyMirrorResourceList(vList);
-                return ret;
-            }
-
-            // register All of VirtualResource
-            while (vList->headerNode)
-            {
-                MirrorResource *mirrorResource = vList->headerNode;
-                ret = ejectMirrorResource(vList, mirrorResource);
-                mirrorResource->next = NULL;
-                OC_LOG_V(DEBUG, HOSTING_TAG,
-                        "register virtual resource uri : %s", mirrorResource->uri);
-                if (ret != OC_STACK_OK)
-                {
-                    continue;
-                }
-
-                ret = registerMirrorResource(mirrorResource);
-                if (ret != OC_STACK_OK)
-                {
-                    continue;
-                }
-
-                ret = insertMirrorResource(s_mirrorResourceList, mirrorResource);
-                if (ret != OC_STACK_OK)
-                {
-                    OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
-                    continue;
-                }
-                printMirrorResourceList(s_mirrorResourceList);
-
-                ret = requestResourceObservation(mirrorResource);
-                if (ret != OC_STACK_OK)
-                {
-                    OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
-                    deleteMirrorResourceFromList(s_mirrorResourceList, mirrorResource);
-                    continue;
-                }
-            }
-            destroyMirrorResourceList(vList);
-            if (ret != OC_STACK_OK)
-            {
-                return ret;
-            }
-        }
-        ret = OC_STACK_KEEP_TRANSACTION;
-    }
-    return ret;
-}
-
-MirrorResourceList *buildMirrorResourceList(OCDoHandle handle, OCClientResponse *clientResponse)
-{
-
-    cJSON *discoveryJson = cJSON_CreateObject();
-    discoveryJson = cJSON_Parse((char *)clientResponse->resJSONPayload);
-
-    cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oc");
-    char *ocArray_str = cJSON_PrintUnformatted(ocArray);
-
-    if ( strstr(ocArray_str, "[{}") == ocArray_str )
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "invalid payload : %s", ocArray_str);
-        cJSON_Delete(discoveryJson);
-        return NULL;
-    }
-
-    MirrorResourceList *retList = createMirrorResourceList();
-
-    uint8_t remoteIpAddr[4];
-    uint16_t remotePortNum;
-
-    OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr,
-                        remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
-    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
-
-    char sourceaddr[OIC_STRING_MAX_VALUE] = {'\0'};
-    snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d", remoteIpAddr[0], remoteIpAddr[1],
-            remoteIpAddr[2], remoteIpAddr[3], remotePortNum);
-
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Host Device =============> Discovered %s @ %s",
-             clientResponse->resJSONPayload, sourceaddr);
-
-    int arraySize = cJSON_GetArraySize(ocArray);
-    for (int i = 0; i < arraySize; ++i)
-    {
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, i);
-        MirrorResource *mirrorResource = buildMirrorResource(ocArray_sub);
-
-        if (mirrorResource == NULL)
-        {
-            continue;
-        }
-        mirrorResource->address[OIC_SOURCE_ADDRESS] =
-                (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
-        if(mirrorResource->address[OIC_SOURCE_ADDRESS] == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : mirrorResource address_source");
-            destroyMirrorResource(mirrorResource);
-            continue;
-        }
-        snprintf(mirrorResource->address[OIC_SOURCE_ADDRESS],
-                sizeof(char) * OIC_STRING_MAX_VALUE, "%s", sourceaddr);
-
-        mirrorResource->address[OIC_MIRROR_ADDRESS] =
-                (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
-        if(mirrorResource->address[OIC_MIRROR_ADDRESS] == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail : mirrorResource address_mirror");
-            destroyMirrorResource(mirrorResource);
-            continue;
-        }
-        snprintf(mirrorResource->address[OIC_MIRROR_ADDRESS],
-                sizeof(char) * OIC_STRING_MAX_VALUE, "0.0.0.0:00");
-
-        if (OC_STACK_OK != insertMirrorResource(retList, mirrorResource))
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "buildVirtualResourceList : insert resource fail");
-            destroyMirrorResource(mirrorResource);
-        }
-    }
-
-    cJSON_Delete(discoveryJson);
-    return retList;
-}
-
-MirrorResource *buildMirrorResource(cJSON *ocArray_sub)
-{
-    MirrorResource *mirrorResource = NULL;
-    const char *curValuestring = cJSON_GetObjectItem(ocArray_sub, "href")->valuestring;
-
-    if ( strstr(curValuestring, OIC_COORDINATING_FLAG) )
-    {
-        mirrorResource = createMirrorResource();
-        if(mirrorResource == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail for mirrorResource");
-            goto RET_ERROR;
-        }
-
-        mirrorResource->uri = (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
-        if(mirrorResource->uri == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "memory alloc fail for mirrorResource uri");
-            goto RET_ERROR;
-        }
-        strncpy(mirrorResource->uri, curValuestring, strlen(curValuestring) - strlen(OIC_COORDINATING_FLAG));
-        mirrorResource->uri[strlen(curValuestring) - strlen(OIC_COORDINATING_FLAG)] = '\0';
-        OC_LOG_V(DEBUG, HOSTING_TAG, "VirtualResource URI : %s", mirrorResource->uri);
-
-        cJSON *inArray_sub = cJSON_GetObjectItem(ocArray_sub, "prop");
-
-        cJSON *tmpJSON = NULL;
-        int sizetemp = 0;
-
-        tmpJSON = cJSON_GetObjectItem(inArray_sub, "rt");
-        sizetemp = cJSON_GetArraySize(tmpJSON);
-        mirrorResource->prop.countResourceType = sizetemp;
-        mirrorResource->prop.resourceType = (char **)malloc(sizeof(char *)*sizetemp);
-        if (mirrorResource->prop.resourceType == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG,
-                    "memory alloc fail for mirrorResource number of resourceType");
-            goto RET_ERROR;
-        }
-        else
-        {
-            for (int k = 0; k < sizetemp; ++k)
-            {
-                mirrorResource->prop.resourceType[k] =
-                        (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
-                if (mirrorResource->prop.resourceType[k] == NULL)
-                {
-                    OC_LOG_V(DEBUG, HOSTING_TAG,
-                            "memory alloc fail for mirrorResource resourceType[n]");
-                    goto RET_ERROR;
-                }
-                memset(mirrorResource->prop.resourceType[k], '\0', OIC_STRING_MAX_VALUE);
-                strncpy(mirrorResource->prop.resourceType[k],
-                        cJSON_GetArrayItem(tmpJSON, k)->valuestring,
-                        sizeof(char) * OIC_STRING_MAX_VALUE);
-            }
-        }
-
-        tmpJSON = cJSON_GetObjectItem(inArray_sub, "if");
-        sizetemp = cJSON_GetArraySize(tmpJSON);
-        mirrorResource->prop.countInterface = sizetemp;
-        mirrorResource->prop.resourceInterfaceName = (char **)malloc(sizeof(char *)*sizetemp);
-        if (mirrorResource->prop.resourceInterfaceName == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG,
-                    "memory alloc fail for mirrorResource number of resourceInterfaceName");
-            goto RET_ERROR;
-        }
-
-        for (int k = 0; k < sizetemp; ++k)
-        {
-            mirrorResource->prop.resourceInterfaceName[k] =
-                    (char *)malloc(sizeof(char) * OIC_STRING_MAX_VALUE);
-            if (mirrorResource->prop.resourceInterfaceName[k] == NULL)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG,
-                        "memory alloc fail for mirrorResource resourceInterfaceName[n]");
-                goto RET_ERROR;
-            }
-
-            memset(mirrorResource->prop.resourceInterfaceName[k], '\0', OIC_STRING_MAX_VALUE);
-            strncpy(mirrorResource->prop.resourceInterfaceName[k],
-                    cJSON_GetArrayItem(tmpJSON, k)->valuestring,
-                    sizeof(char) * OIC_STRING_MAX_VALUE);
-        }
-    }
-
-    return mirrorResource;
-
-RET_ERROR:
-    destroyMirrorResource(mirrorResource);
-    return NULL;
-}
-
-OCStackResult registerMirrorResource(MirrorResource *mirrorResource)
-{
-    OCStackResult result = OC_STACK_ERROR;
-
-    MirrorResource *foundMirrorResource = findMirrorResourceUsingAddressAndURI(s_mirrorResourceList,
-                                          mirrorResource->address[OIC_MIRROR_ADDRESS], OIC_MIRROR_ADDRESS, mirrorResource->uri);
-    if (foundMirrorResource != NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Already registered resource");
-        goto RETURN_ERR;
-    }
-
-    result = OCCreateResource(&(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]),
-                              mirrorResource->prop.resourceType[0],
-                              mirrorResource->prop.resourceInterfaceName[0],
-                              mirrorResource->uri,
-                              resourceEntityHandlerCB,
-                              OC_DISCOVERABLE | OC_OBSERVABLE);
-
-    OC_LOG_V(DEBUG, HOSTING_TAG, "created mirror resource Handle : %u",mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
-
-    if (result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "error return = %s", getResultString(result));
-        mirrorResource->next = NULL;
-        destroyMirrorResource(mirrorResource);
-        return result;
-    }
-
-    if (mirrorResource->prop.countResourceType > 1)
-    {
-        int i = 0;
-        for (i = 1; i < mirrorResource->prop.countResourceType; ++i)
-        {
-            result = OCBindResourceTypeToResource(
-                             mirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
-                             mirrorResource->prop.resourceType[i]);
-            if (result != OC_STACK_OK)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Virtual Resource Registration Fail : BindResourceType");
-                goto RETURN_ERR;
-            }
-        }
-    }
-
-    if (mirrorResource->prop.countInterface > 1)
-    {
-        int i = 0;
-        for (i = 1; i < mirrorResource->prop.countInterface; ++i)
-        {
-            result = OCBindResourceInterfaceToResource(
-                         mirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
-                         mirrorResource->prop.resourceInterfaceName[i]);
-            if (result != OC_STACK_OK)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG,
-                        "Virtual Resource Registration Fail : BindResourceInterfaceName");
-                goto RETURN_ERR;
-            }
-        }
-    }
-
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource Registration Success");
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource uri : %s", mirrorResource->uri);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource source address : %s",
-             mirrorResource->address[OIC_SOURCE_ADDRESS]);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource virtual address : %s",
-             mirrorResource->address[OIC_MIRROR_ADDRESS]);
-    return result;
-
-RETURN_ERR:
-    OCDeleteResource(mirrorResource->resourceHandle[OIC_MIRROR_HANDLE]);
-    mirrorResource->next = NULL;
-    destroyMirrorResource(mirrorResource);
-
-    return result;
-}
-
-OCStackResult requestResourceObservation(MirrorResource *mirrorResource)
-{
-    OCStackResult result;
-    OCCallbackData cbData;
-
-    cbData.cb = requestResourceObservationCB;
-    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
-    cbData.cd = NULL;
-
-    char query[OIC_STRING_MAX_VALUE] = {'\0'};
-    snprintf(query, sizeof(query), "coap://%s%s%s", mirrorResource->address[OIC_SOURCE_ADDRESS], mirrorResource->uri,
-            OIC_COORDINATING_FLAG);
-
-    result = OCDoResource(&mirrorResource->resourceHandle[OIC_REQUEST_HANDLE], OC_REST_OBSERVE, query,
-                          0, NULL, OC_TRANSPORT,
-                          OC_HIGH_QOS, &cbData, NULL, 0);
-
-    if (result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "OCDoResource returns error %s with method %d",
-                 getResultString(result), OC_REST_OBSERVE);
-    }
-
-    return result;
-}
-
-OCStackApplicationResult requestResourceObservationCB(void *context, OCDoHandle handle,
-        OCClientResponse *clientResponse)
-{
-    OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
-
-    if (context == (void *)DEFAULT_CONTEXT_VALUE)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Callback Context for OBS query recvd successfully");
-    }
-
-    if (clientResponse && clientResponse->result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "observeCB result error = %s",
-                 getResultString(clientResponse->result));
-        return checkResourceValidation(handle);
-    }
-
-    if (clientResponse && clientResponse->result == OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG,
-                 "<=============Callback Context for OBSERVE notification recvd successfully");
-        OC_LOG_V(DEBUG, HOSTING_TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-        OC_LOG_V(DEBUG, HOSTING_TAG, "JSON = %s =============> Obs Response",
-                 clientResponse->resJSONPayload);
-
-        MirrorResource *foundMirrorResource = updateMirrorResource(handle, clientResponse->resJSONPayload);
-        if (foundMirrorResource == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource : Fail");
-            return ret;
-        }
-
-        if ( OC_STACK_OK != OCNotifyAllObservers(foundMirrorResource->resourceHandle[OIC_MIRROR_HANDLE],
-                OC_HIGH_QOS) )
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Notify Mirror Resource's Subscriber : Fail");
-        }
-        else
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Notify Mirror Resource's Subscriber : Success");
-        }
-
-        if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "This also serves as a registration confirmation");
-        }
-        else if (clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "This also serves as a deregistration confirmation");
-            return ret;
-        }
-        else if (clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "This also tells you that registration/deregistration failed");
-            return ret;
-        }
-        ret = OC_STACK_KEEP_TRANSACTION;
-    }
-    return ret;
-}
-
-OCStackApplicationResult checkResourceValidation(OCDoHandle handle)
-{
-    OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
-
-    RequestHandle *foundRequestHandle = findRequestHandle(s_requestHandleList, handle,
-                                        OIC_REQUEST_BY_COORDINATOR);
-
-    if (foundRequestHandle == NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Not found any request.");
-        return ret;
-    }
-
-    if (foundRequestHandle->isAliveCheck)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "This response is Alive Check : Expired resource");
-        OCDeleteResource(foundRequestHandle->requestHandle[OIC_REQUEST_BY_CLIENT]);
-    }
-    deleteRequestHandleFromList(s_requestHandleList, foundRequestHandle);
-    return ret;
-}
-
-MirrorResource *updateMirrorResource(OCDoHandle handle, const char *payload)
-{
-    MirrorResource *foundMirrorResource = findMirrorResourceUsingHandle(
-            s_mirrorResourceList, handle, OIC_REQUEST_HANDLE);
-
-    if (!foundMirrorResource)
-    {
-        // TODO
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource. In updateMirrorResource");
-        return NULL;
-    }
-
-    cJSON *repData = NULL;
-    cJSON *observeJson = cJSON_Parse(payload);
-
-    if (observeJson)
-    {
-        cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oc");
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-        cJSON *tempData = cJSON_GetObjectItem(ocArray_sub, "rep");
-        char *temp = cJSON_PrintUnformatted(tempData);
-
-        repData = cJSON_Parse(temp);
-        if (temp != NULL)
-        {
-            free(temp);
-        }
-        cJSON_Delete(observeJson);
-    }
-    else
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror resource payload is not correct");
-        return NULL;
-    }
-
-    if (foundMirrorResource->rep)
-    {
-        cJSON_Delete(foundMirrorResource->rep);
-        foundMirrorResource->rep = NULL;
-    }
-    foundMirrorResource->rep = repData;
-
-    cJSON *json = cJSON_CreateObject();
-
-    char nodeData[OIC_STRING_MAX_VALUE] = {'\0'};
-    snprintf(nodeData, sizeof(nodeData), "%s", foundMirrorResource->uri);
-    cJSON_AddStringToObject(json, "href", nodeData);
-
-    cJSON *nodeRep = cJSON_Parse(cJSON_PrintUnformatted(foundMirrorResource->rep));
-    cJSON_AddItemToObject(json, "rep", nodeRep);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "It will notify resource : %s", cJSON_PrintUnformatted(json));
-
-    cJSON_Delete(json);
-
-    return foundMirrorResource;
-}
-
-char *buildResponsePayload (OCEntityHandlerRequest *entityHandlerRequest)
-{
-    MirrorResource *mirrorResource = findMirrorResourceUsingHandle(s_mirrorResourceList,
-                                     entityHandlerRequest->resource, OIC_MIRROR_HANDLE);
-    if (!mirrorResource)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found Mirror Resource. In buildResponsePayload()");
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Mirror Resource's Handle : %x.", entityHandlerRequest->resource);
-        return NULL;
-    }
-
-    if (entityHandlerRequest->method == OC_REST_PUT)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "oc_rest_put");
-        if (mirrorResource->rep)
-        {
-            cJSON_Delete(mirrorResource->rep);
-            mirrorResource->rep = NULL;
-        }
-        mirrorResource->rep = cJSON_CreateObject();
-        mirrorResource->rep = cJSON_Parse(entityHandlerRequest->reqJSONPayload);
-    }
-
-    OC_LOG_V(DEBUG, HOSTING_TAG, "node's uri : %s", mirrorResource->uri);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "node's source address : %s", mirrorResource->address[0]);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "node's mirror address : %s", mirrorResource->address[1]);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "node's rep : %s", cJSON_PrintUnformatted(mirrorResource->rep));
-
-    cJSON *jsonObject = cJSON_CreateObject();
-
-    char uriString[OIC_STRING_MAX_VALUE] = {'\0'};
-    snprintf(uriString, sizeof(uriString), "%s", mirrorResource->uri);
-    cJSON_AddStringToObject(jsonObject, "href", uriString);
-
-    cJSON *itemRep = cJSON_Parse(cJSON_PrintUnformatted(mirrorResource->rep));
-    cJSON_AddItemToObject(jsonObject, "rep", itemRep);
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Will response resource : %s", cJSON_PrintUnformatted(jsonObject));
-
-    char *jsonResponse = cJSON_Print(jsonObject);
-    cJSON_Delete(jsonObject);
-
-    return jsonResponse;
-}
-
-OCEntityHandlerResult
-resourceEntityHandlerCB (OCEntityHandlerFlag entifyHandlerFlag,
-                         OCEntityHandlerRequest *entityHandlerRequest)
-{
-    OC_LOG_V(DEBUG, HOSTING_TAG, "Inside device default entity handler - flags: 0x%x",
-             entifyHandlerFlag);
-
-    OCEntityHandlerResult entityHandlerResult = OC_EH_OK;
-    OCEntityHandlerResponse entityHandlerResponse;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
-
-    // Validate pointer
-    if (!entityHandlerRequest)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Invalid request pointer");
-        return OC_EH_ERROR;
-    }
-
-    // Initialize certain response fields
-    entityHandlerResponse.numSendVendorSpecificHeaderOptions = 0;
-    memset(entityHandlerResponse.sendVendorSpecificHeaderOptions, 0,
-           sizeof entityHandlerResponse.sendVendorSpecificHeaderOptions);
-    memset(entityHandlerResponse.resourceUri, 0, sizeof entityHandlerResponse.resourceUri);
-
-    if (entifyHandlerFlag & OC_REQUEST_FLAG)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Flag includes OC_REQUEST_FLAG");
-        if (entityHandlerRequest->resource == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received request from client to a non-existing resource");
-            entityHandlerResult = handleNonExistingResourceRequest(entityHandlerRequest, payload,
-                                  sizeof(payload) - 1);
-        }
-        else if (OC_REST_GET == entityHandlerRequest->method)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_REST_GET from client");
-            entityHandlerResult = handleGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_PUT == entityHandlerRequest->method ||
-                 OC_REST_DELETE == entityHandlerRequest->method )
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_REST_PUT/DELETE from client");
-
-            RequestHandle *request = createRequestHandle();
-
-            request->requestHandle[OIC_REQUEST_BY_CLIENT] = entityHandlerRequest;
-            request->resourceHandle = entityHandlerRequest->resource;
-            request->method = entityHandlerRequest->method;
-            request->entityRequestHandle = entityHandlerRequest->requestHandle;
-
-            OCStackResult result = insertRequestHandle(s_requestHandleList, request);
-            if (result != OC_STACK_OK)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Insert request list : fail2(%d)", result);
-                return result;
-            }
-
-            MirrorResource *mirrorResource = findMirrorResourceUsingHandle(s_mirrorResourceList,
-                                             entityHandlerRequest->resource, OIC_MIRROR_HANDLE);
-            if (mirrorResource == NULL)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Not found requested resource");
-                return OC_EH_ERROR;
-            }
-
-            result = requestQuery(request,
-                    entityHandlerRequest->method, mirrorResource->address[OIC_SOURCE_ADDRESS],
-                    mirrorResource->uri);
-            if (result != OC_STACK_OK)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Request query failed");
-                deleteRequestHandleFromList(s_requestHandleList, request);
-            }
-            return OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received unsupported method %d from client",
-                     entityHandlerRequest->method);
-            entityHandlerResult = OC_EH_ERROR;
-        }
-
-        // If the result isn't an error or forbidden, send response
-        if (!((entityHandlerResult == OC_EH_ERROR) || (entityHandlerResult == OC_EH_FORBIDDEN)))
-        {
-            // Format the response.  Note this requires some info about the request
-            entityHandlerResponse.requestHandle = entityHandlerRequest->requestHandle;
-            entityHandlerResponse.resourceHandle = entityHandlerRequest->resource;
-            entityHandlerResponse.ehResult = entityHandlerResult;
-            entityHandlerResponse.payload = (char *)payload;
-            entityHandlerResponse.payloadSize = strlen(payload);
-            // Indicate that response is NOT in a persistent buffer
-            entityHandlerResponse.persistentBufferFlag = 0;
-
-            // Handle vendor specific options
-            if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
-                entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Received vendor specific options");
-                OCHeaderOption *receivedVenderSpecificHeaderOptions =
-                    entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
-                for ( int i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
-                {
-                    if (((OCHeaderOption)receivedVenderSpecificHeaderOptions[i]).protocolID == OC_COAP_ID)
-                    {
-                        OC_LOG_V(DEBUG, HOSTING_TAG, "Received option with OC_COAP_ID and ID %u with",
-                                 ((OCHeaderOption)receivedVenderSpecificHeaderOptions[i]).optionID );
-                    }
-                }
-                OCHeaderOption *sendVenderSpecificHeaderOptions =
-                    entityHandlerResponse.sendVendorSpecificHeaderOptions;
-                uint8_t option2[] = {21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
-                uint8_t option3[] = {31, 32, 33, 34, 35, 36, 37, 38, 39, 40};
-                sendVenderSpecificHeaderOptions[0].protocolID = OC_COAP_ID;
-                sendVenderSpecificHeaderOptions[0].optionID = 2248;
-                memcpy(sendVenderSpecificHeaderOptions[0].optionData, option2, sizeof(option2));
-                sendVenderSpecificHeaderOptions[0].optionLength = 10;
-                sendVenderSpecificHeaderOptions[1].protocolID = OC_COAP_ID;
-                sendVenderSpecificHeaderOptions[1].optionID = 2600;
-                memcpy(sendVenderSpecificHeaderOptions[1].optionData, option3, sizeof(option3));
-                sendVenderSpecificHeaderOptions[1].optionLength = 10;
-                entityHandlerResponse.numSendVendorSpecificHeaderOptions = 2;
-            }
-
-            // Send the response
-            if (OCDoResponse(&entityHandlerResponse) != OC_STACK_OK)
-            {
-                OC_LOG(ERROR, HOSTING_TAG, "Error sending response");
-                entityHandlerResult = OC_EH_ERROR;
-            }
-        }
-    }
-    if (entifyHandlerFlag & OC_OBSERVE_FLAG)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Flag includes OC_OBSERVE_FLAG");
-        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_OBSERVE_REGISTER from client");
-        }
-        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Received OC_OBSERVE_DEREGISTER from client");
-        }
-    }
-
-    return entityHandlerResult;
-}
-OCEntityHandlerResult
-handleGetRequest (OCEntityHandlerRequest *entityHandlerRequest,
-        char *payload, uint16_t maxPayloadSize)
-{
-    OC_LOG_V(DEBUG, HOSTING_TAG, "ProcessGetRequest in....");
-
-    OCEntityHandlerResult entityHandlerResult = OC_EH_ERROR;
-    char *responsePayload = buildResponsePayload(entityHandlerRequest);
-    if(!responsePayload)
-    {
-        return entityHandlerResult;
-    }
-
-    if (maxPayloadSize > strlen ((char *)responsePayload))
-    {
-        strncpy(payload, responsePayload, strlen((char *)responsePayload));
-        entityHandlerResult = OC_EH_OK;
-    }
-    else
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
-    }
-
-    free(responsePayload);
-
-    return entityHandlerResult;
-}
-OCEntityHandlerResult
-handleNonExistingResourceRequest(OCEntityHandlerRequest *entityHandlerRequest,
-        char *payload, uint16_t maxPayloadSize)
-{
-    OC_LOG_V(INFO, HOSTING_TAG, "Executing %s ", __func__);
-
-    char responsePayload[OIC_STRING_MAX_VALUE] = {'\0'};
-    strncpy(responsePayload, "{App determines payload: The resource does not exist.}",
-            sizeof(responsePayload));
-
-    if ( (entityHandlerRequest != NULL) &&
-         (maxPayloadSize > strlen ((char *)responsePayload)) )
-    {
-        strncpy((char *)payload, responsePayload, strlen((char *)responsePayload));
-    }
-    else
-    {
-        OC_LOG_V (INFO, HOSTING_TAG, "Response buffer: %d bytes is too small",
-                  maxPayloadSize);
-    }
-
-    return OC_EH_RESOURCE_DELETED;
-}
-
-OCStackResult requestIsAlive(const char *address)
-{
-    MirrorResourceList *requestMirrorResourceList = findMirrorResourceListUsingAddress(
-                s_mirrorResourceList, address, OIC_SOURCE_ADDRESS);
-
-    if (requestMirrorResourceList == NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found any mirror resource1");
-        return OC_STACK_ERROR;
-    }
-
-    if (requestMirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Cannot found any mirror resource2");
-        return OC_STACK_ERROR;
-    }
-
-    MirrorResource *mirrorResource = requestMirrorResourceList->headerNode;
-    while (mirrorResource)
-    {
-        RequestHandle *requestAlive = createRequestHandle();
-        requestAlive->isAliveCheck = 1;
-        requestAlive->requestHandle[OIC_REQUEST_BY_CLIENT] =
-            mirrorResource->resourceHandle[OIC_MIRROR_HANDLE];
-
-        OCStackResult result = insertRequestHandle(s_requestHandleList, requestAlive);
-        if (result != OC_STACK_OK)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Insert request list : fail3");
-            destroyRequestHandle(requestAlive);
-            mirrorResource = mirrorResource->next;
-            continue;
-        }
-
-        result = requestQuery(requestAlive, OC_REST_GET, address, mirrorResource->uri);
-        if (result != OC_STACK_OK)
-        {
-            deleteRequestHandleFromList(s_requestHandleList, requestAlive);
-        }
-        mirrorResource = mirrorResource->next;
-    }
-    destroyMirrorResourceList(requestMirrorResourceList);
-
-    return OC_STACK_OK;
-}
-
-const char *getResultString(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";
-        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
-            return "OC_STACK_VIRTUAL_DO_NOT_HANDLE";
-        case OC_STACK_PRESENCE_STOPPED:
-            return "OC_STACK_PRESENCE_STOPPED";
-        case OC_STACK_PRESENCE_TIMEOUT:
-            return "OC_STACK_PRESENCE_TIMEOUT";
-        case OC_STACK_PRESENCE_DO_NOT_HANDLE:
-            return "OC_STACK_PRESENCE_DO_NOT_HANDLE";
-        case OC_STACK_ERROR:
-            return "OC_STACK_ERROR";
-        default:
-            return "UNKNOWN";
-    }
-}
-
-void getJsonArrayPair(cJSON *tempData)
-{
-    int countofrep = cJSON_GetArraySize(tempData);
-    OC_LOG_V(DEBUG, HOSTING_TAG,
-             "//////////////////////////////////////////////////////////////////////////");
-    OC_LOG_V(DEBUG, HOSTING_TAG, "//Test");
-    OC_LOG_V(DEBUG, HOSTING_TAG, "rep Size : %d", countofrep);
-
-    for (int i = 0; i < countofrep; ++i)
-    {
-        cJSON *arrayJSON = cJSON_GetArrayItem(tempData, i);
-        OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's name : %s", i, arrayJSON->string);
-
-        switch (arrayJSON->type)
-        {
-            case cJSON_False:
-            case cJSON_True:
-                OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %d", i, arrayJSON->valueint);
-                break;
-            case cJSON_Number:
-                OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %f", i, arrayJSON->valuedouble);
-                break;
-            case cJSON_String:
-                OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : %s", i, arrayJSON->valuestring);
-                break;
-            case cJSON_NULL:
-            default:
-                OC_LOG_V(DEBUG, HOSTING_TAG, "rep#%d's value : NULL", i);
-                break;
-        }
-    }
-    OC_LOG_V(DEBUG, HOSTING_TAG,
-             "//////////////////////////////////////////////////////////////////////////");
-}
-
-OCStackResult requestQuery(RequestHandle *request, OCMethod method,
-                           const char *queryAddress, const char *queryUri)
-{
-
-    OCStackResult result = OC_STACK_ERROR;
-    OCCallbackData cbData;
-
-    /* Start a discovery query*/
-    char queryFullUri[OIC_STRING_MAX_VALUE] = {'\0'};
-    if (queryAddress == NULL)
-    {
-        return result;
-    }
-    else
-    {
-        snprintf(queryFullUri, sizeof(queryFullUri) ,"coap://%s%s%s", queryAddress , queryUri, OIC_COORDINATING_FLAG);
-    }
-
-    cbData.cb = requestQueryCB;
-    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
-    cbData.cd = NULL;
-
-    if(method == OC_REST_PUT)
-    {
-        char payload[OIC_STRING_MAX_VALUE] = {'\0'};
-        snprintf(payload , sizeof(payload), "%s" ,
-         ((OCEntityHandlerRequest*)request->requestHandle[OIC_REQUEST_BY_CLIENT])->reqJSONPayload);
-
-        result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
-                method, queryFullUri, NULL, payload, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
-    }
-    else
-    {
-        result = OCDoResource(&request->requestHandle[OIC_REQUEST_BY_COORDINATOR],
-                method, queryFullUri, NULL, 0, OC_TRANSPORT, OC_LOW_QOS, &cbData, NULL, 0);
-    }
-
-    if (result != OC_STACK_OK)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "OCStack resource error");
-    }
-
-    return result;
-}
-
-OCStackApplicationResult requestQueryCB(void *context, OCDoHandle handle,
-                                        OCClientResponse *clientResponse)
-{
-    OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
-
-    if (context == (void *) DEFAULT_CONTEXT_VALUE)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Callback Context for Request query recvd successfully");
-    }
-
-    if (clientResponse && clientResponse->result != OC_STACK_OK && clientResponse->result != OC_STACK_RESOURCE_DELETED)
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "requestQueryCB result error = %s",
-                 getResultString(clientResponse->result));
-        return checkResourceValidation(handle);
-    }
-
-    if (clientResponse && (clientResponse->result == OC_STACK_OK || clientResponse->result == OC_STACK_RESOURCE_DELETED))
-    {
-        RequestHandle *request = findRequestHandle(s_requestHandleList, handle, OIC_REQUEST_BY_COORDINATOR);
-        if (request == NULL)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "Not found Any request");
-            return ret;
-        }
-        if (request->isAliveCheck == 1)
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "This response is Alive Check : Keep resource");
-        }
-        else
-        {
-            OC_LOG_V(DEBUG, HOSTING_TAG, "requestCB's payload: %s", clientResponse->resJSONPayload);
-            OCEntityHandlerRequest *entityHandler = (OCEntityHandlerRequest *)(
-                    request->requestHandle[OIC_REQUEST_BY_CLIENT]);
-            OC_LOG_V(DEBUG, HOSTING_TAG, "requested resource handle : %u", entityHandler->resource
-                    );
-
-            entityHandler->resource = request->resourceHandle;
-            entityHandler->method = request->method;
-            entityHandler->requestHandle = request->entityRequestHandle;
-
-            OCEntityHandlerResponse response = buildEntityHandlerResponse(
-                                                   entityHandler, clientResponse->resJSONPayload);
-            if (OCDoResponse(&response) != OC_STACK_OK)
-            {
-                OC_LOG_V(DEBUG, HOSTING_TAG, "Error sending response");
-                deleteRequestHandleFromList(s_requestHandleList, request);
-                return ret;
-            }
-            if (entityHandler->method == OC_REST_DELETE)
-            {
-                OCDeleteResource(entityHandler->resource);
-            }
-        }
-        deleteRequestHandleFromList(s_requestHandleList, request);
-        ret = OC_STACK_KEEP_TRANSACTION;
-    }
-
-    return ret;
-}
-
-OCEntityHandlerResponse buildEntityHandlerResponse(OCEntityHandlerRequest *entityHandlerRequest,
-        const char *clientPayload)
-{
-    OC_LOG_V(DEBUG, HOSTING_TAG, "enter buildEntityHandlerResponse");
-    OCEntityHandlerResponse response;
-    memset(&response, 0, sizeof(response));
-    OCEntityHandlerResult entityHandlerResult = OC_EH_OK;
-    char payload[MAX_RESPONSE_LENGTH] = {'\0'};
-
-    // Initialize certain response fields
-    response.numSendVendorSpecificHeaderOptions = 0;
-    memset(response.sendVendorSpecificHeaderOptions, 0,
-           sizeof response.sendVendorSpecificHeaderOptions);
-    memset(response.resourceUri, 0, sizeof response.resourceUri);
-
-    char *temp = NULL;
-    if(entityHandlerRequest->method == OC_REST_PUT)
-    {
-        cJSON *observeJson = cJSON_CreateObject();
-        observeJson = cJSON_Parse(clientPayload);
-
-        cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oc");
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
-        cJSON *tempData = cJSON_GetObjectItem(ocArray_sub, "rep");
-        temp = cJSON_PrintUnformatted(tempData);
-
-        cJSON_Delete(observeJson);
-
-        entityHandlerRequest->reqJSONPayload = temp;
-    }
-    entityHandlerResult = handleRequestPayload(entityHandlerRequest, payload, sizeof(payload) - 1);
-
-    // Format the response.  Note this requires some info about the request
-    response.requestHandle = entityHandlerRequest->requestHandle;
-    response.resourceHandle = entityHandlerRequest->resource;
-    response.ehResult = entityHandlerResult;
-
-    response.payload = (char *)payload;
-    response.payloadSize = strlen(payload);
-    // Indicate that response is NOT in a persistent buffer
-    response.persistentBufferFlag = 0;
-
-    if(entityHandlerRequest->method == OC_REST_PUT){
-        if(temp){
-            free(temp);
-        }
-    }
-
-    return response;
-}
-
-OCEntityHandlerResult handleRequestPayload (OCEntityHandlerRequest *entityHandlerRequest,
-        char *payload, uint16_t maxPayloadSize)
-{
-    OC_LOG_V(DEBUG, HOSTING_TAG, "enter handleRequestPayload");
-    OCEntityHandlerResult entityHandlerResult = OC_EH_ERROR;
-
-    if (entityHandlerRequest->method == OC_REST_DELETE)
-    {
-        memset(payload, '\0', sizeof(char) * (maxPayloadSize + 1));
-        OC_LOG_V(DEBUG, HOSTING_TAG, "DELETE");
-        return OC_EH_RESOURCE_DELETED;
-    }
-
-    char *responsePayload = buildResponsePayload(entityHandlerRequest);
-    if(!responsePayload)
-    {
-        return entityHandlerResult;
-    }
-
-    if (maxPayloadSize > strlen ((char *)responsePayload))
-    {
-        strncpy(payload, responsePayload, strlen ((char *)responsePayload));
-        entityHandlerResult = OC_EH_OK;
-    }
-    else
-    {
-        OC_LOG_V(DEBUG, HOSTING_TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
-        entityHandlerResult = OC_EH_ERROR;
-    }
-
-    free(responsePayload);
-
-    return entityHandlerResult;
-}
diff --git a/service/notification-manager/NotificationManager/src/hosting.cpp b/service/notification-manager/NotificationManager/src/hosting.cpp
new file mode 100644 (file)
index 0000000..d222795
--- /dev/null
@@ -0,0 +1,68 @@
+//******************************************************************
+//
+// 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 "hosting.h"
+
+// Standard API
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include "octypes.h"
+#include "logger.h"
+#include "ResourceHosting.h"
+#include "HostingObject.h"
+
+OCStackResult OICStartCoordinate()
+{
+    using namespace OIC::Service;
+    OCStackResult retResult = OC_STACK_OK;
+    try
+    {
+        ResourceHosting::getInstance()->startHosting();
+    }catch(PlatformException &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[OICStartCoordinate] platformException, reason:%s", e.what());
+        retResult = OC_STACK_ERROR;
+        throw;
+    }catch(InvalidParameterException &e)
+    {
+        OIC_HOSTING_LOG(DEBUG,
+                "[OICStartCoordinate] InvalidParameterException, reason:%s", e.what());
+        retResult = OC_STACK_ERROR;
+        throw;
+    }catch(...)
+    {
+        OIC_HOSTING_LOG(DEBUG, "[OICStartCoordinate] Unknown Exception");
+        retResult = OC_STACK_ERROR;
+    }
+
+    return retResult;
+}
+
+OCStackResult OICStopCoordinate()
+{
+    OCStackResult retResult = OC_STACK_OK;
+    OIC::Service::ResourceHosting::getInstance()->stopHosting();
+
+    return retResult;
+}
diff --git a/service/notification-manager/NotificationManager/src/requestHandler.c b/service/notification-manager/NotificationManager/src/requestHandler.c
deleted file mode 100644 (file)
index 8508d9d..0000000
+++ /dev/null
@@ -1,208 +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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "virtualResource.h"
-
-RequestHandleList *createRequestHandleList()
-{
-    RequestHandleList *requestHandleList = (RequestHandleList*)malloc(sizeof(RequestHandleList));
-    if(!requestHandleList)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Request Handle List Creation Fail.");
-    }
-    else
-    {
-        requestHandleList->headerNode = NULL;
-        requestHandleList->tailNode = NULL;
-    }
-
-    return requestHandleList;
-}
-
-RequestHandle *createRequestHandle()
-{
-    RequestHandle *requestHandle = (RequestHandle*)malloc(sizeof(RequestHandle));
-    if(!requestHandle)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Request Handle Creation Fail.");
-    }
-    else
-    {
-        requestHandle->requestHandle[OIC_REQUEST_BY_CLIENT] = NULL;
-        requestHandle->requestHandle[OIC_REQUEST_BY_COORDINATOR] = NULL;
-        requestHandle->resourceHandle = NULL;
-
-        requestHandle->isAliveCheck = 0;
-
-        requestHandle->next = NULL;
-    }
-
-    return requestHandle;
-
-}
-OCStackResult insertRequestHandle(RequestHandleList *requestHandleList,
-        RequestHandle *requestHandle)
-{
-    if(requestHandleList == NULL || requestHandle == NULL)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    if(requestHandleList->headerNode == NULL)
-    {
-        requestHandleList->headerNode = requestHandle;
-        requestHandleList->tailNode = requestHandle;
-    }
-    else
-    {
-        requestHandleList->tailNode->next = requestHandle;
-        requestHandleList->tailNode = requestHandle;
-    }
-
-    return OC_STACK_OK;
-}
-
-OCStackResult deleteRequestHandleFromList(RequestHandleList *requestHandleList,
-        RequestHandle *requestHandle)
-{
-    if(requestHandleList == NULL || requestHandle == NULL)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Delete Request Handle : invalid parameter.");
-        return OC_STACK_INVALID_PARAM;
-    }
-    if(requestHandleList->headerNode == NULL)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Delete Request Handle : Empty Request Handle List.");
-        return OC_STACK_ERROR;
-    }
-
-    if(requestHandle == requestHandleList->headerNode)
-    {
-        requestHandleList->headerNode = requestHandleList->headerNode->next;
-        requestHandle->next = NULL;
-        return destroyRequestHandle(requestHandle);
-    }
-
-    RequestHandle *preNode = requestHandleList->headerNode;
-    RequestHandle *curNode = preNode->next;
-    while(curNode != NULL)
-    {
-        if(curNode == requestHandle)
-        {
-            if(curNode == requestHandleList->tailNode)
-            {
-                requestHandleList->tailNode = preNode;
-                preNode->next = NULL;
-            }
-            else
-            {
-                preNode->next = curNode->next;
-            }
-            requestHandle->next = NULL;
-            return destroyRequestHandle(requestHandle);
-        }
-        preNode = curNode;
-        curNode = curNode->next;
-    }
-
-    return OC_STACK_ERROR;
-}
-
-OCStackResult destroyRequestHandle(RequestHandle *requestHandle)
-{
-    if(requestHandle)
-    {
-        if(requestHandle->next)
-        {
-//            destroyRequestHandle(requestHandle->next);
-            requestHandle->next = NULL;
-        }
-
-        requestHandle->requestHandle[OIC_REQUEST_BY_CLIENT] = NULL;
-        requestHandle->requestHandle[OIC_REQUEST_BY_COORDINATOR] = NULL;
-
-        requestHandle->isAliveCheck = 0;
-
-        free(requestHandle);
-    }
-    else
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    return OC_STACK_OK;
-}
-
-OCStackResult destroyRequestHandleList(RequestHandleList *requestHandleList){
-    if(requestHandleList)
-    {
-        while(requestHandleList->headerNode)
-        {
-            deleteRequestHandleFromList(requestHandleList,requestHandleList->headerNode);
-        }
-        free(requestHandleList);
-    }
-    else{
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    return OC_STACK_OK;
-}
-
-RequestHandle *findRequestHandle(RequestHandleList *requestHandleList,
-        OCDoHandle handle, OICResourceCoordinatorParamType paramType)
-{
-    if(requestHandleList == NULL || handle == NULL)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Find Virtual Resource : invalid parameter.");
-        return NULL;
-    }
-    if(requestHandleList->headerNode == NULL)
-    {
-        OC_LOG(DEBUG, RH_TAG,"Find Virtual Resource : Empty Virtual Resource List.");
-        return NULL;
-    }
-
-    if(paramType == OIC_REQUEST_BY_CLIENT)
-    {
-        RequestHandle *tempRequestHandle = requestHandleList->headerNode;
-        while(tempRequestHandle != NULL)
-        {
-            if((OCEntityHandlerRequest*)tempRequestHandle->requestHandle[paramType] == handle)
-            {
-                return tempRequestHandle;
-            }
-            tempRequestHandle = tempRequestHandle->next;
-        }
-    }
-    else
-    {
-        RequestHandle *tempRequestHandle = requestHandleList->headerNode;
-        while(tempRequestHandle != NULL)
-        {
-            if((OCDoHandle)tempRequestHandle->requestHandle[paramType] == handle)
-            {
-                return tempRequestHandle;
-            }
-            tempRequestHandle = tempRequestHandle->next;
-        }
-    }
-    return NULL;
-}
diff --git a/service/notification-manager/NotificationManager/src/virtualResource.c b/service/notification-manager/NotificationManager/src/virtualResource.c
deleted file mode 100644 (file)
index 9dae0b2..0000000
+++ /dev/null
@@ -1,406 +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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "virtualResource.h"
-
-
-MirrorResourceList *createMirrorResourceList()
-{
-    MirrorResourceList *mirrorResourceList = (MirrorResourceList *)malloc(sizeof(MirrorResourceList));
-    if (!mirrorResourceList)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Virtual Resource List Creation Fail.");
-    }
-    else
-    {
-        mirrorResourceList->headerNode = NULL;
-        mirrorResourceList->tailNode = NULL;
-    }
-
-    return mirrorResourceList;
-}
-
-MirrorResource *createMirrorResource()
-{
-    MirrorResource *mirrorResource = (MirrorResource*)malloc(sizeof(MirrorResource));
-    if (!mirrorResource)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Virtual Resource List Creation Fail.");
-    }
-    else
-    {
-        mirrorResource->resourceHandle[OIC_REQUEST_HANDLE] = NULL;
-        mirrorResource->resourceHandle[OIC_MIRROR_HANDLE] = NULL;
-        mirrorResource->address[OIC_SOURCE_ADDRESS]    = NULL;
-        mirrorResource->address[OIC_MIRROR_ADDRESS]   = NULL;
-
-        mirrorResource->rep    = NULL;
-        mirrorResource->uri    = NULL;
-        mirrorResource->next   = NULL;
-
-        mirrorResource->prop.countResourceType = 0;
-        mirrorResource->prop.resourceType = NULL;
-        mirrorResource->prop.countInterface = 0;
-        mirrorResource->prop.resourceInterfaceName = NULL;
-    }
-
-    return mirrorResource;
-}
-
-OCStackResult destroyMirrorResourceList(MirrorResourceList *mirrorResourceList)
-{
-    OC_LOG_V(DEBUG, VR_TAG,"enter destroyVirtualResourceList");
-    if(mirrorResourceList)
-    {
-        while (mirrorResourceList->headerNode)
-        {
-            deleteMirrorResourceFromList(mirrorResourceList, mirrorResourceList->headerNode);
-        }
-
-        free(mirrorResourceList);
-    }
-    else
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    return OC_STACK_OK;
-}
-
-OCStackResult destroyMirrorResource(MirrorResource *mirrorResource)
-{
-    OC_LOG_V(DEBUG, VR_TAG,"enter destroy virtual resource.");
-    if(mirrorResource)
-    {
-        if(mirrorResource->next)
-        {
-            mirrorResource->next = NULL;
-        }
-        if (mirrorResource->rep)
-        {
-            cJSON_Delete(mirrorResource->rep);
-        }
-        if (mirrorResource->uri)
-        {
-            free(mirrorResource->uri);
-        }
-        if (mirrorResource->address[OIC_SOURCE_ADDRESS])
-        {
-            free(mirrorResource->address[OIC_SOURCE_ADDRESS]);
-        }
-        if (mirrorResource->address[OIC_MIRROR_ADDRESS])
-        {
-            free(mirrorResource->address[OIC_MIRROR_ADDRESS]);
-        }
-        if (mirrorResource->prop.resourceType)
-        {
-            int i = 0;
-            for (i = 0; i < mirrorResource->prop.countResourceType; ++i)
-            {
-                free(mirrorResource->prop.resourceType[i]);
-                mirrorResource->prop.resourceType[i] = NULL;
-            }
-            free(mirrorResource->prop.resourceType);
-            mirrorResource->prop.countResourceType = 0;
-        }
-        if (mirrorResource->prop.resourceInterfaceName)
-        {
-            int i = 0;
-            for (i = 0; i < mirrorResource->prop.countInterface; ++i)
-            {
-                free(mirrorResource->prop.resourceInterfaceName[i]);
-                mirrorResource->prop.resourceInterfaceName[i] = NULL;
-            }
-            free(mirrorResource->prop.resourceInterfaceName);
-            mirrorResource->prop.countInterface = 0;
-        }
-        free(mirrorResource);
-    }
-    else
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    return OC_STACK_OK;
-}
-
-OCStackResult insertMirrorResource(MirrorResourceList *mirrorResourceList,
-                                   MirrorResource *mirrorResource)
-{
-    if (mirrorResourceList == NULL || mirrorResource == NULL)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        mirrorResourceList->headerNode = mirrorResource;
-        mirrorResourceList->tailNode = mirrorResource;
-    }
-    else
-    {
-        mirrorResourceList->tailNode->next = mirrorResource;
-        mirrorResourceList->tailNode = mirrorResource;
-    }
-
-    return OC_STACK_OK;
-}
-
-MirrorResource *findMirrorResourceUsingAddressAndURI(MirrorResourceList *mirrorResourceList,
-        const char *address, OICResourceCoordinatorParamType paramType, const char *uri)
-{
-    if (mirrorResourceList == NULL || address == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource : invalid parameter.");
-        return NULL;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource : Empty Virtual Resource List.");
-        return NULL;
-    }
-
-    MirrorResource *tempMirrorResource = mirrorResourceList->headerNode;
-    while (tempMirrorResource != NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"node's uri = %s", tempMirrorResource->uri);
-        if (strcmp(tempMirrorResource->address[paramType], address) == 0) // if(It is Same)
-        {
-            if (strcmp(tempMirrorResource->uri, uri) == 0) // if(It is Same)
-            {
-                return tempMirrorResource;
-            }
-        }
-        tempMirrorResource = tempMirrorResource->next;
-    }
-
-    return NULL;
-}
-
-MirrorResource *findMirrorResourceUsingHandle(MirrorResourceList *mirrorResourceList,
-        OCResourceHandle handle, OICResourceCoordinatorParamType paramType)
-{
-    if (mirrorResourceList == NULL || handle == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource : invalid parameter.");
-        return NULL;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource : Empty Virtual Resource List.");
-        return NULL;
-    }
-
-    MirrorResource *tempMirrorResource = mirrorResourceList->headerNode;
-    while (tempMirrorResource != NULL)
-    {
-        if (tempMirrorResource->resourceHandle[paramType] == handle)
-        {
-            return tempMirrorResource;
-        }
-        tempMirrorResource = tempMirrorResource->next;
-    }
-
-    return NULL;
-}
-
-OCStackResult deleteMirrorResourceFromList(MirrorResourceList *mirrorResourceList,
-        MirrorResource *mirrorResource)
-{
-
-    OC_LOG_V(DEBUG, VR_TAG,"enter delete virtual resource.");
-
-    if (mirrorResourceList == NULL || mirrorResource == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Delete Virtual Resource : invalid parameter.");
-        return OC_STACK_INVALID_PARAM;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Delete Virtual Resource : Empty Virtual Resource List.");
-        return OC_STACK_ERROR;
-    }
-
-    if (mirrorResource == mirrorResourceList->headerNode)
-    {
-        mirrorResourceList->headerNode = mirrorResourceList->headerNode->next;
-        mirrorResource->next = NULL;
-        return destroyMirrorResource(mirrorResource);
-    }
-
-    MirrorResource *preNode = mirrorResourceList->headerNode;
-    MirrorResource *curNode = preNode->next;
-    while (curNode != NULL)
-    {
-        if (curNode == mirrorResource)
-        {
-            if (curNode == mirrorResourceList->tailNode)
-            {
-                mirrorResourceList->tailNode = preNode;
-                preNode->next = NULL;
-            }
-            else
-            {
-                preNode->next = curNode->next;
-            }
-            mirrorResource->next = NULL;
-            return destroyMirrorResource(mirrorResource);
-        }
-        preNode = curNode;
-        curNode = curNode->next;
-    }
-
-    return OC_STACK_ERROR;
-}
-
-OCStackResult ejectMirrorResource(MirrorResourceList *mirrorResourceList,
-                                  MirrorResource *mirrorResource)
-{
-    if (mirrorResourceList == NULL || mirrorResource == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Eject Virtual Resource : invalid parameter.");
-        return OC_STACK_INVALID_PARAM;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG, "Eject Virtual Resource : Empty Virtual Resource List.");
-        return OC_STACK_ERROR;
-    }
-
-    if (mirrorResource == mirrorResourceList->headerNode)
-    {
-        mirrorResourceList->headerNode = mirrorResourceList->headerNode->next;
-        return OC_STACK_OK;
-    }
-
-    MirrorResource *preNode = mirrorResourceList->headerNode;
-    MirrorResource *curNode = preNode->next;
-    while (curNode != NULL)
-    {
-        if (curNode == mirrorResource)
-        {
-            if(curNode == mirrorResourceList->headerNode)
-            {
-                mirrorResourceList->headerNode = NULL;
-                mirrorResourceList->tailNode = NULL;
-            }
-            else if(curNode == mirrorResourceList->tailNode)
-            {
-                mirrorResourceList->tailNode = preNode;
-            }
-            else
-            {
-            preNode->next = curNode->next;
-            }
-            return OC_STACK_OK;
-        }
-        preNode = curNode;
-        curNode = curNode->next;
-    }
-
-    return OC_STACK_ERROR;
-
-}
-
-MirrorResource *cloneMirrorResource(MirrorResource *sourceMirrorResource)
-{
-    MirrorResource *clonedMirrorResource = createMirrorResource();
-
-    int sizeofstr = 0;
-    int i = 0;
-
-    clonedMirrorResource->rep = cJSON_Parse(cJSON_PrintUnformatted(sourceMirrorResource->rep));
-
-    sizeofstr = strlen(sourceMirrorResource->uri) + 1;
-    clonedMirrorResource->uri = (char *)malloc(sizeof(char) * sizeofstr);
-    memset(clonedMirrorResource->uri, '\0', sizeofstr);
-    strcpy(clonedMirrorResource->uri, sourceMirrorResource->uri);
-
-    for (i = OIC_SOURCE_ADDRESS; i < OIC_MIRROR_ADDRESS; ++i)
-    {
-        sizeofstr = strlen(sourceMirrorResource->address[i]) + 1;
-        clonedMirrorResource->address[i] = (char *)malloc(sizeof(char) * sizeofstr);
-        memset(clonedMirrorResource->address[i], '\0', sizeofstr);
-        strcpy(clonedMirrorResource->address[i], sourceMirrorResource->address[i]);
-    }
-
-    return clonedMirrorResource;
-}
-
-MirrorResourceList *findMirrorResourceListUsingAddress(MirrorResourceList *mirrorResourceList,
-        const char *address, OICResourceCoordinatorParamType paramType)
-{
-    if (mirrorResourceList == NULL || address == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource List : invalid parameter.");
-        return NULL;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG,"Find Virtual Resource List : Empty Virtual Resource List.");
-        return NULL;
-    }
-
-    MirrorResource *tempNode = mirrorResourceList->headerNode;
-    while (tempNode != NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG, "uri = %s", tempNode->uri);
-        tempNode = tempNode->next;
-    }
-
-
-    MirrorResourceList *resultMirrorResourceList = createMirrorResourceList();
-    MirrorResource *mirrorResource = mirrorResourceList->headerNode;
-    while (mirrorResource != NULL)
-    {
-        if (strcmp(mirrorResource->address[paramType], address) == 0) // if(It is Same)
-        {
-            insertMirrorResource(resultMirrorResourceList, cloneMirrorResource(mirrorResource));
-        }
-        mirrorResource = mirrorResource->next;
-    }
-
-    return resultMirrorResourceList;
-}
-
-
-OCStackResult printMirrorResourceList(MirrorResourceList *mirrorResourceList)
-{
-    if (mirrorResourceList == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG, "print Virtual Resource list : invalid parameter.");
-        return OC_STACK_INVALID_PARAM;
-    }
-    if (mirrorResourceList->headerNode == NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG, "print Virtual Resource list : Empty Virtual Resource List.");
-        return OC_STACK_INVALID_PARAM;
-    }
-    OC_LOG_V(DEBUG, VR_TAG, "==============================================================");
-    MirrorResource *mirrorResource = mirrorResourceList->headerNode;
-    while (mirrorResource != NULL)
-    {
-        OC_LOG_V(DEBUG, VR_TAG, "uri = %s", mirrorResource->uri);
-        mirrorResource = mirrorResource->next;
-    }
-    OC_LOG_V(DEBUG, VR_TAG, "==============================================================");
-
-    return OC_STACK_OK;
-}
diff --git a/service/notification-manager/NotificationManager/src/virtualResource.h b/service/notification-manager/NotificationManager/src/virtualResource.h
deleted file mode 100644 (file)
index 44885ab..0000000
+++ /dev/null
@@ -1,302 +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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#ifndef _VIRTUAL_RESOURCE_H_
-#define _VIRTUAL_RESOURCE_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "ocstack.h"
-#include "logger.h"
-
-#include "cJSON.h"
-#define TAG  PCF("MirrorResource")
-//-----------------------------------------------------------------------------
-// Definition of Constant
-//-----------------------------------------------------------------------------
-#define VR_TAG "__NM__"
-#define RH_TAG "__RM__"
-
-//-----------------------------------------------------------------------------
-// Typedefs
-//-----------------------------------------------------------------------------
-
-/**
-* Resource Coordinating Parameter Type
-*/
-typedef enum
-{
-    /*
-     * for mirrorResourceHandle
-     */
-    OIC_SOURCE_ADDRESS  = 0,
-    OIC_MIRROR_ADDRESS  = 1,
-    OIC_REQUEST_HANDLE  = 0,
-    OIC_MIRROR_HANDLE       = 1,
-
-    /*
-     * for requestHandle
-     */
-    OIC_REQUEST_BY_CLIENT       = 0,
-    OIC_REQUEST_BY_COORDINATOR  = 1,
-
-    OIC_NONE                        = 255
-} OICResourceCoordinatorParamType;
-
-/**
-* Property of Mirror Resource
-*/
-typedef struct MirrorResourceProperty
-{
-    int countResourceType;
-    int countInterface;
-    char **resourceType;
-    char **resourceInterfaceName;
-} MirrorResourceProperty;
-
-/**
-* Mirror Resource Object
-*/
-typedef struct MirrorResource
-{
-    OCDoHandle resourceHandle[2];   // OIC_REQUEST_HANDLE = 0, OIC_VIRTUAL_HANDLE = 1
-    char *address[2];               // OIC_SOURCE_ADDRESS = 0, OIC_VIRTUAL_ADDRESS = 1
-    cJSON *rep;
-    char *uri;
-    MirrorResourceProperty prop;
-
-    struct MirrorResource *next;
-
-    /*
-     * for multiple resource
-     */
-//  virtualRepresentation rep2;
-
-} MirrorResource;
-
-/**
-* Mirror Resource List
-*/
-typedef struct MirrorResourceList
-{
-    struct MirrorResource *headerNode;
-    struct MirrorResource *tailNode;
-} MirrorResourceList;
-
-/**
-* Request Object
-*/
-typedef struct RequestHandle
-{
-    void *requestHandle[2];         // OIC_REQUEST_BY_CLIENT = 0, OIC_REQUEST_BY_COORDINATOR = 1
-    OCResourceHandle resourceHandle;
-    OCRequestHandle entityRequestHandle;
-
-    OCMethod method;
-
-    unsigned char isAliveCheck;
-
-    struct RequestHandle *next;
-} RequestHandle;
-
-/**
-* Request Object List
-*/
-typedef struct RequestHandleList
-{
-    struct RequestHandle *headerNode;
-    struct RequestHandle *tailNode;
-} RequestHandleList;
-
-//-----------------------------------------------------------------------------
-// Function prototypes for mirrorResourceHandle
-//-----------------------------------------------------------------------------
-
-/**
-* Create an empty mirror resource list
-*
-* @return
-*     pointer to empty Mirror resource list
-*/
-MirrorResourceList *createMirrorResourceList();
-
-/**
-* Create an empty mirror resource.
-*
-* @return
-*     pointer to empty mirror resource
-*/
-MirrorResource *createMirrorResource();
-
-/**
-* Insert the mirror resource in the mirror resource list
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be inserted
-* @param mirrorResource - pointer to mirror resource list to be inserted
-* @return
-*     OIC_HOSTING_INVALID_PARAM - if list or vResource is null
-*     OIC_HOSTING_OK - successfully inserted
-*/
-OCStackResult insertMirrorResource(MirrorResourceList *mirrorResourceList,
-                                   MirrorResource *mirrorResource);
-
-/**
-* Delete the mirror resource from the mirror resource list
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be deleted
-* @param mirrorResource - pointer to mirror resource list to be deleted
-* @return
-*     OIC_HOSTING_INVALID_PARAM - if mirrorResourceList or mirrorResource is null
-*     OIC_HOSTING_ERROR - mirror resource delete process error
-*     OIC_HOSTING_OK - successfully deleted
-*/
-OCStackResult deleteMirrorResourceFromList(MirrorResourceList *mirrorResourceList,
-        MirrorResource *mirrorResource);
-
-/**
-* Destroy mirror resource
-*
-* @param mirrorResource - pointer to mirror resource to be destroyed
-* @return
-*     OIC_HOSTING_INVALID_PARAM - if mirrorResource is null
-*     OIC_HOSTING_OK - successfully destroyed
-*/
-OCStackResult destroyMirrorResource(MirrorResource *mirrorResource);
-
-/**
-* Destroy mirror resource list
-*
-* @param mirrorResourceList - pointer to mirror resource list to be destroyed
-* @return
-*     OIC_HOSTING_INVALID_PARAM - if mirrorResourceList is null
-*     OIC_HOSTING_OK - successfully destroyed
-*/
-OCStackResult destroyMirrorResourceList(MirrorResourceList *mirrorResourceList);
-
-/**
-* Find mirror resource using handle
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be found
-* @param handle - handle value to be found
-* @param paramType - handle type to be found
-*
-* NOTE: every parameter(handle and type) will be compared
-*
-* @return
-*     pointer to the found mirror resource
-*     NULL - mirror resource not found
-*/
-MirrorResource *findMirrorResourceUsingHandle(MirrorResourceList *mirrorResourceList,
-        OCResourceHandle handle, OICResourceCoordinatorParamType paramType);
-
-/*
- * find virtual resource using address function 사용하는지 확인 필요.
- */
-//virtualResource *findvResourceUsingAddress(virtualResourceList *list,
-//        const char *Address, OICResourceHostingParamType type, const char *subData);
-
-/**
-* Find mirror resource using Address and URI
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be found
-* @param address - pointer to address to be found
-* @param paramType - address type to be found
-* @param uri - pointer to uri to be found
-*
-* NOTE: every parameter(address, type and uri) will be compared
-*
-* @return
-*     pointer to the found mirror resource
-*     NULL - invalid input parameter or mirror resource not found
-*/
-MirrorResource *findMirrorResourceUsingAddressAndURI(MirrorResourceList *mirrorResourceList,
-        const char *address, OICResourceCoordinatorParamType paramType, const char *uri);
-
-/**
-* Find mirror resource list using Address and Hosting Parameter Type
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be found
-* @param address - pointer to address to be found
-* @param paramType - address type to be found
-*
-* NOTE: every parameter(address, type and uri) will be compared
-*
-* @return
-*     pointer to the found mirror resource
-*     NULL - invalid input parameter or mirror resource list not found
-*/
-MirrorResourceList *findMirrorResourceListUsingAddress(MirrorResourceList *mirrorResourceList,
-        const char *address, OICResourceCoordinatorParamType paramType);
-
-/**
-* Copy mirror resource
-*
-* @param sourceMirrorResource - pointer to source mirror resource
-*
-* @return
-*     pointer to the copied mirror resource
-*/
-MirrorResource *cloneMirrorResource(MirrorResource *sourceMirrorResource);
-
-/**
-* Eject mirror resource from mirror resource list
-*
-* @param mirrorResourceList - pointer to the target mirror resource list that mirror resource will be found
-* @param mirrorResource - pointer to mirror resource to be ejected
-*
-* @return
-*     OIC_HOSTING_INVALID_PARAM - mirrorResourceList or mirrorResource is null
-*     OIC_HOSTING_OK - ejected successfully
-*     OIC_HOSTING_ERROR - cannot found mirror resource from mirrorResourceList same with mirrorResource
-*/
-OCStackResult ejectMirrorResource(MirrorResourceList *mirrorResourceList,
-                                  MirrorResource *mirrorResource);
-
-/**
-* Print mirror resources from mirror resource list
-*
-* @param mirrorResourceList - pointer to the mirror resource list that mirror resource will be printed
-*
-* @return
-*     OIC_HOSTING_INVALID_PARAM - mirrorResourceList is null or mirrorResourceList is empty
-*     OIC_HOSTING_OK - print successfully
-*/
-OCStackResult printMirrorResourceList(MirrorResourceList *mirrorResourceList);
-
-//-----------------------------------------------------------------------------
-// Function prototypes for RequestHandle
-//-----------------------------------------------------------------------------
-RequestHandleList *createRequestHandleList();
-RequestHandle *createRequestHandle();
-OCStackResult insertRequestHandle(RequestHandleList *requestHandleList,
-                                  RequestHandle *requestHandle);
-
-OCStackResult deleteRequestHandleFromList(RequestHandleList *requestHandleList,
-        RequestHandle *requestHandle);
-OCStackResult destroyRequestHandle(RequestHandle *requestHandle);
-
-OCStackResult destroyRequestHandleList(RequestHandleList *requestHandleList);
-
-RequestHandle *findRequestHandle(RequestHandleList *requestHandleList,
-                                 OCDoHandle handle, OICResourceCoordinatorParamType paramType);
-
-#endif //_MIRROR_RESOURCE_H_
index 39c4eb5..1269326 100644 (file)
@@ -31,7 +31,7 @@ else:
        env.AppendUnique(CCFLAGS = ['-g'])
 
 if env.get('LOGGING'):
-       env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 lib_env = env.Clone()
 SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
@@ -42,9 +42,25 @@ target_os = env.get('TARGET_OS')
 # Build flags
 ######################################################################
 notimgr_env.AppendUnique(CPPPATH = ['NotificationManager/include'])
-notimgr_env.AppendUnique(CPPPATH = ['../../extlibs/cjson'])
-notimgr_env.AppendUnique(CPPPATH = ['../../resource/csdk/logger/include'])
-notimgr_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/common/primitiveResource/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/serverBuilder/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/resourceBroker/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/resourceCache/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/common/expiryTimer/include'])
+notimgr_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/common/expiryTimer/src'])
+#notimgr_env.AppendUnique(CPPPATH = ['../../extlibs/cjson'])
+#notimgr_env.AppendUnique(CPPPATH = ['../../resource/csdk/logger/include'])
+notimgr_env.PrependUnique(LIBS = [
+       'rcs_client',
+       'rcs_server',
+       'rcs_common',
+       'oc',
+       'octbstack',
+       'oc_logger',
+       'connectivity_abstraction',
+       'libcoap'
+       ])
 
 if target_os not in ['windows', 'winrt']:
        notimgr_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
@@ -64,12 +80,11 @@ if target_os == 'android':
 ######################################################################
 NOTI_SRC_DIR = 'NotificationManager/src/'
 notimgr_src = [
-        NOTI_SRC_DIR + 'hosting.c',
-        NOTI_SRC_DIR + 'requestHandler.c',
-        NOTI_SRC_DIR + 'virtualResource.c']
-
-if target_os == 'android':
-        notimgr_src.append(NOTI_SRC_DIR + 'resourceCoordinator_JNI.cpp')
+        NOTI_SRC_DIR + 'hosting.cpp',
+        NOTI_SRC_DIR + 'ResourceHosting.cpp',
+        NOTI_SRC_DIR + 'HostingObject.cpp',
+        NOTI_SRC_DIR + 'RequestObject.cpp'
+        ]
 
 if target_os in ['tizen','android'] :
     notificationsdk = notimgr_env.SharedLibrary('NotificationManager', notimgr_src)
@@ -80,4 +95,3 @@ notimgr_env.InstallTarget(notificationsdk, 'libResouceHosting')
 
 # Go to build sample apps
 SConscript('SampleApp/SConscript')
-
diff --git a/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/ic_launcher-web.png b/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/ic_launcher-web.png
deleted file mode 100644 (file)
index a18cbb4..0000000
Binary files a/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/ic_launcher-web.png and /dev/null differ
diff --git a/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/Android.mk b/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/Android.mk
deleted file mode 100644 (file)
index f2f39d8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ca
-LOCAL_SRC_FILES := ../libs/libconnectivity_abstraction.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := oc_logger_core
-LOCAL_SRC_FILES := ../libs/liboc_logger_core.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := oc_logger
-LOCAL_SRC_FILES := ../libs/liboc_logger.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := octbstack
-LOCAL_SRC_FILES := ../libs/liboctbstack.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := oc
-LOCAL_SRC_FILES := ../libs/liboc.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libNotificationManager
-LOCAL_SRC_FILES := ../libs/libNotificationManager.so
-include $(PREBUILT_SHARED_LIBRARY)
diff --git a/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/armeabi b/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/armeabi
deleted file mode 100644 (file)
index a2f1b66..0000000
Binary files a/service/notification-manager/SampleApp/android/ResourceHostingSampleApp/jni/armeabi and /dev/null differ
index b24ab35..4005515 100644 (file)
@@ -56,7 +56,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
     OcPlatform.OnResourceFoundListener, OnGetListener, OnDeleteListener,
     OnObserveListener, OnPutListener
 {
-        private final String TAG = "sample_consumer";
+        private final String TAG = "NMConsumer : " + this.getClass().getSimpleName();
 
         public static final int OC_STACK_OK = 0;
         public static final String OBSERVE = "Observe";
@@ -169,6 +169,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
             OcPlatform.Configure(cfg);
             current_log_result += "Created Platform...\n";
             tv_current_log_result.setText(current_log_result);
+            Log.i(TAG, current_log_result);
             findResourceCandidate();
             PRINT();
         }
@@ -178,6 +179,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
             nmfindResource("", "/oc/core?rt=Resource.Hosting");
             current_log_result += "Finding Resource... \n";
             tv_current_log_result.setText(current_log_result);
+            Log.i(TAG, current_log_result);
         }
 
         public void nmfindResource(String host, String resourceName)
@@ -192,6 +194,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                 e.printStackTrace();
                 current_log_result += e.getMessage() + "\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
             }
         }
 
@@ -204,6 +207,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
             {
                 current_log_result += "Getting Light Representation...\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
             }
         }
 
@@ -216,6 +220,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
             {
                 current_log_result += "Getting Light Representation...\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
 
                 try
                 {
@@ -227,6 +232,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     e.printStackTrace();
                     current_log_result += e.getMessage() + "\n";
                     tv_current_log_result.setText(current_log_result);
+                    Log.i(TAG, current_log_result);
                 }
             }
         }
@@ -248,6 +254,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                 Map<String, String> queryParamsMap = new HashMap<String, String>();
                 current_log_result += "startObserve\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
 
                 try
                 {
@@ -258,6 +265,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     e.printStackTrace();
                     current_log_result += e.getMessage() + "\n";
                     tv_current_log_result.setText(current_log_result);
+                    Log.i(TAG, current_log_result);
                 }
             }
         }
@@ -269,6 +277,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                 Map<String, String> queryParamsMap = new HashMap<String, String>();
                 current_log_result += "startGet\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
 
                 try
                 {
@@ -279,6 +288,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     e.printStackTrace();
                     current_log_result += e.getMessage() + "\n";
                     tv_current_log_result.setText(current_log_result);
+                    Log.i(TAG, current_log_result);
                 }
             }
         }
@@ -294,6 +304,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                 Map<String, String> queryParamsMap = new HashMap<String, String>();
                 current_log_result += "startPut\n";
                 tv_current_log_result.setText(current_log_result);
+                Log.i(TAG, current_log_result);
 
                 try
                 {
@@ -304,6 +315,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     e.printStackTrace();
                     current_log_result += e.getMessage() + "\n";
                     tv_current_log_result.setText(current_log_result);
+                    Log.i(TAG, current_log_result);
                 }
             }
         }
@@ -324,16 +336,19 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
             {
                 case R.id.btn_observe:
                     tv_select_method_type.setText(OBSERVE);
+                    Log.i(TAG, "Method: " + OBSERVE);
                     startObserve(curResource);
                     btn_observe.setClickable(false);
                     break;
                 case R.id.btn_get:
                     tv_select_method_type.setText(GET);
+                    Log.i(TAG, "Method: " + GET);
                     startGet(curResource);
                     btn_get.setClickable(false);
                     break;
                 case R.id.btn_put:
                     tv_select_method_type.setText(PUT);
+                    Log.i(TAG, "Method: " + PUT);
                     startPut(curResource);
                     btn_put.setClickable(false);
                     break;
@@ -341,9 +356,11 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     tv_select_method_type.setText(POST);
                     Toast.makeText(this, "Not Supported Yet", Toast.LENGTH_SHORT)
                     .show();
+                    Log.i(TAG, "Method: " + POST);
                     break;
                 case R.id.btn_delete:
                     tv_select_method_type.setText(DELETE);
+                    Log.i(TAG, "Method: " + DELETE);
                 try {
                     startDelete(curResource);
                 } catch (OcException e) {
@@ -354,6 +371,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     break;
                 case R.id.btn_clean:
                     cleanLogString();
+                    Log.i(TAG, "Log textbox is cleared");
                     break;
 
                 default:
@@ -376,14 +394,17 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     if (receive_result != null)
                     {
                         tv_receive_result.setText(receive_result);
+                        Log.i(TAG, "Received: " + receive_result);
                     }
                     if (found_uri != null)
                     {
                         tv_found_uri.setText(found_uri);
+                        Log.i(TAG, "URI: " + found_uri);
                     }
                     if (current_log_result != null)
                     {
                         tv_current_log_result.setText(current_log_result);
+                        Log.i(TAG, current_log_result);
                     }
 
                 }
@@ -475,6 +496,7 @@ public class SampleConsumer extends Activity implements View.OnClickListener,
                     final String message = intent
                                            .getStringExtra(MESSAGE);
                     tv_current_log_result.setText(message);
+                    Log.i(TAG, message);
                     viewText();
                 }
         }
index 26bd9b5..48c45da 100644 (file)
@@ -32,6 +32,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Message;
 import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
@@ -46,7 +47,7 @@ import android.widget.TextView;
 public class SampleProvider extends Activity implements OnClickListener,
     IMessageLogger
 {
-        private final static String TAG = "SampleProvider : ";
+        private final static String TAG = "NMProvider : SampleProvider";
         private TextView mLogTextView;
         private TextView mTempValue;
         private TextView mHumValue;
@@ -54,6 +55,12 @@ public class SampleProvider extends Activity implements OnClickListener,
         private boolean isExecutePresence;
         private ScrollView sv_sclLog;
         private MessageReceiver mMessageReceiver = new MessageReceiver();
+        private Handler mHandler;
+        private static String message;
+        private static SampleProvider  sampleProviderObj;
+        private String temp;
+        private String hum;
+
         /*
          * To initialize UI Function Setting
          * To execute initOICStack for running find resource
@@ -62,6 +69,7 @@ public class SampleProvider extends Activity implements OnClickListener,
         public void onCreate(Bundle savedInstanceState)
         {
 
+            sampleProviderObj = this;
             super.onCreate(savedInstanceState);
             setContentView(R.layout.sampleprovider_layout);
             registerReceiver(mMessageReceiver, new IntentFilter(
@@ -80,6 +88,18 @@ public class SampleProvider extends Activity implements OnClickListener,
             findViewById(R.id.btnLogClear).setOnClickListener(this);
 
             isExecutePresence = false;
+            mHandler = new Handler() {
+                @Override
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case 0:
+                            String[] tempHum = message.split(":");
+                            mTempValue.setText(tempHum[0]);
+                            mHumValue.setText(tempHum[1]);
+                    }
+                }
+            };
+            setmHandler(mHandler);
         }
 
         private void initOICStack()
@@ -233,6 +253,7 @@ public class SampleProvider extends Activity implements OnClickListener,
                     break;
                 case R.id.btnLogClear:
                     mLogTextView.setText("");
+                    Log.i(TAG, "Log message cleared");
                     break;
             }
 
@@ -268,4 +289,20 @@ public class SampleProvider extends Activity implements OnClickListener,
             }
             return super.onKeyDown(keyCode, event);
         }
+
+        public Handler getmHandler() {
+            return mHandler;
+        }
+
+        public void setmHandler(Handler mHandler) {
+            this.mHandler = mHandler;
+        }
+
+        public static SampleProvider getSampleProviderObject() {
+            return sampleProviderObj;
+        }
+
+        public static void setmessage(String msg) {
+            message = msg;
+        }
 }
\ No newline at end of file
index 98f6f47..e72c54b 100644 (file)
@@ -18,6 +18,7 @@ import org.iotivity.base.ResourceProperty;
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.Message;
 import android.util.Log;
 
 public class TemperatureResource implements IMessageLogger
@@ -29,7 +30,7 @@ public class TemperatureResource implements IMessageLogger
         private OcResourceHandle mResourceHandle;
         private List<Byte> mObservationIds;
 
-        private static String TAG = "SampleProvider : ";
+        private static String TAG = "NMProvider : TemperatureResource";
 
         TemperatureResource(Context context)
         {
@@ -114,7 +115,7 @@ public class TemperatureResource implements IMessageLogger
             {
                 Log.e(TAG, "go exception");
                 logMessage(TAG + "RegisterResource error. " + e.getMessage());
-                Log.e(TAG, e.getMessage());
+                Log.e(TAG, "RegisterResource error. " + e.getMessage());
             }
 
             // logMessage(TAG + "Successfully registered resource");
@@ -125,8 +126,16 @@ public class TemperatureResource implements IMessageLogger
         {
             mtemp = rep.getValueInt(StringConstants.TEMPERATURE);
             mhumidity = rep.getValueInt(StringConstants.HUMIDITY);
-            logMessage(TAG + "temperature : " + mtemp + "humidity : " + mhumidity);
+            logMessage(TAG + "PUT Request" +"temperature : " + mtemp + "humidity : " + mhumidity);
+             notifyObserver();
             // " Power: " + mPower);
+             String message = mtemp+":"+mhumidity; 
+             Message msg = Message.obtain();
+             msg.what = 0;
+             SampleProvider mainActivityObj = SampleProvider.getSampleProviderObject();
+             SampleProvider.setmessage(message);
+             mainActivityObj.getmHandler().sendMessage(msg);
+
         }
 
         protected OcRepresentation get()
@@ -156,7 +165,7 @@ public class TemperatureResource implements IMessageLogger
                 {
                     try
                     {
-                        logMessage(TAG + "Request");
+                        logMessage(TAG + requestType + "Request");
                         OcResourceResponse ocResourceResponse = new OcResourceResponse();
                         ocResourceResponse.setRequestHandle(request
                                                             .getRequestHandle());
@@ -234,6 +243,7 @@ public class TemperatureResource implements IMessageLogger
         public void logMessage(String msg)
         {
             logMsg(msg);
+            Log.i(TAG, msg);
         }
 
         public void logMsg(final String text)
@@ -29,7 +29,7 @@
         android:label="@string/app_name"
         android:theme="@style/AppTheme" >
         <activity
-            android:name="com.example.resourcehostingsampleapp.ResourceHosting"
+            android:name="com.example.resourcehostingsampleapp.ResourceHostingSampleApp"
             android:label="@string/app_name" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 package com.example.resourcehostingsampleapp;
 
+import java.lang.reflect.Method;
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.Enumeration;
 
+import org.iotivity.ResourceHosting.ResourceHosting;
 import org.iotivity.base.ModeType;
 import org.iotivity.base.OcPlatform;
 import org.iotivity.base.OcResourceHandle;
@@ -47,7 +49,7 @@ import android.widget.Toast;
  *
  */
 
-public class ResourceHosting extends Activity implements OnClickListener
+public class ResourceHostingSampleApp extends Activity implements OnClickListener
 {
         private final int OCSTACK_OK = 0;
         private final int OCSTACK_ERROR = 255;
@@ -58,6 +60,7 @@ public class ResourceHosting extends Activity implements OnClickListener
         private String  mIpAddress;
         private TextView mLogTextView;
         private String mLog = "";
+        private ResourceHosting resourceHosting;
         /**
          * To initialize UI Function Setting.
          * @see Class   class : com_example_resourcehostingsampleapp_ResourceHosting</br>
@@ -73,7 +76,7 @@ public class ResourceHosting extends Activity implements OnClickListener
             findViewById(R.id.btLogClear).setOnClickListener(this);
 
             PlatformConfig platformConfigObj;
-
+            resourceHosting = new ResourceHosting();
             platformConfigObj = new PlatformConfig(this,ServiceType.IN_PROC,
                     ModeType.CLIENT_SERVER, "0.0.0.0", 0, QualityOfService.LOW);
 
@@ -104,7 +107,7 @@ public class ResourceHosting extends Activity implements OnClickListener
         {
             super.onStop();
             int result;
-            result = ResourceHostingTerminate();
+            result = resourceHosting.ResourceHostingTerminate();
             Log.d(TAG, "ResourceHostingTerminate : "+ result);
         }
 
@@ -144,8 +147,8 @@ public class ResourceHosting extends Activity implements OnClickListener
             try
             {
                 mIpAddress = getIpAddress();
-                int result;
-                result = ResourceHostingInit(mIpAddress);
+                int result = 0;
+                result = resourceHosting.ResourceHostingInit(mIpAddress);
                 Log.d(TAG, "ResourceHostingInit : " + result);
             }
             catch (Exception e)
@@ -199,7 +202,7 @@ public class ResourceHosting extends Activity implements OnClickListener
                     try
                     {
                         int result;
-                        result = OICCoordinatorStart();
+                        result = resourceHosting.OICCoordinatorStart();
                         Log.d(TAG, "OICCoordinatorStart : " + result);
                     }
                     catch (Exception e)
@@ -209,81 +212,13 @@ public class ResourceHosting extends Activity implements OnClickListener
                     break;
                 case R.id.btnStopHosting:
                     int result;
-                    result = OICCoordinatorStop();
+                    result = resourceHosting.OICCoordinatorStop();
                     Log.d(TAG, "OICCoordinatorStop : "+ result);
                     break;
                 case R.id.btLogClear:
-                    clearLog();
                 default:
                     break;
             }
         }
 
-        /**
-         * all clear log view
-         * @see Class   class :  com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method :  clearLog</br>
-         */
-        private void clearLog()
-        {
-            mLog = "";
-            mLogTextView.setText(mLog);
-        }
-
-        /**
-         * recieve the callback log message.
-         * @see Class   class :  com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method :  cbMessage</br>
-         * @param msg callback log message
-         */
-        public void cbMessage(String msg)
-        {
-            mLog += msg + "\n";
-            mLogTextView.setText(mLog);
-        }
-
-        /**
-         * jni function - OicCorrdinatorstart() method.
-         * @see Class   class :    com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method :  OICCoordinatorStart</br>
-         * @see Signature signature : ()V</br>
-         */
-        public native int OICCoordinatorStart();
-
-        /**
-         * jni function - OICCoordinatorStop() method.
-         * @see Class   class :  com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method :  OICCoordinatorStop</br>
-         * @see signature  signature : ()V</br>
-         */
-        public native int OICCoordinatorStop();
-
-        /**
-         * jni function - ResourceHostingInit() method in order to execute OICCoordinatorStart() method.
-         * @see Class   class :  com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method :  ResourceHostingInit</br>
-         * @param addr ipAddress
-         * @see signature signature : (Ljava/lang/String;)V</br>
-         */
-        public native int ResourceHostingInit(String addr);
-
-        /**
-         * jni function - ResourceHostingTerminate() method in order to terminate resource hosting
-         * @see Class   class  : com_example_resourcehostingsampleapp_ResourceHosting</br>
-         * @see Method  method : ResourceHostingTerminate</br>
-         * @see signature signature : ()V</br>
-         */
-        public native int ResourceHostingTerminate();
-
-    static
-    {
-        System.loadLibrary("gnustl_shared");
-        System.loadLibrary("oc_logger");
-        System.loadLibrary("connectivity_abstraction");
-        System.loadLibrary("ca-interface");
-        System.loadLibrary("octbstack");
-        System.loadLibrary("oc");
-        System.loadLibrary("ocstack-jni");
-        System.loadLibrary("NotificationManager");
-    }
 }
index 0a436f6..772c7d8 100644 (file)
@@ -15,26 +15,44 @@ notimgr_env.AppendUnique(CPPPATH = ['../../NotificationManager/include'])
 notimgr_env.AppendUnique(CPPPATH = ['../../../../extlibs/cjson'])
 notimgr_env.AppendUnique(CPPPATH = ['../../../../resource/csdk/connectivity/api'])
 notimgr_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
-notimgr_c_env = notimgr_env.Clone()
-notimgr_env.AppendUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
-notimgr_c_env.AppendUnique(LIBS = ['octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread','NotificationManager'])
+notimgr_sample_env = notimgr_env.Clone()
+notimgr_env.AppendUnique(LIBS = [
+    'NotificationManager',
+    'rcs_client',
+    'rcs_server',
+    'rcs_common',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    'pthread'
+    ])
+notimgr_sample_env.AppendUnique(LIBS = [
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    'pthread'
+    ])
 
 if env.get('SECURED') == '1':
     notimgr_env.AppendUnique(LIBS = ['tinydtls'])
-    notimgr_c_env.AppendUnique(LIBS = ['tinydtls'])
+    notimgr_sample_env.AppendUnique(LIBS = ['tinydtls'])
 if 'rt' in notimgr_env.get('LIBS'):
     notimgr_env.Append(LIBS = ['rt'])
-if 'rt' in notimgr_c_env.get('LIBS'):
-    notimgr_c_env.Append(LIBS = ['rt'])
+if 'rt' in notimgr_sample_env.get('LIBS'):
+    notimgr_sample_env.Append(LIBS = ['rt'])
 
 ####################################################################
 # Source files and Targets
 ######################################################################
-sampleprovider = notimgr_env.Program('sampleprovider', 'sampleProvider/SampleProvider.cpp')
-sampleconsumer = notimgr_env.Program('sampleconsumer', 'sampleConsumer/SampleConsumer.cpp')
+sampleprovider = notimgr_sample_env.Program('sampleprovider', 'sampleProvider/SampleProvider.cpp')
+sampleconsumer = notimgr_sample_env.Program('sampleconsumer', 'sampleConsumer/SampleConsumer.cpp')
 
-notificationmanager = notimgr_c_env.Program('notificationmanager', 'notificationManager/main.c')
+notificationmanager = notimgr_env.Program('notificationmanager', 'notificationManager/main.cpp')
 
-#notimgr_env.InstallTarget(sampleprovider, 'sampleprovider')
-#notimgr_env.InstallTarget(sampleconsumer, 'sampleconsumer')
-#notimgr_env.InstallTarget(notificationmanager, 'notificationmanager')
+notimgr_sample_env.InstallTarget(sampleprovider, 'sampleprovider')
+notimgr_sample_env.InstallTarget(sampleconsumer, 'sampleconsumer')
+notimgr_env.InstallTarget(notificationmanager, 'notificationmanager')
\ No newline at end of file
@@ -35,47 +35,30 @@ int main()
 {
     printf("OCResourceHosting is starting...\n");
 
-    if (OCInit((char *) NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
-    {
-        printf("OCStack init error\n");
-        return 0;
-    }
-
     if (OICStartCoordinate() != OC_STACK_OK)
     {
-        printf("OIC coordinate start fail\n");
+        printf("OICStartCoordinate fail\n");
         return 0;
     }
 
+    printf("OCResourceHosting Started Successfully \n");
+
     signal(SIGINT, handleSigInt);
     while (!g_quitFlag)
     {
-        if (OCProcess() != OC_STACK_OK)
-        {
-            OICStopCoordinate();
-            printf("OCStack process error\n");
-            return 0;
-        }
-
         sleep(2);
     }
 
     if (OICStopCoordinate() != OC_STACK_OK)
     {
-        printf("OIC coordinate stop error\n");
+        printf("OICStopCoordinate error\n");
     }
     else
     {
-        printf("OIC coordinate stop success\n");
+        printf("OICStopCoordinate success\n");
     }
 
     printf("Exiting occlient main loop...\n");
-
-    if (OCStop() != OC_STACK_OK)
-    {
-        printf("OCStack stop error\n");
-    }
-
     return 0;
 
 }
index afb6de4..28a6a20 100644 (file)
@@ -34,7 +34,7 @@ using namespace OC;
 
 const int SUCCESS_RESPONSE = OC_STACK_OK;
 
-#define OC_WELL_KNOWN_COORDINATING_QUERY "/oc/core?rt=Resource.Hosting"
+#define OC_WELL_KNOWN_COORDINATING_QUERY "/oic/res?rt=Resource.Hosting"
 
 #define OBSERVE 1
 #define GET     2
@@ -150,7 +150,7 @@ int observe_count()
     return ++oc;
 }
 
-void onObserve(const HeaderOptions &headerOption , const OCRepresentation &rep , const int &eCode,
+void onObserve(const HeaderOptions &/*headerOption*/, const OCRepresentation &rep , const int &eCode,
                const int &sequenceNumber)
 {
     std::cout << "onObserve" << std::endl;
@@ -225,7 +225,7 @@ void foundResource(std::shared_ptr< OCResource > resource)
 
 OCStackResult nmfindResource(const std::string &host , const std::string &resourceName)
 {
-    return OCPlatform::findResource(host , resourceName , OC_ALL, &foundResource);
+    return OCPlatform::findResource(host , resourceName , CT_DEFAULT, &foundResource);
 }
 
 void getRepresentation(std::shared_ptr< OCResource > resource)
@@ -236,7 +236,7 @@ void getRepresentation(std::shared_ptr< OCResource > resource)
     }
 }
 
-void onPut(const HeaderOptions &headerOption, const OCRepresentation &rep, const int eCode)
+void onPut(const HeaderOptions &/*headerOption*/, const OCRepresentation &rep, const int eCode)
 {
     try
     {
@@ -265,7 +265,7 @@ void onPut(const HeaderOptions &headerOption, const OCRepresentation &rep, const
 }
 
 //callback hadnler on DELETE request
-void onDelete(const HeaderOptions &headerOption , const int eCode)
+void onDelete(const HeaderOptions &/*headerOption*/, const int eCode)
 {
     try
     {
@@ -286,7 +286,7 @@ void onDelete(const HeaderOptions &headerOption , const int eCode)
 }
 
 // callback handler on GET request
-void onGet(const HeaderOptions &headerOption , const OCRepresentation &rep , const int eCode)
+void onGet(const HeaderOptions &/*headerOption*/, const OCRepresentation &rep , const int eCode)
 {
     std::cout << "GET request was successful1" << std::endl;
     if (eCode == SUCCESS_RESPONSE)
@@ -334,7 +334,7 @@ void PRINT()
     std::cout << std::endl;
 }
 
-int main(int argc , char *argv[])
+int main()
 {
 
     int in;
@@ -388,7 +388,7 @@ int main(int argc , char *argv[])
                     std::cout << "Invalid input, please try again" << std::endl;
                     break;
             }
-        }catch(OCException e) {
+        }catch(OCException e) {
             std::cout<< "Caught OCException [Code: "<<e.code()<<" Reason: "<<e.reason()<<std::endl;
         }
     }
index abb40db..e8540c3 100644 (file)
@@ -180,7 +180,7 @@ class TempHumidResource
 
 TempHumidResource myResource;
 
-void *ChangeLightRepresentation(void *param)
+void *ChangeLightRepresentation(void */*param*/)
 {
     cout << "ChangeLigthRepresentation Enter\n";
     while (1)
index cd1b3e5..ad584dd 100644 (file)
                                     <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/lib}&quot;"/>
                                 </option>
                                 <option id="gnu.cpp.link.option.libs.1032324584" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
-                                    <listOptionValue builtIn="false" value="NOTISDKLibrary"/>
+                                    <listOptionValue builtIn="false" value="uuid"/>
+                                    <listOptionValue builtIn="false" value="NotificationManager"/>
                                     <listOptionValue builtIn="false" value="oc"/>
                                     <listOptionValue builtIn="false" value="octbstack"/>
-                                    <listOptionValue builtIn="false" value="coap"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="connectivity_abstraction"/>
                                 </option>
index 8ec9645..227772b 100644 (file)
@@ -46,16 +46,15 @@ static void start_hosting(int seconds)
     logMessage = logMessage + "Interface Name : " + reinterpret_cast<char *>(interfaceName) + "<br>";
     printLog(DLOG_INFO, logMessage);
 
-    if (OCInit((char *) NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
+    if (OICStartCoordinate() != OC_STACK_OK)
     {
-        logMessage = "OCStack init error <br>";
+        logMessage = "OICStartCoordinate FAILED <br>";
         printLog(DLOG_ERROR, logMessage);
         return;
     }
 
-    OICStartCoordinate();
     g_quitFlag = 0;
-    logMessage = "OICStartCoordinate done successfully";
+    logMessage = "OICStartCoordinate done successfully <br>";
     printLog(DLOG_INFO, logMessage);
 
     while (!g_quitFlag)
@@ -70,15 +69,13 @@ static void start_hosting(int seconds)
         sleep(seconds);
     }
 
-    OICStopCoordinate();
-    logMessage = "OICStopCoordinate done successfully <br>";
-    printLog(DLOG_INFO, logMessage);
-
-    if (OCStop() != OC_STACK_OK)
+    if (OICStopCoordinate() != OC_STACK_OK)
     {
-        logMessage = "OCStack stop error <br>";
+        logMessage = "OICStopCoordinate FAILED <br>";
         printLog(DLOG_ERROR, logMessage);
     }
+    logMessage = "OICStopCoordinate done successfully <br>";
+    printLog(DLOG_INFO, logMessage);
     LOGI("start EXIT");
 }
 
@@ -88,7 +85,15 @@ void stop_hosting()
     string logMessage = "Terminating Resource Hosting <br>";
     printLog(DLOG_INFO, logMessage);
 
-    g_quitFlag = 1;
+    if(!g_quitFlag)
+    {
+       g_quitFlag = 1;
+    }
+    else
+    {
+       string logMessage = "Resource Hosting already terminated <br>";
+       printLog(DLOG_INFO, logMessage);
+    }
     LOGI("stop_hosting EXIT");
 }
 
index 0dc1b9f..3778456 100644 (file)
@@ -35,3 +35,4 @@ cpluff_src.extend(env.Glob('kazlib/*.c'))
 
 cpluff = cpluff_env.StaticLibrary('cpluff', cpluff_src)
 cpluff_env.InstallTarget(cpluff, 'libcpluff')
+cpluff_env.UserInstallTargetLib(cpluff, 'libcpluff')
index 681ab10..25edfce 100644 (file)
@@ -19,13 +19,16 @@ plugin_manager_env.AppendUnique(CPPPATH = [
                env.get('SRC_DIR')+'/extlibs/rapidxml'
                ])
 
+if target_os == 'tizen':
+    plugin_manager_env.ParseConfig("pkg-config --cflags --libs capi-appfw-app-common")
+
 if target_os not in ['windows', 'winrt']:
        plugin_manager_env.AppendUnique(CXXFLAGS = ['-Wall','-std=c++0x',
                '-fpermissive', '-Wsign-compare'])
 
 if target_os == 'android':
        plugin_manager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions', '-DANDROID'])
-       plugin_manager_env.AppendUnique(LIBS = ['boost_thread', 'boost_system', 'gnustl_shared', 'log'])
+       plugin_manager_env.AppendUnique(LIBS = ['gnustl_shared', 'log'])
 
 plugin_manager_env.AppendUnique(CPPDEFINES = ['CP_C_API=CP_EXPORT',
                                        'CP_HOST=\"\\"'+env.get('TARGET_OS')+'\\"\"',
@@ -61,7 +64,8 @@ pmimpl_env.PrependUnique(LIBS = File(env.get('BUILD_DIR') + '/libcpluff.a'))
 pmimpl = pmimpl_env.SharedLibrary('pmimpl', pmimpl_src)
 
 plugin_manager_env.InstallTarget([ppm, pmimpl], 'libppm')
+plugin_manager_env.UserInstallTargetLib([ppm, pmimpl], 'libppm')
 
 # Build JNI library for android
 if env.get('TARGET_OS') == 'android':
-        SConscript('src/Android/jni/SConscript')
\ No newline at end of file
+        SConscript('src/Android/jni/SConscript')
index 9bf9102..e7203dd 100644 (file)
@@ -6,16 +6,6 @@ LOCAL_SRC_FILES        := ../../../../../../dep/android/armeabi/usr/lib/libexpat.so
 include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE   := libboost_thread
-LOCAL_SRC_FILES        := ../../../../../../dep/android/armeabi/usr/lib/libboost_thread.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE   := libboost_system
-LOCAL_SRC_FILES        := ../../../../../../dep/android/armeabi/usr/lib/libboost_system.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_MODULE   := libcpluff
 LOCAL_SRC_FILES        := ../../../../../../out/android/armeabi/release/libcpluff.a
 include $(PREBUILT_STATIC_LIBRARY)
@@ -35,12 +25,9 @@ LOCAL_LDLIBS                         := -llog -ldl -lz
 
 LOCAL_STATIC_LIBRARIES         := libcpluff
 LOCAL_STATIC_LIBRARIES         += libpmimpl
-LOCAL_STATIC_LIBRARIES         += libboost_thread
-LOCAL_STATIC_LIBRARIES         += libboost_system
 LOCAL_STATIC_LIBRARIES         += libexpat
 
-LOCAL_C_INCLUDES                       := ../../../../../../extlibs/boost/boost_1_58_0
-LOCAL_C_INCLUDES                       += ../../../../lib/cpluff/libcpluff
+LOCAL_C_INCLUDES                       := ../../../../lib/cpluff/libcpluff
 LOCAL_C_INCLUDES                       += ../../../src
 LOCAL_C_INCLUDES                       += ../../../../../../extlibs/rapidxml
 
index 0279730..7065cc7 100644 (file)
  * Method:    startPlugins
  * Signature: (Ljava/lang/String;Ljava/lang/String;)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugins(JNIEnv *env, jobject jobj,
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugins(JNIEnv *env,
+        jobject jobj,
         jstring jkey, jstring jvalue)
 {
     LOGD("jniStartPlugins() Called.");
 
-    if((!jkey)||(!jvalue))
+    if ((!jkey) || (!jvalue))
         return 0;
     std::string ckey = env->GetStringUTFChars(jkey, 0);
     std::string cvalue = env->GetStringUTFChars(jvalue, 0);
@@ -50,12 +51,13 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugi
  * Method:    stopPlugins
  * Signature: (Ljava/lang/String;Ljava/lang/String;)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugins(JNIEnv *env, jobject jobj,
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugins(JNIEnv *env,
+        jobject jobj,
         jstring jkey, jstring jvalue)
 {
     LOGD("jniStopPlugins() Called.");
 
-    if((!jkey)||(!jvalue))
+    if ((!jkey) || (!jvalue))
         return 0;
     std::string ckey = env->GetStringUTFChars(jkey, 0);
     std::string cvalue = env->GetStringUTFChars(jvalue, 0);
@@ -68,7 +70,8 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugin
  * Method:    jniRescanPlugin
  * Signature: (V)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniRescanPlugin(JNIEnv *env, jobject jobj)
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniRescanPlugin(JNIEnv *env,
+        jobject jobj)
 {
     LOGD("jniRescanPlugin() Called.");
 
@@ -81,8 +84,9 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniRescanPlug
  * Method:    getPlugins
  * Signature: (V)[Lorg/iotivity/service/ppm/Plugin;
  */
-JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetPlugins(JNIEnv *env,
-        jobject jobj)
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetPlugins(
+    JNIEnv *env,
+    jobject jobj)
 {
     LOGD("jniGetPlugins() Called.");
 
@@ -110,7 +114,8 @@ JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGe
  * Method:    getState
  * Signature: (Ljava/lang/String;)Ljava/lang/String;
  */
-JNIEXPORT jstring JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetState(JNIEnv *env, jobject jobj,
+JNIEXPORT jstring JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetState(JNIEnv *env,
+        jobject jobj,
         jstring jplugID)
 {
     LOGD("jniGetState() Called.");
index cc4df34..319a4ab 100644 (file)
@@ -55,7 +55,8 @@ JavaVM *jvm;
  * Method:    jniStartPlugins
  * Signature: (Ljava/lang/String;Ljava/lang/String;)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugins(JNIEnv *, jobject,
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugins(JNIEnv *,
+        jobject,
         jstring, jstring);
 
 /*
@@ -63,7 +64,8 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStartPlugi
  * Method:    jniStopPlugins
  * Signature: (Ljava/lang/String;Ljava/lang/String;)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugins(JNIEnv *, jobject, jstring,
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugins(JNIEnv *, jobject,
+        jstring,
         jstring);
 
 /*
@@ -71,14 +73,16 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniStopPlugin
  * Method:    jniRescanPlugin
  * Signature: (V)I
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniRescanPlugin(JNIEnv *, jobject);
+JNIEXPORT jint JNICALL Java_org_iotivity_service_ppm_PluginManager_jniRescanPlugin(JNIEnv *,
+        jobject);
 
 /*
  * Class:     org_iotivity_service_ppm_PluginManager
  * Method:    jniGetPlugins
  * Signature: (V)[Lorg/iotivity/service/ppm/Plugin;
  */
-JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetPlugins(JNIEnv *, jobject);
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_ppm_PluginManager_jniGetPlugins(JNIEnv *,
+        jobject);
 
 /*
  * Class:     org_iotivity_service_ppm_PluginManager
index 55ec004..9b54f72 100644 (file)
@@ -18,7 +18,7 @@ ppm_sdk = env.get('SRC_DIR') + '/service/protocol-plugin/plugin-manager'
 ######################################################################
 ppm_jni_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-DLINUX', '-DNDEBUG'])
 ppm_jni_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
-ppm_jni_env.PrependUnique(LIBS = ['pmimpl', 'ppm', 'expat', 'cpluff', 'boost_system', 'boost_thread', 'gnustl_shared', 'log'])
+ppm_jni_env.PrependUnique(LIBS = ['pmimpl', 'ppm', 'expat', 'cpluff', 'gnustl_shared', 'log'])
 
 ppm_jni_env.AppendUnique(CPPPATH = [ppm_sdk+'/src'])
 ppm_jni_env.AppendUnique(CPPPATH = [ppm_sdk+'/../lib/cpluff/libcpluff'])
@@ -31,6 +31,7 @@ ppm_jni_src = ['PluginManager.cpp']
 ppm_jni = ppm_jni_env.SharedLibrary('PluginManager', ppm_jni_src)
 
 ppm_jni_env.InstallTarget(ppm_jni, 'libPluginManager')
+ppm_jni_env.UserInstallTargetLib(ppm_jni, 'libPluginManager')
 
 ######################################################################
 # Install the libraries to /libs/<TARGET_ARCH> directory
@@ -44,6 +45,7 @@ for gnu_lib_path in gnu_lib_paths:
     gnu_lib_path = gnu_lib_path + '/libgnustl_shared.so'
     if os.path.exists(gnu_lib_path):
         ppm_jni_env.Install(ppm_sdk+'/src/Android/libs/'+env.get('TARGET_ARCH'), gnu_lib_path)
+        ppm_jni_env.Install(ppm_sdk+'/src/Android/libs/'+env.get('TARGET_ARCH'), gnu_lib_path)
         break
 
 
index b7d7c87..f841e64 100644 (file)
@@ -50,6 +50,7 @@ public class FelixManager {
     private static Context                 m_context;
     private static final int               TRUE                       = 1;
     private static final int               FALSE                      = 0;
+    private static final String            LOG_TAG                    = "PPMSampleApp : FelixManager";
 
     static final String                    ANDROID_FRAMEWORK_PACKAGES = ("android,"
                                                                   + "android.app,"
@@ -101,7 +102,7 @@ public class FelixManager {
     }
 
     public static void LogEx(String info) {
-        Log.d("felix", info);
+        Log.d(LOG_TAG, info);
     }
 
     private FelixManager(Context ctx) {
@@ -129,7 +130,7 @@ public class FelixManager {
                 LogEx("Bundle: " + b.getSymbolicName());
             }
         } catch (Throwable ex) {
-            Log.d("Felix", "could not create framework: " + ex.getMessage(), ex);
+            Log.d(LOG_TAG, "could not create framework: " + ex.getMessage(), ex);
         }
     }
 
@@ -162,10 +163,10 @@ public class FelixManager {
             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
             for (org.osgi.framework.Bundle b : bundles) {
                 if (b.getSymbolicName().equals(id)) {
-                    Log.d("Felix", "bundle: " + b.getBundleId()
+                    Log.d(LOG_TAG, "bundle: " + b.getBundleId()
                             + "   symbolicName : " + b.getSymbolicName());
                     b.uninstall();
-                    Log.d("Felix", "uninstall end");
+                    Log.d(LOG_TAG, "uninstall end");
                 }
             }
         } catch (BundleException e) {
@@ -183,10 +184,10 @@ public class FelixManager {
             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
             for (org.osgi.framework.Bundle b : bundles) {
                 if (!b.getSymbolicName().equals("org.apache.felix.framework")) {
-                    Log.d("Felix", "bundle: " + b.getBundleId()
+                    Log.d(LOG_TAG, "bundle: " + b.getBundleId()
                             + "   symbolicName : " + b.getSymbolicName());
                     b.uninstall();
-                    Log.d("Felix", "uninstall end");
+                    Log.d(LOG_TAG, "uninstall end");
                 }
             }
         } catch (BundleException e) {
@@ -230,19 +231,19 @@ public class FelixManager {
 
     public static int start(String id) {
         int flag = TRUE;
-        Log.d("Felix", "String id : " + id);
+        Log.d(LOG_TAG, "String id : " + id);
         try {
             BundleContext bContext = m_felix.getBundleContext();
             bContext.registerService(Context.class.getName(), m_context, null);
 
             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
             for (org.osgi.framework.Bundle b : bundles) {
-                Log.d("Felix", "symbolicName : " + b.getSymbolicName());
+                Log.d(LOG_TAG, "symbolicName : " + b.getSymbolicName());
                 if (b.getSymbolicName().equals(id)) {
-                    Log.d("Felix", "bundle: " + b.getBundleId()
+                    Log.d(LOG_TAG, "bundle: " + b.getBundleId()
                             + "   symbolicName : " + b.getSymbolicName());
                     b.start();
-                    Log.d("Felix", "start end");
+                    Log.d(LOG_TAG, "start end");
                 }
             }
         } catch (BundleException e) {
@@ -259,11 +260,10 @@ public class FelixManager {
             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
             for (org.osgi.framework.Bundle b : bundles) {
                 if (b.getSymbolicName().equals(id)) {
-                    Log.d("Felix", "bundle: " + b.getBundleId()
+                    Log.d(LOG_TAG, "bundle: " + b.getBundleId()
                             + "   symbolicName : " + b.getSymbolicName());
                     b.stop();
-                    b.uninstall();
-                    Log.d("Felix", "stop end");
+                    Log.d(LOG_TAG, "stop end");
                 }
             }
         } catch (BundleException e) {
@@ -281,20 +281,20 @@ public class FelixManager {
     }
 
     public static String getValue(String name, String key) {
-        Log.d("FELIX", "getValue");
+        Log.d(LOG_TAG, "getValue");
         BundleContext bContext = m_felix.getBundleContext();
         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
         for (org.osgi.framework.Bundle b : bundles) {
             Dictionary<String, String> dic = b.getHeaders();
             String bundlename = b.getSymbolicName();
-            Log.d("FELIX", "Bundlename: " + bundlename);
+            Log.d(LOG_TAG, "Bundlename: " + bundlename);
 
             if (bundlename.equals(name)) {
                 if (dic.get("Bundle-" + key) == null) {
-                    Log.d("FELIX", name + " null");
+                    Log.d(LOG_TAG, name + " null");
                     return "";
                 }
-                Log.d("FELIX", name + " " + dic.get("Bundle-" + key));
+                Log.d(LOG_TAG, name + " " + dic.get("Bundle-" + key));
                 return dic.get("Bundle-" + key);
             }
         }
@@ -302,7 +302,7 @@ public class FelixManager {
     }
 
     public static String getState(String name) {
-        Log.d("FELIX", "getState");
+        Log.d(LOG_TAG, "getState");
         BundleContext bContext = m_felix.getBundleContext();
         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
         for (org.osgi.framework.Bundle b : bundles) {
@@ -310,11 +310,11 @@ public class FelixManager {
             String bundlename = b.getSymbolicName();
 
             if (bundlename.equals(name)) {
-                Log.d("FELIX", state_to_string(b.getState()));
+                Log.d(LOG_TAG, state_to_string(b.getState()));
                 return state_to_string(b.getState());
             }
         }
-        Log.d("FELIX", "null");
+        Log.d(LOG_TAG, "null");
         return "";
     }
 
@@ -452,13 +452,13 @@ public class FelixManager {
 
     public static int ObservePluginPath(String path) {
         int flag = TRUE;
-        Log.d("FELIX", "ObservePluginPath" + path);
+        Log.d(LOG_TAG, "ObservePluginPath" + path);
 
         FileObserver observer = new FileObserver(path) {
             @Override
             public void onEvent(int event, String path) {
-                Log.d("FELIX", "Observing start : " + path);
-                Log.d("FELIX", "Observing event : " + getEventString(event));
+                Log.d(LOG_TAG, "Observing start : " + path);
+                Log.d(LOG_TAG, "Observing event : " + getEventString(event));
             }
         };
         observer.startWatching();
@@ -471,7 +471,7 @@ public class FelixManager {
         int flag = TRUE;
         if (path == "") {
             System.out.println("PluginManager path is Null\n");
-            Log.d("FELIX", "PluginManager path is Null\n");
+            Log.d(LOG_TAG, "PluginManager path is Null\n");
             flag = FALSE;
             return flag;
         }
@@ -535,7 +535,7 @@ public class FelixManager {
             } else {
                 String fullPath = "/data/data/"
                         + m_context.getPackageName() + "/" + path;
-                Log.d("FELIX", fullPath);
+                Log.d(LOG_TAG, fullPath);
                 File dir = new File(fullPath);
 
                 if (!dir.exists())
@@ -545,7 +545,7 @@ public class FelixManager {
                 }
             }
         } catch (IOException ex) {
-            Log.e("tag", "I/O Exception", ex);
+            Log.e(LOG_TAG, "I/O Exception", ex);
         }
     }
 
@@ -572,7 +572,7 @@ public class FelixManager {
             out.close();
             out = null;
         } catch (Exception e) {
-            Log.e("tag", e.getMessage());
+            Log.e(LOG_TAG, e.getMessage());
         }
     }
 }
\ No newline at end of file
index 1fa7ef5..9965832 100644 (file)
@@ -31,7 +31,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class FoundResource implements OcPlatform.OnResourceFoundListener {
-    final private static String TAG = "FoundResource";
+    final private static String TAG = "PPMSampleApp : FoundResource";
 
     public void onResourceFound(OcResource resource) {
 
index 8a866d8..44381e6 100644 (file)
 
 package org.iotivity.service.ppm;
 
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
+
 import org.iotivity.base.ModeType;
 import org.iotivity.base.OcConnectivityType;
 import org.iotivity.base.OcException;
@@ -33,7 +35,6 @@ import org.iotivity.base.OcResource;
 import org.iotivity.base.PlatformConfig;
 import org.iotivity.base.QualityOfService;
 import org.iotivity.base.ServiceType;
-import org.iotivity.service.ppm.R;
 
 import android.app.Activity;
 import android.content.Context;
@@ -68,6 +69,7 @@ public class MainActivity extends Activity implements
     static ToggleButton                Hue;
     static android.widget.NumberPicker hue_color;
     static Activity                    mActivity;
+    final private static String LOG_TAG = "PPMSampleApp : MainActivity";
 
     PluginManager                      m_pm;
 
@@ -101,6 +103,7 @@ public class MainActivity extends Activity implements
     Map<Integer, Integer>              onValueChangefinalVal    = new HashMap<Integer, Integer>();
     Map<Integer, Boolean>              onValueChangeThreadStart = new HashMap<Integer, Boolean>();
     String[]                           np_h                     = new String[11];
+    
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -138,31 +141,31 @@ public class MainActivity extends Activity implements
         try {
             FoundResource foundResource = new FoundResource();
             OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY,
-                    OcConnectivityType.ALL, foundResource);
+                    EnumSet.of(OcConnectivityType.CT_DEFAULT), foundResource);
         } catch (Exception e) {
-            Log.e("Felix", "Exception : " + e);
+            Log.e(LOG_TAG, "Exception : " + e);
         }
 
         Belkin = (Button) findViewById(R.id.btn_belkin);
         Belkin.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Belkin button click listener");
+                Log.i(LOG_TAG, "Belkin button click listener");
                 OcRepresentation rep = new OcRepresentation();
                 try {
                     if (belkinplug.m_power == null) {
-                        Log.i("Felix", "m_power is null");
+                        Log.i(LOG_TAG, "m_power is null");
                         belkinplug.m_power = "on";
                         rep.setValue("power", "on");
                     }
                     if (belkinplug.m_power.equals("on")) {
                         Toast.makeText(getApplicationContext(), "Off",
                                 Toast.LENGTH_SHORT).show();
-                        Log.i("Felix", "belkin wemo off");
+                        Log.i(LOG_TAG, "belkin wemo off");
                         rep.setValue("power", "off");
                     } else if (belkinplug.m_power.equals("off")) {
                         Toast.makeText(getApplicationContext(), "On",
                                 Toast.LENGTH_SHORT).show();
-                        Log.i("Felix", "belkin wemo on");
+                        Log.i(LOG_TAG, "belkin wemo on");
                         rep.setValue("power", "on");
                     } else {
                         rep.setValue("power", "on");
@@ -172,7 +175,7 @@ public class MainActivity extends Activity implements
                     rep.setValue("brightness", 0);
                     rep.setValue("color", 0);
                 } catch (OcException e) {
-                    Log.e("Felix", e.getMessage());
+                    Log.e(LOG_TAG, e.getMessage());
                 }
                 OnPutBelkinplug onPut = new OnPutBelkinplug();
                 if (belkinResource != null) {
@@ -185,6 +188,7 @@ public class MainActivity extends Activity implements
                 } else {
                     Toast.makeText(getApplicationContext(), "Belkinplug null",
                             Toast.LENGTH_SHORT).show();
+                    Log.i(LOG_TAG, "Belkinplug null");
                 }
             }
         });
@@ -192,20 +196,20 @@ public class MainActivity extends Activity implements
         belkinstart = (Button) findViewById(R.id.Button01);
         belkinstart.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "start button click listener");
+                Log.i(LOG_TAG, "start button click listener");
                 m_pm.startPlugins("ResourceType", "device.smartplug");
 
                 Handler handler = new Handler();
                 handler.postDelayed(new Runnable() {
                     @Override
                     public void run() {
-                        Log.i("Felix", "run called!!!");
+                        Log.i(LOG_TAG, "run called!!!");
                         FoundResource foundResource = new FoundResource();
                         try {
                             OcPlatform
                                     .findResource(
                                             "", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "device.smartplug",
-                                            OcConnectivityType.ALL, foundResource);
+                                            EnumSet.of(OcConnectivityType.CT_DEFAULT), foundResource);
                         } catch (OcException e) {
                             e.printStackTrace();
                         }
@@ -217,7 +221,7 @@ public class MainActivity extends Activity implements
         belkinstop = (Button) findViewById(R.id.Button02);
         belkinstop.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "stop button click listener");
+                Log.i(LOG_TAG, "stop button click listener");
                 m_pm.stopPlugins("ResourceType", "device.smartplug");
                 belkinResource = null;
                 try {
@@ -231,7 +235,7 @@ public class MainActivity extends Activity implements
         belkingetPlugins = (Button) findViewById(R.id.Button03);
         belkingetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getPlugins button click listener");
+                Log.i(LOG_TAG, "getPlugins button click listener");
                 user_plugin = m_pm.getPlugins();
                 // key = "name";
                 state = "";
@@ -248,7 +252,7 @@ public class MainActivity extends Activity implements
         belkingetPlugins = (Button) findViewById(R.id.Button04);
         belkingetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getState click listener");
+                Log.i(LOG_TAG, "getState click listener");
                 state = m_pm.getState("wemo");
                 if (state == "")
                     state = "null";
@@ -264,7 +268,7 @@ public class MainActivity extends Activity implements
         belkinrescan = (Button) findViewById(R.id.Button05);
         belkinrescan.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Rescan Plugin click listener");
+                Log.i(LOG_TAG, "Rescan Plugin click listener");
                 m_pm.rescanPlugin();
                 try {
                     Thread.sleep(2000);
@@ -277,7 +281,7 @@ public class MainActivity extends Activity implements
         Gear = (Button) findViewById(R.id.btn_gear);
         Gear.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Gear button click listener");
+                Log.i(LOG_TAG, "Gear button click listener");
                 OcRepresentation rep = new OcRepresentation();
                 
                 try{   
@@ -287,12 +291,13 @@ public class MainActivity extends Activity implements
                     rep.setValue("brightness", 0);
                     rep.setValue("color", 0);
                 } catch (OcException e) {
-                    Log.e("Felix", e.getMessage());
+                    Log.e(LOG_TAG, e.getMessage());
                 }
                 
                 if (gearResource != null) {
                     Toast.makeText(getApplicationContext(),
                             "Send Noti. to Gear", Toast.LENGTH_SHORT).show();
+                    Log.i(LOG_TAG, "Send Noti. to Gear");
                     try {
                         OnPutGear onPut = new OnPutGear();
                         gearResource.put(rep, new HashMap<String, String>(),
@@ -303,6 +308,7 @@ public class MainActivity extends Activity implements
                 } else {
                     Toast.makeText(getApplicationContext(), "Gear is null",
                             Toast.LENGTH_SHORT).show();
+                    Log.i(LOG_TAG, "Gear is null");
                 }
             }
         });
@@ -310,20 +316,20 @@ public class MainActivity extends Activity implements
         gearstart = (Button) findViewById(R.id.Button06);
         gearstart.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "start button click listener");
+                Log.i(LOG_TAG, "start button click listener");
                 m_pm.startPlugins("ResourceType", "device.notify");
 
                 Handler handler = new Handler();
                 handler.postDelayed(new Runnable() {
                     @Override
                     public void run() {
-                        Log.i("Felix", "run called!!!");
+                        Log.i(LOG_TAG, "run called!!!");
                         FoundResource foundResource = new FoundResource();
                         try {
                             OcPlatform
                             .findResource(
                                     "", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "device.notify",
-                                    OcConnectivityType.ALL, foundResource);
+                                    EnumSet.of(OcConnectivityType.CT_DEFAULT), foundResource);
                         } catch (OcException e) {
                             e.printStackTrace();
                         }
@@ -335,7 +341,7 @@ public class MainActivity extends Activity implements
         gearstop = (Button) findViewById(R.id.Button07);
         gearstop.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "stop button click listener");
+                Log.i(LOG_TAG, "stop button click listener");
                 m_pm.stopPlugins("ResourceType", "device.notify");
                 gearResource = null;
                 try {
@@ -349,7 +355,7 @@ public class MainActivity extends Activity implements
         geargetPlugins = (Button) findViewById(R.id.Button08);
         geargetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getPlugins button click listener");
+                Log.i(LOG_TAG, "getPlugins button click listener");
                 user_plugin = m_pm.getPlugins();
                 state = "";
                 id = "";
@@ -365,7 +371,7 @@ public class MainActivity extends Activity implements
         geargetPlugins = (Button) findViewById(R.id.Button09);
         geargetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getState click listener");
+                Log.i(LOG_TAG, "getState click listener");
                 state = m_pm.getState("gearnoti");
                 if (state == "")
                     state = "null";
@@ -381,7 +387,7 @@ public class MainActivity extends Activity implements
         gearrescan = (Button) findViewById(R.id.Button10);
         gearrescan.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Rescan Plugin click listener");
+                Log.i(LOG_TAG, "Rescan Plugin click listener");
                 m_pm.rescanPlugin();
                 try {
                     Thread.sleep(2000);
@@ -394,14 +400,15 @@ public class MainActivity extends Activity implements
         Hue = (ToggleButton) findViewById(R.id.tbtn_hue_power);
         Hue.setOnClickListener(new ToggleButton.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Hue button click listener");
+                Log.i(LOG_TAG, "Hue button click listener");
                 OcRepresentation rep = new OcRepresentation();
                 ToggleButton t = (ToggleButton) v;
                 if (t.isChecked()) {
                     Toast.makeText(getApplicationContext(), "Hue ON",
                             Toast.LENGTH_SHORT).show();
+                    Log.i(LOG_TAG, "Hue ON");
                     if (hueplug.m_bright == 0) {
-                        Log.e("Felix", "hueplug m_bright is 0");
+                        Log.e(LOG_TAG, "hueplug m_bright is 0");
                         hueplug.m_bright = 128;
                     }
                     try {
@@ -411,7 +418,7 @@ public class MainActivity extends Activity implements
                         rep.setValue("brightness", hueplug.m_bright);
                         rep.setValue("color", hueplug.m_color);
                     } catch (OcException e) {
-                        Log.e("Felix", e.getMessage());
+                        Log.e(LOG_TAG, e.getMessage());
                     }
 
                     OnPutHuebulb onPut = new OnPutHuebulb();
@@ -425,12 +432,14 @@ public class MainActivity extends Activity implements
                     } else {
                         Toast.makeText(getApplicationContext(),
                                 "HueResource null", Toast.LENGTH_SHORT).show();
+                        Log.i(LOG_TAG, "HueResource null");
                     }
                 } else {
                     Toast.makeText(getApplicationContext(), "Hue OFF",
                             Toast.LENGTH_SHORT).show();
+                    Log.i(LOG_TAG, "Hue OFF");
                     if (hueplug.m_bright == 0) {
-                        Log.e("Felix", "hueplug m_bright is 0");
+                        Log.e(LOG_TAG, "hueplug m_bright is 0");
                         hueplug.m_bright = 128;
                     }
                     try {
@@ -440,7 +449,7 @@ public class MainActivity extends Activity implements
                         rep.setValue("brightness", hueplug.m_bright);
                         rep.setValue("color", hueplug.m_color);
                     } catch (OcException e) {
-                        Log.e("Felix", e.getMessage());
+                        Log.e(LOG_TAG, e.getMessage());
                     }
 
                     OnPutHuebulb onPut = new OnPutHuebulb();
@@ -451,10 +460,12 @@ public class MainActivity extends Activity implements
                                     onPut);
                         } catch (OcException e) {
                             e.printStackTrace();
+                            Log.e(LOG_TAG, e.getMessage());
                         }
                     } else {
                         Toast.makeText(getApplicationContext(),
                                 "HueResource null", Toast.LENGTH_SHORT).show();
+                        Log.i(LOG_TAG, "HueResource null");
                     }
                 }
             }
@@ -463,20 +474,20 @@ public class MainActivity extends Activity implements
         huestart = (Button) findViewById(R.id.Button11);
         huestart.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "start button click listener");
+                Log.i(LOG_TAG, "start button click listener");
                 m_pm.startPlugins("ResourceType", "device.light");
 
                 Handler handler = new Handler();
                 handler.postDelayed(new Runnable() {
                     @Override
                     public void run() {
-                        Log.i("Felix", "run called!!!");
+                        Log.i(LOG_TAG, "run called!!!");
                         FoundResource foundResource = new FoundResource();
                         try {
                             OcPlatform
                             .findResource(
                                     "", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "device.light",
-                                    OcConnectivityType.ALL, foundResource);
+                                    EnumSet.of(OcConnectivityType.CT_DEFAULT), foundResource);
                         } catch (OcException e) {
                             e.printStackTrace();
                         }
@@ -488,7 +499,7 @@ public class MainActivity extends Activity implements
         huestop = (Button) findViewById(R.id.Button12);
         huestop.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "stop button click listener");
+                Log.i(LOG_TAG, "stop button click listener");
                 m_pm.stopPlugins("ResourceType", "device.light");
                 hueResource = null;
                 try {
@@ -502,7 +513,7 @@ public class MainActivity extends Activity implements
         huegetPlugins = (Button) findViewById(R.id.Button13);
         huegetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getPlugins button click listener");
+                Log.i(LOG_TAG, "getPlugins button click listener");
                 user_plugin = m_pm.getPlugins();
                 key = "name";
                 state = "";
@@ -519,7 +530,7 @@ public class MainActivity extends Activity implements
         huegetPlugins = (Button) findViewById(R.id.Button14);
         huegetPlugins.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "getState click listener");
+                Log.i(LOG_TAG, "getState click listener");
                 state = m_pm.getState("hue");
                 if (state == "")
                     state = "null";
@@ -535,7 +546,7 @@ public class MainActivity extends Activity implements
         huerescan = (Button) findViewById(R.id.Button15);
         huerescan.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
-                Log.i("Felix", "Rescan Plugin click listener");
+                Log.i(LOG_TAG, "Rescan Plugin click listener");
                 m_pm.rescanPlugin();
                 try {
                     Thread.sleep(2000);
@@ -549,33 +560,39 @@ public class MainActivity extends Activity implements
     static public void updateConnectStatus(String device, boolean status) {
         if (device.equals("belkinplug")) {
             if (status) {
-                Log.i("Felix", "belkingplug status green");
+                Log.i(LOG_TAG, "belkingplug status green");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Belkin Connected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Belkin Connected");
             } else {
-                Log.i("Felix", "belkingplug status gray");
+                Log.i(LOG_TAG, "belkingplug status gray");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Belkin Disonnected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Belkin Disonnected");
             }
         } else if (device.equals("gear")) {
             if (status) {
-                Log.i("Felix", "gear status green");
+                Log.i(LOG_TAG, "gear status green");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Gear Connected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Gear Connected");
             } else {
-                Log.i("Felix", "gear status gray");
+                Log.i(LOG_TAG, "gear status gray");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Gear Disconnected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Gear Disonnected");
             }
         } else if (device.equals("huebulb")) {
             if (status) {
-                Log.i("Felix", "huebulb status green");
+                Log.i(LOG_TAG, "huebulb status green");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Hue Connected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Hue Connected");
             } else {
-                Log.i("Felix", "huebulb status gray");
+                Log.i(LOG_TAG, "huebulb status gray");
                 Toast.makeText(mActivity.getApplicationContext(),
                         "Hue Disconnected", Toast.LENGTH_SHORT).show();
+                Log.i(LOG_TAG, "Hue Disconnected");
             }
 
             if (hueplug.m_power.equals("on")) {
@@ -600,26 +617,26 @@ public class MainActivity extends Activity implements
 
     @Override
     protected void onResume() {
-        Log.i("Felix", "onResume()");
+        Log.i(LOG_TAG, "onResume()");
         super.onResume();
     }
 
     @Override
     protected void onPause() {
-        Log.i("Felix", "onPause()");
+        Log.i(LOG_TAG, "onPause()");
         super.onPause();
         finish();
     }
 
     @Override
     protected void onStop() {
-        Log.i("Felix", "onStop()");
+        Log.i(LOG_TAG, "onStop()");
         super.onStop();
     }
 
     @Override
     protected void onDestroy() {
-        Log.i("Felix", "onDestroy()");
+        Log.i(LOG_TAG, "onDestroy()");
         System.exit(1);
         super.onDestroy();
     }
@@ -636,14 +653,14 @@ public class MainActivity extends Activity implements
             try {
                 sleep(1000, 0);
             } catch (Exception e) {
-                Log.i("Felix", "waitForFinal exception : " + e);
+                Log.i(LOG_TAG, "waitForFinal exception : " + e);
             }
-            Log.i("Felix", "Final Value for NUMBERPICKER[" + idx + "] : "
+            Log.i(LOG_TAG, "Final Value for NUMBERPICKER[" + idx + "] : "
                     + onValueChangefinalVal.get(idx));
 
             if (idx == R.id.np_hue_color) {
                 hueplug.m_color = 6300 * onValueChangefinalVal.get(idx);
-                Log.i("Felix", "m_color = " + hueplug.m_color);
+                Log.i(LOG_TAG, "m_color = " + hueplug.m_color);
 
                 OcRepresentation rep = new OcRepresentation();
                 if (hueplug.m_power == null) {
@@ -659,12 +676,12 @@ public class MainActivity extends Activity implements
                     rep.setValue("brightness", hueplug.m_bright = 180);
                     rep.setValue("color", hueplug.m_color);
                 } catch (OcException e) {
-                    Log.e("Felix", e.getMessage());
+                    Log.e(LOG_TAG, e.getMessage());
                 }
 
                 OnPutHuebulb onPut = new OnPutHuebulb();
                 if (hueResource != null) {
-                    Log.i("Felix", "huebulbResource is not null");
+                    Log.i(LOG_TAG, "huebulbResource is not null");
                     try {
                         hueResource.put(rep, new HashMap<String, String>(),
                                 onPut);
@@ -672,7 +689,7 @@ public class MainActivity extends Activity implements
                         e.printStackTrace();
                     }
                 } else {
-                    Log.i("Felix", "huebulbResource is null");
+                    Log.i(LOG_TAG, "huebulbResource is null");
                 }
             }
             onValueChangeThreadStart.put(idx, false);
index 3e58264..2308405 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnGetBelkinplug implements OcResource.OnGetListener {
-    final private static String TAG = "OnGetBelkinplug";
+    final private static String TAG = "PPMSampleApp : OnGetBelkinplug";
 
     @Override
     public void onGetCompleted(List<OcHeaderOption> headerOptions,
index 309f1d6..136199c 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnGetGear implements OcResource.OnGetListener {
-    final private static String TAG = "OnGetGear";
+    final private static String TAG = "PPMSampleApp : OnGetGear";
 
     @Override
     public void onGetCompleted(List<OcHeaderOption> headerOptions,
index dfb89f0..2404882 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnGetHuebulb implements OcResource.OnGetListener {
-    final private static String TAG = "OnGetHuebulb";
+    final private static String TAG = "PPMSampleApp : OnGetHuebulb";
 
     @Override
     public void onGetCompleted(List<OcHeaderOption> headerOptions,
index c949ca9..079638a 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnPutBelkinplug implements OcResource.OnPutListener {
-    final private static String TAG = "OnPutBelkinplug";
+    final private static String TAG = "PPMSampleApp : OnPutBelkinplug";
 
     @Override
     public void onPutCompleted(List<OcHeaderOption> options,
index 081247f..1d789cd 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnPutGear implements OcResource.OnPutListener {
-    final private static String TAG = "OnPutGear";
+    final private static String TAG = "PPMSampleApp : OnPutGear";
 
     @Override
     public void onPutCompleted(List<OcHeaderOption> options,
index defd511..1fb1870 100644 (file)
@@ -35,7 +35,7 @@ import org.iotivity.base.OcResource;
 import android.util.Log;
 
 public class OnPutHuebulb implements OcResource.OnPutListener {
-    final private static String TAG = "OnPutHuebulb";
+    final private static String TAG = "PPMSampleApp : OnPutHuebulb";
 
     @Override
     public void onPutCompleted(List<OcHeaderOption> options,
index ad875d9..13f1374 100644 (file)
@@ -92,6 +92,8 @@ public class PluginManager {
         System.loadLibrary("PluginManager");
     }
 
+    private static final String LOG_TAG = "PPMSampleApp : PluginManager";
+
     private native int jniStartPlugins(String key, String value);
 
     private native int jniStopPlugins(String key, String value);
@@ -103,6 +105,6 @@ public class PluginManager {
     private native String jniGetState(String plugID);
 
     private static void LogEx(String info) {
-        Log.d("PluginManager.java", info);
+        Log.d(LOG_TAG, info);
     }
 }
index 963c89e..4553e2e 100644 (file)
@@ -25,6 +25,9 @@
 
 #include "Config.h"
 
+#ifdef __TIZEN__
+#include <appfw/app_common.h>
+#endif
 
 using namespace OIC;
 using namespace rapidxml;
@@ -35,14 +38,6 @@ Config *Config::s_configinstance = NULL;
 Config::Config(void *args)
 {
     std::string path = ".";
-/**
- * For Tizen Platform, specifiy the absolute location of config file. It is required for
- * Tizen 2.3 EFL App to work.
- */
-#ifdef __TIZEN__
-    if (loadConfigFile("/opt/usr/apps/org.iotivity.service.ppm.ppmsampleapp/lib/pluginmanager.xml")
-                                                                                        != PM_S_OK)
-#else
 #ifdef ANDROID
     JavaVM *jvm = (JavaVM *)args;
     JNIEnv *env;
@@ -52,13 +47,21 @@ Config::Config(void *args)
     jmethodID mid = env->GetStaticMethodID(cls, "getPackageName", "()Ljava/lang/String;");
     jstring jpath = (jstring)env->CallStaticObjectMethod(cls, mid);
     path = env->GetStringUTFChars(jpath, 0);
-
-    if(path != ".")
+    if (path != ".")
         path = "/data/data/" + path + "/files";
+#elif __TIZEN__
+    char *app_id = NULL;
+    int res = app_get_id(&app_id);
+    if (APP_ERROR_NONE == res)
+    {
+        path = "/opt/usr/apps/";
+        path += app_id;
+        path += "/lib";
+    }
+    free(app_id);
 #endif
 
     if (loadConfigFile(path + "/pluginmanager.xml") != PM_S_OK)
-#endif //#ifdef __TIZEN__
     {
         fprintf(stderr, "PM Configuration file is not exist current Folder.\n" );
         exit(EXIT_FAILURE);
@@ -67,7 +70,7 @@ Config::Config(void *args)
 
 Config::~Config(void)
 {
-    if (s_configinstance) 
+    if (s_configinstance)
     {
         s_configinstance->deleteinstance();
         s_configinstance = NULL;
@@ -77,7 +80,7 @@ Config::~Config(void)
 PMRESULT Config::loadConfigFile(const std::string configfilepath)
 {
     // Read the xml file
-   xml_document< char > doc;
+    xml_document< char > doc;
     std::basic_ifstream< char > xmlFile(configfilepath.c_str());
     if (!xmlFile.good())
     {
@@ -99,7 +102,7 @@ PMRESULT Config::loadConfigFile(const std::string configfilepath)
 
     // Find our root node
     xml_node< char > *root_node = doc.first_node("pluginManager");
-    if(!root_node)
+    if (!root_node)
     {
         throw parse_error("No Root Element", 0);
     }
@@ -129,9 +132,14 @@ PMRESULT Config::parsing(char *xmlData, xml_document<> *doc)
 
 PMRESULT Config::getXmlData(xml_node<> *pluginInfo, std::string key)
 {
-    xml_attribute<> *iAttr = NULL;
+    if (pluginInfo == NULL)
+    {
+        return PM_S_FALSE;
+    }
+
     std::string value  = "";
-    if (iAttr = pluginInfo->first_attribute(key.c_str()))
+    xml_attribute<> *iAttr = pluginInfo->first_attribute(key.c_str());
+    if (iAttr)
     {
         value = iAttr->value();
         setValue(key, value);
@@ -197,4 +205,4 @@ std::string Config::getPluginPath()
     {
         return "";
     }
-}
\ No newline at end of file
+}
index 553f0d1..9db7827 100644 (file)
@@ -36,6 +36,8 @@
 #include <jni.h>
 #endif
 
+#define PATH_MAX_SIZE 100
+
 using namespace rapidxml;
 
 namespace OIC
index 8db6d6e..e2b3d68 100644 (file)
@@ -194,20 +194,6 @@ int CpluffAdapter::loadPluginInfoToManager(const std::string path)
         }
         if (plugin_compare_flag)
         {
-            //Auto plugin detection is disabled
-            /*
-            try
-            {
-                boost::thread *t = new boost::thread(boost::bind(&CpluffAdapter::observePluginPath,
-                                                     //this, (void *)path.c_str()));
-                                                     this, (void *)m_cp_plugins[i]->plugin_path));
-                m_thread_g.add_thread(t);
-            }
-            catch (...)
-            {
-                printf("thread throw exception\n");
-            }
-            */
             m_plugins.push_back(*plugin);
             delete(plugin);
         }
@@ -313,7 +299,8 @@ std::vector<Plugin> *CpluffAdapter::findPlugins(const std::string key, const std
 
     for (unsigned int i = 0; i < m_plugins.size(); i++)
     {
-        if (!m_plugins[i].getValueByAttribute(key).compare(value))
+        std::string attributeValue = m_plugins[i].getValueByAttribute(key);
+        if (!attributeValue.empty() && !attributeValue.compare(value))
         {
             re_plugins->push_back(m_plugins[i]);
         }
index 2248665..221c305 100644 (file)
@@ -34,8 +34,6 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
 #include <internal.h>
 
 #include "Plugin.h"
@@ -196,7 +194,6 @@ namespace OIC
             cp_status_t m_status;
             cp_plugin_info_t **m_cp_plugins;
             cp_plugin_info_t *m_plugin;
-            //boost::thread_group m_thread_g;
             static CpluffAdapter *s_pinstance;
 
             /**
index 44df0bf..c747cd7 100644 (file)
@@ -173,7 +173,7 @@ std::vector<Plugin> &FelixAdapter::getAllPlugins(void)
         mid = env->GetStaticMethodID(cls, "getValue",
                                      "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
         std::string key = "Name";
-        jstring jname = (jstring)env->CallStaticObjectMethod(cls, mid, jid, 
+        jstring jname = (jstring)env->CallStaticObjectMethod(cls, mid, jid,
                         env->NewStringUTF(key.c_str()));
         std::string name = env->GetStringUTFChars(jname, 0);
         plugin->setValue("Name", name);
@@ -183,6 +183,14 @@ std::vector<Plugin> &FelixAdapter::getAllPlugins(void)
                                 env->NewStringUTF(key.c_str()));
         std::string resourcetype = env->GetStringUTFChars(jresourcetype, 0);
         plugin->setValue("ResourceType", resourcetype);
+
+        // set ResourceURL value
+        key = "Url";
+        jstring juritype = (jstring)env->CallStaticObjectMethod(cls, mid, jid,
+                           env->NewStringUTF(key.c_str()));
+        std::string url = env->GetStringUTFChars(juritype, 0);
+        plugin->setValue("Url", url);
+
         // push the plugin into the vector
         m_plugins.push_back(*plugin);
     }
@@ -200,7 +208,7 @@ std::vector<Plugin> *FelixAdapter::findPlugins(const std::string key, const std:
 
     jclass cls = env->FindClass("org/iotivity/service/ppm/FelixManager");
     jmethodID mid = env->GetStaticMethodID(cls, "findPlugins",
-                        "(Ljava/lang/String;Ljava/lang/String;)[Lorg/osgi/framework/Bundle;");
+                                           "(Ljava/lang/String;Ljava/lang/String;)[Lorg/osgi/framework/Bundle;");
 
     // call findPlugins() function
     jobjectArray jresultArray = (jobjectArray)env->CallStaticObjectMethod(cls, mid, (jstring)jkey,
@@ -235,9 +243,9 @@ std::vector<Plugin> *FelixAdapter::findPlugins(const std::string key, const std:
         // set Name value
         cls = env->FindClass("org/iotivity/service/ppm/FelixManager");
         mid = env->GetStaticMethodID(cls, "getValue",
-                    "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+                                     "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
         std::string key = "Name";
-        jstring jname = (jstring)env->CallStaticObjectMethod(cls, mid, jid, 
+        jstring jname = (jstring)env->CallStaticObjectMethod(cls, mid, jid,
                         env->NewStringUTF(key.c_str()));
         std::string name = env->GetStringUTFChars(jname, 0);
         plugin->setValue("Name", name);
@@ -326,8 +334,8 @@ const std::string FelixAdapter::getState(const std::string plugID)
 
     jstring jplugID = env->NewStringUTF(plugID.c_str());
     jclass cls = env->FindClass("org/iotivity/service/ppm/FelixManager");
-    jmethodID mid = env->GetStaticMethodID(cls, "getState", 
-                    "(Ljava/lang/String;)Ljava/lang/String;");
+    jmethodID mid = env->GetStaticMethodID(cls, "getState",
+                                           "(Ljava/lang/String;)Ljava/lang/String;");
 
     // call getState() function
     jstring jresult = (jstring)env->CallStaticObjectMethod(cls, mid, jplugID);
index f4d655d..c19f458 100644 (file)
@@ -34,8 +34,6 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
 #include <internal.h>
 #include <jni.h>
 
@@ -186,7 +184,6 @@ namespace OIC
             Config *config;
             typedef std::map<std::string, bool> File_list;
             std::vector<Plugin> m_plugins;
-            boost::thread m_file_detect_thread;
 
             static FelixAdapter *s_pinstance;
 
index 43b41a8..16a861b 100644 (file)
 
 
 #include "PluginManager.h"
+#ifdef __TIZEN__
+#include <appfw/app_common.h>
+#endif
 
 using namespace OIC;
 
 PluginManager::PluginManager()
 {
-/**
- * For Tizen Platform, specifiy the absolute location of dynamic library. It is required for
- * Tizen 2.3 EFL App to work.
- */
 #ifdef __TIZEN__
-    handle = dlopen("/opt/usr/apps/org.iotivity.service.ppm.ppmsampleapp/lib/libpmimpl.so",
-                                                                                        RTLD_LAZY);
+    char *app_id = NULL;
+    std::string completePath = "";
+    int res = app_get_id(&app_id);
+    if (APP_ERROR_NONE == res)
+    {
+        completePath = "/opt/usr/apps/";
+        completePath += app_id;
+        completePath += "/lib/libpmimpl.so";
+    }
+    free(app_id);
+    app_id = NULL;
+    handle = dlopen(completePath.c_str(), RTLD_LAZY);
 #else
     handle = dlopen("./libpmimpl.so", RTLD_LAZY);
 #endif //#ifdef __TIZEN__
@@ -80,4 +89,4 @@ std::vector<Plugin> PluginManager::getPlugins(void)
 std::string PluginManager::getState(const std::string plugID)
 {
     return pluginManagerImpl->getState(plugID);
-}
\ No newline at end of file
+}
index 19bfc42..0d63e22 100644 (file)
@@ -43,8 +43,8 @@ extern "C" void destroy_object( PluginManagerImpl *object )
 PluginManagerImpl::PluginManagerImpl(void *args)
 {
 #ifndef ANDROID
-        m_args = args;
-        cppm = CpluffAdapter::Getinstance();
+    m_args = args;
+    cppm = CpluffAdapter::Getinstance();
 #endif
 #ifdef ANDROID
     m_args = args;
@@ -161,7 +161,8 @@ std::vector<Plugin> *PluginManagerImpl::findPlugins(const std::string key,
     re_plugins = new std::vector<Plugin>;
     for (unsigned int i = 0; i < m_plugins.size(); i++)
     {
-        if (!m_plugins[i].getValueByAttribute(key).compare(value))
+        std::string attributeValue = m_plugins[i].getValueByAttribute(key);
+        if (!attributeValue.empty() && !attributeValue.compare(value))
         {
             re_plugins->push_back(m_plugins[i]);
         }
index c49768b..39f0e95 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "Plugin.h"
 #include "CpluffAdapter.h"
+#include <algorithm>
 
 #ifdef ANDROID
 #include "FelixAdapter.h"
diff --git a/service/protocol-plugin/plugins/Android/plugin.gear.noti/.project b/service/protocol-plugin/plugins/Android/plugin.gear.noti/.project
new file mode 100644 (file)
index 0000000..728c962
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>plugin.gear.noti</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
index 1d95080..701c148 100644 (file)
@@ -122,9 +122,12 @@ public class Activator extends Activity implements BundleActivator,
             EntityHandlerNoti entitycb = new EntityHandlerNoti();
 
             resourceHandle = OcPlatform.registerResource("/a/galaxy/gear",
-                    "device.notify", "oc.mi.def", entitycb,
+                    "device.notify", OcPlatform.DEFAULT_INTERFACE, entitycb,
                     EnumSet.of(ResourceProperty.DISCOVERABLE));
         }
+        else{
+            Log.w(TAG, "Something Happened");
+        }
     }
 
     @Override
index a9b5d74..b283f2a 100644 (file)
@@ -22,6 +22,7 @@
 
 package oic.plugin.gear.noti;
 
+import java.util.EnumSet;
 import java.util.UUID;
 
 import oic.plugin.gear.noti.Activator.TemplateTypes;
@@ -69,29 +70,18 @@ public class EntityHandlerNoti implements OcPlatform.EntityHandler {
                         .getRequestHandle());
                 response.setResourceHandle(resourcerequest
                         .getResourceHandle());
-                Log.d("JUDO",
-                        "/******************************************************************************/");
-                Log.d("JUDO", "Name: "
-                        + resourcerequest.getResourceRepresentation()
-                                .getValueString("name"));
-                Log.d("JUDO", "Name: "
-                        + resourcerequest.getResourceRepresentation()
-                                .getValueString("power"));
-                Log.d("JUDO", "Name: "
-                        + resourcerequest.getResourceRepresentation()
-                                .getValueInt("brigthness"));
-                Log.d("JUDO", "Name: "
-                        + resourcerequest.getResourceRepresentation()
-                                .getValueInt("color"));
-                Log.d("JUDO",
-                        "/******************************************************************************/");
                 switch (requestType) {
                     case GET:
                         break;
                     case PUT:
+                    try {
                         textNoti = resourcerequest
                                 .getResourceRepresentation()
-                                .getValueString("power");
+                                .getValue("power");
+                    } catch (OcException e) {
+                        // TODO Auto-generated catch block
+                        Log.e(TAG, e.getMessage());
+                    }
                         perform(0);
                         break;
                     case POST:
@@ -99,13 +89,19 @@ public class EntityHandlerNoti implements OcPlatform.EntityHandler {
                 }
                 response.setErrorCode(200);
                 // representation.setUri("/a/galaxy/gear");
-                representation.setValueString("name",
-                        Activator.myNotify.m_name);
-                representation.setValueString("power",
-                        Activator.myNotify.m_power);
-                representation.setValueInt("brightness", 0);
-                representation.setValueInt("color", 0);
-                response.setResourceRepresentation(representation);
+                try {
+                    representation.setValue("name",
+                            Activator.myNotify.m_name);
+                    representation.setValue("power",
+                            Activator.myNotify.m_power);
+                    representation.setValue("brightness", 0);
+                    representation.setValue("color", 0);
+                    response.setResourceRepresentation(representation);
+                } catch (OcException e) {
+                    // TODO Auto-generated catch block
+                    Log.e(TAG, e.getMessage());
+                }
+                
                 try {
                     OcPlatform.sendResponse(response);
                 } catch (OcException e) {
diff --git a/service/protocol-plugin/plugins/Android/plugin.hue/.project b/service/protocol-plugin/plugins/Android/plugin.hue/.project
new file mode 100644 (file)
index 0000000..c04a197
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>plugin.hue</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
index 64f831c..22eb81b 100644 (file)
@@ -230,7 +230,7 @@ public class Activator extends Activity implements BundleActivator {
                                                            System.currentTimeMillis());
 
                                            PlatformConfig cfg = new PlatformConfig(
-                                                   this,
+                                                   getBaseContext(),
                                                    ServiceType.IN_PROC,
                                                    ModeType.CLIENT_SERVER,
                                                    "0.0.0.0", 0,
@@ -244,7 +244,7 @@ public class Activator extends Activity implements BundleActivator {
                                                        .registerResource(
                                                                "/a/huebulb",
                                                                "device.light",
-                                                               "oc.mi.def",
+                                                               OcPlatform.DEFAULT_INTERFACE,
                                                                entitycb,
                                                                EnumSet.of(ResourceProperty.DISCOVERABLE));
                                            } catch (OcException e) {
index 278d3de..e401d6d 100644 (file)
@@ -22,6 +22,7 @@
 
 package oic.plugin.hue;
 
+import java.util.EnumSet;
 import java.util.List;
 
 import org.iotivity.base.EntityHandlerResult;
@@ -95,22 +96,28 @@ public class EntityHandlerHue implements OcPlatform.EntityHandler {
                                 .getResourceCache().getAllLights();
                         for (PHLight light : mmyLights) {
                             PHLightState lightState = new PHLightState();
-                            String str = resourcerequest
-                                    .getResourceRepresentation()
-                                    .getValueString("power");
-                            if (str.equals("on")) {
-                                lightState.setOn(true);
-                                Activator.myLight.m_power = "on";
-                            } else if (str.equals("off")) {
-                                lightState.setOn(false);
-                                Activator.myLight.m_power = "off";
+                            try {
+                                String str = resourcerequest
+                                        .getResourceRepresentation()
+                                        .getValue("power");
+                                if (str.equals("on")) {
+                                    lightState.setOn(true);
+                                    Activator.myLight.m_power = "on";
+                                } else if (str.equals("off")) {
+                                    lightState.setOn(false);
+                                    Activator.myLight.m_power = "off";
+                                }
+                                int setHueValue = resourcerequest
+                                        .getResourceRepresentation()
+                                        .getValue("color");
+                                lightState.setHue(setHueValue);
+                                Activator.myLight.m_color = resourcerequest
+                                        .getResourceRepresentation()
+                                        .getValue("color");
+                            } catch (OcException e) {
+                                // TODO Auto-generated catch block
+                                Log.e(TAG, e.getMessage());
                             }
-                            lightState.setHue(resourcerequest
-                                    .getResourceRepresentation()
-                                    .getValueInt("color"));
-                            Activator.myLight.m_color = resourcerequest
-                                    .getResourceRepresentation()
-                                    .getValueInt("color");
                             mbridge.updateLightState(light, lightState);
                         }
                         break;
@@ -119,14 +126,19 @@ public class EntityHandlerHue implements OcPlatform.EntityHandler {
                 }
                 response.setErrorCode(200);
                 // representation.setUri("/a/huebulb");
-                representation.setValueString("name",
-                        Activator.myLight.m_name);
-                representation.setValueString("power",
-                        Activator.myLight.m_power);
-                representation.setValueInt("brightness",
-                        Activator.myLight.m_brightness);
-                representation.setValueInt("color",
-                        Activator.myLight.m_color);
+                try { 
+                    representation.setValue("name",
+                            Activator.myLight.m_name);
+                    representation.setValue("power",
+                            Activator.myLight.m_power);
+                    representation.setValue("brightness",
+                            Activator.myLight.m_brightness);
+                    representation.setValue("color",
+                            Activator.myLight.m_color);
+                } catch (OcException e) {
+                    // TODO Auto-generated catch block
+                    Log.e(TAG, e.getMessage());
+                }
                 response.setResourceRepresentation(representation);
                 try {
                     OcPlatform.sendResponse(response);
diff --git a/service/protocol-plugin/plugins/Android/plugin.wemo/.project b/service/protocol-plugin/plugins/Android/plugin.wemo/.project
new file mode 100644 (file)
index 0000000..e38bedf
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>plugin.wemo</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
index 42aa81e..4dbd3d0 100644 (file)
@@ -150,7 +150,7 @@ public class Activator extends Activity implements BundleActivator,
                                 .getWeMoDeviceByUDN(udn);
                         if ((listDevice != null) && (listDevice.isAvailable())) {
                             PlatformConfig cfg = new PlatformConfig(
-                                    this,
+                                    getBaseContext(),
                                     ServiceType.IN_PROC,
                                     ModeType.CLIENT_SERVER, "0.0.0.0", 0,
                                     QualityOfService.LOW);
@@ -163,7 +163,7 @@ public class Activator extends Activity implements BundleActivator,
                                         .registerResource(
                                                 "/a/wemo",
                                                 "device.smartplug",
-                                                "oc.mi.def",
+                                                OcPlatform.DEFAULT_INTERFACE,
                                                 entitycb,
                                                 EnumSet.of(ResourceProperty.DISCOVERABLE));
                             } catch (OcException e) {
index 559cc21..679bd7c 100644 (file)
@@ -23,6 +23,7 @@
 package oic.plugin.wemo;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 
 import org.iotivity.base.EntityHandlerResult;
 import org.iotivity.base.OcException;
@@ -87,19 +88,25 @@ public class EntityHandlerWemo implements OcPlatform.EntityHandler {
                             String type = wemoDevice.getType();
                             if (type.equals(WeMoDevice.SWITCH)) {
                                 String newState = "";
-                                if (resourcerequest
-                                        .getResourceRepresentation()
-                                        .getValueString("power")
-                                        .equals("on")) {
-                                    Activator.mySmartPlug.m_power = "on";
-                                    newState = WeMoDevice.WEMO_DEVICE_ON;
-                                } else if (resourcerequest
-                                        .getResourceRepresentation()
-                                        .getValueString("power")
-                                        .equals("off")) {
-                                    Activator.mySmartPlug.m_power = "off";
-                                    newState = WeMoDevice.WEMO_DEVICE_OFF;
-                                }
+                                try {
+                                    if (resourcerequest
+                                            .getResourceRepresentation()
+                                            .getValue("power")
+                                            .equals("on")) {
+                                        Activator.mySmartPlug.m_power = "on";
+                                        newState = WeMoDevice.WEMO_DEVICE_ON;
+                                    } else if (resourcerequest
+                                                .getResourceRepresentation()
+                                                .getValue("power")
+                                                .equals("off")) {
+                                            Activator.mySmartPlug.m_power = "off";
+                                            newState = WeMoDevice.WEMO_DEVICE_OFF;
+                                        }
+                                    } catch (OcException e) {
+                                        // TODO Auto-generated catch block
+                                        Log.e(TAG, e.getMessage());
+                                    }
+
                                 Activator.mWeMoSDKContext.setDeviceState(
                                         newState, wemoDevice.getUDN());
                             }
@@ -110,12 +117,18 @@ public class EntityHandlerWemo implements OcPlatform.EntityHandler {
                 }
                 response.setErrorCode(200);
                 // representation.setUri("/a/wemo");
-                representation.setValueString("name",
-                        Activator.mySmartPlug.m_name);
-                representation.setValueString("power",
-                        Activator.mySmartPlug.m_power);
-                representation.setValueInt("brightness", 0);
-                representation.setValueInt("color", 0);
+                try {
+                    representation.setValue("name",
+                            Activator.mySmartPlug.m_name);
+                    representation.setValue("power",
+                            Activator.mySmartPlug.m_power);
+                    representation.setValue("brightness", 0);
+                    representation.setValue("color", 0);
+                } catch (OcException e) {
+                    // TODO Auto-generated catch block
+                    Log.e(TAG, e.getMessage());
+                }
+                
                 response.setResourceRepresentation(representation);
                 try {
                     OcPlatform.sendResponse(response);
index 376fe96..ecce64e 100644 (file)
@@ -40,8 +40,6 @@ if target_os not in ['windows', 'winrt']:
     plugins_env.PrependUnique(CCFLAGS = ['-fPIC'])
     plugins_env.AppendUnique(LINKFLAGS = ['-fPIC'])
 
-#plugins_env.AppendUnique(LIBS=['libconnectivity-abstraction'])
-
     if target_os not in ['arduino', 'android']:
         plugins_env.AppendUnique(LIBS = ['pthread'])
 
@@ -60,8 +58,10 @@ plugins_env['LIBPREFIX'] = ''
 
 mqtt_fan_src = Glob('mqtt-fan/src/' + '*.cpp')
 fanserver = plugins_env.SharedLibrary('mqtt-fan/fanserver_mqtt_plugin', mqtt_fan_src)
+Command("mqtt-fan/plugin.xml","mqtt-fan/build/linux/plugin.xml", Copy("$TARGET", "$SOURCE"))
 
 mqtt_light_src = Glob('mqtt-light/src/' + '*.cpp')
 lightserver = plugins_env.SharedLibrary('mqtt-light/lightserver_mqtt_plugin', mqtt_light_src)
+Command("mqtt-light/plugin.xml","mqtt-light/build/linux/plugin.xml", Copy("$TARGET", "$SOURCE"))
 
 SConscript('mqtt-fan/lib/SConscript')
index fc2add8..103a29a 100644 (file)
@@ -25,5 +25,6 @@ mosquitto_src = env.Glob('*.c')
 
 mosquitto = mosquitto_env.StaticLibrary('mosquitto', mosquitto_src)
 mosquitto_env.InstallTarget(mosquitto, 'libmosquitto')
+mosquitto_env.UserInstallTargetLib(mosquitto, 'libmosquitto')
 
 SConscript('cpp/SConscript')
index 55e2333..f935f79 100644 (file)
@@ -22,3 +22,4 @@ mosquittopp_env.AppendUnique(LIBS = ['mosquitto', 'ssl', 'crypto'])
 ######################################################################
 mosquittopp = mosquittopp_env.SharedLibrary('mosquittopp', 'mosquittopp.cpp')
 mosquittopp_env.InstallTarget(mosquittopp, 'libmosquittopp')
+mosquittopp_env.UserInstallTargetLib(mosquittopp, 'libmosquittopp')
index 5c35aa1..c499321 100644 (file)
@@ -57,5 +57,8 @@ sample_env.AppendUnique(LIBS = ['pthread'])
 ######################################################################
 mqttclient = sample_env.Program('mqtt/mqttclient', 'mqtt/mqttclient.cpp')
 
+Command("mqtt/pluginmanager.xml","../../plugin-manager/src/pluginmanager.xml", Copy("$TARGET", "$SOURCE"))
+Command("mqtt/libpmimpl.so","../../../../libpmimpl.so", Copy("$TARGET", "$SOURCE"))
+
 Alias('mqttclient', mqttclient)
 env.AppendTarget('mqttclient')
index 065b2d4..67abc20 100644 (file)
@@ -20,7 +20,7 @@
 
 /// @file mqttclient.cpp
 
-/// @brief Samplecode which controls MQTT-fan plugin using Protocol Plugin Manager. 
+/// @brief Samplecode which controls MQTT-fan plugin using Protocol Plugin Manager.
 
 #include <string>
 #include <cstdlib>
@@ -394,8 +394,8 @@ int main(int argc, char *argv[])
         // makes it so that all boolean values are printed as 'true/false' in this stream
         std::cout.setf(std::ios::boolalpha);
         // Find all resources
-        requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.fan";
-        OCPlatform::findResource("", requestURI.str(), OC_ALL, &foundResourceFan);
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.fan";
+        OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResourceFan);
         std::cout << "Finding Resource... " << std::endl;
         while (true)
         {
index 9f8ba20..519f982 100644 (file)
                                 </option>
                                 <option id="gnu.cpp.link.option.libs.1981950125" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
                                     <listOptionValue builtIn="false" value="ppm"/>
+                                    <listOptionValue builtIn="false" value="uuid"/>
                                     <listOptionValue builtIn="false" value="oc"/>
                                     <listOptionValue builtIn="false" value="octbstack"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="connectivity_abstraction"/>
-                                    <listOptionValue builtIn="false" value="coap"/>
-                                    <listOptionValue builtIn="false" value="boost_system"/>
-                                    <listOptionValue builtIn="false" value="boost_thread"/>
                                 </option>
                                 <option id="sbi.gnu.cpp.linker.option.shared_flag.core.1600357455" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" value="true" valueType="boolean"/>
                                 <option id="gnu.cpp.link.option.other.1278390791" name="Other options (-Xlinker [option])" superClass="gnu.cpp.link.option.other"/>
                                     <listOptionValue builtIn="false" value="coap"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="oc_logger_core"/>
-                                    <listOptionValue builtIn="false" value="boost_system"/>
-                                    <listOptionValue builtIn="false" value="boost_thread"/>
                                 </option>
                                 <option id="sbi.gnu.cpp.linker.option.shared_flag.core.870017078" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" value="true" valueType="boolean"/>
                                 <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.204670616" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
index 54f9b03..5383695 100644 (file)
@@ -127,7 +127,8 @@ void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
         strcat(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
 
         if (observe_count() > 30)
@@ -147,7 +148,8 @@ void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
         sprintf(buf, "onObserve Response error:  = %d<br>", eCode);
         strcpy(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
         std::exit(-1);
     }
@@ -182,7 +184,8 @@ void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, co
             sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
             strcat(temp_string, buf);
             m_ThreadContext.log = temp_string;
-            ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+            ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                   &m_ThreadContext);
         }
 
@@ -200,7 +203,8 @@ void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, co
         sprintf(buf, "onPost Response error:  = %d<br>", eCode);
         strcpy(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
         std::exit(-1);
     }
@@ -235,7 +239,8 @@ void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, con
             sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
             strcat(temp_string, buf);
             m_ThreadContext.log = temp_string;
-            ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+            ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                   &m_ThreadContext);
         }
 
@@ -257,7 +262,8 @@ void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, con
         sprintf(buf, "onPost Response error:  = %d<br>", eCode);
         strcpy(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
         std::exit(-1);
     }
@@ -306,7 +312,8 @@ void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, cons
         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
         strcat(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
 
         putFanRepresentation(curFanResource);
@@ -317,7 +324,8 @@ void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, cons
         sprintf(buf, "onPut Response error:  = %d<br>", eCode);
         strcpy(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
         std::exit(-1);
     }
@@ -370,7 +378,8 @@ void onFanGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, c
         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
         strcat(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
 
         putFanRepresentation(curFanResource);
@@ -381,7 +390,8 @@ void onFanGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, c
         sprintf(buf, "onGET Response error:  = %d<br>", eCode);
         strcpy(temp_string, buf);
         m_ThreadContext.log = temp_string;
-        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+        ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                               &m_ThreadContext);
         std::exit(-1);
     }
@@ -434,7 +444,7 @@ void foundResourceFan(std::shared_ptr<OCResource> resource)
             // Get the resource types
             std::cout << "\tList of resource types: " << std::endl;
             strcat(temp_string, "List of resource types: <br>");
-            for (auto & resourceTypes : resource->getResourceTypes())
+            for (auto &resourceTypes : resource->getResourceTypes())
             {
                 std::cout << "\t\t" << resourceTypes << std::endl;
                 sprintf(buf, "%s<br>", resourceTypes.c_str());
@@ -443,7 +453,7 @@ void foundResourceFan(std::shared_ptr<OCResource> resource)
 
             // Get the resource interfaces
             std::cout << "\tList of resource interfaces: " << std::endl;
-            for (auto & resourceInterfaces : resource->getResourceInterfaces())
+            for (auto &resourceInterfaces : resource->getResourceInterfaces())
             {
                 std::cout << "\t\t" << resourceInterfaces << std::endl;
                 sprintf(buf, "%s<br>", resourceInterfaces.c_str());
@@ -458,7 +468,8 @@ void foundResourceFan(std::shared_ptr<OCResource> resource)
                 putFanRepresentation(curFanResource);
             }
             m_ThreadContext.log = temp_string;
-            ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+            ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                   &m_ThreadContext);
         }
         else
@@ -467,7 +478,8 @@ void foundResourceFan(std::shared_ptr<OCResource> resource)
             std::cout << "Resource is invalid" << std::endl;
             strcpy(temp_string, "Resource is invalid");
             m_ThreadContext.log = temp_string;
-            ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+            ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                   &m_ThreadContext);
         }
 
@@ -521,7 +533,8 @@ send_msg_clicked_cb(void *data , Evas_Object *obj , void *event_info)
                 sprintf(buf, "value ID = %s<br>", user_plugin[i].getID().c_str());
                 strcat(temp_string, buf);
                 m_ThreadContext.log = temp_string;
-                ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+                dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+                ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                       &m_ThreadContext);
                 std::cout << "value Name = " << user_plugin[i].getName() << std::endl;
                 std::cout << "value ID = " << user_plugin[i].getID() << std::endl;
@@ -532,7 +545,8 @@ send_msg_clicked_cb(void *data , Evas_Object *obj , void *event_info)
             strcpy(temp_string, "start fan Plugin<br>");
             strcat(temp_string, "fan Plugin is getting started. Please wait...<br>");
             m_ThreadContext.log = temp_string;
-            ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", m_ThreadContext.log);
+            ecore_main_loop_thread_safe_call_sync((void *( *)(void *))updateCallbackLog,
                                                   &m_ThreadContext);
             m_pm->startPlugins("ResourceType", "oic.fan");
             sleep(2);
@@ -542,7 +556,7 @@ send_msg_clicked_cb(void *data , Evas_Object *obj , void *event_info)
 
             // Find fan resources
             std::ostringstream requestURI;
-            requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.fan";
+            requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.fan";
             OCPlatform::findResource("", requestURI.str(), OC_ALL, &foundResourceFan);
             std::cout << "Finding Resource... " << std::endl;
         }
diff --git a/service/resource-encapsulation/README b/service/resource-encapsulation/README
new file mode 100644 (file)
index 0000000..b482100
--- /dev/null
@@ -0,0 +1,14 @@
+== Brief Guide to Service Basis 
+
+resource encapsulation provides common functions such as resource broker, cache, resource container.
+
+1. resourceBroker 
+resourceBroker checks and monitors the status of resources. 
+This module notifies the change of reachability of selected resource to users. 
+
+2. resourceCache
+resourceCache provides the up-to-date "DATA" of remote resource to users.
+It tracks the most recent value of the selected resource and notifies to users according to called API
+
+3. resourceContainer
+Need to be updated.
diff --git a/service/resource-encapsulation/SConscript b/service/resource-encapsulation/SConscript
new file mode 100644 (file)
index 0000000..6c32a81
--- /dev/null
@@ -0,0 +1,107 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+######################################################################
+#  Resource-encapsulation build script
+######################################################################
+import platform
+Import('env')
+
+SConscript('src/common/SConscript')
+SConscript('src/serverBuilder/SConscript')
+SConscript('src/resourceContainer/SConscript')
+
+######################################################################
+#building Resource client, resourceBroker and resourceCache
+######################################################################
+
+if env.get('RELEASE'):
+    env.AppendUnique(CCFLAGS = ['-Os'])
+    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+resourceClient_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+resourceClient_env.AppendUnique(CPPPATH = [
+    'include',
+    'src/common/primitiveResource/include',
+    'src/common/expiryTimer/include',
+    'src/common/utils/include',
+    'src/resourceBroker/include',
+    'src/resourceCache/include'
+])
+
+resourceClient_env.PrependUnique(LIBS = ['oc', 'rcs_common', 'octbstack', 'gnustl_shared','oc_logger', 'compatibility', 'log'])
+
+if target_os not in ['windows', 'winrt']:
+    resourceClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+if target_os == 'linux':
+   resourceClient_env.AppendUnique(LIBS = ['pthread'])
+   
+if target_os == 'android':
+    resourceClient_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    resourceClient_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+
+resourceClient_env.AppendUnique(LIBS = ['dl'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+BROKER_SRC_DIR = 'src/resourceBroker/src/'
+CACHE_SRC_DIR = 'src/resourceCache/src/'
+RESOURCECLIENT_DIR = 'src/resourceClient/'
+
+client_src = [
+        BROKER_SRC_DIR + 'DeviceAssociation.cpp',
+        BROKER_SRC_DIR + 'DevicePresence.cpp',
+        BROKER_SRC_DIR + 'ResourcePresence.cpp',
+        BROKER_SRC_DIR + 'ResourceBroker.cpp',
+        CACHE_SRC_DIR + 'DataCache.cpp',
+        CACHE_SRC_DIR + 'ResourceCacheManager.cpp',
+        RESOURCECLIENT_DIR + 'RCSDiscoveryManager.cpp',
+        RESOURCECLIENT_DIR + 'RCSRemoteResourceObject.cpp'
+               ]
+ResourceClientsdk = resourceClient_env.StaticLibrary('rcs_client', client_src)
+resourceClient_env.InstallTarget(ResourceClientsdk , 'librcs_client')
+
+######################################################################
+# Build Sample App: SampleResourceClient & SampleResourceServer
+######################################################################
+SConscript('examples/SConscript')
+
+######################################################################
+# Build UnitTests Resource Client , resourceCache and resourceBroker
+################################################ ######################
+SConscript('unittests/SConscript')
+SConscript('src/resourceCache/unittests/SConscript')
+SConscript('src/resourceBroker/unittest/SConscript')
+
diff --git a/service/resource-encapsulation/examples/SConscript b/service/resource-encapsulation/examples/SConscript
new file mode 100644 (file)
index 0000000..c023f3f
--- /dev/null
@@ -0,0 +1,8 @@
+##
+# Examples build script
+##
+Import('env')
+
+target_os = env.get('TARGET_OS')
+if target_os == 'linux':
+       SConscript('linux/SConscript')
diff --git a/service/resource-encapsulation/examples/linux/SConscript b/service/resource-encapsulation/examples/linux/SConscript
new file mode 100644 (file)
index 0000000..0031212
--- /dev/null
@@ -0,0 +1,70 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# linux sample app  build script (Sample Client & Sample Server)
+##
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+ResourceClient_env = lib_env.Clone()
+ResourceServer_env = lib_env.Clone()
+
+######################################################################
+# ##### Resource Client #####
+######################################################################
+
+ResourceClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+ResourceClient_env.AppendUnique(LIBS = ['rcs_client', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
+ResourceClient_env.AppendUnique(CPPPATH = ['../../include'])
+ResourceClient_env.AppendUnique(CPPPATH = ['../../src/resourceBroker/include'])
+ResourceClient_env.AppendUnique(CPPPATH = ['../../src/resourceCache/include'])
+ResourceClient_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
+
+######################################################################
+# ##### Resource Server #####
+######################################################################
+
+ResourceServer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+ResourceServer_env.AppendUnique(LIBS = ['rcs_server', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
+ResourceServer_env.AppendUnique(CPPPATH = ['../../include'])
+ResourceServer_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
+ResourceServer_env.AppendUnique(CPPPATH = ['../../src/serverBuilder/include'])
+
+if env.get('SECURED') == '1':
+    ResourceClient_env.AppendUnique(LIBS = ['tinydtls'])
+    ResourceServer_env.AppendUnique(LIBS = ['tinydtls'])
+       
+if 'rt' in ResourceClient_env.get('LIBS'):
+    ResourceClient_env.Append(LIBS = ['rt'])
+if 'rt' in ResourceServer_env.get('LIBS'):
+    ResourceServer_env.Append(LIBS = ['rt'])
+
+####################################################################
+# Source files and Targets
+####################################################################
+sampleResourceClient = ResourceClient_env.Program('sampleResourceClient', 'SampleResourceClient.cpp')
+sampleResourceServer = ResourceServer_env.Program('sampleResourceServer', 'SampleResourceServer.cpp')
+
+ResourceClient_env.InstallTarget(sampleResourceClient, 'sampleResourceClient')
+ResourceServer_env.InstallTarget(sampleResourceServer, 'sampleResourceServer')
diff --git a/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp b/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp
new file mode 100755 (executable)
index 0000000..316042e
--- /dev/null
@@ -0,0 +1,432 @@
+//******************************************************************
+//
+// 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 "mutex"
+#include "condition_variable"
+
+#include "RCSDiscoveryManager.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSResourceAttributes.h"
+#include "RCSAddress.h"
+
+#include "OCPlatform.h"
+
+using namespace OC;
+using namespace OIC::Service;
+
+constexpr int CORRECT_INPUT = 1;
+constexpr int INCORRECT_INPUT = 2;
+constexpr int QUIT_INPUT = 3;
+
+std::shared_ptr<RCSRemoteResourceObject>  resource;
+
+const std::string defaultKey = "Temperature";
+const std::string resourceType = "?rt=core.TemperatureSensor";
+const std::string targetUri = OC_RSRVD_WELL_KNOWN_URI + resourceType;
+
+std::mutex mtx;
+std::condition_variable cond;
+
+void startMonitoring();
+void startMonitoring();
+void stopMonitoring();
+void getAttributeFromRemoteServer();
+void setAttributeToRemoteServer();
+void startCachingWithoutCallback();
+void startCachingWithCallback();
+void getResourceCacheState();
+void getCachedAttributes();
+void getCachedAttribute();
+void stopCaching();
+
+enum Menu
+{
+    START_MONITORING = 1,
+    STOP_MONITORING,
+    GET_ATTRIBUTE,
+    SET_ATTRIBUTE,
+    START_CACHING_NO_UPDATE,
+    START_CACHING_UPDATE,
+    GET_RESOURCE_CACHE_STATE,
+    GET_CACHED_ATTRIBUTES,
+    GET_CACHED_ATTRIBUTE,
+    STOP_CACHING,
+    QUIT,
+    END_OF_MENU
+};
+
+typedef void(*ClientMenuHandler)();
+typedef int ReturnValue;
+
+struct ClientMenu
+{
+    Menu m_menu;
+    ClientMenuHandler m_handler;
+    ReturnValue m_result;
+};
+
+ClientMenu clientMenu[] = {
+        {Menu::START_MONITORING, startMonitoring, CORRECT_INPUT},
+        {Menu::STOP_MONITORING, stopMonitoring, CORRECT_INPUT},
+        {Menu::GET_ATTRIBUTE, getAttributeFromRemoteServer, CORRECT_INPUT},
+        {Menu::SET_ATTRIBUTE, setAttributeToRemoteServer, CORRECT_INPUT},
+        {Menu::START_CACHING_NO_UPDATE, startCachingWithoutCallback, CORRECT_INPUT},
+        {Menu::START_CACHING_UPDATE, startCachingWithCallback, CORRECT_INPUT},
+        {Menu::GET_RESOURCE_CACHE_STATE, getResourceCacheState, CORRECT_INPUT},
+        {Menu::GET_CACHED_ATTRIBUTES, getCachedAttributes, CORRECT_INPUT},
+        {Menu::GET_CACHED_ATTRIBUTE, getCachedAttribute, CORRECT_INPUT},
+        {Menu::STOP_CACHING, stopCaching, CORRECT_INPUT},
+        {Menu::QUIT, [](){}, QUIT_INPUT},
+        {Menu::END_OF_MENU, nullptr, INCORRECT_INPUT}
+    };
+
+void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
+{
+    std::cout << "onResourceDiscovered callback" << std::endl;
+
+    std::string resourceURI = foundResource->getUri();
+    std::string hostAddress = foundResource->getAddress();
+
+    std::cout << "\t\tResource URI : " << resourceURI << std::endl;
+    std::cout << "\t\tResource Host : " << hostAddress << std::endl;
+
+    resource = foundResource;
+
+    cond.notify_all();
+}
+
+void onResourceStateChanged(const ResourceState& resourceState)
+{
+    std::cout << "onResourceStateChanged callback" << std::endl;
+
+    switch(resourceState)
+    {
+        case ResourceState::NONE:
+            std::cout << "\tState changed to : NOT_MONITORING" << std::endl;
+            break;
+
+        case ResourceState::ALIVE:
+            std::cout << "\tState changed to : ALIVE" << std::endl;
+            break;
+
+        case ResourceState::REQUESTED:
+            std::cout << "\tState changed to : REQUESTED" << std::endl;
+            break;
+
+        case ResourceState::LOST_SIGNAL:
+            std::cout << "\tState changed to : LOST_SIGNAL" << std::endl;
+            resource = nullptr;
+            break;
+
+        case ResourceState::DESTROYED:
+            std::cout << "\tState changed to : DESTROYED" << std::endl;
+            break;
+    }
+}
+
+void onCacheUpdated(const RCSResourceAttributes& attributes)
+{
+    std::cout << "onCacheUpdated callback" << std::endl;
+
+    if (attributes.empty())
+    {
+        std::cout << "\tAttribute is Empty" << std::endl;
+        return;
+    }
+
+    for(const auto& attr : attributes)
+    {
+        std::cout << "\tkey : " << attr.key() << std::endl
+                  << "\tvalue : " << attr.value().toString() << std::endl;
+    }
+}
+
+void onRemoteAttributesReceivedCallback(const RCSResourceAttributes& attributes)
+{
+    std::cout << "onRemoteAttributesReceivedCallback callback" << std::endl;
+
+    if (attributes.empty())
+    {
+        std::cout << "\tAttribute is Empty" << std::endl;
+        return;
+    }
+
+    for(const auto& attr : attributes)
+    {
+        std::cout << "\tkey : " << attr.key() << std::endl
+                  << "\tvalue : " << attr.value().toString() << std::endl;
+    }
+}
+
+void displayMenu()
+{
+    std::cout << std::endl;
+    std::cout << "1 :: Start Monitoring" << std::endl;
+    std::cout << "2 :: Stop Monitoring" << std::endl;
+    std::cout << "3 :: Get Attribute" << std::endl;
+    std::cout << "4 :: Set Attribute" << std::endl;
+    std::cout << "5 :: Start Caching (No update to Application)" << std::endl;
+    std::cout << "6 :: Start Caching (Update the application when data change)"<< std::endl;
+    std::cout << "7 :: Get Resource cache State" << std::endl;
+    std::cout << "8 :: Get Cached Attributes" << std::endl;
+    std::cout << "9 :: Get Cached Attribute"  << std::endl;
+    std::cout << "10 :: Stop Caching" << std::endl;
+    std::cout << "11 :: Stop Server" << std::endl;
+}
+
+int processUserInput()
+{
+    int userInput;
+    std::cin >> userInput;
+    if (std::cin.fail())
+    {
+        std::cin.clear();
+        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+        return -1;
+    }
+    return userInput;
+}
+
+void startMonitoring()
+{
+    if (!resource->isMonitoring())
+    {
+        resource->startMonitoring(&onResourceStateChanged);
+        std::cout << "\tHosting Started..." << std::endl;
+    }
+    else
+    {
+        std::cout << "\tAlready Started..." << std::endl;
+    }
+}
+
+void stopMonitoring()
+{
+    if (resource->isMonitoring())
+    {
+        resource->stopMonitoring();
+        std::cout << "\tHosting stopped..." << std::endl;
+    }
+    else
+    {
+       std::cout << "\tHosting not started..." << std::endl;
+    }
+}
+
+void getAttributeFromRemoteServer()
+{
+    resource->getRemoteAttributes(&onRemoteAttributesReceivedCallback);
+}
+
+void setAttributeToRemoteServer()
+{
+    std::string key;
+    int value;
+
+    RCSResourceAttributes setAttribute;
+
+    std::cout << "\tEnter the Key you want to set : ";
+    std::cin >> key;
+    std::cout << "\tEnter the value you want to set :";
+    std::cin >> value;
+
+    setAttribute[key] = value;
+    resource->setRemoteAttributes(setAttribute,
+                                  &onRemoteAttributesReceivedCallback);
+}
+
+void startCaching(std::function <void (const RCSResourceAttributes&)>cb)
+{
+    if (!resource->isCaching())
+    {
+        if(cb) resource->startCaching(&onCacheUpdated);
+
+        else resource->startCaching();
+
+        std::cout << "\tCaching Started..." << std::endl;
+    }
+    else
+    {
+        std::cout << "\tAlready Started Caching..." << std::endl;
+    }
+}
+
+void startCachingWithoutCallback()
+{
+    startCaching(nullptr);
+}
+
+void startCachingWithCallback()
+{
+    startCaching(onCacheUpdated);
+}
+
+void getResourceCacheState()
+{
+    switch(resource->getCacheState())
+    {
+        case CacheState::READY:
+            std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::READY" << std::endl;
+            break;
+
+        case CacheState::UNREADY:
+            std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::UNREADY" << std::endl;
+            break;
+
+        case CacheState::LOST_SIGNAL:
+            std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::LOST_SIGNAL" << std::endl;
+            break;
+
+        case CacheState::NONE:
+            std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::NONE" << std::endl;
+            break;
+
+        default:
+            break;
+    }
+}
+
+void getCachedAttributes()
+{
+    try
+    {
+        if (resource->getCachedAttributes().empty())
+        {
+            std::cout << "\tReceived cached attribute is empty" << std::endl;
+        }
+        else
+        {
+            for(const auto& attr : resource->getCachedAttributes())
+            {
+                std::cout << "\tkey : " << attr.key() << std::endl
+                          << "\tvalue : " << attr.value().toString() << std::endl;
+            }
+        }
+    }
+    catch (const BadRequestException& e)
+    {
+        std::cout << "Exception in getCachedAttributes : " << e.what() << std::endl;
+    }
+}
+
+void getCachedAttribute()
+{
+    try
+    {
+        std::cout << "\tkey : " << defaultKey << std::endl
+                  << "\tvalue : " << resource->getCachedAttribute(defaultKey).get< int >()
+                  << std::endl;
+    }
+    catch (const BadRequestException& e)
+    {
+        std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
+    }
+    catch (const BadGetException& e)
+    {
+        std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
+    }
+}
+
+void stopCaching()
+{
+    if(resource->isCaching())
+    {
+        resource->stopCaching();
+        std::cout << "\tCaching stopped..." << std::endl;
+    }
+    else
+    {
+        std::cout << "\tCaching not started..." << std::endl;
+    }
+}
+
+int selectClientMenu(int selectedMenu)
+{
+    for(int i = 0; clientMenu[i].m_menu != Menu::END_OF_MENU; i++)
+    {
+        if(clientMenu[i].m_menu == selectedMenu)
+        {
+            clientMenu[i].m_handler();
+            return clientMenu[i].m_result;
+        }
+    }
+
+    std::cout << "Invalid input, please try again" << std::endl;
+
+    return INCORRECT_INPUT;
+}
+
+void process()
+{
+    while(true)
+    {
+        displayMenu();
+
+        if(selectClientMenu(processUserInput()) == QUIT_INPUT) break;
+    }
+}
+
+void platFormConfigure()
+{
+    PlatformConfig config
+    {
+        OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
+    };
+    OCPlatform::Configure(config);
+}
+
+bool discoverResource()
+{
+    std::cout << "Wait 2 seconds until discovered." << std::endl;
+
+    RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(), targetUri,
+                                                         &onResourceDiscovered);
+
+    std::unique_lock<std::mutex> lck(mtx);
+    cond.wait_for(lck,std::chrono::seconds(2));
+
+    return resource != nullptr;
+}
+
+int main()
+{
+    platFormConfigure();
+
+    if (!discoverResource())
+    {
+        std::cout << "Can't discovered Server... Exiting the Client." << std::endl;
+        return -1;
+    }
+
+    try
+    {
+        process();
+    }
+    catch (const std::exception& e)
+    {
+        std::cout << "main exception : " << e.what() << std::endl;
+    }
+
+    std::cout << "Stopping the Client" << std::endl;
+
+    return 0;
+}
+
diff --git a/service/resource-encapsulation/examples/linux/SampleResourceServer.cpp b/service/resource-encapsulation/examples/linux/SampleResourceServer.cpp
new file mode 100755 (executable)
index 0000000..f7c946c
--- /dev/null
@@ -0,0 +1,250 @@
+/******************************************************************
+ *
+ * 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 "PrimitiveResource.h"
+#include "RCSResourceObject.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace OC::OCPlatform;
+using namespace OIC::Service;
+
+constexpr int DEFALUT_VALUE = 0;
+
+constexpr int DEFALUT_SERVER = 1;
+constexpr int CUSTOM_SERVER = 2;
+constexpr int STOP = 3;
+
+constexpr int INCREASE_TEMPERATURE = 1;
+constexpr int DECREASE_TEMPERATURE = 2;
+constexpr int STOP_SENSOR = 3;
+
+constexpr int CORRECT_INPUT = 1;
+constexpr int INCORRECT_INPUT = 2;
+constexpr int QUIT = 3;
+
+std::string resourceUri = "/a/TempSensor";
+std::string resourceType = "core.TemperatureSensor";
+std::string resourceInterface = "oic.if.";
+std::string attributeKey = "Temperature";
+
+RCSResourceObject::Ptr server;
+
+enum class Control{
+    INCREASE,
+    DECREASE
+};
+
+void displayMenu()
+{
+    std::cout << "====================================================================="
+              << std::endl;
+    std::cout << "   1 - Creation of Resource [Auto control for requests]" << std::endl;
+    std::cout << "   2 - Creation of Resource [Developer control for Get and Set requests]"
+              << std::endl;
+    std::cout << "   3 - Quit" << std::endl;
+    std::cout << "====================================================================="
+              << std::endl;
+}
+
+void displayControlTemperatureMenu()
+{
+    std::cout << "========================================================" << std::endl;
+    std::cout << "1. Increase Temperature by 10 degree" << std::endl;
+    std::cout << "2. Decrease Temperature by 10 degree" << std::endl;
+    std::cout << "3. Stop the Sensor" << std::endl;
+    std::cout << "========================================================" << std::endl;
+}
+
+void printAttribute(const RCSResourceAttributes& attrs)
+{
+    for(const auto& attr : attrs)
+    {
+        std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
+                  << attr.value().toString() << std::endl;
+    }
+}
+
+//hander for get request (if developer choose second option for resource Creation)
+RCSGetResponse requestHandlerForGet(const RCSRequest& request,
+        RCSResourceAttributes& attrs)
+{
+    std::cout << "Recieved a Get request from Client" << std::endl;
+
+    RCSResourceObject::LockGuard lock(*server);
+    RCSResourceAttributes attributes = server->getAttributes();
+
+    std::cout << "\nSending response to Client : " << std::endl;
+    printAttribute(attributes);
+
+    return RCSGetResponse::defaultAction();
+}
+
+//hander for set request (if developer choose second option for resource Creation)
+RCSSetResponse requestHandlerForSet(const RCSRequest& request,
+        RCSResourceAttributes& attrs)
+{
+    std::cout << "Recieved a Set request from Client" << std::endl;
+
+    std::cout << "\n\nSending response to Client : " << std::endl;
+    RCSResourceObject::LockGuard lock(*server);
+    printAttribute(attrs);
+    return RCSSetResponse::defaultAction();
+}
+
+void createResource()
+{
+    server = RCSResourceObject::Builder(resourceUri, resourceType,
+                             resourceInterface).setDiscoverable(true).setObservable(true).build();
+}
+
+void initServer()
+{
+    try
+    {
+        createResource();
+    }
+    catch (const PlatformException& e)
+    {
+        std::cout << "Exception in initServer : " << e.what() << std::endl;
+    }
+
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
+    server->setAttribute(attributeKey, DEFALUT_VALUE);
+}
+
+void changeTemperature(Control control)
+{
+    RCSResourceObject::LockGuard lock(server);
+    if(Control::INCREASE == control)
+    {
+        server->getAttributes()[attributeKey] =
+                server->getAttribute<int>(attributeKey) + 10;
+        std::cout << "\nTemperature increased by 10 degree" << std::endl;
+    }
+    else if(Control::DECREASE == control)
+    {
+        server->getAttributes()[attributeKey] =
+                        server->getAttribute<int>(attributeKey) - 10;
+        std::cout << "\nTemperature Decreased by 10 degree" << std::endl;
+    }
+    std::cout << "\nCurrent Temperature : "
+            << server->getAttributeValue(attributeKey).get<int>() << std::endl;
+}
+
+int processUserInput()
+{
+    int userInput;
+    std::cin >> userInput;
+    if (std::cin.fail())
+    {
+        std::cin.clear();
+        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+        return -1;
+    }
+    return userInput;
+}
+
+int selectServerMenu()
+{
+    switch (processUserInput())
+    {
+        case DEFALUT_SERVER: // Creation of Resource & Auto control for all requests from Client.
+            initServer();
+            return CORRECT_INPUT;
+
+        case CUSTOM_SERVER:
+            // Creation of Resource & setting get and set handler for handling get and
+            // set request from client in application.
+            initServer();
+
+            server->setGetRequestHandler(requestHandlerForGet);
+            server->setSetRequestHandler(requestHandlerForSet);
+            return CORRECT_INPUT;
+        case STOP :
+            return QUIT;
+
+        default :
+            std::cout << "Invalid input, please try again" << std::endl;
+            return INCORRECT_INPUT;
+    }
+}
+
+int selectControlTemperatureMenu()
+{
+   switch (processUserInput())
+   {
+       case INCREASE_TEMPERATURE:
+           changeTemperature(Control::INCREASE);
+           return CORRECT_INPUT;
+
+       case DECREASE_TEMPERATURE:
+           changeTemperature(Control::DECREASE);
+           return CORRECT_INPUT;
+
+       case STOP_SENSOR:
+           return QUIT;
+
+       default:
+           std::cout << "Invalid input. Please try again." << std::endl;
+           return INCORRECT_INPUT;
+   }
+}
+
+void process()
+{
+    while(true)
+    {
+        displayMenu();
+
+        int ret = selectServerMenu();
+
+        if(ret == QUIT) return;
+        if(ret == CORRECT_INPUT) break;
+    }
+
+    while(true)
+    {
+        displayControlTemperatureMenu();
+
+        if (selectControlTemperatureMenu() == QUIT) return;
+    }
+}
+
+int main(void)
+{
+    startPresence(3);
+
+    try
+    {
+        process();
+        server = NULL;
+    }
+    catch (const std::exception& e)
+    {
+        std::cout << "main exception  : " << e.what() << std::endl;
+    }
+
+    std::cout << "Stopping the Server" << std::endl;
+}
+
+
diff --git a/service/resource-encapsulation/include/RCSAddress.h b/service/resource-encapsulation/include/RCSAddress.h
new file mode 100644 (file)
index 0000000..7a571f4
--- /dev/null
@@ -0,0 +1,51 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OIC_SERVICE_RCSADDRESS_H
+#define OIC_SERVICE_RCSADDRESS_H
+
+#include <string>
+#include <memory>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSAddressDetail;
+
+        class RCSAddress
+        {
+        public:
+            static RCSAddress multicast();
+            static RCSAddress unicast(const std::string& address);
+            static RCSAddress unicast(std::string&& address);
+
+        private:
+            RCSAddress(const std::shared_ptr< RCSAddressDetail >&);
+
+        private:
+            std::shared_ptr< RCSAddressDetail > m_detail;
+
+            friend class RCSAddressDetail;
+        };
+    }
+}
+
+#endif // OIC_SERVICE_RCSADDRESS_H
diff --git a/service/resource-encapsulation/include/RCSBundleInfo.h b/service/resource-encapsulation/include/RCSBundleInfo.h
new file mode 100644 (file)
index 0000000..9a45524
--- /dev/null
@@ -0,0 +1,141 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains RCSBundleInfo class, which provides APIs related to Bundle information.
+ */
+
+#ifndef BUNDLEINFO_H_
+#define BUNDLEINFO_H_
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class  RCSBundleInfo
+        * @brief   This class provides APIs for creating, getting and setting the Bundle Information
+        *
+        */
+        class RCSBundleInfo
+        {
+            public:
+                RCSBundleInfo();
+                virtual ~RCSBundleInfo();
+
+                /**
+                * API for setting the Id of the bundle
+                *
+                * @param name - Id of the bundle in string form
+                *
+                */
+                virtual void setID(const std::string &name) = 0;
+
+                /**
+                * API for getting the Id of the bundle
+                *
+                * @return string - Id of the bundle
+                *
+                */
+                virtual const std::string &getID() = 0;
+
+                /**
+                * API for setting the path of the bundle
+                *
+                * @param path - path of the bundle in string form
+                *
+                */
+                virtual void setPath(const std::string &path) = 0;
+
+                /**
+                * API for getting the path of the bundle
+                *
+                * @return path - path of the bundle
+                *
+                */
+                virtual const std::string &getPath() = 0;
+
+                /**
+                * API for setting the Activator name for the bundle
+                *
+                * @param activator - Activator name in string form
+                *
+                */
+                virtual void setActivatorName(const std::string &activator) = 0;
+
+                /**
+                * API for setting the Activator name for the bundle
+                *
+                * @return string - Name of the activator
+                *
+                */
+                virtual const std::string &getActivatorName() = 0;
+
+                /**
+                * API for setting the library path for the bundle
+                *
+                * @param libpath - Library path in string form
+                *
+                */
+                virtual void setLibraryPath(const std::string &libpath) = 0;
+
+                /**
+                * API for getting the library path for the bundle
+                *
+                * @return string - Library path  in string form
+                *
+                */
+                virtual const std::string& getLibraryPath() = 0;
+
+                /**
+                * API for setting the version of the bundle
+                *
+                * @param version - version of the bundle in string form
+                *
+                */
+                virtual void setVersion(const std::string &version) = 0;
+
+                /**
+                * API for getting the version of the bundle
+                *
+                * @return string - version of the bundle
+                *
+                */
+                virtual const std::string &getVersion() = 0;
+
+                /**
+                 * API for creating new bundle information
+                 *
+                 * @return  RCSBundleInfo - RCSBundleInfo pointer.
+                 *
+                 */
+                static RCSBundleInfo *build();
+            protected:
+                std::string m_ID, m_path, m_version;
+        };
+    }
+}
+
+#endif /* BUNDLEINFO_H_ */
diff --git a/service/resource-encapsulation/include/RCSDiscoveryManager.h b/service/resource-encapsulation/include/RCSDiscoveryManager.h
new file mode 100644 (file)
index 0000000..53ad2b1
--- /dev/null
@@ -0,0 +1,89 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the RCSDiscoveryManager class which provide API to discover the Resource in the network
+ *
+ */
+
+#ifndef RCSDISCOVERYMANAGER_H
+#define RCSDISCOVERYMANAGER_H
+
+#include <memory>
+#include <functional>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class RCSRemoteResourceObject;
+        class RCSAddress;
+
+        /**
+         * This class contains the resource discovery method.
+         *
+         * @see RCSRemoteResourceObject
+         */
+        class RCSDiscoveryManager
+        {
+        public:
+
+            /**
+             * Typedef for callback of discoverResource API
+             *
+             * @see discoverResource
+             */
+            typedef std::function< void(std::shared_ptr< RCSRemoteResourceObject >) >
+                ResourceDiscoveredCallback;
+
+            /**
+             * Returns RCSDiscoveryManager instance.
+             *
+             */
+            static RCSDiscoveryManager* getInstance();
+
+            /**
+             * API for discovering the resource of Interest.
+             *
+             * @param address A RCSAddress object
+             * @param resourceURI The uri of resource to be searched
+             * @param cb A callback to obtain discovered resource
+             *
+             * @throws InvalidParameterException If cb is empty.
+             *
+             * @note The callback will be invoked in an internal thread.
+             *
+             * @see RCSAddress
+             *
+             */
+            void discoverResource(const RCSAddress& address, const std::string& resourceURI,
+                    ResourceDiscoveredCallback cb);
+
+        private:
+            RCSDiscoveryManager() = default;
+            ~RCSDiscoveryManager() = default;
+
+        };
+    }
+}
+#endif // RCSDISCOVERYMANAGER_H
diff --git a/service/resource-encapsulation/include/RCSException.h b/service/resource-encapsulation/include/RCSException.h
new file mode 100644 (file)
index 0000000..256ba59
--- /dev/null
@@ -0,0 +1,150 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file defines a class to handle exception thrown for resource encapsulation.
+ */
+
+#ifndef RES_ENCAPSULATION_RCSEXCEPTION_H
+#define RES_ENCAPSULATION_RCSEXCEPTION_H
+
+#include <string>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+         * The base exception class for resource encapsulation.
+         *
+         */
+        class RCSException: public std::exception
+        {
+        public:
+
+            /**
+             * Constructs an exception with an empty description.
+             */
+            RCSException();
+
+            /**
+             * Constructs an exception with a description.
+             *
+             * @param what The description for the error.
+             */
+            explicit RCSException(const std::string &what);
+
+            /**
+             * @overload
+             */
+            explicit RCSException(std::string &&what);
+
+            virtual ~RCSException() noexcept;
+
+            /**
+             * Returns the exception description.
+             *
+             */
+            virtual const char *what() const noexcept;
+
+        private:
+            /**
+             *  Exception description
+             */
+            const std::string m_what;
+        };
+
+        /**
+         * Thrown when OC layer returns an error.
+         *
+         */
+        class PlatformException: public RCSException
+        {
+        public:
+            explicit PlatformException(OCStackResult reason);
+
+            /**
+             * Returns the reason.
+             *
+             */
+            OCStackResult getReasonCode() const;
+
+            /**
+             * Returns the reason description.
+             *
+             */
+            std::string getReason() const;
+
+        private:
+            OCStackResult m_reason;
+        };
+
+        /**
+         * Thrown when a request is not acceptable.
+         *
+         */
+        class BadRequestException: public RCSException
+        {
+        public:
+            explicit BadRequestException(const std::string& what);
+            explicit BadRequestException(std::string&& what);
+        };
+
+        /**
+         * Thrown when a parameter is not valid.
+         *
+         */
+        class InvalidParameterException: public RCSException
+        {
+        public:
+            explicit InvalidParameterException(const std::string& what);
+            explicit InvalidParameterException(std::string&& what);
+        };
+
+        /**
+         * Thrown when getting value with wrong template parameter.
+         */
+        class BadGetException: public RCSException
+        {
+        public:
+            explicit BadGetException(const std::string& what);
+            explicit BadGetException(std::string&& what);
+        };
+
+        /**
+         * Thrown when a key is invalid.
+         *
+         */
+        class InvalidKeyException: public RCSException
+        {
+        public:
+            explicit InvalidKeyException(const std::string& what);
+            explicit InvalidKeyException(std::string&& what);
+        };
+
+    }
+}
+
+#endif // RES_ENCAPSULATION_RCSEXCEPTION_H
diff --git a/service/resource-encapsulation/include/RCSRemoteResourceObject.h b/service/resource-encapsulation/include/RCSRemoteResourceObject.h
new file mode 100644 (file)
index 0000000..0503488
--- /dev/null
@@ -0,0 +1,350 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the Resource Client APIs provided to the developers.
+ */
+
+#ifndef RCSREMOTERESOURCEOBJECT_H
+#define RCSREMOTERESOURCEOBJECT_H
+
+#include <vector>
+
+#include "RCSResourceAttributes.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+         * The states of caching.
+         *
+         * @see startCaching
+         * @see getCacheState
+         */
+        enum class CacheState
+        {
+            NONE, /**< Caching is not started.*/
+            UNREADY, /**< Caching is started, but the data is not ready yet.
+                          This is the default state after startCaching. */
+            READY, /**< The data is ready.*/
+            LOST_SIGNAL, /**< Failed to reach the resource. */
+        };
+
+        /**
+         * The states of monitoring.
+         *
+         * @see startMonitoring
+         * @see getState
+         */
+        enum class ResourceState
+        {
+            NONE, /**< Monitoring is not started.*/
+            REQUESTED, /**< Monitoring is started and checking state is in progress.
+                            This is the default state after startMonitoring. */
+            ALIVE, /**< The resource is alive. */
+            LOST_SIGNAL, /**< Failed to reach the resource. */
+            DESTROYED /**< The resource is deleted. */
+        };
+
+        class PrimitiveResource;
+
+        /**
+         *
+         * The resource can be discovered with discoverResource.
+         * This class is an interaction point between Resource
+         * and the developers. Developer will get the RCSRemoteResourceObject
+         * by calling RCSDiscoveryManager::discoverResource.
+         *
+         * @see RCSDiscoveryManager
+         *
+         */
+        class RCSRemoteResourceObject
+        {
+        public:
+            typedef std::shared_ptr< RCSRemoteResourceObject > Ptr;
+
+            /**
+             * Typedef for callback of startMonitoring API
+             *
+             * @see ResourceState
+             */
+            typedef std::function< void(ResourceState) > StateChangedCallback;
+
+            /**
+             * Typedef for callback of startCaching API
+             *
+             * @see RCSResourceAttributes
+             */
+            typedef std::function< void(const RCSResourceAttributes&) > CacheUpdatedCallback;
+
+            /**
+             * Typedef for callback of getRemoteAttributes API
+             *
+             * @see RCSResourceAttributes
+             */
+            typedef std::function< void(const RCSResourceAttributes&) >
+                RemoteAttributesGetCallback;
+
+            /**
+             * Typedef for callback of setRemoteAttributes API
+             *
+             * @see RCSResourceAttributes
+             */
+            typedef std::function< void(const RCSResourceAttributes&) >
+                RemoteAttributesSetCallback;
+
+        private:
+            typedef int CacheID;
+            typedef unsigned int BrokerID;
+
+        public:
+            //! @cond
+            RCSRemoteResourceObject(std::shared_ptr< PrimitiveResource >);
+            //! @endcond
+
+            ~RCSRemoteResourceObject();
+
+            /**
+             * Returns whether monitoring is enabled.
+             *
+             * @see startMonitoring()
+             */
+            bool isMonitoring() const;
+
+            /**
+             * Returns whether caching is enabled.
+             *
+             * @see startCaching()
+             */
+
+            bool isCaching() const;
+
+            /**
+             * Returns whether the resource is observable.
+             *
+             */
+            bool isObservable() const;
+
+            /**
+             * Starts monitoring the resource.
+             *
+             * Monitoring provides a feature to check the presence of a resource,
+             * even when the server is not announcing Presence using startPresnece.
+             *
+             * @param cb A Callback to get changed resource state.
+             *
+             * @throws InvalidParameterException If cb is an empty function or null.
+             * @throws BadRequestException If monitoring is already started.
+             *
+             * @note The callback will be invoked in an internal thread.
+             *
+             * @see StateChangedCallback
+             * @see ResourceState
+             * @see isMonitoring()
+             * @see stopMonitoring()
+             *
+             */
+            void startMonitoring(StateChangedCallback cb);
+
+            /**
+             * Stops monitoring the resource.
+             *
+             * It does nothing if monitoring is not started.
+             *
+             * @see startMonitoring()
+             *
+             */
+            void stopMonitoring();
+
+            /**
+             * Returns the current state of the resource.
+             *
+             * @see startMonitoring
+             */
+            ResourceState getState() const;
+
+            /**
+             * Starts caching attributes of the resource.
+             *
+             * This will start data caching for the resource.
+             * Once caching started it will look for the data updation on the resource
+             * and updates the cache data accordingly.
+             *
+             * It is equivalent to calling startCaching(CacheUpdatedCallback) with an empty function.
+             *
+             * @see getCacheState()
+             * @see getCachedAttributes()
+             * @see getCachedAttribute(const std::string&) const
+             *
+             * @throws BadRequestException
+             *
+             */
+            void startCaching();
+
+            /**
+             * Starts caching attributes for the resource.
+             *
+             * This will start data caching for the resource.
+             * Once caching started it will look for the data updation on the resource and
+             * updates the cached data accordingly.
+             *
+             * @param cb If non-empty function, it will be invoked whenever the cache updated.
+             *
+             * @throws BadRequestException If caching is already started.
+             *
+             * @note The callback will be invoked in an internal thread.
+             *
+             * @see CacheUpdatedCallback
+             * @see getCacheState()
+             * @see isCachedAvailable()
+             * @see getCachedAttributes()
+             * @see getCachedAttribute(const std::string&) const
+             *
+             */
+            void startCaching(CacheUpdatedCallback cb);
+
+            /**
+             * Stops caching.
+             *
+             * It does nothing if caching is not started.
+             *
+             * @see startCaching()
+             * @see startCaching(CacheUpdatedCallback)
+             */
+            void stopCaching();
+
+            /**
+             * Returns the current cache state.
+             *
+             */
+            CacheState getCacheState() const;
+
+            /**
+             * Returns whether cached data is available.
+             *
+             * Cache will be available always after CacheState::READY even if current state is
+             * CacheState::LOST_SIGNAL.
+             *
+             * @see getCacheState()
+             */
+            bool isCachedAvailable() const;
+
+            /**
+             * Gets the cached RCSResourceAttributes data.
+             *
+             * @pre Cache should be available.
+             *
+             * @return The cached attributes.
+             *
+             * @throws BadRequestException If the precondition is not fulfilled.
+             *
+             * @see RCSResourceAttributes
+             * @see isCachedAvailable()
+             * @see startCaching()
+             * @see startCaching(CacheUpdatedCallback)
+             *
+             */
+            RCSResourceAttributes getCachedAttributes() const;
+
+            /**
+             * Gets a particular cached a ResourceAttribute Value.
+             *
+             * @pre Cache should be available.
+             *
+             * @return A requested attribute value.
+             *
+             * @throws BadRequestException If the precondition is not fulfilled.
+             * @throws InvalidKeyException If @a key doesn't match the key of any value.
+             *
+             * @see RCSResourceAttributes::Value
+             * @see isCachedAvailable()
+             * @see startCaching()
+             * @see startCaching(CacheUpdatedCallback)
+             *
+             */
+            RCSResourceAttributes::Value getCachedAttribute(const std::string& key) const;
+
+            /**
+             * Gets resource attributes directly from the server.
+             *
+             * This API send a get request to the resource of interest and provides
+             * the attributes to the caller in the RemoteAttributesReceivedCallback.
+             *
+             * @throw InvalidParameterException If cb is an empty function or null.
+             *
+             * @see RCSResourceAttributes::Value
+             *
+             * @note The callback will be invoked in an internal thread.
+             */
+            void getRemoteAttributes(RemoteAttributesGetCallback cb);
+
+            /**
+             * Sends a set request with resource attributes to the server.
+             *
+             * The SetRequest behavior depends on the server, whether updating its attributes or not.
+             *
+             * @param attributes Attributes to set
+             * @param cb A callback to receive the response.
+             *
+             * @throw InvalidParameterException If cb is an empty function or null.
+             *
+             * @see RCSResourceObject
+             * @see RCSResourceObject::SetRequestHandlerPolicy
+             *
+             * @note The callback will be invoked in an internal thread.
+             */
+            void setRemoteAttributes(const RCSResourceAttributes& attributes,
+                    RemoteAttributesSetCallback cb);
+
+            /**
+             * Returns the uri of the resource.
+             *
+             */
+            std::string getUri() const;
+
+            /**
+             * Returns the address of the resource .
+             *
+             */
+            std::string getAddress() const;
+
+            /**
+             * Returns the resource types of the resource.
+             *
+             */
+            std::vector< std::string > getTypes() const;
+
+            /**
+             * Returns the resource interfaces of the resource.
+             *
+             */
+            std::vector< std::string > getInterfaces() const;
+
+        private:
+            std::shared_ptr< PrimitiveResource > m_primitiveResource;
+            CacheID m_cacheId;
+            BrokerID m_brokerId;
+        };
+    }
+}
+#endif // RCSREMOTERESOURCEOBJECT_H
diff --git a/service/resource-encapsulation/include/RCSRequest.h b/service/resource-encapsulation/include/RCSRequest.h
new file mode 100644 (file)
index 0000000..6b531db
--- /dev/null
@@ -0,0 +1,64 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file cotains RCSRequest class, which provide API to get resource URI from the request.
+ */
+#ifndef SERVERBUILDER_PRIMITIVEREQUEST_H
+#define SERVERBUILDER_PRIMITIVEREQUEST_H
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+        * This class describes the request.
+        *
+        */
+        class RCSRequest
+        {
+            public:
+                /**
+                * Constructor to set resource URI.
+                *
+                * @param resourceUri - URI of the resource for which the request is generated.
+                */
+                explicit RCSRequest(const std::string &resourceUri);
+
+                RCSRequest &operator=(RCSRequest &) = delete;
+
+                /**
+                * Returns the URI of the request.
+                *
+                */
+                std::string getResourceUri() const;
+
+            private:
+                std::string m_resourceUri;
+        };
+
+    }
+}
+
+#endif // SERVERBUILDER_PRIMITIVEREQUEST_H
diff --git a/service/resource-encapsulation/include/RCSResourceAttributes.h b/service/resource-encapsulation/include/RCSResourceAttributes.h
new file mode 100644 (file)
index 0000000..5ab8c92
--- /dev/null
@@ -0,0 +1,770 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the "RCSResourceAttributes" class & its helper classes
+ */
+#ifndef RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
+#define RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
+
+// To avoid conflict using different boost::variant configuration with OC.
+// It causes compile errors.
+#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#define BOOST_MPL_LIMIT_LIST_SIZE 30
+#define BOOST_MPL_LIMIT_VECTOR_SIZE 30
+
+#include <functional>
+#include <unordered_map>
+
+#include <boost/variant.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <RCSException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * RCSResourceAttributes represents the attributes for a resource.
+        *
+        * It provides similar usage to c++ standard containers. (iterator,
+        * operators and accessors)<br/>
+        * An attribute value can be one of various types. <br/>
+        *
+        * @note If client developer wants to get the RCSResourceAttributes for the resource of
+        *            interest following are the steps:
+        *            - first call the discover API of DiscoveryManager class.
+        *            - After getting the RemoteResourceObject, call getRemoteAttributes() API
+        *               of RemoteResourceObject class
+        *
+        * @see Value
+        * @see Type
+        * @see iterator
+        * @see const_iterator
+        * @see RCSDiscoveryManager
+        * @see RCSRemoteResourceObject
+        * @see RCSResourceObject
+        */
+        class RCSResourceAttributes
+        {
+        private:
+            template< typename T > struct IsSupportedTypeHelper;
+
+            typedef boost::variant<
+                std::nullptr_t,
+                int,
+                double,
+                bool,
+                std::string,
+                RCSResourceAttributes
+            > ValueVariant;
+
+            template< typename T, typename V = void,
+                    typename = typename std::enable_if<
+                        IsSupportedTypeHelper< T >::type::value, V >::type >
+            struct enable_if_supported
+            {
+                typedef V type;
+            };
+
+            template< typename VISITOR >
+            class KeyValueVisitorHelper: public boost::static_visitor< >
+            {
+            public:
+                KeyValueVisitorHelper(VISITOR& visitor) :
+                        m_visitor( visitor )
+                {
+                }
+
+                template< typename T >
+                void operator()(const std::string& key, const T& value) const
+                {
+                    m_visitor(key, value);
+                }
+
+            private:
+                VISITOR& m_visitor;
+            };
+
+            template <typename T> struct IndexOfType;
+
+        public:
+
+            /**
+             * Trait class that identifies whether T is supported by the Value.
+             */
+            template< typename T >
+            struct is_supported_type: public std::conditional<
+                IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
+
+            /**
+             * Identifier for types of Value.
+             *
+             * @see Type
+             */
+            enum class TypeId
+            {
+                NULL_T, /**< nullptr_t */
+                INT, /**< int */
+                DOUBLE, /**< double */
+                BOOL, /**< bool */
+                STRING, /**< std::string */
+                ATTRIBUTES, /**< RCSResourceAttributes */
+                VECTOR /**< std::vector */
+            };
+
+            /**
+             * A Helper class to identify types of Value.
+             *
+             * @see RCSResourceAttributes
+             * @see Value
+             * @see TypeId
+             */
+            class Type
+            {
+            public:
+                Type(const Type&) = default;
+                Type(Type&&) = default;
+
+                Type& operator=(const Type&) = default;
+                Type& operator=(Type&&) = default;
+
+                /**
+                 * Returns type identifier.
+                 *
+                 * @return Identifier of type.
+                 */
+                TypeId getId() const;
+
+                /**
+                 * Factory method to create Type instance from T.
+                 *
+                 * @return An instance that has TypeId for T.
+                 *
+                 * @note T must be supported by Value. Otherwise, it won't be compiled.
+                 *
+                 * @see is_supported_type
+                 */
+                template < typename T >
+                static Type typeOf(const T& value)
+                {
+                    return Type(value);
+                }
+
+                //! @cond
+                friend bool operator==(const Type&, const Type&);
+                //! @endcond
+
+            private:
+                template < typename T >
+                explicit Type(const T&) :
+                    m_which{ IndexOfType< T >::value }
+                {
+                }
+
+            private:
+                int m_which;
+            };
+
+            /**
+             * Value holds a value among various types at a time.
+             *
+             * Type helps identify type information of Value.
+             *
+             * @see RCSResourceAttributes
+             * @see Type
+             * @see is_supported_type
+             */
+            class Value
+            {
+            public:
+                class ComparisonHelper;
+
+                Value();
+                Value(const Value&);
+                Value(Value&&);
+
+                /**
+                 * Constructs a Value if T is a supported type.<br/>
+                 *       Otherwise it won't be compiled.
+                 */
+                template< typename T, typename = typename enable_if_supported< T >::type >
+                Value(T&& value) :
+                        m_data{ new ValueVariant{ std::forward< T >(value) } }
+                {
+                }
+
+                Value(const char* value);
+
+                Value& operator=(const Value&);
+                Value& operator=(Value&&);
+
+                template< typename T, typename = typename enable_if_supported< T >::type >
+                Value& operator=(T&& rhs)
+                {
+                    *m_data = std::forward< T >(rhs);
+                    return *this;
+                }
+
+                Value& operator=(const char*);
+                Value& operator=(std::nullptr_t);
+
+                /**
+                 * Returns the underlying value as T.
+                 *
+                 * @return const reference to the underlying value.
+                 *
+                 * @throws BadGetException If type of the underlying value is not T.
+                 */
+                template< typename T >
+                typename std::add_lvalue_reference< const T >::type get() const
+                {
+                    return checkedGet< T >();
+                }
+
+                /**
+                 * Returns the underlying value as T.
+                 *
+                 * @return reference to the underlying value.
+                 *
+                 * @throws BadGetException If type of the underlying value is not T.
+                 */
+                template< typename T >
+                typename std::add_lvalue_reference< T >::type get()
+                {
+                    return checkedGet< T >();
+                }
+
+                /**
+                 * Returns Type information.
+                 *
+                 * @see Type
+                 */
+                Type getType() const;
+
+                /**
+                 * Returns a string representation.
+                 *
+                 */
+                std::string toString() const;
+
+                /**
+                 * Exchanges the content of the object by the content of the parameter.
+                 */
+                void swap(Value&);
+
+                //! @cond
+                friend class RCSResourceAttributes;
+                //! @endcond
+
+            private:
+                template< typename T, typename = typename enable_if_supported< T >::type >
+                typename std::add_lvalue_reference< T >::type checkedGet() const
+                {
+                    try
+                    {
+                        return boost::get< T >(*m_data);
+                    }
+                    catch (const boost::bad_get&)
+                    {
+                        throw BadGetException{ "Wrong type" };
+                    }
+                }
+
+                template< typename T, typename U >
+                bool equals(const U& rhs) const
+                {
+                    try
+                    {
+                        return get< T >() == rhs;
+                    }
+                    catch (const BadGetException&)
+                    {
+                        return false;
+                    }
+                }
+
+            private:
+                boost::scoped_ptr< ValueVariant > m_data;
+            };
+
+            class KeyValuePair;
+            class iterator;
+            class const_iterator;
+
+        public:
+            RCSResourceAttributes() = default;
+            RCSResourceAttributes(const RCSResourceAttributes&) = default;
+            RCSResourceAttributes(RCSResourceAttributes&&) = default;
+
+            RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
+            RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
+
+            /**
+             * Returns an {@link iterator} referring to the first element.
+             */
+            iterator begin();
+
+            /**
+             * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
+             */
+            iterator end();
+
+            /**
+             * @copydoc cbegin()
+             */
+            const_iterator begin() const;
+
+            /**
+             * @copydoc cend()
+             */
+            const_iterator end() const;
+
+            /**
+             * Returns a const_iterator referring to the first element.
+             */
+            const_iterator cbegin() const;
+
+            /**
+             * Returns a const_iterator referring to the <i>past-the-end element</i>.
+             */
+            const_iterator cend() const;
+
+            /**
+             * Accesses a value.
+             *
+             * If @a key matches the key of a value,
+             * returns a reference to its mapped value. <br/>
+             * If @a key doesn't match the key of any value,
+             * inserts a new value with that key and returns a reference to it.
+             * The element is a Value that has null.
+             *
+             * @param key Key of the element whose mapped value is accessed.
+             *
+             * @return A reference to the mapped value with @a key.
+             *
+             * @see at
+             */
+            Value& operator[](const std::string& key);
+
+            /**
+             * Accesses a value.
+             *
+             * If @a key matches the key of a value,
+             * returns a reference to its mapped value. <br/>
+             * If @a key doesn't match the key of any value,
+             * inserts a new value with that key and returns a reference to it.
+             * The value has null.
+             *
+             * @param key Key of the element whose mapped value is accessed.
+             *        This is moved instead of copied when a new value is inserted.
+             *
+             * @return A reference to the mapped value with @a key.
+             *
+             * @see at
+             */
+            Value& operator[](std::string&& key);
+
+            /**
+             * Accesses a value.
+             *
+             * If @a key matches the key of a value,
+             * returns a reference to its mapped value. <br/>
+             * If @a key doesn't match the key of any value, throws InvalidKeyException.
+             *
+             * @param key Key of the element whose mapped value is accessed.
+             *
+             * @throws InvalidKeyException If @a key doesn't match the key of any value.
+             *
+             * @return A reference to the mapped value with @a key.
+             *
+             * @see operator[]
+             */
+            Value& at(const std::string& key);
+
+            /**
+              * Accesses a value.
+              *
+              * If @a key matches the key of a value,
+              * returns a reference to its mapped value. <br/>
+              * If @a key doesn't match the key of any value, throws InvalidKeyException.
+              *
+              * @param key Key of the element whose mapped value is accessed.
+              *
+              * @throws InvalidKeyException If @a key doesn't match the key of any value.
+              *
+              * @return A const reference to the mapped value with @a key.
+              *
+              * @see operator[]
+              */
+            const Value& at(const std::string& key) const;
+
+            /**
+             * Removes all elements.
+             */
+            void clear();
+
+            /**
+             * Removes a single element.
+             *
+             * @param key Key of the element to be removed.
+             *
+             * @return true if an element is erased, false otherwise.
+             */
+            bool erase(const std::string& key);
+
+            /**
+             * Checks the container has an element with a Key equivalent to key.
+             *
+             * @param key Key to check.
+             *
+             * @return true if an element exists, false otherwise.
+             */
+            bool contains(const std::string& key) const;
+
+            /**
+             * Returns whether it is empty.
+             *
+             * @see size
+             */
+            bool empty() const;
+
+            /**
+             * Returns the number of elements.
+             *
+             * @see empty
+             */
+            size_t size() const;
+
+        private:
+            template< typename VISITOR >
+            void visit(VISITOR& visitor) const
+            {
+                KeyValueVisitorHelper< VISITOR > helper{ visitor };
+
+                for (const auto& i : m_values)
+                {
+                    boost::variant< const std::string& > key{ i.first };
+                    boost::apply_visitor(helper, key, *i.second.m_data);
+                }
+            }
+
+        private:
+            std::unordered_map< std::string, Value > m_values;
+
+            //! @cond
+            friend class ResourceAttributesConverter;
+
+            friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
+            //! @endcond
+        };
+
+        /**
+         * A helper class to avoid obscure comparisons of values which are supported
+         * by RCSResourceAttributes::Value caused by implicitly converting a value
+         * to a RCSResourceAttributes::Value.
+         *
+         * @see Value
+         * @see RCSResourceAttributes
+         * @see is_supported_type
+         */
+        class RCSResourceAttributes::Value::ComparisonHelper
+        {
+        public:
+            ComparisonHelper(const Value&);
+
+            template< typename T >
+            typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
+                    const T& v) const
+            {
+                return m_valueRef.equals< T >(v);
+            }
+
+            bool equals(const std::string& v) const
+            {
+                return m_valueRef.equals< std::string >(v);
+            }
+
+            bool operator==(const ComparisonHelper&) const;
+
+        private:
+            const Value& m_valueRef;
+        };
+
+        template< typename T >
+        struct RCSResourceAttributes::IsSupportedTypeHelper
+        {
+            typedef boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type> type;
+        };
+
+        template <typename T>
+        struct RCSResourceAttributes::IndexOfType
+        {
+            typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
+            typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
+
+            static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
+        };
+
+        /**
+         * @relates RCSResourceAttributes::Type
+         *
+         * Checks if the objects are equal, that is, whether types are exactly same.
+         *
+         * @return true if the objects are equal, false otherwise.
+         */
+        bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
+
+        /**
+         * @relates RCSResourceAttributes::Type
+         *
+         * Checks if the objects are not equal, that is, whether types are not exactly same.
+         *
+         * @return true if the objects are not equal, false otherwise.
+         */
+        bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
+
+        /**
+         * @relates RCSResourceAttributes::Value
+         *
+         * Checks if the contents are equal, that is,
+         * whether types are matched and underlying values are equal.
+         *
+         * @return true if the contents are equal, false otherwise.
+         */
+        bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
+                const RCSResourceAttributes::Value::ComparisonHelper&);
+
+        /**
+         * @relates RCSResourceAttributes::Value
+         *
+         * Checks if the contents are not equal, that is,
+         * whether types are not matched or underlying values are not equal.
+         *
+         * @return true if the contents are not equal, false otherwise.
+         */
+        bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
+                const RCSResourceAttributes::Value::ComparisonHelper&);
+
+        //! @cond
+        template< typename T >
+        typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
+            std::is_constructible< std::string, T >::value, bool >::type
+        operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
+        {
+            return lhs.equals(rhs);
+        }
+
+        template< typename T >
+        typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
+                    std::is_constructible< std::string, T >::value, bool >::type
+        operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
+        {
+            return rhs == lhs;
+        }
+
+        template< typename T >
+        typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
+                    std::is_constructible< std::string, T >::value, bool >::type
+        operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template< typename T >
+        typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
+                    std::is_constructible< std::string, T >::value, bool >::type
+        operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
+        {
+            return !(rhs == lhs);
+        }
+        //! @endcond
+
+        /**
+          * @relates RCSResourceAttributes
+          *
+          * Checks if the attributes are equal, that is, whether contents are equal.
+          *
+          * @return true if the attributes are equal, false otherwise.
+          */
+        bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
+
+        /**
+          * @relates RCSResourceAttributes
+          *
+          * Checks if the attributes are not equal, that is, whether contents are not equal.
+          *
+          * @return true if the attributes are not equal, false otherwise.
+          */
+        bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
+
+        /**
+         * KeyValuePair is a class to access attribute's key and value of an element pointed by
+         * iterators of RCSResourceAttributes.
+         *
+         *
+         * @see RCSResourceAttributes
+         * @see iterator
+         * @see const_iterator
+         */
+        class RCSResourceAttributes::KeyValuePair
+        {
+        private:
+            class KeyVisitor: public boost::static_visitor< const std::string& >
+            {
+            public:
+                result_type operator()(iterator*) const;
+                result_type operator()(const_iterator*) const;
+            };
+
+            class ValueVisitor: public boost::static_visitor< Value& >
+            {
+            public:
+                result_type operator()(iterator*);
+                result_type operator()(const_iterator*);
+            };
+
+            class ConstValueVisitor: public boost::static_visitor< const Value& >
+            {
+            public:
+                result_type operator()(iterator*) const;
+                result_type operator()(const_iterator*) const;
+            };
+
+        public:
+            const std::string& key() const;
+            const RCSResourceAttributes::Value& value() const;
+            RCSResourceAttributes::Value& value();
+
+        private:
+            KeyValuePair(const KeyValuePair&) = default;
+            KeyValuePair(boost::variant< iterator*, const_iterator* >&&);
+
+            KeyValuePair& operator=(const KeyValuePair&) = default;
+
+        private:
+            boost::variant< iterator*, const_iterator* > m_iterRef;
+
+            KeyVisitor m_keyVisitor;
+            ValueVisitor m_valueVisitor;
+            ConstValueVisitor m_constValueVisitor;
+
+            //! @cond
+            friend class iterator;
+            friend class const_iterator;
+            //! @endcond
+        };
+
+        /**
+         * A forward iterator to KeyValuePair.
+         *
+         * @see RCSResourceAttributes
+         * @see KeyValuePair
+         * @see const_iterator
+         */
+        class RCSResourceAttributes::iterator:
+                public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
+        {
+        private:
+            typedef std::unordered_map< std::string, Value >::iterator base_iterator;
+
+        public:
+            iterator();
+            iterator(const iterator&) = default;
+
+            iterator& operator=(const iterator&) = default;
+
+            reference operator*();
+            pointer operator->();
+
+            iterator& operator++();
+            iterator operator++(int);
+
+            bool operator==(const iterator&) const;
+            bool operator!=(const iterator&) const;
+
+        private:
+            explicit iterator(base_iterator&&);
+
+        private:
+            base_iterator m_cur;
+            RCSResourceAttributes::KeyValuePair m_keyValuePair;
+
+            //! @cond
+            friend class RCSResourceAttributes;
+            //! @endcond
+        };
+
+
+        /**
+         * A forward iterator to const KeyValuePair.
+         *
+         * @see RCSResourceAttributes
+         * @see KeyValuePair
+         * @see iterator
+         */
+        class RCSResourceAttributes::const_iterator:
+                public std::iterator < std::forward_iterator_tag,
+                                       const RCSResourceAttributes::KeyValuePair >
+        {
+        private:
+            typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
+
+        public:
+            const_iterator();
+            const_iterator(const const_iterator&) = default;
+            const_iterator(const RCSResourceAttributes::iterator&);
+
+            const_iterator& operator=(const const_iterator&) = default;
+            const_iterator& operator=(const RCSResourceAttributes::iterator&);
+
+            reference operator*() const;
+            pointer operator->() const;
+
+            const_iterator& operator++();
+            const_iterator operator++(int);
+
+            bool operator==(const const_iterator&) const;
+            bool operator!=(const const_iterator&) const;
+
+        private:
+            explicit const_iterator(base_iterator&&);
+
+        private:
+            base_iterator m_cur;
+            RCSResourceAttributes::KeyValuePair m_keyValuePair;
+
+            //! @cond
+            friend class RCSResourceAttributes;
+            //! @endcond
+        };
+
+    }
+}
+
+#endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
diff --git a/service/resource-encapsulation/include/RCSResourceContainer.h b/service/resource-encapsulation/include/RCSResourceContainer.h
new file mode 100644 (file)
index 0000000..cab5aa3
--- /dev/null
@@ -0,0 +1,156 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the resource container APIs provided to the developers.
+ */
+
+#ifndef RCSRESOURCECONTAINER_H_
+#define RCSRESOURCECONTAINER_H_
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <list>
+
+#include "RCSBundleInfo.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+         * @class   ResourceContainer
+         * @brief    This class provides APIs for managing the container and bundles in the container.
+         *
+         */
+        class RCSResourceContainer
+        {
+            public:
+                /**
+                * Constructor
+                */
+                RCSResourceContainer();
+
+                /**
+                *virtual Destructor
+                */
+                virtual ~RCSResourceContainer();
+
+                /**
+                 * API for starting the Container
+                 *
+                 * @details This API start the container with the provided Configuration file.
+                 *
+                 * @param configFile - configuration File that contains the Bundle/Bundles information.
+                 *
+                 */
+                virtual void startContainer(const std::string &configFile) = 0;
+                /**
+                * API for stopping the Container
+                */
+                virtual void stopContainer() = 0;
+
+                // list of bundle ids
+                /**
+                * API for getting the list of all bundles in the container
+                *
+                * @return  list<BundleInfo*> -List of BundleInfo pointer each associated with a bundle
+                *
+                */
+                virtual std::list<RCSBundleInfo *> listBundles() = 0;
+                /**
+                 * API for starting the bundle.
+                 *
+                 * @param bundleId - Id of the Bundle
+                 *
+                 */
+                virtual void startBundle(const std::string &bundleId) = 0;
+                /**
+                * API for Stopping the bundle
+                *
+                * @param bundleId - Id of the Bundle
+                *
+                */
+                virtual void stopBundle(const std::string &bundleId) = 0;
+
+                // dynamic configuration
+                /**
+                 * API for adding the bundle to the Container
+                 *
+                 * @param bundleId - Id of the Bundle
+                 * @param bundleUri - Uri of the bundle
+                 * @param bundlePath - Path of the bundle
+                 * @param params  - key-value pairs in string form for other Bundle parameters
+                 *
+                 */
+                virtual void addBundle(const std::string &bundleId, const std::string &bundleUri, const std::string &bundlePath,
+                                       std::map<std::string, std::string> params) = 0;
+                /**
+                 * API for removing the bundle from the container
+                 *
+                 * @param bundleId - Id of the Bundle
+                 *
+                 */
+                virtual void removeBundle(const std::string &bundleId) = 0;
+
+                /**
+                * API for adding the Resource configuration information to the bundle
+                *
+                * @param bundleId - Id of the Bundle
+                * @param resourceUri - URI of the resource
+                * @param params  - key-value pairs in string form for other Bundle parameters
+                *
+                */
+                virtual void addResourceConfig(const std::string &bundleId, const std::string &esourceUri,
+                                               std::map<std::string, std::string> params) = 0;
+                /**
+                * API for removing the Resource configuration information from the bundle
+                *
+                * @param bundleId - Id of the Bundle
+                * @param resourceUri - URI of the resource
+                *
+                */
+                virtual void removeResourceConfig(const std::string &bundleId, const std::string &resourceUri) = 0;
+
+                /**
+                * API for getting the list of Bundle Resources
+                *
+                * @param bundleId - Id of the Bundle
+                *
+                */
+                virtual std::list<std::string> listBundleResources(const std::string &bundleId) = 0;
+
+                /**
+                 * API for getting the Instance of ResourceContainer class
+                 *
+                 * @return RCSResourceContainer - Instance of the "RCSResourceContainer" class
+                 *
+                 */
+                static RCSResourceContainer *getInstance();
+        };
+    }
+}
+
+#endif /* RCSRESOURCECONTAINER_H_ */
diff --git a/service/resource-encapsulation/include/RCSResourceObject.h b/service/resource-encapsulation/include/RCSResourceObject.h
new file mode 100755 (executable)
index 0000000..7c0c636
--- /dev/null
@@ -0,0 +1,514 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the resource object APIs provided to the developers.
+ * RCSResourceObject is a part of the server builder module.
+ */
+#ifndef SERVER_RCSRESOURCEOBJECT_H
+#define SERVER_RCSRESOURCEOBJECT_H
+
+#include <string>
+#include <mutex>
+#include <thread>
+
+#include <boost/atomic.hpp>
+
+#include <RCSResourceAttributes.h>
+#include <RCSResponse.h>
+#include <RCSRequest.h>
+
+namespace OC
+{
+    class OCResourceRequest;
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+         * @brief Thrown when lock has not been acquired.
+         *
+         * @see RCSResourceObject::LockGuard
+         * @see RCSResourceObject::getAttributes
+         */
+        class NoLockException: public RCSException
+        {
+            public:
+                NoLockException(std::string &&what) : RCSException { std::move(what) } {}
+        };
+
+        /**
+         * @brief  RCSResourceObject represents a resource. It handles any requests from
+         *        clients automatically with attributes.
+         *        It also provides an auto notification mechanism that notifies to the observers.
+         *        <br/>
+         *         Requests are handled automatically by defaultAction of RCSGetResponse and
+         *        RCSSetResponse. You can override them and send your own response.
+         *        <br/>
+         *         For simple resources, you may want to know whenever attributes are changed
+         *        by a set request. In this case, add an AttributeUpdatedListener
+         *        with a key interested in instead of overriding SetRequestHandler.
+         */
+        class RCSResourceObject
+        {
+            private:
+                class WeakGuard;
+
+            public:
+                /**
+                 * @brief represents the policy of AutoNotify function.
+                 *        In accord with this policy, observers are notified of attributes that
+                 *        are changed or updated.
+                 * @note Attributes are changed or updated according to execution of some functions
+                 *       or receipt of 'set-request'.
+                 *       (functions - RCSResourceObject::setAttribute,
+                 *       RCSResourceObject::removeAttribute, RCSResourceObject::getAttributes)
+                 */
+                enum class AutoNotifyPolicy
+                {
+                    NEVER,  /**< Never notify.*/
+                    ALWAYS, /**< Always notify.*/
+                    UPDATED /**< When attributes are changed, notify.*/
+                };
+
+                /**
+                 * @brief represents the policy of Set-Request Handler.
+                 *        In accord with this policy, attributes of 'set-request' are created or
+                 *        ignored.
+                 */
+                enum class SetRequestHandlerPolicy
+                {
+                    NEVER,     /**< Server ignore when server is received set-request of attributes
+                                    of the new key. */
+                    ACCEPTANCE /**< Server creates attributes of the new key When server is received
+                                    set-request of attributes of the new key. */
+                };
+
+                typedef std::shared_ptr< RCSResourceObject > Ptr;
+                typedef std::shared_ptr< const RCSResourceObject > ConstPtr;
+
+                /**
+                 * @class   Builder
+                 * @brief   This class provides APIs for resource creation, setting properties &
+                 *          attributes for the constructed resource.
+                 *          It provides the build() API
+                 *          which builds a resource and return pointer to RCSResourceObject class.
+                 *
+                 *@see build()
+                 */
+                class Builder
+                {
+                    public:
+                        /**
+                         * @brief Constructor.
+                         *           Sets the resource property values using initializers list.
+                         *
+                         * @param uri Resource URI value to be set
+                         * @param type Resource type value to be set
+                         * @param interface Interface value to be set
+                         *
+                         *NOTE : m_properties value is by default set to
+                         *       OC_DISCOVERABLE | OC_OBSERVABLE.
+                         *       OC_DISCOVERABLE and OC_OBSERVABLE are defined in octypes.h.
+                         */
+                        Builder(const std::string &uri, const std::string &type,
+                                const std::string &interface);
+
+                        /**
+                        * Sets the discoverable(OC_DISCOVERABLE) property for the resource.
+                        *
+                        * @param discoverable Whether to be discovered.
+                        *
+                        * @return reference of this Builder
+                        *
+                        *@see OC_DISCOVERABLE
+                        */
+                        Builder &setDiscoverable(bool discoverable);
+
+                        /**
+                        * Sets the observable(OC_OBSERVABLE) property of the resource.
+                        *
+                        * @param observable Whether to be observed.
+                        *
+                        * @return reference of this Builder
+                        *
+                        *@see  OC_OBSERVABLE
+                        */
+                        Builder &setObservable(bool observable);
+
+                        /**
+                        * Sets attribute of the resource.
+                        *
+                        * @param attributes Resource attributes to set
+                        *
+                        * @return reference of this Builder
+                        */
+                        Builder &setAttributes(const RCSResourceAttributes &attributes);
+
+                        /**
+                        * API for setting attributes of the resource.
+                        *
+                        * @param attributes Resource Attributes to set
+                        *
+                        * @return reference of this Builder
+                        */
+                        Builder &setAttributes(RCSResourceAttributes &&attributes);
+
+                        /**
+                         * API for constructing a new RCSResourceObject.
+                         *
+                         * @return Pointer to RCSResourceObject instance created.
+                         *
+                         * @throw PlatformException
+                         *       It catches exception from registerResource API of OCPlatform and
+                         *       throws it to developer.
+                         *
+                         */
+                        RCSResourceObject::Ptr build();
+
+                    private:
+                        std::string m_uri;
+                        std::string m_type;
+                        std::string m_interface;
+                        uint8_t m_properties;
+                        RCSResourceAttributes m_resourceAttributes;
+                };
+
+                class LockGuard;
+
+                typedef std::function < RCSGetResponse(const RCSRequest&,
+                                                       RCSResourceAttributes&) > GetRequestHandler;
+                typedef std::function < RCSSetResponse(const RCSRequest&,
+                                                       RCSResourceAttributes&) > SetRequestHandler;
+
+                typedef std::function < void(const RCSResourceAttributes::Value&,
+                                     const RCSResourceAttributes::Value &) > AttributeUpdatedListener;
+
+            public:
+                RCSResourceObject(RCSResourceObject&&) = delete;
+                RCSResourceObject(const RCSResourceObject&) = delete;
+
+                RCSResourceObject& operator=(RCSResourceObject&&) = delete;
+                RCSResourceObject& operator=(const RCSResourceObject&) = delete;
+
+                virtual ~RCSResourceObject();
+
+                /**
+                 * API for setting a particular attribute value.
+                 *
+                 * @param key name of attribute(used to map the attribute value).
+                 * @param value attribute value to be mapped against the key.
+                 *
+                 * @note It is guaranteed thread-safety about attributes.
+                 */
+                void setAttribute(const std::string& key, const RCSResourceAttributes::Value& value);
+
+                /**
+                 * @overload
+                 */
+                void setAttribute(const std::string& key, RCSResourceAttributes::Value&& value);
+
+                /**
+                 * @overload
+                 */
+                void setAttribute(std::string&& key, const RCSResourceAttributes::Value& value);
+
+                /**
+                 * @overload
+                 */
+                void setAttribute(std::string&& key, RCSResourceAttributes::Value&& value);
+
+                /**
+                 * API for getting attribute value corresponding to a key(name of that attribute).
+                 *
+                 * @param key name of the attribute value to look for.
+                 *
+                 * @return value of the resource attribute.
+                 *
+                 * @note It is guaranteed thread-safety about attributes.
+                 *
+                 * @throw InvalidKeyException
+                 *              Throw exception when empty string is provided as Attribute key.
+                 */
+                RCSResourceAttributes::Value getAttributeValue(const std::string& key) const;
+
+                /**
+                 * API for retrieving the attribute value associated with the supplied name.
+                 *
+                 * @param key Name of the attribute
+                 *
+                 * @return resource attributes value.
+                 *
+                 * It is guaranteed thread-safety about attributes.
+                 */
+                template< typename T >
+                T getAttribute(const std::string& key) const
+                {
+                    WeakGuard lock(*this);
+                    return m_resourceAttributes.at(key).get< T >();
+                }
+
+                /**
+                 * API for removing a particular attribute of the resource.
+                 *
+                 * @param key Name of the attribute.
+                 *
+                 * @return If the key exist and matched attribute is deleted, return true.
+                 *
+                 * It is guaranteed thread-safety about attributes.
+                 */
+                bool removeAttribute(const std::string& key);
+
+                /**
+                 * API for checking whether a particular attribute is there for a resource or not.
+                 *
+                 * @param key Name of the attribute.
+                 *
+                 * @return If the key exist, return true.
+                 *
+                 * It is guaranteed thread-safety about attributes.
+                 */
+                bool containsAttribute(const std::string& key) const;
+
+                /**
+                 * API for getting all the attributes of the RCSResourceObject.
+                 * It invokes the expectOwnLock() API to check the owner of the lock using the
+                 * thread id.
+                 * If it is not the owner then it throws exception.
+                 *
+                 * @return reference of the attributes of this RCSResourceObject.
+                 *
+                 * @see expectOwnLock()
+                 *
+                 * @throw NoLockException
+                 *              If you don't do lock with LockGuard, throw exception.
+                 */
+                RCSResourceAttributes& getAttributes();
+
+                /**
+                 * @overload
+                 */
+                const RCSResourceAttributes& getAttributes() const;
+
+                /**
+                * API for checking whether the particular resource is observable or not
+                */
+                virtual bool isObservable() const;
+
+                /**
+                * API for checking whether the particular resource is discoverable or not
+                */
+                virtual bool isDiscoverable() const;
+
+                /**
+                 * API for setting the resource's get request handler by the developer/application.
+                 * If developer set this handler then all get request will come to the application &
+                 * developer can send the response to the client using APIs of RCSGetResponse class.
+                 *
+                 * @param handler Request handler for get requests
+                 *
+                 * @see RCSGetResponse
+                 *
+                 */
+                virtual void setGetRequestHandler(GetRequestHandler handler);
+
+                /**
+                 * API for setting the resource's set request handler by the developer/application.
+                 * If developer set this handler then all set request for the resource
+                 * will come to the application & developer can send the response to the client
+                 * using APIs of RCSSetResponse class.
+                 *
+                 * @param handler Request handler for set requests
+                 *
+                 * @see RCSSetResponse
+                 *
+                 */
+                virtual void setSetRequestHandler(SetRequestHandler handler);
+
+                /**
+                 * API for setting the Listener for a particular attribute update.
+                 *
+                 * @param key The interested attribute's key
+                 * @param listener Listener for updation of the interested attribute
+                 *
+                 */
+                virtual void addAttributeUpdatedListener(const std::string& key,
+                        AttributeUpdatedListener listener);
+
+                /**
+                 * API for setting the Listener for a particular attribute update.
+                 *
+                 * @param key The interested attribute's key
+                 * @param listener Listener for updation of the interested attribute
+                 *
+                 */
+                virtual void addAttributeUpdatedListener(std::string&& key,
+                        AttributeUpdatedListener listener);
+
+                /**
+                * API for removing the handler for a particular attribute update.
+                *
+                * @param key The interested attribute's key
+                *
+                */
+                virtual bool removeAttributeUpdatedListener(const std::string& key);
+
+                /**
+                 * API for notifying all observers of the RCSResourceObject
+                 * with the updated attributes value
+                 */
+                virtual void notify() const;
+
+                /**
+                * API for setting Auto notify policy
+                *
+                * @param policy policy to be set
+                *
+                * @see AutoNotifyPolicy
+                *
+                */
+                void setAutoNotifyPolicy(AutoNotifyPolicy policy);
+
+                /**
+                * API for getting auto notify policy
+                *
+                * @returns AntoNotify policy
+                *
+                * @see AutoNotifyPolicy
+                *
+                */
+                AutoNotifyPolicy getAutoNotifyPolicy() const;
+
+                /**
+                * API for setting the policy for a setRequestHandler.
+                *
+                * @param policy policy to be set
+                *
+                * @see SetRequestHandlerPolicy
+                *
+                */
+                void setSetRequestHandlerPolicy(SetRequestHandlerPolicy policy);
+
+                /**
+                * API for getting the SetRequestHandler Policy.
+                *
+                * @returns Property of setRequesthandler
+                *
+                * @see SetRequestHandlerPolicy
+                *
+                */
+                SetRequestHandlerPolicy getSetRequestHandlerPolicy() const;
+
+        private:
+            RCSResourceObject(uint8_t, RCSResourceAttributes&&);
+
+            OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest >);
+
+            OCEntityHandlerResult handleRequest(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleRequestGet(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleRequestSet(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleObserve(std::shared_ptr< OC::OCResourceRequest >);
+
+            void expectOwnLock() const;
+
+            void autoNotify(bool, AutoNotifyPolicy) const;
+            void autoNotify(bool) const;
+
+            bool testValueUpdated(const std::string&, const RCSResourceAttributes::Value&) const;
+
+            template< typename K, typename V >
+            void setAttributeInternal(K&&, V&&);
+
+        private:
+            const uint8_t m_properties;
+
+            OCResourceHandle m_resourceHandle;
+            RCSResourceAttributes m_resourceAttributes;
+
+            GetRequestHandler m_getRequestHandler;
+            SetRequestHandler m_setRequestHandler;
+            AutoNotifyPolicy m_autoNotifyPolicy;
+            SetRequestHandlerPolicy m_setRequestHandlerPolicy;
+
+            std::unordered_map< std::string, AttributeUpdatedListener >
+                    m_keyAttributesUpdatedListeners;
+
+            mutable boost::atomic< std::thread::id > m_lockOwner;
+            mutable std::mutex m_mutex;
+
+            std::mutex m_mutexKeyAttributeUpdate;
+
+        };
+
+        class RCSResourceObject::LockGuard
+        {
+        public:
+            LockGuard(const RCSResourceObject&);
+            LockGuard(const RCSResourceObject::Ptr);
+            LockGuard(const RCSResourceObject&, AutoNotifyPolicy);
+            LockGuard(const RCSResourceObject::Ptr, AutoNotifyPolicy);
+            ~LockGuard();
+
+            LockGuard(const LockGuard&) = delete;
+            LockGuard(LockGuard&&) = delete;
+
+            LockGuard& operator=(const LockGuard&) = delete;
+            LockGuard& operator=(LockGuard&&) = delete;
+
+        private:
+            void init();
+
+        private:
+            const RCSResourceObject& m_resourceObject;
+
+            AutoNotifyPolicy m_autoNotifyPolicy;
+
+            bool m_isOwningLock;
+
+            std::function<void()> m_autoNotifyFunc;
+        };
+
+        class RCSResourceObject::WeakGuard
+        {
+        public:
+            WeakGuard(const RCSResourceObject&);
+            ~WeakGuard();
+
+            WeakGuard(const WeakGuard&) = delete;
+            WeakGuard(WeakGuard&&) = delete;
+
+            WeakGuard& operator=(const WeakGuard&) = delete;
+            WeakGuard& operator=(WeakGuard&&) = delete;
+
+            bool hasLocked() const;
+
+        private:
+            bool m_isOwningLock;
+            const RCSResourceObject& m_resourceObject;
+        };
+    }
+}
+
+#endif // SERVER_RCSRESOURCEOBJECT_H
diff --git a/service/resource-encapsulation/include/RCSResponse.h b/service/resource-encapsulation/include/RCSResponse.h
new file mode 100644 (file)
index 0000000..afe6c10
--- /dev/null
@@ -0,0 +1,286 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the classes for creating Get & Set response for the Get & Set request.
+ */
+#ifndef SERVERBUILDER_RCSRESPONSE_H
+#define SERVERBUILDER_RCSRESPONSE_H
+
+#include <cstdint>
+#include <memory>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSResourceAttributes;
+
+        class RequestHandler;
+        class SetRequestHandler;
+
+        /**
+         * This class provides factory methods to create the response for a received get request.
+         * The response consists of a result code, an error code and result attributes.
+         *
+         * @see RCSResourceObject
+         */
+        class RCSGetResponse
+        {
+        public:
+            /**
+             * Creates a default RCSGetResponse.
+             * The response will have OC_EH_OK for the result and 200 for the errorCode.
+             * The attributes of RCSResourceObject will be set as the result attributes.
+             *
+             */
+            static RCSGetResponse defaultAction();
+
+            /**
+             * Creates a RCSGetResponse with a result and error code passed.
+             * The attributes of the RCSResourceObject will be set as the result attributes.
+             *
+             * @param result The response result.
+             * @param errorCode The error code to set in response.
+             *
+             */
+            static RCSGetResponse create(const OCEntityHandlerResult& result, int errorCode);
+
+            /**
+             * Creates a RCSGetResponse with custom attributes.
+             * This sends the passed attributes as the result attributes
+             * instead of the one the RCSResourceObject holds.
+             *
+             * @param attrs The attributes to set.
+             *
+             * @see RCSResourceAttributes
+             *
+             */
+            static RCSGetResponse create(const RCSResourceAttributes& attrs);
+
+            /**
+             * @override
+             */
+            static RCSGetResponse create(RCSResourceAttributes&& attrs);
+
+            /**
+             * Creates a RCSGetResponse with a result and error code passed.
+             * This sends the passed attributes as the result attributes
+             * instead of the one the RCSResourceObject holds.
+             *
+             * @param attrs The attributes to set.
+             * @param result The response result.
+             * @param errorCode The error code for response.
+             *
+             * @see RCSResourceAttributes
+             *
+             */
+            static RCSGetResponse create(const RCSResourceAttributes& attrs,
+                    const OCEntityHandlerResult& result, int errorCode);
+
+            /**
+             * @override
+             */
+            static RCSGetResponse create(RCSResourceAttributes&& attrs,
+                    const OCEntityHandlerResult& result, int errorCode);
+
+            //! @cond
+            RequestHandler* getHandler() const;
+            //! @endcond
+
+        private:
+            RCSGetResponse(std::shared_ptr< RequestHandler >&&);
+
+        private:
+            std::shared_ptr< RequestHandler > m_handler;
+        };
+
+        /**
+         * This class provides factory methods to create the response for a received set request.
+         * The response consists of a result code, an error code and result attributes.
+         *
+         * AcceptanceMethod provides ways how to handle attributes from a request.
+         *
+         * @see RCSResourceObject
+         */
+        class RCSSetResponse
+        {
+        public:
+            /**
+             * Options for handling a set request.
+             *
+             * This overrides SetRequestHandlerPolicy.
+             *
+             * @see SetRequestHandlerPolicy
+             *
+             */
+            enum class AcceptanceMethod
+            {
+                /**
+                 * Follow SetRequestHandlerPolicy of the RCSResourceObject.
+                 */
+                DEFAULT,
+
+                /**
+                 * Accept the request attributes even if there is an unknown key or mismatched type.
+                 */
+                ACCEPT,
+
+                /**
+                 * Ignore the request attributes.
+                 */
+                IGNORE
+            };
+
+            /**
+             * Creates a default RCSSetResponse that has AcceptanceMethod::DEFAULT.
+             * The response will have OC_EH_OK for the result and 200 for the errorCode.
+             * The attributes of RCSResourceObject will be set as the result attributes.
+             *
+             */
+            static RCSSetResponse defaultAction();
+
+            /**
+             * Creates a default RCSSetResponse that has AcceptanceMethod::ACCEPT.
+             * The response will have OC_EH_OK for the result and 200 for the errorCode.
+             * The attributes of RCSResourceObject will be set as the result attributes.
+             *
+             */
+            static RCSSetResponse accept();
+
+            /**
+             * Creates a RCSSetResponse that has AcceptanceMethod::ACCEPT
+             * with a result and error code passed.
+             * The attributes of the RCSResourceObject will be set as the result attributes.
+             *
+             * @param result The response result.
+             * @param errorCode The error code to set in response.
+             *
+             */
+            static RCSSetResponse accept(const OCEntityHandlerResult& result, int errorCode);
+
+            /**
+             * Creates a default RCSSetResponse that has AcceptanceMethod::IGNORE.
+             * The response will have OC_EH_OK for the result and 200 for the errorCode.
+             * The attributes of RCSResourceObject will be set as the result attributes.
+             *
+             */
+            static RCSSetResponse ignore();
+
+            /**
+             * Creates a RCSSetResponse that has AcceptanceMethod::IGNORE
+             * with a result and error code passed.
+             * The attributes of the RCSResourceObject will be set as the result attributes.
+             *
+             * @param result The response result.
+             * @param errorCode The error code to set in response.
+             *
+             */
+            static RCSSetResponse ignore(const OCEntityHandlerResult& result, int errorCode);
+
+            /**
+             * Creates a RCSSetResponse that has AcceptanceMethod::DEFAULT
+             * with a result and error code passed.
+             * The attributes of the RCSResourceObject will be set as the result attributes.
+             *
+             * @param result The response result.
+             * @param errorCode The error code to set in response.
+             *
+             */
+            static RCSSetResponse create(const OCEntityHandlerResult& result, int errorCode);
+
+            /**
+             * Creates a RCSSetResponse that has AcceptanceMethod::DEFAULT with custom attributes.
+             * This sends the passed attributes as the result attributes
+             * instead of the one the RCSResourceObject holds.
+             *
+             * @param attrs The attributes to set.
+             *
+             * @see RCSResourceAttributes
+             *
+             */
+            static RCSSetResponse create(const RCSResourceAttributes& attrs);
+
+            /**
+             * @override
+             */
+            static RCSSetResponse create(RCSResourceAttributes &&attrs);
+
+            /**
+             * Creates a RCSSetResponse with a result and error code passed.
+             * This sends the passed attributes as the result attributes
+             * instead of the one the RCSResourceObject holds.
+             *
+             * @param attrs The attributes to set.
+             * @param result The response result.
+             * @param errorCode The error code for response.
+             *
+             * @see RCSResourceAttributes
+             *
+             */
+            static RCSSetResponse create(const RCSResourceAttributes& attrs,
+                    const OCEntityHandlerResult& result, int errorCode);
+
+
+            /**
+             * @override
+             */
+            static RCSSetResponse create(RCSResourceAttributes &&attrs,
+                    const OCEntityHandlerResult &result, int errorCode);
+
+
+            //! @cond/
+            SetRequestHandler* getHandler() const;
+            //! @endcond
+
+            /**
+             * Returns the acceptance method.
+             *
+             */
+            AcceptanceMethod getAcceptanceMethod() const;
+
+            /**
+             * Sets the acceptance method for the RCSSetResponse.
+             *
+             * @param method - AcceptanceMethod value to set
+             *
+             * @return The reference to this RCSSetResponse
+             *
+             * @see AcceptanceMethod
+             *
+             */
+            RCSSetResponse& setAcceptanceMethod(AcceptanceMethod method);
+
+        private:
+            RCSSetResponse(std::shared_ptr< SetRequestHandler >&&);
+            RCSSetResponse(std::shared_ptr< SetRequestHandler >&&, AcceptanceMethod);
+
+        private:
+            AcceptanceMethod m_acceptanceMethod;
+            std::shared_ptr< SetRequestHandler > m_handler;
+        };
+    }
+}
+
+#endif // SERVERBUILDER_RCSRESPONSE_H
diff --git a/service/resource-encapsulation/src/common/SConscript b/service/resource-encapsulation/src/common/SConscript
new file mode 100755 (executable)
index 0000000..447a44c
--- /dev/null
@@ -0,0 +1,130 @@
+#******************************************************************\r
+#\r
+# Copyright 2015 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
+# rcs_common (primitiveResource and expiryTimer) build script\r
+##\r
+import os\r
+Import('env')\r
+\r
+# Add third party libraries\r
+lib_env = env.Clone()\r
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')\r
+\r
+src_dir = lib_env.get('SRC_DIR')\r
+\r
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'\r
+\r
+rcs_common_env = lib_env.Clone()\r
+target_os = env.get('TARGET_OS')\r
+\r
+release = env.get('RELEASE')\r
+\r
+######################################################################\r
+# Build flags\r
+######################################################################\r
+rcs_common_env.AppendUnique(CPPPATH = [\r
+    env.get('SRC_DIR')+'/extlibs',\r
+    '../../include',\r
+    'primitiveResource/include'])\r
+       \r
+rcs_common_env.AppendUnique(CPPPATH = [\r
+    'expiryTimer/include',\r
+    'expiryTimer/src'])\r
+\r
+rcs_common_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])\r
+\r
+if target_os not in ['windows', 'winrt']:\r
+    rcs_common_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])\r
+    if target_os != 'android':\r
+        rcs_common_env.AppendUnique(CXXFLAGS = ['-pthread'])\r
+        rcs_common_env.AppendUnique(LIBS = ['pthread'])\r
+\r
+if target_os == 'android':\r
+    rcs_common_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])\r
+    rcs_common_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])\r
+\r
+rcs_common_env.AppendUnique(LIBS = ['dl'])\r
+\r
+if not release:\r
+    rcs_common_env.AppendUnique(CXXFLAGS = ['--coverage'])\r
+    rcs_common_env.PrependUnique(LIBS = ['gcov'])\r
+\r
+######################################################################\r
+# Source files and Targets\r
+######################################################################\r
+TIMER_SRC_DIR = 'expiryTimer/src/'\r
+RESOURCE_SRC = 'primitiveResource/src/'\r
+rcs_common_src = [\r
+        TIMER_SRC_DIR + 'ExpiryTimerImpl.cpp', \r
+               TIMER_SRC_DIR + 'ExpiryTimer.cpp',\r
+               RESOURCE_SRC + 'PresenceSubscriber.cpp',\r
+               RESOURCE_SRC + 'PrimitiveResource.cpp',\r
+               RESOURCE_SRC + 'RCSException.cpp',\r
+               RESOURCE_SRC + 'RCSAddress.cpp',\r
+               RESOURCE_SRC + 'RCSResourceAttributes.cpp',\r
+               RESOURCE_SRC + 'ResponseStatement.cpp'\r
+        ]\r
+               \r
+rcs_common_static = rcs_common_env.StaticLibrary('rcs_common', rcs_common_src)\r
+rcs_common_shared = rcs_common_env.SharedLibrary('rcs_common', rcs_common_src)\r
+rcs_common_env.InstallTarget([rcs_common_static,rcs_common_shared], 'rcs_common')\r
+\r
+######################################################################\r
+# Build Test primitive Resource\r
+######################################################################\r
+rcs_common_test_env = rcs_common_env.Clone();\r
+\r
+rcs_common_test_env.PrependUnique(CPPPATH = [\r
+    env.get('SRC_DIR')+'/extlibs/hippomocks-master',\r
+    gtest_dir + '/include',\r
+    'utils/include'\r
+    ])\r
+\r
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')\r
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')\r
+\r
+rcs_common_test_env.PrependUnique(LIBS = [\r
+       'oc',\r
+    'octbstack',\r
+    'oc_logger',\r
+    'connectivity_abstraction',\r
+    'coap',\r
+    'rcs_common',\r
+    gtest,\r
+    gtest_main,\r
+    'pthread'\r
+    ])\r
+\r
+rcs_common_test_src = [\r
+    env.Glob('primitiveResource/unittests/*.cpp'),\r
+    'expiryTimer/unittests/ExpiryTimerTest.cpp'\r
+    ]\r
+\r
+rcs_common_test = rcs_common_test_env.Program('rcs_common_test', rcs_common_test_src)\r
+Alias("rcs_common_test", rcs_common_test)\r
+env.AppendTarget('rcs_common_test')\r
+
+if env.get('TEST') == '1':
+    target_os = env.get('TARGET_OS')
+    if target_os == 'linux':
+        from tools.scons.RunTest import *
+        run_test(rcs_common_test_env, '',
+                'service/resource-encapsulation/src/common/rcs_common_test')
diff --git a/service/resource-encapsulation/src/common/expiryTimer/include/ExpiryTimer.h b/service/resource-encapsulation/src/common/expiryTimer/include/ExpiryTimer.h
new file mode 100644 (file)
index 0000000..9eb859f
--- /dev/null
@@ -0,0 +1,70 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_H_
+#define _EXPIRY_TIMER_H_
+
+#include <functional>
+#include <unordered_map>
+#include <memory>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class TimerTask;
+
+        class ExpiryTimer
+        {
+        public:
+            typedef unsigned int Id;
+            typedef std::function< void(Id) > Callback;
+            typedef long long DelayInMilliSec;
+
+        public:
+            ExpiryTimer();
+            ~ExpiryTimer();
+
+            ExpiryTimer(ExpiryTimer&&) = default;
+            ExpiryTimer& operator=(ExpiryTimer&&) = default;
+
+            ExpiryTimer(const ExpiryTimer&) = delete;
+            ExpiryTimer& operator=(const ExpiryTimer&) = delete;
+
+            Id post(DelayInMilliSec, Callback);
+            bool cancel(Id);
+            void cancelAll();
+
+            size_t getNumOfPending();
+            size_t getNumOfPending() const;
+
+        private:
+            void sweep();
+
+        private:
+            size_t m_nextSweep;
+
+            std::unordered_map< Id, std::shared_ptr< TimerTask > > m_tasks;
+        };
+
+    }
+}
+#endif //_EXPIRY_TIMER_H_
diff --git a/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimer.cpp b/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimer.cpp
new file mode 100644 (file)
index 0000000..a3758c6
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// 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 "ExpiryTimer.h"
+#include "ExpiryTimerImpl.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        namespace
+        {
+            constexpr size_t DEFAULT_SWEEP_SIZE{ 50 };
+        }
+
+        ExpiryTimer::ExpiryTimer() :
+               m_nextSweep { DEFAULT_SWEEP_SIZE }
+        {
+        }
+
+        ExpiryTimer::~ExpiryTimer()
+        {
+            cancelAll();
+        }
+
+        ExpiryTimer::Id ExpiryTimer::post(DelayInMilliSec milliSec, Callback cb)
+        {
+            auto task = ExpiryTimerImpl::getInstance()->post(milliSec, std::move(cb));
+            m_tasks[task->getId()] = task;
+
+            if (m_tasks.size() == m_nextSweep) sweep();
+
+            return task->getId();
+        }
+
+        bool ExpiryTimer::cancel(Id id)
+        {
+            auto it = m_tasks.find(id);
+
+            if (it == m_tasks.end()) return false;
+
+            auto task = it->second;
+            m_tasks.erase(it);
+
+            if (task->isExecuted()) return false;
+
+            return ExpiryTimerImpl::getInstance()->cancel(id);
+        }
+
+        void ExpiryTimer::cancelAll()
+        {
+            sweep();
+
+            std::unordered_set< std::shared_ptr< TimerTask > > set;
+
+            for(const auto& p : m_tasks)
+            {
+                set.insert(p.second);
+            }
+
+            ExpiryTimerImpl::getInstance()->cancelAll(set);
+            m_tasks.clear();
+        }
+
+        size_t ExpiryTimer::getNumOfPending()
+        {
+            sweep();
+            return m_tasks.size();
+        }
+
+        size_t ExpiryTimer::getNumOfPending() const
+        {
+            size_t ret{ 0 };
+
+            for (const auto& p : m_tasks)
+            {
+                ret += p.second->isExecuted() ? 0U : 1U;
+            }
+
+            return ret;
+        }
+
+        void ExpiryTimer::sweep()
+        {
+            for (auto it = m_tasks.begin(); it != m_tasks.end();)
+            {
+                if (it->second->isExecuted())
+                {
+                    it = m_tasks.erase(it);
+                }
+                else
+                {
+                    ++it;
+                }
+            }
+
+            m_nextSweep = m_tasks.size() << 1;
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp b/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp
new file mode 100644 (file)
index 0000000..ac4b088
--- /dev/null
@@ -0,0 +1,227 @@
+//******************************************************************
+//
+// 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 "ExpiryTimerImpl.h"
+
+#include "RCSException.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        namespace
+        {
+            constexpr ExpiryTimerImpl::Id INVALID_ID{ 0U };
+        }
+
+        ExpiryTimerImpl::ExpiryTimerImpl() :
+                m_tasks{ },
+                m_thread{ std::thread(&ExpiryTimerImpl::run, this) },
+                m_mutex{ },
+                m_cond{ },
+                m_stop{ false },
+                m_mt{ std::random_device{ }() },
+                m_dist{ }
+        {
+        }
+
+        ExpiryTimerImpl::~ExpiryTimerImpl()
+        {
+            {
+                std::lock_guard< std::mutex > lock{ m_mutex };
+                m_tasks.clear();
+                m_stop = true;
+            }
+            m_cond.notify_all();
+            m_thread.join();
+        }
+
+        ExpiryTimerImpl* ExpiryTimerImpl::getInstance()
+        {
+            static ExpiryTimerImpl instance;
+            return &instance;
+        }
+
+        std::shared_ptr< TimerTask > ExpiryTimerImpl::post(DelayInMillis delay, Callback cb)
+        {
+            if (delay < 0LL)
+            {
+                throw InvalidParameterException{ "delay can't be negative." };
+            }
+
+            if (!cb)
+            {
+                throw InvalidParameterException{ "callback is empty." };
+            }
+
+            return addTask(convertToTime(Milliseconds{ delay }), std::move(cb), generateId());
+        }
+
+        bool ExpiryTimerImpl::cancel(Id id)
+        {
+            if (id == INVALID_ID) return false;
+
+            std::lock_guard< std::mutex > lock{ m_mutex };
+
+            for(auto it = m_tasks.begin(); it != m_tasks.end(); ++it)
+            {
+                if(it->second->getId() == id)
+                {
+                    m_tasks.erase(it);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        size_t ExpiryTimerImpl::cancelAll(
+                const std::unordered_set< std::shared_ptr<TimerTask > >& tasks)
+        {
+            std::lock_guard< std::mutex > lock{ m_mutex };
+            size_t erased { 0 };
+
+            for(auto it = m_tasks.begin(); it != m_tasks.end();)
+            {
+                if(tasks.count(it->second))
+                {
+                    it = m_tasks.erase(it);
+                    ++erased;
+                }
+                else
+                {
+                    ++it;
+                }
+            }
+            return erased;
+        }
+
+        ExpiryTimerImpl::Milliseconds ExpiryTimerImpl::convertToTime(Milliseconds delay)
+        {
+            const auto now = std::chrono::system_clock::now();
+            return std::chrono::duration_cast< Milliseconds >(now.time_since_epoch()) + delay;
+        }
+
+        std::shared_ptr< TimerTask > ExpiryTimerImpl::addTask(
+                Milliseconds delay, Callback cb, Id id)
+        {
+            std::lock_guard< std::mutex > lock{ m_mutex };
+
+            auto newTask = std::make_shared< TimerTask >(id, std::move(cb));
+            m_tasks.insert({ delay, newTask });
+            m_cond.notify_all();
+
+            return newTask;
+        }
+
+        bool ExpiryTimerImpl::containsId(Id id) const
+        {
+            for (const auto& info : m_tasks)
+            {
+                if (info.second->getId() == id) return true;
+            }
+            return false;
+        }
+
+        ExpiryTimerImpl::Id ExpiryTimerImpl::generateId()
+        {
+            Id newId = m_dist(m_mt);
+
+            std::lock_guard< std::mutex > lock{ m_mutex };
+
+            while (newId == INVALID_ID || containsId(newId))
+            {
+                newId = m_dist(m_mt);
+            }
+            return newId;
+        }
+
+        void ExpiryTimerImpl::executeExpired()
+        {
+            if (m_tasks.empty()) return;
+
+            auto now = std::chrono::system_clock::now().time_since_epoch();
+
+            auto it = m_tasks.begin();
+            for (; it != m_tasks.end() && it->first <= now; ++it)
+            {
+                it->second->execute();
+            }
+
+            m_tasks.erase(m_tasks.begin(), it);
+        }
+
+        ExpiryTimerImpl::Milliseconds ExpiryTimerImpl::remainingTimeForNext() const
+        {
+            const Milliseconds& expiredTime = m_tasks.begin()->first;
+
+            return std::chrono::duration_cast< Milliseconds >(expiredTime -
+                    std::chrono::system_clock::now().time_since_epoch()) + Milliseconds{ 1 };
+        }
+
+        void ExpiryTimerImpl::run()
+        {
+            auto hasTaskOrStop = [this](){ return !m_tasks.empty() || m_stop; };
+
+            std::unique_lock< std::mutex > lock{ m_mutex };
+
+            while(!m_stop)
+            {
+                m_cond.wait(lock, hasTaskOrStop);
+
+                if (m_stop) break;
+
+                m_cond.wait_for(lock, remainingTimeForNext());
+
+                executeExpired();
+            }
+        }
+
+
+        TimerTask::TimerTask(ExpiryTimerImpl::Id id, ExpiryTimerImpl::Callback cb) :
+            m_id{ id },
+            m_callback{ std::move(cb) }
+        {
+        }
+
+        void TimerTask::execute()
+        {
+            if (isExecuted()) return;
+
+            ExpiryTimerImpl::Id id { m_id };
+            m_id = INVALID_ID;
+
+            std::thread(std::move(m_callback), id).detach();
+
+            m_callback = ExpiryTimerImpl::Callback{ };
+        }
+
+        bool TimerTask::isExecuted() const
+        {
+            return m_id == INVALID_ID;
+        }
+
+        ExpiryTimerImpl::Id TimerTask::getId() const
+        {
+            return m_id;
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.h b/service/resource-encapsulation/src/common/expiryTimer/src/ExpiryTimerImpl.h
new file mode 100644 (file)
index 0000000..084ce3c
--- /dev/null
@@ -0,0 +1,128 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_IMPL_H_
+#define _EXPIRY_TIMER_IMPL_H_
+
+#include <functional>
+#include <map>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <condition_variable>
+#include <random>
+#include <unordered_set>
+#include <atomic>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class TimerTask;
+
+        class ExpiryTimerImpl
+        {
+        public:
+            typedef unsigned int Id;
+            typedef std::function< void(Id) > Callback;
+
+            typedef long long DelayInMillis;
+
+        private:
+            typedef std::chrono::milliseconds Milliseconds;
+
+        private:
+            ExpiryTimerImpl();
+            ~ExpiryTimerImpl();
+
+            ExpiryTimerImpl(const ExpiryTimerImpl&) = delete;
+            ExpiryTimerImpl& operator=(const ExpiryTimerImpl&) = delete;
+
+        public:
+            static ExpiryTimerImpl* getInstance();
+
+            std::shared_ptr< TimerTask > post(DelayInMillis, Callback);
+
+            bool cancel(Id);
+            size_t cancelAll(const std::unordered_set< std::shared_ptr<TimerTask > >&);
+
+        private:
+            static Milliseconds convertToTime(Milliseconds);
+
+            std::shared_ptr< TimerTask > addTask(Milliseconds, Callback, Id);
+
+            /**
+             * @pre The lock must be acquired with m_mutex.
+             */
+            bool containsId(Id) const;
+            Id generateId();
+
+            /**
+             * @pre The lock must be acquired with m_mutex.
+             */
+            void executeExpired();
+
+            /**
+             * @pre The lock must be acquired with m_mutex.
+             */
+            Milliseconds remainingTimeForNext() const;
+
+            void run();
+
+        private:
+            std::multimap< Milliseconds, std::shared_ptr< TimerTask > > m_tasks;
+
+            std::thread m_thread;
+            std::mutex m_mutex;
+            std::condition_variable m_cond;
+            bool m_stop;
+
+            std::mt19937 m_mt;
+            std::uniform_int_distribution< Id > m_dist;
+
+        };
+
+        class TimerTask
+        {
+        public:
+            TimerTask(ExpiryTimerImpl::Id, ExpiryTimerImpl::Callback);
+
+            TimerTask(const TimerTask&) = delete;
+            TimerTask(TimerTask&&) = delete;
+
+            TimerTask& operator=(const TimerTask&) = delete;
+            TimerTask& operator=(TimerTask&&) = delete;
+
+            bool isExecuted() const;
+            ExpiryTimerImpl::Id getId() const;
+
+        private:
+            void execute();
+
+        private:
+            std::atomic< ExpiryTimerImpl::Id > m_id;
+            ExpiryTimerImpl::Callback m_callback;
+
+            friend class ExpiryTimerImpl;
+        };
+
+    }
+}
+#endif //_EXPIRY_TIMER_IMPL_H_
diff --git a/service/resource-encapsulation/src/common/expiryTimer/unittests/ExpiryTimerTest.cpp b/service/resource-encapsulation/src/common/expiryTimer/unittests/ExpiryTimerTest.cpp
new file mode 100644 (file)
index 0000000..bf96c77
--- /dev/null
@@ -0,0 +1,332 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <mutex>
+#include <atomic>
+
+#include "RCSException.h"
+#include "ExpiryTimer.h"
+#include "ExpiryTimerImpl.h"
+
+using namespace OIC::Service;
+
+constexpr int TOLERANCE_IN_MILLIS{ 50 };
+
+class FunctionObject
+{
+public:
+    virtual ~FunctionObject() { }
+
+    virtual void execute(ExpiryTimerImpl::Id) { }
+};
+
+class ExpiryTimerImplTest: public TestWithMock
+{
+public:
+    void Proceed()
+    {
+        cond.notify_all();
+    }
+
+    void Wait(int waitingTime = TOLERANCE_IN_MILLIS)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+private:
+    std::condition_variable cond;
+    std::mutex mutex;
+};
+
+
+TEST_F(ExpiryTimerImplTest, PostThrowsIfDelayIsNegative)
+{
+    ASSERT_THROW(ExpiryTimerImpl::getInstance()->post(-1, [](ExpiryTimerImpl::Id){}), RCSException);
+}
+
+TEST_F(ExpiryTimerImplTest, PostThrowsIfCallbackIsEmpty)
+{
+    ASSERT_THROW(ExpiryTimerImpl::getInstance()->post(1, { }), RCSException);
+}
+
+TEST_F(ExpiryTimerImplTest, CallbackBeInvokedWithinTolerance)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Do(
+            [this](ExpiryTimerImpl::Id){
+                Proceed();
+            }
+    );
+
+    ExpiryTimerImpl::getInstance()->post(10,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+
+    Wait();
+}
+
+TEST_F(ExpiryTimerImplTest, CallbackBeInvokedWithTimerId)
+{
+    ExpiryTimerImpl::Id returnedId;
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Match(
+            [this, &returnedId](ExpiryTimerImpl::Id id){
+                return returnedId == id;
+            }
+    ).Do(
+            [this](ExpiryTimerImpl::Id){
+                Proceed();
+            }
+    );
+
+    returnedId = ExpiryTimerImpl::getInstance()->post(1,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1))->getId();
+
+    Wait();
+}
+
+TEST_F(ExpiryTimerImplTest, CanceledTaskBeNotCalled)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.NeverCall(functor, FunctionObject::execute);
+
+    ExpiryTimerImpl::Id id = ExpiryTimerImpl::getInstance()->post(10,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1))->getId();
+    ExpiryTimerImpl::getInstance()->cancel(id);
+    Wait(100);
+}
+
+TEST_F(ExpiryTimerImplTest, CancelReturnsTrueIfCanceledCorrectly)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    ExpiryTimerImpl::Id id = ExpiryTimerImpl::getInstance()->post(10,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1))->getId();
+
+    ASSERT_TRUE(ExpiryTimerImpl::getInstance()->cancel(id));
+}
+
+TEST_F(ExpiryTimerImplTest, CancelReturnsFalseIfAlreadyExecuted)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Do(
+        [this](ExpiryTimerImpl::Id){
+            Proceed();
+        }
+    );
+
+    ExpiryTimerImpl::Id id = ExpiryTimerImpl::getInstance()->post(1,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1))->getId();
+    Wait();
+
+    ASSERT_FALSE(ExpiryTimerImpl::getInstance()->cancel(id));
+}
+
+TEST_F(ExpiryTimerImplTest, CallbackBeInvokedWithinToleranceWithMultiplePost)
+{
+    constexpr int NUM_OF_POST{ 10000 };
+    std::atomic_int called{ 0 };
+
+    for (int i=0; i<NUM_OF_POST; ++i)
+    {
+        FunctionObject* functor = mocks.Mock< FunctionObject >();
+        mocks.OnCall(functor, FunctionObject::execute).Do(
+                [&called](ExpiryTimerImpl::Id)
+                {
+                    ++called;
+                }
+        );
+
+        ExpiryTimerImpl::getInstance()->post(rand() % 20 + 5,
+                std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    }
+
+    Wait(TOLERANCE_IN_MILLIS + 25);
+
+    ASSERT_EQ(NUM_OF_POST, called);
+}
+
+class ExpiryTimerTest: public TestWithMock
+{
+public:
+    ExpiryTimer timer;
+
+public:
+    void Proceed()
+    {
+        cond.notify_all();
+    }
+
+    void Wait(int waitingTime = TOLERANCE_IN_MILLIS)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+private:
+    std::condition_variable cond;
+    std::mutex mutex;
+};
+
+TEST_F(ExpiryTimerTest, PostThrowsIfDelayIsNegative)
+{
+    ASSERT_THROW(timer.post(-1, [](ExpiryTimer::Id){}), RCSException);
+}
+
+TEST_F(ExpiryTimerTest, PostThrowsIfCallbackIsEmpty)
+{
+    ASSERT_THROW(timer.post(1, { }), RCSException);
+}
+
+TEST_F(ExpiryTimerTest, CallbackBeInvokedWithinTolerance)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Do(
+            [this](ExpiryTimer::Id){
+                Proceed();
+            }
+    );
+
+    timer.post(10,
+            std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+
+    Wait();
+}
+
+TEST_F(ExpiryTimerTest, CallbackBeInvokedWithTimerId)
+{
+    ExpiryTimer::Id returnedId;
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Match(
+            [this, &returnedId](ExpiryTimer::Id id){
+                return returnedId == id;
+            }
+    ).Do(
+            [this](ExpiryTimer::Id){
+                Proceed();
+            }
+    );
+
+    returnedId = timer.post(1, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+
+    Wait();
+}
+
+TEST_F(ExpiryTimerTest, CanceledTaskBeNotCalled)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.NeverCall(functor, FunctionObject::execute);
+
+    auto id = timer.post(10, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    timer.cancel(id);
+    Wait(100);
+}
+
+TEST_F(ExpiryTimerTest, CancelReturnsTrueIfCanceledCorrectly)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    auto id = timer.post(10, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+
+    ASSERT_TRUE(timer.cancel(id));
+}
+
+TEST_F(ExpiryTimerTest, CancelReturnsFalseIfAlreadyExecuted)
+{
+    FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+    mocks.ExpectCall(functor, FunctionObject::execute).Do(
+        [this](ExpiryTimer::Id){
+            Proceed();
+        }
+    );
+
+    auto id = timer.post(1, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    Wait();
+
+    ASSERT_FALSE(timer.cancel(id));
+}
+
+TEST_F(ExpiryTimerTest, NumOfPendingReturnsNumberOfNotExecuted)
+{
+    constexpr size_t numOfFutureTask{ 100 };
+    constexpr size_t numOfShortDelayTask{ 100 };
+
+    for (size_t i=0; i<numOfFutureTask; ++i)
+    {
+        FunctionObject* functor = mocks.Mock< FunctionObject >();
+        mocks.OnCall(functor, FunctionObject::execute);
+
+        timer.post(1000, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    }
+
+    for (size_t i=0; i<numOfShortDelayTask; ++i)
+     {
+         FunctionObject* functor = mocks.Mock< FunctionObject >();
+         mocks.OnCall(functor, FunctionObject::execute);
+
+         timer.post(i, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+     }
+
+    Wait(numOfShortDelayTask + TOLERANCE_IN_MILLIS);
+
+    ASSERT_EQ(timer.getNumOfPending(), numOfFutureTask);
+}
+
+TEST_F(ExpiryTimerTest, CancelAllCancelsAllTasks)
+{
+    constexpr size_t numOfTask{ 100 };
+
+    for (size_t i=0; i<numOfTask; ++i)
+    {
+        FunctionObject* functor = mocks.Mock< FunctionObject >();
+        mocks.NeverCall(functor, FunctionObject::execute);
+
+        timer.post(50 + i, std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    }
+
+    timer.cancelAll();
+
+    Wait(200);
+}
+
+TEST_F(ExpiryTimerTest, AllTasksAreCancelledAfterTimerDestroyed)
+{
+    {
+        ExpiryTimer localTimer;
+        FunctionObject* functor = mocks.Mock< FunctionObject >();
+
+        mocks.NeverCall(functor, FunctionObject::execute);
+
+        localTimer.post(50,
+                std::bind(&FunctionObject::execute, functor, std::placeholders::_1));
+    }
+
+    Wait(200);
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h b/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h
new file mode 100644 (file)
index 0000000..6faaf8c
--- /dev/null
@@ -0,0 +1,222 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_ASSERTUTILS_H
+#define COMMON_INTERNAL_ASSERTUTILS_H
+
+#include <cstdint>
+
+#include <memory>
+
+#include <octypes.h>
+#include <OCException.h>
+
+#include <RCSException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        namespace Detail
+        {
+            struct NotOCStackResult;
+
+            template <typename FUNC, typename ...PARAMS>
+            struct ResultType
+            {
+                typedef decltype(std::declval<FUNC>()(std::declval<PARAMS>()...)) type;
+            };
+
+            template< typename A, typename B, typename ENABLER = void >
+            struct EnableIfTypeIs;
+
+            template< typename A >
+            struct EnableIfTypeIs< A, OCStackResult,
+                    typename std::enable_if< std::is_same< A, OCStackResult >::value >::type >
+            {
+                typedef void type;
+            };
+
+            template< typename A >
+            struct EnableIfTypeIs< A, NotOCStackResult,
+                    typename std::enable_if< !std::is_same< A, OCStackResult >::value >::type >
+            {
+                typedef A type;
+            };
+
+            template< typename T, typename = typename std::enable_if<
+                    std::is_class<T>::value && std::is_pointer<T>::value>::type >
+            struct EnableIfClassPointer
+            {
+                typedef void type;
+            };
+
+            template< typename T, typename = typename std::enable_if< std::is_class< T >::value > >
+            struct EnableIfClass
+            {
+                typedef void type;
+            };
+        }
+
+        inline void expectOCStackResult(OCStackResult actual,
+                std::initializer_list<OCStackResult> allowed)
+        {
+            for (auto r : allowed)
+            {
+                if (actual == r) return;
+            }
+
+            throw PlatformException(actual);
+        }
+
+        inline void expectOCStackResult(OCStackResult actual, OCStackResult expected)
+        {
+            if (actual != expected)
+            {
+                throw PlatformException(actual);
+            }
+        }
+
+        inline void expectOCStackResultOK(OCStackResult actual)
+        {
+            expectOCStackResult(actual, OC_STACK_OK);
+        }
+
+        template< typename FUNC, typename ...PARAMS >
+        typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
+                OCStackResult >::type
+        invokeOCFuncWithResultExpect(std::initializer_list<OCStackResult> allowed,
+                FUNC&& fn, PARAMS&& ...params)
+        {
+            try
+            {
+                expectOCStackResult(fn(std::forward< PARAMS >(params)...), std::move(allowed));
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+
+        template< typename FUNC, typename ...PARAMS >
+        typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
+                OCStackResult >::type
+        invokeOCFunc(FUNC&& fn, PARAMS&& ...params)
+        {
+            try
+            {
+                expectOCStackResultOK(fn(std::forward< PARAMS >(params)...));
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename FUNC, typename ...PARAMS >
+        typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
+                        Detail::NotOCStackResult >::type
+        invokeOCFunc(FUNC* fn, PARAMS&& ...params)
+        {
+            try
+            {
+                return fn(std::forward< PARAMS >(params)...);
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
+            typename Detail::EnableIfTypeIs<
+                decltype((obj->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
+                type
+        {
+            try
+            {
+                expectOCStackResultOK(obj->*fn(std::forward< PARAMS >(params)...));
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
+                typename Detail::EnableIfTypeIs<
+                    decltype((obj->*fn)(std::forward< PARAMS >(params)...)),
+                    Detail::NotOCStackResult>::
+                    type
+        {
+            try
+            {
+                obj->*fn(std::forward< PARAMS >(params)...);
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClass<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(const std::shared_ptr< OBJ >& obj, FUNC&& fn, PARAMS&& ...params) ->
+                typename Detail::EnableIfTypeIs<
+                    decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
+                    type
+        {
+            try
+            {
+                expectOCStackResultOK((obj.get()->*fn)(std::forward< PARAMS >(params)...));
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClass< OBJ >::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(const std::shared_ptr<OBJ>& obj, FUNC&& fn, PARAMS&& ...params) ->
+            typename Detail::EnableIfTypeIs<
+                   decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)),
+                   Detail::NotOCStackResult>::
+                   type
+        {
+            try
+            {
+                return (obj.get()->*fn)(std::forward< PARAMS >(params)...);
+            }
+            catch (const OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+    }
+}
+
+#endif // COMMON_INTERNAL_ASSERTUTILS_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/PresenceSubscriber.h b/service/resource-encapsulation/src/common/primitiveResource/include/PresenceSubscriber.h
new file mode 100644 (file)
index 0000000..e986cd3
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_PRESENCESUBSCRIBER_H
+#define COMMON_PRESENCESUBSCRIBER_H
+
+#include <string>
+#include <functional>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        typedef std::function< void(OCStackResult, const unsigned int, const std::string&) >
+            SubscribeCallback;
+
+        class PresenceSubscriber
+        {
+        public:
+            PresenceSubscriber();
+
+            PresenceSubscriber(PresenceSubscriber&&);
+
+            /**
+             * @throw PlatformException
+             */
+            PresenceSubscriber(const std::string& host, OCConnectivityType connectivityType,
+                    SubscribeCallback presenceHandler);
+
+            /**
+             * @throw PlatformException
+             */
+            PresenceSubscriber(const std::string& host, const std::string& resourceType,
+                    OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+            ~PresenceSubscriber();
+
+            PresenceSubscriber& operator=(PresenceSubscriber&&);
+
+            /**
+             * @throw PlatformException
+             */
+            void unsubscribe();
+
+            bool isSubscribing() const;
+
+        private:
+            OCDoHandle m_handle;
+        };
+
+        /**
+         * @throw PlatformException
+         */
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+        /**
+         * @throw PlatformException
+         */
+        void subscribePresence(OCDoHandle& handle, const std::string& host, const std::string& resourceType,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+        void unsubscribePresence(OCDoHandle handle);
+
+    }
+}
+
+#endif // COMMON_PRESENCESUBSCRIBER_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h
new file mode 100644 (file)
index 0000000..7b36f4f
--- /dev/null
@@ -0,0 +1,98 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_PRIMITIVERESOURCE_H
+#define COMMON_PRIMITIVERESOURCE_H
+
+#include <functional>
+#include <string>
+#include <vector>
+
+#include <OCResource.h>
+
+#include <ResponseStatement.h>
+#include <RCSAddress.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        typedef OC::HeaderOption::OCHeaderOption HeaderOption;
+        typedef std::vector<HeaderOption> HeaderOptions;
+
+        class RCSResourceAttributes;
+        class ResponseStatement;
+
+        class PrimitiveResource: public std::enable_shared_from_this< PrimitiveResource >
+        {
+        public:
+            typedef std::shared_ptr< PrimitiveResource > Ptr;
+            typedef std::shared_ptr< const PrimitiveResource > ConstPtr;
+
+            typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int)>
+                    GetCallback;
+
+            typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int)>
+                    SetCallback;
+
+            typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int, int)>
+                    ObserveCallback;
+
+        public:
+            static PrimitiveResource::Ptr create(const std::shared_ptr<OC::OCResource>&);
+
+            virtual ~PrimitiveResource() { };
+
+            virtual void requestGet(GetCallback) = 0;
+            virtual void requestSet(const RCSResourceAttributes&, SetCallback) = 0;
+            virtual void requestObserve(ObserveCallback) = 0;
+            virtual void cancelObserve() = 0;
+
+            virtual std::string getSid() const = 0;
+            virtual std::string getUri() const = 0;
+            virtual std::string getHost() const = 0;
+            virtual std::vector< std::string > getTypes() const = 0;
+            virtual std::vector< std::string > getInterfaces() const = 0;
+
+            virtual bool isObservable() const = 0;
+
+        protected:
+            PrimitiveResource() = default;
+
+            PrimitiveResource(const PrimitiveResource&) = delete;
+            PrimitiveResource(PrimitiveResource&&) = delete;
+
+            PrimitiveResource& operator=(const PrimitiveResource&) = delete;
+            PrimitiveResource& operator=(PrimitiveResource&&) = delete;
+        };
+
+        typedef std::function<void(std::shared_ptr<PrimitiveResource>)> DiscoverCallback;
+
+        void discoverResource(const std::string& host, const std::string& resourceURI,
+                OCConnectivityType, DiscoverCallback);
+
+        void discoverResource(const RCSAddress& address, const std::string& resourceURI,
+                DiscoverCallback);
+
+    }
+}
+
+#endif // COMMON_PRIMITIVERESOURCE_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h
new file mode 100644 (file)
index 0000000..fb22426
--- /dev/null
@@ -0,0 +1,179 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
+#define COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
+
+#include <PrimitiveResource.h>
+#include <ResponseStatement.h>
+#include <AssertUtils.h>
+
+#include <ResourceAttributesConverter.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        template< typename BaseResource >
+        class PrimitiveResourceImpl: public PrimitiveResource
+        {
+        private:
+            typedef std::shared_ptr< BaseResource > BaseResourcePtr;
+
+        private:
+            static ResponseStatement createResponseStatement(
+                    const OC::OCRepresentation& rep)
+            {
+                return ResponseStatement::create(
+                        ResourceAttributesConverter::fromOCRepresentation(rep));
+            }
+
+            template< typename CALLBACK, typename ...ARGS >
+            static inline void checkedCall(const std::weak_ptr< const PrimitiveResource >& resource,
+                    const CALLBACK& cb, ARGS&&... args)
+            {
+                auto checkedRes = resource.lock();
+
+                if (!checkedRes) return;
+
+                cb(std::forward< ARGS >(args)...);
+            }
+
+            template< typename CALLBACK >
+            static void safeCallback(const std::weak_ptr< const PrimitiveResource >& resource,
+                    const CALLBACK& cb, const HeaderOptions& headerOptions,
+                    const OC::OCRepresentation& rep, int errorCode)
+            {
+                checkedCall(resource, cb, headerOptions, createResponseStatement(rep), errorCode);
+            }
+
+            static void safeObserveCallback(const std::weak_ptr< const PrimitiveResource >& res,
+                    const PrimitiveResource::ObserveCallback& cb,
+                    const HeaderOptions& headerOptions, const OC::OCRepresentation& rep,
+                    int errorCode, int sequenceNumber)
+            {
+                checkedCall(res, cb, headerOptions, createResponseStatement(rep), errorCode,
+                        sequenceNumber);
+            }
+
+            std::weak_ptr< PrimitiveResource > WeakFromThis()
+            {
+                return shared_from_this();
+            }
+
+            std::weak_ptr< const PrimitiveResource > WeakFromThis() const
+            {
+                return shared_from_this();
+            }
+
+        public:
+            PrimitiveResourceImpl(const BaseResourcePtr& baseResource) :
+                    m_baseResource{ baseResource }
+            {
+            }
+
+            void requestGet(GetCallback callback)
+            {
+                using namespace std::placeholders;
+
+                typedef OCStackResult(BaseResource::*GetFunc)(
+                        const OC::QueryParamsMap&, OC::GetCallback);
+
+                invokeOC(m_baseResource, static_cast< GetFunc >(&BaseResource::get),
+                        OC::QueryParamsMap{ },
+                        std::bind(safeCallback< GetCallback >, WeakFromThis(),
+                                std::move(callback), _1, _2, _3));
+            }
+
+            void requestSet(const RCSResourceAttributes& attrs, SetCallback callback)
+            {
+                using namespace std::placeholders;
+
+                typedef OCStackResult(BaseResource::*PutFunc)(
+                        const OC::OCRepresentation&,
+                        const OC::QueryParamsMap&, OC::PutCallback);
+
+                invokeOC(m_baseResource, static_cast< PutFunc >(&BaseResource::put),
+                        ResourceAttributesConverter::toOCRepresentation(attrs),
+                        OC::QueryParamsMap{ },
+                        std::bind(safeCallback< SetCallback >, WeakFromThis(),
+                                std::move(callback), _1, _2, _3));
+            }
+
+            void requestObserve(ObserveCallback callback)
+            {
+                using namespace std::placeholders;
+
+                typedef OCStackResult (BaseResource::*ObserveFunc)(OC::ObserveType,
+                        const OC::QueryParamsMap&, OC::ObserveCallback);
+
+                invokeOC(m_baseResource, static_cast< ObserveFunc >(&BaseResource::observe),
+                        OC::ObserveType::ObserveAll, OC::QueryParamsMap{ },
+                        std::bind(safeObserveCallback, WeakFromThis(),
+                                                       std::move(callback), _1, _2, _3, _4));
+            }
+
+            void cancelObserve()
+            {
+                typedef OCStackResult (BaseResource::*CancelObserveFunc)();
+
+                invokeOC(m_baseResource,
+                        static_cast< CancelObserveFunc >(&BaseResource::cancelObserve));
+            }
+
+            std::string getSid() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::sid);
+            }
+
+            std::string getUri() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::uri);
+            }
+
+            std::string getHost() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::host);
+            }
+
+            std::vector< std::string > getTypes() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::getResourceTypes);
+            }
+
+            std::vector< std::string > getInterfaces() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::getResourceInterfaces);
+            }
+
+            bool isObservable() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::isObservable);
+            }
+
+        private:
+            BaseResourcePtr m_baseResource;
+        };
+
+    }
+}
+
+#endif // COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/RCSAddressDetail.h b/service/resource-encapsulation/src/common/primitiveResource/include/RCSAddressDetail.h
new file mode 100644 (file)
index 0000000..0281ee3
--- /dev/null
@@ -0,0 +1,49 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OIC_SERVICE_RCSADDRESSDETAIL_H
+#define OIC_SERVICE_RCSADDRESSDETAIL_H
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSAddress;
+
+        class RCSAddressDetail
+        {
+        public:
+            static const RCSAddressDetail* getDetail(const RCSAddress&);
+
+            RCSAddressDetail(const std::string& addr);
+            RCSAddressDetail(std::string&& addr);
+
+            const std::string& getAddress() const;
+
+        private:
+            std::string m_addr;
+        };
+
+    }
+}
+
+#endif // OIC_SERVICE_RCSADDRESSDETAIL_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesConverter.h b/service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesConverter.h
new file mode 100644 (file)
index 0000000..a5b6033
--- /dev/null
@@ -0,0 +1,154 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+#define COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+
+#include <RCSResourceAttributes.h>
+
+#include <OCRepresentation.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class ResourceAttributesConverter
+        {
+        private:
+            ResourceAttributesConverter() = delete;
+
+            class ResourceAttributesBuilder
+            {
+            public:
+                ResourceAttributesBuilder() = default;
+
+                void insertItemTo(const OC::OCRepresentation::AttributeItem& item)
+                {
+                    switch (item.type())
+                    {
+                        case OC::AttributeType::Null:
+                            return putValue(item.attrname(), nullptr);
+
+                        case OC::AttributeType::Integer:
+                            return putValue(item.attrname(), item.getValue< int >());
+
+                        case OC::AttributeType::Double:
+                            return putValue(item.attrname(), item.getValue< double >());
+
+                        case OC::AttributeType::Boolean:
+                            return putValue(item.attrname(), item.getValue< bool >());
+
+                        case OC::AttributeType::String:
+                            return putValue(item.attrname(), item.getValue< std::string >());
+
+                        case OC::AttributeType::OCRepresentation:
+                            return putValue(item.attrname(),
+                                    ResourceAttributesConverter::fromOCRepresentation(
+                                            item.getValue< OC::OCRepresentation >()));
+
+                        case OC::AttributeType::Vector:
+                            // RCSResourceAttributes doesn't support vector yet!
+                            return;
+                    }
+                }
+
+                RCSResourceAttributes&& extract()
+                {
+                    return std::move(m_target);
+                }
+
+            private:
+                template< typename T >
+                typename std::enable_if<RCSResourceAttributes::is_supported_type< T >::value >::type
+                putValue(const std::string& key, T && value)
+                {
+                    m_target[key] = std::forward< T >(value);
+                }
+
+                template< typename T >
+                typename std::enable_if<!RCSResourceAttributes::is_supported_type< T >::value >::type
+                putValue(const std::string& key, T && value)
+                {
+                }
+
+            private:
+                RCSResourceAttributes m_target;
+            };
+
+            class OCRepresentationBuilder
+            {
+            public:
+                OCRepresentationBuilder() = default;
+
+                template< typename T >
+                void operator()(const std::string& key, const T& value)
+                {
+                    m_target[key] = value;
+                }
+
+                void operator()(const std::string& key, const std::nullptr_t&)
+                {
+                    m_target.setNULL(key);
+                }
+
+                void operator()(const std::string& key, const RCSResourceAttributes& value)
+                {
+                    m_target[key] = ResourceAttributesConverter::toOCRepresentation(value);
+                }
+
+                OC::OCRepresentation&& extract()
+                {
+                    return std::move(m_target);
+                }
+
+            private:
+                OC::OCRepresentation m_target;
+            };
+
+        public:
+            static RCSResourceAttributes fromOCRepresentation(
+                    const OC::OCRepresentation& ocRepresentation)
+            {
+                ResourceAttributesBuilder builder;
+
+                for (const auto& item : ocRepresentation)
+                {
+                    builder.insertItemTo(item);
+                }
+
+                return builder.extract();
+            }
+
+            static OC::OCRepresentation toOCRepresentation(
+                    const RCSResourceAttributes& resourceAttributes)
+            {
+                OCRepresentationBuilder builder;
+
+                resourceAttributes.visit(builder);
+
+                return builder.extract();
+            }
+        };
+
+    }
+}
+
+#endif // COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesUtils.h b/service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesUtils.h
new file mode 100644 (file)
index 0000000..f83b003
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_RESOURCEATTRIBUTESUTILS_H
+#define COMMON_RESOURCEATTRIBUTESUTILS_H
+
+#include <vector>
+#include <string>
+
+#include <RCSResourceAttributes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        typedef std::pair< std::string, RCSResourceAttributes::Value > AttrKeyValuePair;
+        typedef std::vector< AttrKeyValuePair > AttrKeyValuePairs;
+
+        bool acceptableAttributes(const RCSResourceAttributes& dest, const RCSResourceAttributes& attr);
+
+        bool acceptableAttributeValue(const RCSResourceAttributes::Value& dest,
+                const RCSResourceAttributes::Value& value);
+
+        AttrKeyValuePairs replaceAttributes(RCSResourceAttributes& dest,
+                const RCSResourceAttributes& attrs);
+    }
+}
+
+#endif // COMMON_RESOURCEATTRIBUTESUTILS_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/ResponseStatement.h b/service/resource-encapsulation/src/common/primitiveResource/include/ResponseStatement.h
new file mode 100644 (file)
index 0000000..7181e75
--- /dev/null
@@ -0,0 +1,74 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_RESPONSESTATEMENT_H
+#define COMMON_RESPONSESTATEMENT_H
+
+#include <string>
+#include <vector>
+
+#include <RCSResourceAttributes.h>
+
+namespace OC
+{
+    class OCRepresentation;
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSResourceAttributes;
+
+        class ResponseStatement
+        {
+        public:
+            static ResponseStatement create(const OC::OCRepresentation&);
+            static ResponseStatement create(RCSResourceAttributes&&);
+
+            explicit ResponseStatement(const RCSResourceAttributes&);
+            explicit ResponseStatement(RCSResourceAttributes&&);
+
+            ResponseStatement(RCSResourceAttributes&&, std::string&& uri,
+                    std::vector< std::string >&& resourceTypes,
+                    std::vector< std::string >&& resourceInterfaces);
+
+            ResponseStatement(ResponseStatement&&) = default;
+
+            ResponseStatement& operator=(ResponseStatement&&) = default;
+
+            std::string getUri() const;
+            std::vector< std::string > getResourceTypes() const;
+            std::vector< std::string > getResourceInterfaces() const;
+
+            const RCSResourceAttributes& getAttributes() const;
+
+        private:
+            RCSResourceAttributes m_attrs;
+
+            std::string m_uri;
+            std::vector< std::string > m_resourceTypes;
+            std::vector< std::string > m_resourceInterfaces;
+        };
+
+    }
+}
+
+#endif // COMMON_RESPONSESTATEMENT_H
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/PresenceSubscriber.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/PresenceSubscriber.cpp
new file mode 100644 (file)
index 0000000..5c1ab3f
--- /dev/null
@@ -0,0 +1,122 @@
+//******************************************************************
+//
+// 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 <PresenceSubscriber.h>
+
+#include <AssertUtils.h>
+
+#include <OCPlatform.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler)
+        {
+            typedef OCStackResult (*SubscribePresence)(OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, OCConnectivityType, SubscribeCallback);
+
+            invokeOCFunc(static_cast<SubscribePresence>(OC::OCPlatform::subscribePresence),
+                    handle, host, connectivityType, std::move(presenceHandler));
+        }
+
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                const std::string& resourceType, OCConnectivityType connectivityType,
+                SubscribeCallback presenceHandler)
+        {
+            typedef OCStackResult (*SubscribePresence)(OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, const std::string&, OCConnectivityType, SubscribeCallback);
+
+            invokeOCFunc(static_cast<SubscribePresence>(OC::OCPlatform::subscribePresence),
+                    handle, host, resourceType, connectivityType, std::move(presenceHandler));
+        }
+
+        void unsubscribePresence(OCDoHandle handle)
+        {
+            invokeOCFunc(OC::OCPlatform::unsubscribePresence, handle);
+        }
+
+
+        PresenceSubscriber::PresenceSubscriber() :
+            m_handle{ nullptr }
+        {
+        }
+
+        PresenceSubscriber::PresenceSubscriber(PresenceSubscriber&& from) :
+            m_handle{ nullptr }
+        {
+            std::swap(m_handle, from.m_handle);
+        }
+
+        PresenceSubscriber::PresenceSubscriber(const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler) :
+                m_handle{ nullptr }
+        {
+            subscribePresence(m_handle, host, connectivityType, std::move(presenceHandler));
+        }
+
+        PresenceSubscriber::PresenceSubscriber(const std::string& host,
+                const std::string& resourceType, OCConnectivityType connectivityType,
+                SubscribeCallback presenceHandler) :
+                m_handle{ nullptr }
+        {
+            subscribePresence(m_handle, host, resourceType, connectivityType,
+                    std::move(presenceHandler));
+        }
+
+        PresenceSubscriber::~PresenceSubscriber()
+        {
+            if (m_handle)
+            {
+                try
+                {
+                    unsubscribe();
+                }
+                catch (...)
+                {
+                }
+            }
+        }
+
+        PresenceSubscriber& PresenceSubscriber::operator=(PresenceSubscriber&& from)
+        {
+            unsubscribe();
+            std::swap(m_handle, from.m_handle);
+            return *this;
+        }
+
+        void PresenceSubscriber::unsubscribe()
+        {
+            if (m_handle == nullptr) return;
+
+            unsubscribePresence(m_handle);
+
+            m_handle = nullptr;
+        }
+
+        bool PresenceSubscriber::isSubscribing() const
+        {
+            return m_handle != nullptr;
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/PrimitiveResource.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/PrimitiveResource.cpp
new file mode 100644 (file)
index 0000000..ef2dd9b
--- /dev/null
@@ -0,0 +1,63 @@
+//******************************************************************
+//
+// 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 <PrimitiveResource.h>
+
+#include <PrimitiveResourceImpl.h>
+#include <AssertUtils.h>
+#include <RCSAddressDetail.h>
+
+#include <OCPlatform.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        PrimitiveResource::Ptr PrimitiveResource::create(
+                const std::shared_ptr<OC::OCResource>& ptr)
+        {
+            return std::shared_ptr< PrimitiveResource >(
+                    new PrimitiveResourceImpl< OC::OCResource >{ ptr });
+        }
+
+        void discoverResource(const std::string& host, const std::string& resourceURI,
+                OCConnectivityType connectivityType, DiscoverCallback callback)
+        {
+            typedef OCStackResult (*FindResource)(const std::string&, const std::string&,
+                    OCConnectivityType, OC::FindCallback);
+
+            invokeOCFunc(static_cast< FindResource >(OC::OCPlatform::findResource),
+                    host, resourceURI, connectivityType, static_cast < OC::FindCallback >(
+                        std::bind(std::move(callback),
+                                std::bind(&PrimitiveResource::create, std::placeholders::_1))));
+        }
+
+        void discoverResource(const RCSAddress& address, const std::string& resourceURI,
+                DiscoverCallback callback)
+        {
+            const RCSAddressDetail* addressDetail = RCSAddressDetail::getDetail(address);
+
+            discoverResource(addressDetail->getAddress(), resourceURI, OCConnectivityType{ },
+                    std::move(callback));
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/RCSAddress.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/RCSAddress.cpp
new file mode 100644 (file)
index 0000000..3bc4021
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// 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 <RCSAddress.h>
+#include <RCSAddressDetail.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        RCSAddress::RCSAddress(const std::shared_ptr< RCSAddressDetail >& ptr) :
+                m_detail{ ptr }
+        {
+        }
+
+        RCSAddress RCSAddress::multicast()
+        {
+            return RCSAddress{ std::make_shared< RCSAddressDetail >("") };
+        }
+
+        RCSAddress RCSAddress::unicast(const std::string& address)
+        {
+            return RCSAddress{ std::make_shared< RCSAddressDetail >(address) };
+        }
+
+        RCSAddress RCSAddress::unicast(std::string&& address)
+        {
+            return RCSAddress{ std::make_shared< RCSAddressDetail >(std::move(address)) };
+        }
+
+
+
+        RCSAddressDetail::RCSAddressDetail(const std::string& address) :
+                m_addr{ address }
+        {
+        }
+
+        RCSAddressDetail::RCSAddressDetail(std::string&& address) :
+                m_addr{ std::move(address) }
+        {
+        }
+
+        const RCSAddressDetail* RCSAddressDetail::getDetail(const RCSAddress& rcsAddr)
+        {
+            return rcsAddr.m_detail.get();
+        }
+
+        const std::string& RCSAddressDetail::getAddress() const
+        {
+            return m_addr;
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp
new file mode 100644 (file)
index 0000000..02e8dce
--- /dev/null
@@ -0,0 +1,114 @@
+//******************************************************************
+//
+// 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 <RCSException.h>
+
+#include <OCException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RCSException::RCSException()
+        {
+        }
+
+        RCSException::RCSException(const std::string& what) :
+                m_what{ what }
+        {
+        }
+
+        RCSException::RCSException(std::string&& what) :
+                m_what{ std::move(what) }
+        {
+        }
+
+        RCSException::~RCSException() noexcept
+        {
+        }
+
+        const char* RCSException::what() const noexcept
+        {
+            return m_what.c_str();
+        }
+
+
+        PlatformException::PlatformException(OCStackResult reason) :
+                RCSException{ "Failed : " + OC::OCException::reason(reason) },
+                m_reason { reason }
+        {
+        }
+
+        OCStackResult PlatformException::getReasonCode() const
+        {
+            return m_reason;
+        }
+
+        std::string PlatformException::getReason() const
+        {
+            return  OC::OCException::reason(m_reason);
+        }
+
+
+        BadRequestException::BadRequestException(const std::string& what) :
+                RCSException{ what }
+        {
+        }
+
+        BadRequestException::BadRequestException(std::string&& what) :
+                RCSException{ std::move(what) }
+        {
+        }
+
+
+        InvalidParameterException::InvalidParameterException(const std::string& what) :
+                RCSException{ what }
+        {
+        }
+
+        InvalidParameterException::InvalidParameterException(std::string&& what) :
+                RCSException{ std::move(what) }
+        {
+        }
+
+
+        BadGetException::BadGetException(const std::string& what) :
+                RCSException{ what }
+        {
+        }
+
+        BadGetException::BadGetException(std::string&& what) :
+                RCSException{ std::move(what) }
+        {
+        }
+
+
+        InvalidKeyException::InvalidKeyException(const std::string& what) :
+                RCSException{ what }
+        {
+        }
+
+        InvalidKeyException::InvalidKeyException(std::string&& what) :
+                RCSException{ std::move(what) }
+        {
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp
new file mode 100644 (file)
index 0000000..99de4a6
--- /dev/null
@@ -0,0 +1,604 @@
+//******************************************************************
+//
+// 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 <RCSResourceAttributes.h>
+
+#include <ResourceAttributesUtils.h>
+#include <ResourceAttributesConverter.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/mpl/advance.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/deref.hpp>
+
+namespace
+{
+
+    using namespace OIC::Service;
+
+    class ToStringVisitor: public boost::static_visitor< std::string >
+    {
+    public:
+        ToStringVisitor() = default;
+        ToStringVisitor(const ToStringVisitor&) = delete;
+        ToStringVisitor(ToStringVisitor&&) = delete;
+
+        ToStringVisitor& operator=(const ToStringVisitor&) = delete;
+        ToStringVisitor& operator=(ToStringVisitor&&) = delete;
+
+        template < typename T >
+        std::string operator()(const T& value) const
+        {
+            return boost::lexical_cast<std::string>(value);
+        }
+
+        std::string operator()(std::nullptr_t) const
+        {
+            return "";
+        }
+
+        std::string operator()(bool value) const
+        {
+            return value ? "true" : "false";
+        }
+
+        std::string operator()(const std::string& value) const
+        {
+            return value;
+        }
+
+        std::string operator()(const OIC::Service::RCSResourceAttributes&) const
+        {
+            return "Attributes";
+        }
+    };
+
+    class TypeVisitor: public boost::static_visitor< RCSResourceAttributes::Type >
+    {
+    public:
+        TypeVisitor() = default;
+        TypeVisitor(const TypeVisitor&) = delete;
+        TypeVisitor(TypeVisitor&&) = delete;
+
+        TypeVisitor& operator=(const TypeVisitor&) = delete;
+        TypeVisitor& operator=(TypeVisitor&&) = delete;
+
+        template< typename T >
+        RCSResourceAttributes::Type operator()(const T& value) const
+        {
+            return RCSResourceAttributes::Type::typeOf(value);
+        }
+
+    };
+
+    template< int >
+    struct Int2Type {};
+
+    template< typename T >
+    struct TypeInfoConverter;
+
+    template< >
+    struct TypeInfoConverter< int >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::INT;
+    };
+
+    template< >
+    struct TypeInfoConverter< std::nullptr_t >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::NULL_T;
+    };
+
+    template< >
+    struct TypeInfoConverter< double >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::DOUBLE;
+    };
+
+    template< >
+    struct TypeInfoConverter< bool >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::BOOL;
+    };
+
+    template< >
+    struct TypeInfoConverter< std::string >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::STRING;
+    };
+
+    template< >
+    struct TypeInfoConverter< RCSResourceAttributes >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::ATTRIBUTES;
+    };
+
+    struct TypeInfo
+    {
+        RCSResourceAttributes::TypeId typeId;
+
+        template< typename TRAIT >
+        constexpr TypeInfo(TRAIT) :
+                typeId{ TRAIT::typeId }
+        {
+        }
+
+        template< typename VARIANT, int POS >
+        static constexpr TypeInfo get()
+        {
+            return TypeInfo(TypeInfoConverter<
+                        typename boost::mpl::deref<
+                            typename boost::mpl::advance<
+                                typename boost::mpl::begin< typename VARIANT::types>::type,
+                                boost::mpl::int_< POS >
+                            >::type
+                        >::type >{ });
+        }
+    };
+
+    template< typename VARIANT, int POS >
+    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >)
+    {
+        auto&& vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
+        vec.push_back(TypeInfo::get< VARIANT, POS >());
+        return vec;
+    }
+
+    template< typename VARIANT >
+    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >)
+    {
+        return { TypeInfo::get< VARIANT, 0 >() };
+    }
+
+    template< typename VARIANT >
+    inline TypeInfo getTypeInfo(int which)
+    {
+        static constexpr int variantEnd = boost::mpl::size< typename VARIANT::types >::value - 1;
+        static const std::vector< TypeInfo > typeInfos = getTypeInfo< VARIANT >(
+                Int2Type< variantEnd >{ });
+
+        return typeInfos[which];
+    }
+
+} // unnamed namespace
+
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RCSResourceAttributes::Value::ComparisonHelper::ComparisonHelper(const Value& v) :
+                m_valueRef(v)
+        {
+        }
+
+        bool RCSResourceAttributes::Value::ComparisonHelper::operator==
+                (const Value::ComparisonHelper& rhs) const
+        {
+            return *m_valueRef.m_data == *rhs.m_valueRef.m_data;
+        }
+
+        bool operator==(const RCSResourceAttributes::Type& lhs, const RCSResourceAttributes::Type& rhs)
+        {
+            return lhs.m_which == rhs.m_which;
+        }
+
+        bool operator!=(const RCSResourceAttributes::Type& lhs, const RCSResourceAttributes::Type& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        bool operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs,
+                const RCSResourceAttributes::Value::ComparisonHelper& rhs)
+        {
+            return lhs.operator==(rhs);
+        }
+
+        bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs,
+                const RCSResourceAttributes::Value::ComparisonHelper& rhs)
+        {
+            return !lhs.operator==(rhs);
+        }
+
+        bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs)
+        {
+            return lhs.m_values == rhs.m_values;
+        }
+
+        bool operator!=(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        auto RCSResourceAttributes::Type::getId() const -> TypeId
+        {
+            return ::getTypeInfo< ValueVariant >(m_which).typeId;
+        }
+
+        RCSResourceAttributes::Value::Value() :
+                m_data{ new ValueVariant{} }
+        {
+        }
+
+        RCSResourceAttributes::Value::Value(const Value& from) :
+                m_data{ new ValueVariant{ *from.m_data } }
+        {
+        }
+
+        RCSResourceAttributes::Value::Value(Value&& from) :
+                m_data{ new ValueVariant{} }
+        {
+            m_data->swap(*from.m_data);
+        }
+
+        RCSResourceAttributes::Value::Value(const char* value) :
+                m_data{ new ValueVariant{ std::string{ value } } }
+        {
+        }
+
+        auto RCSResourceAttributes::Value::operator=(const Value& rhs) -> Value&
+        {
+            *m_data = *rhs.m_data;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::Value::operator=(Value&& rhs) -> Value&
+        {
+            *m_data = ValueVariant{};
+            m_data->swap(*rhs.m_data);
+            return *this;
+        }
+
+        auto RCSResourceAttributes::Value::operator=(const char* rhs) -> Value&
+        {
+            *m_data = std::string{ rhs };
+            return *this;
+        }
+
+        auto RCSResourceAttributes::Value::operator=(std::nullptr_t) -> Value&
+        {
+            *m_data = nullptr;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::Value::getType() const -> Type
+        {
+            return boost::apply_visitor(TypeVisitor(), *m_data);
+        }
+
+        std::string RCSResourceAttributes::Value::toString() const
+        {
+            return boost::apply_visitor(ToStringVisitor(), *m_data);
+        }
+
+        void RCSResourceAttributes::Value::swap(Value& rhs)
+        {
+            m_data.swap(rhs.m_data);
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()(
+                iterator* iter) const -> result_type
+        {
+            return iter->m_cur->first;
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()(
+                const_iterator* iter) const -> result_type
+        {
+            return iter->m_cur->first;
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (iterator* iter)
+                -> result_type
+        {
+            return iter->m_cur->second;
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (const_iterator*)
+                -> result_type
+        {
+            // should not reach here.
+            throw BadGetException("");
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()(
+                iterator*iter) const -> result_type
+        {
+            return iter->m_cur->second;
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()(
+                const_iterator* iter) const -> result_type
+        {
+            return iter->m_cur->second;
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::key() const -> const std::string&
+        {
+            return boost::apply_visitor(m_keyVisitor, m_iterRef);
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::value() const -> const Value&
+        {
+            return boost::apply_visitor(m_constValueVisitor, m_iterRef);
+        }
+
+        auto RCSResourceAttributes::KeyValuePair::value() -> Value&
+        {
+            return boost::apply_visitor(m_valueVisitor, m_iterRef);
+        }
+
+        RCSResourceAttributes::KeyValuePair::KeyValuePair(boost::variant<iterator*,
+                const_iterator*>&& ref) :
+                m_iterRef{ ref }
+        {
+        }
+
+
+        RCSResourceAttributes::iterator::iterator() :
+                m_cur{ base_iterator{ } },
+                m_keyValuePair{ this }
+        {
+        }
+
+        RCSResourceAttributes::iterator::iterator(base_iterator&& iter) :
+                m_cur{ std::move(iter) },
+                m_keyValuePair{ this }
+        {
+        }
+
+        auto RCSResourceAttributes::iterator::operator*() -> KeyValuePair&
+        {
+            return m_keyValuePair;
+        }
+
+        auto RCSResourceAttributes::iterator::iterator::operator->() -> KeyValuePair*
+        {
+            return &m_keyValuePair;
+        }
+
+        auto RCSResourceAttributes::iterator::operator++() -> iterator&
+        {
+            ++m_cur;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::iterator::operator++(int) -> iterator
+        {
+            iterator iter(*this);
+            ++(*this);
+            return iter;
+        }
+
+        bool RCSResourceAttributes::iterator::operator==(const iterator& rhs) const
+        {
+            return m_cur == rhs.m_cur;
+        }
+
+        bool RCSResourceAttributes::iterator::operator!=(const iterator& rhs) const
+        {
+            return !(*this == rhs);
+        }
+
+
+        RCSResourceAttributes::const_iterator::const_iterator() :
+                m_cur{ base_iterator{} }, m_keyValuePair{ this }
+        {
+        }
+
+        RCSResourceAttributes::const_iterator::const_iterator(base_iterator&& iter) :
+                m_cur{ iter }, m_keyValuePair{ this }
+        {
+        }
+
+        RCSResourceAttributes::const_iterator::const_iterator(
+                const RCSResourceAttributes::iterator& iter) :
+                m_cur{ iter.m_cur }, m_keyValuePair{ this }
+        {
+        }
+
+        auto RCSResourceAttributes::const_iterator::operator=(const RCSResourceAttributes::iterator& iter)
+            -> const_iterator& {
+            m_cur = iter.m_cur;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::const_iterator::operator*() const -> reference
+        {
+            return m_keyValuePair;
+        }
+        auto RCSResourceAttributes::const_iterator::operator->() const -> pointer
+        {
+            return &m_keyValuePair;
+        }
+
+        auto RCSResourceAttributes::const_iterator::operator++() -> const_iterator&
+        {
+            ++m_cur;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::const_iterator::operator++(int) -> const_iterator
+        {
+            const_iterator iter(*this);
+            ++(*this);
+            return iter;
+        }
+
+        bool RCSResourceAttributes::const_iterator::operator==(const const_iterator& rhs) const
+        {
+            return m_cur == rhs.m_cur;
+        }
+
+        bool RCSResourceAttributes::const_iterator::operator!=(const const_iterator& rhs) const
+        {
+            return !(*this == rhs);
+        }
+
+        auto RCSResourceAttributes::begin() -> iterator
+        {
+            return iterator{ m_values.begin() };
+        }
+
+        auto RCSResourceAttributes::end() -> iterator
+        {
+            return iterator{ m_values.end() };
+        }
+
+        auto RCSResourceAttributes::begin() const -> const_iterator
+        {
+            return const_iterator{ m_values.begin() };
+        }
+
+        auto RCSResourceAttributes::end() const -> const_iterator
+        {
+            return const_iterator{ m_values.end() };
+        }
+
+        auto RCSResourceAttributes::cbegin() const -> const_iterator
+        {
+            return const_iterator{ m_values.begin() };
+        }
+
+        auto RCSResourceAttributes::cend() const -> const_iterator
+        {
+            return const_iterator{ m_values.end() };
+        }
+
+        auto RCSResourceAttributes::operator[](const std::string& key) -> Value&
+        {
+            return m_values[key];
+        }
+
+        auto RCSResourceAttributes::operator[](std::string&& key) -> Value&
+        {
+            return m_values[std::move(key)];
+        }
+
+        auto RCSResourceAttributes::at(const std::string& key) -> Value&
+        {
+            try
+            {
+                return m_values.at(key);
+            }
+            catch (const std::out_of_range&)
+            {
+                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+            }
+        }
+
+        auto RCSResourceAttributes::at(const std::string& key) const -> const Value&
+        {
+            try
+            {
+                return m_values.at(key);
+            }
+            catch (const std::out_of_range&)
+            {
+                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+            }
+        }
+
+        void RCSResourceAttributes::clear()
+        {
+            return m_values.clear();
+        }
+
+        bool RCSResourceAttributes::erase(const std::string& key)
+        {
+            return m_values.erase(key) == 1U;
+        }
+
+        bool RCSResourceAttributes::contains(const std::string& key) const
+        {
+            return m_values.find(key) != m_values.end();
+        }
+
+        bool RCSResourceAttributes::empty() const
+        {
+            return m_values.empty();
+        }
+
+        size_t RCSResourceAttributes::size() const
+        {
+            return m_values.size();
+        }
+
+
+        bool acceptableAttributeValue(const RCSResourceAttributes::Value& dest,
+                const RCSResourceAttributes::Value& value)
+        {
+            if (dest.getType() != value.getType())
+            {
+                return false;
+            }
+
+            static_assert(RCSResourceAttributes::is_supported_type< RCSResourceAttributes >::value,
+                    "RCSResourceAttributes doesn't have RCSResourceAttributes recursively.");
+            if (dest.getType().getId() == RCSResourceAttributes::TypeId::ATTRIBUTES
+                    && !acceptableAttributes(dest.get< RCSResourceAttributes >(),
+                            value.get< RCSResourceAttributes >()))
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        bool acceptableAttributes(const RCSResourceAttributes& dest, const RCSResourceAttributes& attr)
+        {
+            for (const auto& kv : attr)
+            {
+                if (!dest.contains(kv.key()))
+                {
+                    return false;
+                }
+
+                if (!acceptableAttributeValue(dest.at(kv.key()), kv.value()))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        AttrKeyValuePairs replaceAttributes(RCSResourceAttributes& dest,
+                const RCSResourceAttributes& newAttrs)
+        {
+            AttrKeyValuePairs replacedList;
+
+            for (const auto& kv : newAttrs)
+            {
+                if (dest[kv.key()] != kv.value())
+                {
+                    RCSResourceAttributes::Value replacedValue;
+                    replacedValue.swap(dest[kv.key()]);
+                    dest[kv.key()] = kv.value();
+
+                    replacedList.push_back(AttrKeyValuePair{ kv.key(), std::move(replacedValue) });
+                }
+            }
+
+            return replacedList;
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/ResponseStatement.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/ResponseStatement.cpp
new file mode 100644 (file)
index 0000000..444547a
--- /dev/null
@@ -0,0 +1,82 @@
+//******************************************************************
+//
+// 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 <ResponseStatement.h>
+
+#include <ResourceAttributesConverter.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResponseStatement ResponseStatement::create(const OC::OCRepresentation& ocRepresentation)
+        {
+            return ResponseStatement::create(
+                    ResourceAttributesConverter::fromOCRepresentation(ocRepresentation));
+        }
+
+        ResponseStatement ResponseStatement::create(RCSResourceAttributes&& attrs)
+        {
+            return ResponseStatement(std::move(attrs));
+        }
+
+        ResponseStatement::ResponseStatement(const RCSResourceAttributes& attrs) :
+                m_attrs{ attrs }
+        {
+        }
+
+        ResponseStatement::ResponseStatement(RCSResourceAttributes&& attrs) :
+                m_attrs{ std::move(attrs) }
+        {
+        }
+
+        ResponseStatement::ResponseStatement(RCSResourceAttributes&& attrs, std::string&& uri,
+                std::vector< std::string >&& resourceTypes,
+                std::vector< std::string >&& resourceInterfaces) :
+                m_attrs{ std::move(attrs) },
+                m_uri{ std::move(uri) },
+                m_resourceTypes { std::move(resourceTypes) },
+                m_resourceInterfaces{ std::move(resourceInterfaces) }
+        {
+        }
+
+        std::string ResponseStatement::getUri() const
+        {
+            return m_uri;
+        }
+
+        std::vector< std::string > ResponseStatement::getResourceTypes() const
+        {
+            return m_resourceTypes;
+        }
+
+        std::vector< std::string > ResponseStatement::getResourceInterfaces() const
+        {
+            return m_resourceInterfaces;
+        }
+
+        const RCSResourceAttributes& ResponseStatement::getAttributes() const
+        {
+            return m_attrs;
+        }
+
+    }
+}
+
diff --git a/service/resource-encapsulation/src/common/primitiveResource/unittests/PresenceSubscriberTest.cpp b/service/resource-encapsulation/src/common/primitiveResource/unittests/PresenceSubscriberTest.cpp
new file mode 100644 (file)
index 0000000..845737a
--- /dev/null
@@ -0,0 +1,164 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <PresenceSubscriber.h>
+#include <RCSException.h>
+
+#include <OCPlatform.h>
+
+using namespace OIC::Service;
+
+typedef OCStackResult (*SubscribePresence1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+typedef OCStackResult (*SubscribePresence2)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, const std::string&, OCConnectivityType, SubscribeCallback);
+
+const std::string HOST{ "host" };
+const OCConnectivityType CONTYPE{ };
+
+
+class PresenceSubscriberNonMemberTest: public TestWithMock
+{
+public:
+    OCDoHandle handle;
+};
+
+TEST_F(PresenceSubscriberNonMemberTest, OCPlatformSubscribePresenceWillBeCalled)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< SubscribePresence1 >(OC::OCPlatform::subscribePresence))
+                        .With(_, HOST,CONTYPE, _).Return(OC_STACK_OK);
+
+    subscribePresence(handle, HOST, CONTYPE, SubscribeCallback());
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, SubscribePresenceThrowsIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< SubscribePresence1>(OC::OCPlatform::subscribePresence))
+                    .Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(subscribePresence(handle, "", CONTYPE, SubscribeCallback()), PlatformException);
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, OCPlatformUnsubscribePresenceWillBeCalled)
+{
+    mocks.ExpectCallFuncOverload(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+
+    unsubscribePresence(handle);
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, UnsubscribePresenceThrowIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(unsubscribePresence(handle), PlatformException);
+}
+
+class PresenceSubscriberTest: public TestWithMock
+{
+protected:
+    void SetUp() {
+        mocks.OnCallFuncOverload(
+                static_cast< SubscribePresence1 >(OC::OCPlatform::subscribePresence)).Do(
+
+            [](OC::OCPlatform::OCPresenceHandle& handle, const std::string&,
+                    OCConnectivityType, SubscribeCallback) -> OCStackResult
+            {
+                handle = reinterpret_cast<OC::OCPlatform::OCPresenceHandle>(1);
+                return OC_STACK_OK;
+            }
+        );
+
+        mocks.OnCallFunc(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+    }
+
+};
+
+TEST_F(PresenceSubscriberTest, IsNotSubscribingWhenCreatedWithDefaultConstructor)
+{
+    PresenceSubscriber subscriber;
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorCallOCPlatformSubscribe)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< SubscribePresence1 >(OC::OCPlatform::subscribePresence))
+                     .With(_, HOST, CONTYPE, _).Return(OC_STACK_OK);
+
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorWithResourceTypeCallOCPlatformSubscribe)
+{
+    const std::string resType { "resType" };
+
+    mocks.ExpectCallFuncOverload(
+            static_cast< SubscribePresence2 >(OC::OCPlatform::subscribePresence))
+                     .With(_, HOST, resType, CONTYPE, _).Return(OC_STACK_OK);
+
+    PresenceSubscriber subscriber{ HOST, resType, CONTYPE, SubscribeCallback() };
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorThrowsIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< SubscribePresence1 >(OC::OCPlatform::subscribePresence))
+                    .Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(PresenceSubscriber(HOST, CONTYPE, SubscribeCallback()), PlatformException);
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingIfConstructedWithoutException)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    ASSERT_TRUE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingOfMovedSubscriberReturnsFalse)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    PresenceSubscriber newSubscriber{ std::move(subscriber) };
+
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingOfMovedSubscriberWithAssignmentReturnsFalse)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    PresenceSubscriber newSubscriber;
+
+    newSubscriber = std::move(subscriber);
+
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, UnsubscribeWillBeCalledWhenSubscriberIsDestoryed)
+{
+    mocks.ExpectCallFunc(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+}
diff --git a/service/resource-encapsulation/src/common/primitiveResource/unittests/PrimitiveResourceTest.cpp b/service/resource-encapsulation/src/common/primitiveResource/unittests/PrimitiveResourceTest.cpp
new file mode 100644 (file)
index 0000000..8f15ad5
--- /dev/null
@@ -0,0 +1,209 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <PrimitiveResourceImpl.h>
+#include <AssertUtils.h>
+
+#include <OCResource.h>
+#include <OCPlatform.h>
+
+using namespace OIC::Service;
+
+const std::string KEY{ "key" };
+
+class FakeOCResource
+{
+public:
+    virtual ~FakeOCResource() {};
+
+    virtual OCStackResult get(const OC::QueryParamsMap&, OC::GetCallback) = 0;
+
+    virtual OCStackResult put(
+            const OC::OCRepresentation&, const OC::QueryParamsMap&, OC::PutCallback) = 0;
+
+    virtual OCStackResult observe(
+            OC::ObserveType, const OC::QueryParamsMap&, OC::ObserveCallback) = 0;
+
+    virtual OCStackResult cancelObserve() = 0;
+
+    virtual std::string sid() const = 0;
+    virtual std::string uri() const = 0;
+    virtual std::string host() const = 0;
+    virtual std::vector<std::string> getResourceTypes() const = 0;
+    virtual std::vector<std::string> getResourceInterfaces() const = 0;
+
+    virtual bool isObservable() const = 0;
+};
+
+class PrimitiveResourceTest: public TestWithMock
+{
+public:
+    PrimitiveResource::Ptr resource;
+    FakeOCResource* fakeResource;
+
+protected:
+    void SetUp() {
+        TestWithMock::SetUp();
+
+        fakeResource = mocks.Mock< FakeOCResource >();
+
+        resource.reset(new PrimitiveResourceImpl< FakeOCResource >{
+            std::shared_ptr< FakeOCResource >(fakeResource, [](FakeOCResource*) {}) });
+    }
+};
+
+TEST_F(PrimitiveResourceTest, RequestGetInvokesOCResourceGet)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::get).Return(OC_STACK_OK);
+
+    resource->requestGet(PrimitiveResource::GetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestGetThrowsOCResourceGetReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::get).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestGet(PrimitiveResource::GetCallback()), PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetInvokesOCResourcePut)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::put).Return(OC_STACK_OK);
+
+    resource->requestSet(RCSResourceAttributes{ }, PrimitiveResource::SetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetThrowsOCResourcePutReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::put).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestSet(RCSResourceAttributes{ }, PrimitiveResource::SetCallback()),
+            PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetPassResourceAttributesToOCResourcePut)
+{
+    constexpr int value{ -200 };
+
+    RCSResourceAttributes attrs;
+
+    mocks.ExpectCall(fakeResource, FakeOCResource::put).Match(
+            [](const OC::OCRepresentation& ocRep, const OC::QueryParamsMap&, OC::PutCallback)
+            {
+                return ocRep.getValue<int>(KEY) == value;
+            }
+        ).Return(OC_STACK_OK);
+
+    attrs[KEY] = value;
+
+    resource->requestSet(attrs, PrimitiveResource::SetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestObserveInvokesOCResourceObserve)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::observe).Return(OC_STACK_OK);
+
+    resource->requestObserve(PrimitiveResource::ObserveCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestObserveThrowsOCResourceObserveReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::observe).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestObserve(PrimitiveResource::ObserveCallback()), PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, DelegteGettersToOCResource)
+{
+    const std::string host{ "host_test_" };
+    const std::string uri{ "uri/test/" };
+
+    mocks.OnCall(fakeResource, FakeOCResource::isObservable).Return(false);
+    mocks.OnCall(fakeResource, FakeOCResource::host).Return(host);
+    mocks.OnCall(fakeResource, FakeOCResource::uri).Return(uri);
+
+    ASSERT_FALSE(resource->isObservable());
+    ASSERT_EQ(host, resource->getHost());
+    ASSERT_EQ(uri, resource->getUri());
+}
+
+
+TEST_F(PrimitiveResourceTest, ResponseStatementHasSameValuesWithOCRepresentationReceived)
+{
+    constexpr int errorCode{ 202 };
+    constexpr int value{ 1999 };
+
+    mocks.OnCall(fakeResource, FakeOCResource::get).Do(
+            [](const OC::QueryParamsMap&, OC::GetCallback cb)
+            {
+                OC::OCRepresentation ocRep;
+                ocRep[KEY] = value;
+
+                cb(OC::HeaderOptions(), ocRep, errorCode);
+                return OC_STACK_OK;
+            }
+        ).Return(OC_STACK_OK);
+
+    resource->requestGet(
+            [&](const HeaderOptions&, const ResponseStatement& response, int e)
+            {
+                ASSERT_EQ(e, errorCode);
+                ASSERT_EQ(response.getAttributes().at(KEY).get<int>(), value);
+            }
+        );
+}
+
+
+class DiscoverResourceTest: public TestWithMock
+{
+public:
+    typedef OCStackResult (*FindResource)(const std::string&, const std::string&,
+            OCConnectivityType, OC::FindCallback);
+
+public:
+    static void discovered(std::shared_ptr< PrimitiveResource >) {}
+};
+
+TEST_F(DiscoverResourceTest, CallbackIsInvokedWhenResourceIsDiscovered)
+{
+    mocks.ExpectCallFuncOverload(static_cast<FindResource>(OC::OCPlatform::findResource)).Do(
+            [](const std::string&, const std::string&, OCConnectivityType,
+                    OC::FindCallback callback) -> OCStackResult
+            {
+                callback(nullptr);
+                return OC_STACK_OK;
+            }
+        ).Return(OC_STACK_OK);
+
+    mocks.ExpectCallFunc(discovered);
+
+    discoverResource("", "", OCConnectivityType{ }, discovered);
+}
+
+TEST_F(DiscoverResourceTest, ThrowsdWhenOCPlatformFindResourceReturnsNotOK)
+{
+    mocks.ExpectCallFuncOverload(static_cast<FindResource>(OC::OCPlatform::findResource)).
+            Return(OC_STACK_ERROR);
+
+    EXPECT_THROW(discoverResource("", "", OCConnectivityType{ }, discovered), PlatformException);
+}
+
diff --git a/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp b/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp
new file mode 100644 (file)
index 0000000..e60d242
--- /dev/null
@@ -0,0 +1,436 @@
+//******************************************************************
+//
+// 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 <RCSResourceAttributes.h>
+#include <ResourceAttributesConverter.h>
+#include <ResourceAttributesUtils.h>
+
+#include <gtest/gtest.h>
+
+using namespace testing;
+using namespace OIC::Service;
+
+constexpr char KEY[]{ "key" };
+
+class ResourceAttributesTest: public Test
+{
+public:
+    RCSResourceAttributes resourceAttributes;
+};
+
+TEST_F(ResourceAttributesTest, InitialSizeIsZero)
+{
+    ASSERT_EQ(0U, resourceAttributes.size());
+    ASSERT_TRUE(resourceAttributes.empty());
+}
+
+TEST_F(ResourceAttributesTest, InsertWithSquareBracket)
+{
+    resourceAttributes[KEY] = 1;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == 1);
+}
+
+TEST_F(ResourceAttributesTest, ValueThrowsIfTypeDoesNotMatch)
+{
+     resourceAttributes[KEY] = 1;
+    auto& valueRef = resourceAttributes[KEY];
+
+    ASSERT_THROW(valueRef.get< std::string >(), BadGetException);
+}
+
+TEST_F(ResourceAttributesTest, GettingWithAtThrowsIfThereIsNoMatchedValue)
+{
+    ASSERT_THROW(resourceAttributes.at(KEY), InvalidKeyException);
+}
+
+TEST_F(ResourceAttributesTest, CopyingValueDoesNotShareState)
+{
+    const char arbitraryStr[] { "ftryb457" };
+    resourceAttributes[KEY] = 1;
+
+    RCSResourceAttributes::Value copied { resourceAttributes[KEY] };
+    copied = arbitraryStr;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == 1);
+    ASSERT_TRUE(copied == arbitraryStr);
+}
+
+TEST_F(ResourceAttributesTest, IsNullWhenAssignmentNullptr)
+{
+    resourceAttributes[KEY] = nullptr;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == nullptr);
+}
+
+TEST_F(ResourceAttributesTest, ValueChangedIfPutWithSameKey)
+{
+    resourceAttributes[KEY] = "string";
+    resourceAttributes[KEY] = true;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == true);
+}
+
+TEST_F(ResourceAttributesTest, ObjectIsEmptyAfterMoved)
+{
+    resourceAttributes[KEY] = 1;
+
+    RCSResourceAttributes moved{ std::move(resourceAttributes) };
+
+    ASSERT_TRUE(resourceAttributes.empty());
+}
+
+TEST_F(ResourceAttributesTest, GettingWithAtThrowsAfterRemoved)
+{
+    resourceAttributes[KEY] = 1;
+
+    resourceAttributes.erase(KEY);
+
+    ASSERT_THROW(resourceAttributes.at(KEY), InvalidKeyException);
+}
+
+TEST_F(ResourceAttributesTest, NoDataErasedIfKeyDoesNotMatch)
+{
+    ASSERT_FALSE(resourceAttributes.erase(KEY));
+}
+
+TEST_F(ResourceAttributesTest, ChangeValueWithAtGetter)
+{
+    resourceAttributes[KEY] = 1;
+
+    resourceAttributes.at(KEY) = "after";
+
+    ASSERT_TRUE(resourceAttributes[KEY] == "after");
+}
+
+TEST_F(ResourceAttributesTest, CanHaveNestedResourceAttributes)
+{
+    RCSResourceAttributes nested;
+    nested["nested"] = "nested_value";
+    resourceAttributes[KEY] = nested;
+
+    ASSERT_TRUE("nested_value" == resourceAttributes[KEY].get<RCSResourceAttributes>()["nested"]);
+}
+
+TEST_F(ResourceAttributesTest, ToStringReturnsStringForValue)
+{
+    resourceAttributes[KEY] = true;
+
+    ASSERT_EQ("true", resourceAttributes[KEY].toString());
+}
+
+TEST_F(ResourceAttributesTest, ToStringReturnsEmptyStringForNullValue)
+{
+    resourceAttributes[KEY] = nullptr;
+
+    ASSERT_EQ("", resourceAttributes[KEY].toString());
+}
+
+
+class ResourceAttributesIteratorTest: public Test
+{
+public:
+    RCSResourceAttributes resourceAttributes;
+};
+
+TEST_F(ResourceAttributesIteratorTest, BeginEqualsEndWhenEmpty)
+{
+    ASSERT_TRUE(resourceAttributes.begin() == resourceAttributes.end());
+}
+
+TEST_F(ResourceAttributesIteratorTest, CanIteratesWithForeach)
+{
+    resourceAttributes["first"] = 1;
+    resourceAttributes["second"] = 2;
+
+    int count = 0;
+
+    for (auto& i : resourceAttributes) {
+        i.key();
+        ++count;
+    }
+
+    ASSERT_EQ(2, count);
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratesWithRef)
+{
+    const char arbitraryStr[] { "ftryb457" };
+    resourceAttributes[KEY] = 1;
+
+    for (auto& i : resourceAttributes) {
+        i.value() = arbitraryStr;
+    }
+
+    ASSERT_TRUE(resourceAttributes[KEY] == arbitraryStr);
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorIsCopyable)
+{
+    RCSResourceAttributes::iterator it;
+
+    it = resourceAttributes.begin();
+
+    ASSERT_EQ(it, resourceAttributes.begin());
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorIndicateNextItemAfterIncreased)
+{
+    resourceAttributes[KEY] = 1;
+
+    RCSResourceAttributes::iterator it = resourceAttributes.begin();
+
+    it++;
+
+    ASSERT_TRUE(it == resourceAttributes.end());
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorCanBeConvertedIntoConstIterator)
+{
+    resourceAttributes[KEY] = 1;
+    RCSResourceAttributes::const_iterator it { resourceAttributes.begin() };
+    it = resourceAttributes.cbegin();
+
+    it++;
+
+    ASSERT_TRUE(it == resourceAttributes.cend());
+}
+
+TEST_F(ResourceAttributesIteratorTest, ConstIteratorIsUsedForConst)
+{
+    resourceAttributes[KEY] = 1;
+    const RCSResourceAttributes& constAttrs = resourceAttributes;
+
+    auto iter = constAttrs.begin();
+
+    ASSERT_TRUE((std::is_same<decltype(iter), RCSResourceAttributes::const_iterator>::value));
+}
+
+
+TEST(ResourceAttributesValueTest, MovedValueHasNull)
+{
+    RCSResourceAttributes::Value one { 1 };
+    RCSResourceAttributes::Value another { std::move(one) };
+
+    ASSERT_EQ(nullptr, one);
+}
+
+TEST(ResourceAttributesValueTest, MovedValueWithAssignmentHasNull)
+{
+    RCSResourceAttributes::Value one { 1 };
+    RCSResourceAttributes::Value another;
+
+    another = std::move(one);
+
+    ASSERT_EQ(nullptr, one);
+}
+
+TEST(ResourceAttributesValueTest, SameValuesAreEqual)
+{
+    RCSResourceAttributes::Value one { 1 };
+    RCSResourceAttributes::Value another { 1 };
+
+    ASSERT_EQ(one, another);
+}
+
+TEST(ResourceAttributesValueTest, DifferentValuesAreNotEqual)
+{
+    RCSResourceAttributes::Value one { 1 };
+    RCSResourceAttributes::Value another { 2 };
+
+    ASSERT_NE(one, another);
+}
+
+TEST(ResourceAttributesValueTest, ValuesCanBeSwapped)
+{
+    constexpr int i { 0 };
+    constexpr char str[]{ "abc" };
+
+    RCSResourceAttributes::Value intValue { i };
+    RCSResourceAttributes::Value strValue { str };
+
+    intValue.swap(strValue);
+
+    ASSERT_EQ(str, intValue);
+    ASSERT_EQ(i, strValue);
+}
+
+TEST(ResourceAttributesTypeTest, TypeIdMatchesTypeOfValue)
+{
+    RCSResourceAttributes::Value intValue { 0 };
+
+    ASSERT_EQ(intValue.getType().getId(), RCSResourceAttributes::TypeId::INT);
+}
+
+TEST(ResourceAttributesTypeTest, TypeCanBeConstructedFromValue)
+{
+    RCSResourceAttributes::Value intValue { 1 };
+
+    RCSResourceAttributes::Type t = RCSResourceAttributes::Type::typeOf(0);
+
+    ASSERT_EQ(intValue.getType(), t);
+}
+
+TEST(ResourceAttributesConverterTest, OCRepresentationCanBeConvertedIntoResourceAttributes)
+{
+    constexpr double value = 9876;
+    OC::OCRepresentation ocRep;
+    ocRep[KEY] = value;
+
+    RCSResourceAttributes resourceAttributes{
+        ResourceAttributesConverter::fromOCRepresentation(ocRep) };
+
+    ASSERT_TRUE(value == resourceAttributes[KEY]);
+}
+
+
+TEST(ResourceAttributesConverterTest, NestedOCRepresentationCanBeConvertedIntoResourceAttributes)
+{
+    std::string nested_value { "nested" };
+    OC::OCRepresentation ocRep;
+    OC::OCRepresentation nested;
+    nested[KEY] = nested_value;
+    ocRep[KEY] = nested;
+
+    RCSResourceAttributes resourceAttributes{
+        ResourceAttributesConverter::fromOCRepresentation(ocRep) };
+
+    ASSERT_TRUE(nested_value == resourceAttributes[KEY].get<RCSResourceAttributes>()[KEY]);
+}
+
+
+TEST(ResourceAttributesConverterTest, ResourceAttributesCanBeConvertedIntoOCRepresentation)
+{
+    double value { 3453453 };
+    RCSResourceAttributes resourceAttributes;
+    resourceAttributes[KEY] = value;
+
+    OC::OCRepresentation ocRep{
+        ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
+
+    ASSERT_TRUE(value == ocRep[KEY].getValue<double>());
+}
+
+TEST(ResourceAttributesConverterTest, NestedResourceAttributesCanBeConvertedIntoOCRepresentation)
+{
+    std::string nested_value { "nested" };
+    RCSResourceAttributes resourceAttributes;
+    RCSResourceAttributes nested;
+    nested[KEY] = nested_value;
+    resourceAttributes[KEY] = nested;
+
+    OC::OCRepresentation ocRep{
+        ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
+
+    ASSERT_EQ(nested_value,
+            ocRep[KEY].getValue<OC::OCRepresentation>()[KEY].getValue<std::string>());
+}
+
+TEST(ResourceAttributesConverterTest, OCRepresentationNullTypeIsNullptrInResourceAttributes)
+{
+    OC::OCRepresentation ocRep;
+    ocRep.setNULL(KEY);
+
+    RCSResourceAttributes resourceAttributes{
+        ResourceAttributesConverter::fromOCRepresentation(ocRep) };
+
+    ASSERT_EQ(nullptr, resourceAttributes[KEY]);
+}
+
+TEST(ResourceAttributesConverterTest, OCRepresentationHasNullWhenResourceAttributeIsNullptr)
+{
+    RCSResourceAttributes resourceAttributes;
+    resourceAttributes[KEY] = nullptr;
+
+    OC::OCRepresentation ocRep{
+        ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
+
+    ASSERT_TRUE(ocRep.isNULL(KEY));
+}
+
+
+
+class ResourceAttributesUtilTest: public Test
+{
+public:
+    RCSResourceAttributes resourceAttributes;
+
+protected:
+    void SetUp()
+    {
+        resourceAttributes[KEY] = 1;
+    }
+};
+
+TEST_F(ResourceAttributesUtilTest, EmptyAttributesIsAcceptable)
+{
+    ASSERT_TRUE(acceptableAttributes(resourceAttributes, RCSResourceAttributes()));
+}
+
+TEST_F(ResourceAttributesUtilTest, AttributesItselfIsAcceptable)
+{
+    ASSERT_TRUE(acceptableAttributes(resourceAttributes, resourceAttributes));
+}
+
+TEST_F(ResourceAttributesUtilTest, UnknownKeyIsNotAcceptable)
+{
+    RCSResourceAttributes newAttrs;
+    newAttrs["unknown"] = 1;
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+TEST_F(ResourceAttributesUtilTest, DifferentTypeWithOriginalIsNotAcceptable)
+{
+    RCSResourceAttributes newAttrs;
+    newAttrs[KEY] = "";
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+
+TEST_F(ResourceAttributesUtilTest, DifferentTypeOfNestedAttributeIsNotAcceptable)
+{
+    constexpr char KEY_NESTED_ATTR[]{ "nested" };
+    constexpr char KEY_NESTED_VALUE[]{ "nested_value" };
+
+    RCSResourceAttributes nested;
+    nested[KEY_NESTED_VALUE] = -99;
+    resourceAttributes[KEY_NESTED_ATTR] = nested;
+
+
+    RCSResourceAttributes newAttrs;
+    nested[KEY_NESTED_VALUE] = "abc";
+    newAttrs[KEY_NESTED_ATTR] = nested;
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+TEST_F(ResourceAttributesUtilTest, ReplaceWillOverwriteOriginal)
+{
+    constexpr char NEW_VALUE[]{ "newValue" };
+
+    RCSResourceAttributes newAttrs;
+    newAttrs[KEY] = NEW_VALUE;
+
+    replaceAttributes(resourceAttributes, newAttrs);
+
+    ASSERT_EQ(NEW_VALUE, resourceAttributes[KEY]);
+}
diff --git a/service/resource-encapsulation/src/common/utils/include/ScopeLogger.h b/service/resource-encapsulation/src/common/utils/include/ScopeLogger.h
new file mode 100644 (file)
index 0000000..018e538
--- /dev/null
@@ -0,0 +1,91 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_UTILS_SCOPELOGGER_H
+#define COMMON_UTILS_SCOPELOGGER_H
+
+#include "logger.h"
+
+#ifdef TB_LOG
+#include <exception>
+
+namespace OIC
+{
+    namespace Service
+    {
+        namespace Logging
+        {
+
+            class ScopeLogger
+            {
+            public:
+                ScopeLogger(LogLevel level, const char* tag, const char* scopeName) :
+                    m_level{ level },
+                    m_tag{ tag },
+                    m_scopeName{ scopeName }
+                {
+                    static constexpr char DEFAULT_ENTER_STR[]{ "IN" };
+
+                    OC_LOG_V(m_level, m_tag, "%s %s", m_scopeName, DEFAULT_ENTER_STR);
+                }
+
+                ~ScopeLogger()
+                {
+                    static constexpr char DEFAULT_EXIT_STR[]{ "OUT" };
+
+                    if (std::uncaught_exception())
+                    {
+                        OC_LOG_V(m_level, m_tag, "%s %s by stack unwinding (uncaught exception)",
+                                m_scopeName, DEFAULT_EXIT_STR);
+                    }
+                    else
+                    {
+                        OC_LOG_V(m_level, m_tag, "%s %s", m_scopeName, DEFAULT_EXIT_STR);
+                    }
+                }
+
+                ScopeLogger(const ScopeLogger&) = delete;
+                ScopeLogger(ScopeLogger&&) = delete;
+
+                ScopeLogger& operator=(const ScopeLogger&) = delete;
+                ScopeLogger& operator=(ScopeLogger&&) = delete;
+
+            private:
+                const LogLevel m_level;
+                const char* m_tag;
+                const char* m_scopeName;
+            };
+        }
+
+    }
+}
+
+#define SCOPE_LOG(level, tag, scopeName) \
+            Logging::ScopeLogger rcsScopeLogger__((level), (tag), (scopeName))
+
+#define SCOPE_LOG_F(level, tag) SCOPE_LOG((level), (tag), __func__)
+
+#else
+#define SCOPE_LOG_F(level, tag)
+#define SCOPE_LOG(level, tag, scopeName)
+#endif
+
+
+#endif // COMMON_UTILS_SCOPELOGGER_H
diff --git a/service/resource-encapsulation/src/common/utils/include/UnitTestHelper.h b/service/resource-encapsulation/src/common/utils/include/UnitTestHelper.h
new file mode 100644 (file)
index 0000000..3a9e490
--- /dev/null
@@ -0,0 +1,48 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_UTILS_UNITTESTHELPER_H
+#define COMMON_UTILS_UNITTESTHELPER_H
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+class TestWithMock: public testing::Test
+{
+public:
+    MockRepository mocks;
+
+protected:
+    virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
+
+    virtual void TearDown() {
+        try
+        {
+            mocks.VerifyAll();
+        }
+        catch (...)
+        {
+            mocks.reset();
+            throw;
+        }
+    }
+};
+
+#endif // COMMON_UTILS_UNITTESTHELPER_H
diff --git a/service/resource-encapsulation/src/resourceBroker/include/BrokerTypes.h b/service/resource-encapsulation/src/resourceBroker/include/BrokerTypes.h
new file mode 100644 (file)
index 0000000..8ef780f
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RB_BROKERTYPES_H_
+#define RB_BROKERTYPES_H_
+
+#include <iostream>
+#include <functional>
+#include <list>
+
+#include "logger.h"
+#include "PrimitiveResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        #define BROKER_TAG PCF("BROKER")
+        #define BROKER_DEVICE_PRESENCE_TIMEROUT (15000l)
+        #define BROKER_SAFE_SECOND (5l)
+        #define BROKER_SAFE_MILLISECOND (BROKER_SAFE_SECOND * (1000))
+        #define BROKER_TRANSPORT OCConnectivityType::CT_ADAPTER_IP
+
+        /*
+         * @BROKER_STATE
+         * brief : resourcePresence state
+         * ALIVE       - It means that 'getCB' function receives 'OK' message
+         * REQUESTED   - It means that broker receives the request for presence checking
+         * LOST_SIGNAL - In case that 'getCB' function receives the message except 'OK'
+         * DESTROYED   - In case that the presence checking is dismissed for the resource ,
+         *               or there is no matched value in the Broker Callback list
+         * NONE        - To be determined.
+         */
+        enum class BROKER_STATE
+        {
+            ALIVE = 0,
+            REQUESTED,
+            LOST_SIGNAL,
+            DESTROYED,
+            NONE
+        };
+
+        /*
+         * @DEVICE_STATE
+         * brief : devicePresence state
+         * ALIVE       - It means that 'subscribeCB' function receives 'OK' message
+         * REQUESTED   - It means that broker receives the request for presence checking
+         * LOST_SIGNAL - In case that 'subscribeCB' function receives the message except 'OK'
+         */
+        enum class DEVICE_STATE
+        {
+            ALIVE = 0,
+            REQUESTED,
+            LOST_SIGNAL
+        };
+
+        enum class BROKER_MODE
+        {
+            DEVICE_PRESENCE_MODE = 0,
+            NON_PRESENCE_MODE
+        };
+
+        typedef unsigned int BrokerID;
+
+        typedef std::function<void(BROKER_STATE)> BrokerCB;
+        struct BrokerRequesterInfo
+        {
+            BrokerRequesterInfo(BrokerID _id, BrokerCB _cb) : brokerId(_id), brokerCB(_cb){}
+            BrokerID brokerId;
+            BrokerCB brokerCB;
+        };
+        typedef std::shared_ptr<BrokerRequesterInfo> BrokerRequesterInfoPtr;
+
+        class ResourcePresence;
+        class DevicePresence;
+
+        typedef std::function<void(std::shared_ptr<OC::OCResource>)> FindCB;
+
+        typedef std::shared_ptr<PrimitiveResource> PrimitiveResourcePtr;
+
+        typedef std::shared_ptr<ResourcePresence> ResourcePresencePtr;
+        typedef std::shared_ptr<DevicePresence> DevicePresencePtr;
+        typedef std::list< ResourcePresencePtr > PresenceList;
+
+        struct BrokerCBResourcePair
+        {
+            BrokerCBResourcePair(ResourcePresencePtr pResource, BrokerCB cb)
+            : pResource(pResource), brokerCB(cb){}
+            ResourcePresencePtr pResource;
+            BrokerCB brokerCB;
+        };
+        typedef std::map<BrokerID, BrokerCBResourcePair> BrokerIDMap;
+
+        typedef std::function<void(OCStackResult, const unsigned int,
+                const std::string&)> SubscribeCB;
+
+        typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int)> RequestGetCB;
+        typedef std::function<void(long long)> TimerCB;
+    } // namespace Service
+} // namespace OIC
+
+#endif // RB_BROKERTYPES_H_
diff --git a/service/resource-encapsulation/src/resourceBroker/include/DeviceAssociation.h b/service/resource-encapsulation/src/resourceBroker/include/DeviceAssociation.h
new file mode 100644 (file)
index 0000000..1f3bc2a
--- /dev/null
@@ -0,0 +1,58 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RB_DEVICEASSOCIATION_H_
+#define RB_DEVICEASSOCIATION_H_
+
+#include <list>
+#include <string>
+#include <algorithm>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        class DeviceAssociation {
+        public:
+
+            static DeviceAssociation * getInstance();
+
+            DevicePresencePtr findDevice(const std::string & address);
+            void addDevice(DevicePresencePtr dPresence);
+            void removeDevice(DevicePresencePtr dPresence);
+            bool isEmptyDeviceList();
+
+        private:
+            DeviceAssociation();
+            ~DeviceAssociation();
+
+            static DeviceAssociation * s_instance;
+            static std::mutex s_mutexForCreation;
+            static std::list< DevicePresencePtr > s_deviceList;
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RB_DEVICEASSOCIATION_H_ */
diff --git a/service/resource-encapsulation/src/resourceBroker/include/DevicePresence.h b/service/resource-encapsulation/src/resourceBroker/include/DevicePresence.h
new file mode 100644 (file)
index 0000000..a964e65
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RB_DEVICEPRESENCE_H_
+#define RB_DEVICEPRESENCE_H_
+
+#include <list>
+#include <string>
+#include <boost/atomic.hpp>
+
+#include "BrokerTypes.h"
+#include "ResourcePresence.h"
+#include "PresenceSubscriber.h"
+#include "ExpiryTimer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class DevicePresence
+        {
+        public:
+            typedef long long TimerID;
+
+            DevicePresence();
+            ~DevicePresence();
+
+            void initializeDevicePresence(PrimitiveResourcePtr pResource);
+
+            void addPresenceResource(ResourcePresence * rPresence);
+            void removePresenceResource(ResourcePresence * rPresence);
+
+            bool isEmptyResourcePresence() const;
+            const std::string getAddress() const;
+            DEVICE_STATE getDeviceState() const;
+        private:
+            std::list<ResourcePresence * > resourcePresenceList;
+
+            std::string address;
+            boost::atomic<DEVICE_STATE> state;
+            boost::atomic_bool isRunningTimeOut;
+
+            std::mutex timeoutMutex;
+            std::condition_variable condition;
+
+            ExpiryTimer presenceTimer;
+            TimerID presenceTimerHandle;
+            TimerCB pTimeoutCB;
+            SubscribeCB pSubscribeRequestCB;
+            PresenceSubscriber presenceSubscriber;
+
+            void changeAllPresenceMode(BROKER_MODE mode);
+            void subscribeCB(OCStackResult ret,const unsigned int seq, const std::string& Hostaddress);
+            void timeOutCB(TimerID id);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RB_DEVICEPRESENCE_H_ */
diff --git a/service/resource-encapsulation/src/resourceBroker/include/ResourceBroker.h b/service/resource-encapsulation/src/resourceBroker/include/ResourceBroker.h
new file mode 100644 (file)
index 0000000..56e2545
--- /dev/null
@@ -0,0 +1,83 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RB_RESOURCEBROKER_H_
+#define RB_RESOURCEBROKER_H_
+
+#include <functional>
+#include <list>
+#include <string>
+#include <algorithm>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+#include "ResourcePresence.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceBroker
+        {
+        public:
+            class InvalidParameterException: public RCSException
+            {
+            public:
+                InvalidParameterException(std::string&& what)
+                : RCSException{ std::move(what) } {}
+            };
+            class FailedSubscribePresenceException: public PlatformException
+            {
+            public:
+                FailedSubscribePresenceException(OCStackResult reason)
+                : PlatformException{reason} {}
+            };
+
+            static ResourceBroker * getInstance();
+
+            BrokerID hostResource(PrimitiveResourcePtr pResource, BrokerCB cb);
+            void cancelHostResource(BrokerID brokerId);
+
+            BROKER_STATE getResourceState(BrokerID brokerId);
+            BROKER_STATE getResourceState(PrimitiveResourcePtr pResource);
+
+        private:
+            static ResourceBroker * s_instance;
+            static std::mutex s_mutexForCreation;
+            static std::unique_ptr<PresenceList>  s_presenceList;
+            static std::unique_ptr<BrokerIDMap> s_brokerIDMap;
+
+            ResourceBroker() = default;
+            ~ResourceBroker();
+            ResourceBroker(const ResourceBroker&) = delete;
+            ResourceBroker(ResourceBroker&&) = delete;
+
+            ResourceBroker& operator=(const ResourceBroker&) const = delete;
+            ResourceBroker& operator=(ResourceBroker&&) const = delete;
+
+            void initializeResourceBroker();
+            BrokerID generateBrokerID();
+            ResourcePresencePtr findResourcePresence(PrimitiveResourcePtr pResource);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RB_RESOURCEBROKER_H_ */
diff --git a/service/resource-encapsulation/src/resourceBroker/include/ResourcePresence.h b/service/resource-encapsulation/src/resourceBroker/include/ResourcePresence.h
new file mode 100644 (file)
index 0000000..acb54b6
--- /dev/null
@@ -0,0 +1,91 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RB_RESOURCEPRESENCE_H_
+#define RB_RESOURCEPRESENCE_H_
+
+#include <functional>
+#include <list>
+#include <string>
+#include <boost/atomic.hpp>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+#include "ExpiryTimer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourcePresence : public std::enable_shared_from_this<ResourcePresence>
+        {
+        public:
+            ResourcePresence();
+            ~ResourcePresence();
+
+            void initializeResourcePresence(PrimitiveResourcePtr pResource);
+
+            void addBrokerRequester(BrokerID _id, BrokerCB _cb);
+            void removeBrokerRequester(BrokerID _id);
+            void removeAllBrokerRequester();
+
+            void requestResourceState() const;
+            void changePresenceMode(BROKER_MODE newMode);
+
+            bool isEmptyRequester() const;
+            int  requesterListSize() const;
+            const PrimitiveResourcePtr getPrimitiveResource() const;
+            BROKER_STATE getResourceState() const;
+
+        private:
+            std::unique_ptr<std::list<BrokerRequesterInfoPtr>> requesterList;
+            PrimitiveResourcePtr primitiveResource;
+            ExpiryTimer expiryTimer;
+
+            BROKER_STATE state;
+            BROKER_MODE mode;
+
+            bool isWithinTime;
+            boost::atomic_long receivedTime;
+            std::mutex cbMutex;
+            unsigned int timeoutHandle;
+
+            RequestGetCB pGetCB;
+            TimerCB pTimeoutCB;
+            TimerCB pPollingCB;
+
+            void registerDevicePresence();
+        public:
+            void getCB(const HeaderOptions &hos, const ResponseStatement& rep, int eCode);
+            void timeOutCB(unsigned int msg);
+        private:
+            void verifiedGetResponse(int eCode);
+
+            void pollingCB(unsigned int msg = 0);
+
+            void executeAllBrokerCB(BROKER_STATE changedState);
+            void setResourcestate(BROKER_STATE _state);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RB_RESOURCEPRESENCE_H_ */
+
diff --git a/service/resource-encapsulation/src/resourceBroker/src/DeviceAssociation.cpp b/service/resource-encapsulation/src/resourceBroker/src/DeviceAssociation.cpp
new file mode 100644 (file)
index 0000000..0176c7b
--- /dev/null
@@ -0,0 +1,103 @@
+//******************************************************************
+//
+// 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 "DeviceAssociation.h"
+#include "DevicePresence.h"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        DeviceAssociation * DeviceAssociation::s_instance = nullptr;
+        std::mutex DeviceAssociation::s_mutexForCreation;
+        std::list< DevicePresencePtr >  DeviceAssociation::s_deviceList;
+
+        DeviceAssociation::DeviceAssociation()
+        {
+            // TODO Auto-generated constructor stub
+        }
+
+        DeviceAssociation::~DeviceAssociation()
+        {
+            // TODO Auto-generated destructor stub
+        }
+
+        DeviceAssociation * DeviceAssociation::getInstance()
+        {
+            if (!s_instance)
+            {
+                s_mutexForCreation.lock();
+                if (!s_instance)
+                {
+                    s_instance = new DeviceAssociation();
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        DevicePresencePtr DeviceAssociation::findDevice(const std::string & address)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"findDevice()");
+            DevicePresencePtr retDevice = nullptr;
+            for(auto it : s_deviceList)
+            {
+                if(address == it->getAddress())
+                {
+                    OC_LOG_V(DEBUG,BROKER_TAG,"find device in deviceList");
+                    retDevice = it;
+                    break;
+                }
+            }
+
+            return retDevice;
+        }
+
+        void DeviceAssociation::addDevice(DevicePresencePtr dPresence)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"addDevice()");
+            DevicePresencePtr foundDevice = findDevice(dPresence->getAddress());
+            if(foundDevice == nullptr)
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"add device in deviceList");
+                s_deviceList.push_back(dPresence);
+            }
+        }
+
+        void DeviceAssociation::removeDevice(DevicePresencePtr dPresence)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"removeDevice()");
+            DevicePresencePtr foundDevice = findDevice(dPresence->getAddress());
+            if(foundDevice != nullptr)
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"remove device in deviceList");
+                s_deviceList.remove(foundDevice);
+                foundDevice.reset();
+            }
+        }
+
+        bool DeviceAssociation::isEmptyDeviceList()
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"isEmptyDeviceList()");
+            return s_deviceList.empty();
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceBroker/src/DevicePresence.cpp b/service/resource-encapsulation/src/resourceBroker/src/DevicePresence.cpp
new file mode 100644 (file)
index 0000000..629ef14
--- /dev/null
@@ -0,0 +1,178 @@
+//******************************************************************
+//
+// 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 "DevicePresence.h"
+#include "RCSException.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        DevicePresence::DevicePresence()
+        {
+            state = DEVICE_STATE::REQUESTED;
+
+            presenceTimerHandle = 0;
+            isRunningTimeOut = false;
+
+            pSubscribeRequestCB = std::bind(&DevicePresence::subscribeCB, this,
+                        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
+            pTimeoutCB = std::bind(&DevicePresence::timeOutCB, this, std::placeholders::_1);
+        }
+
+        DevicePresence::~DevicePresence()
+        {
+            if(presenceSubscriber.isSubscribing())
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"unsubscribed presence.");
+                presenceSubscriber.unsubscribe();
+            }
+            resourcePresenceList.clear();
+            OC_LOG_V(DEBUG,BROKER_TAG,"destroy Timer.");
+        }
+
+        void DevicePresence::initializeDevicePresence(PrimitiveResourcePtr pResource)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "initializeDevicePresence()");
+            address = pResource->getHost();
+
+            OC_LOG_V(DEBUG, BROKER_TAG, "%s",address.c_str());
+
+            try
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "subscribe Presence");
+                presenceSubscriber
+                = PresenceSubscriber(address, BROKER_TRANSPORT, pSubscribeRequestCB);
+            } catch(PlatformException &e)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG,
+                        "exception in subscribe Presence %s", e.getReason().c_str());
+                throw;
+            }
+            presenceTimerHandle
+            = presenceTimer.post(BROKER_DEVICE_PRESENCE_TIMEROUT, pTimeoutCB);
+        }
+        DEVICE_STATE DevicePresence::getDeviceState() const
+        {
+            return state;
+        }
+        const std::string DevicePresence::getAddress() const
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "getAddress()");
+            return address;
+        }
+
+        void DevicePresence::addPresenceResource(ResourcePresence * rPresence)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "addPresenceResource()");
+            resourcePresenceList.push_back(rPresence);
+        }
+
+        void DevicePresence::removePresenceResource(ResourcePresence * rPresence)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "removePresenceResource()");
+            resourcePresenceList.remove(rPresence);
+        }
+
+        void DevicePresence::changeAllPresenceMode(BROKER_MODE mode)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "changeAllPresenceMode()");
+            if(!resourcePresenceList.empty())
+            {
+                for(auto it : resourcePresenceList)
+                {
+                    it->changePresenceMode(mode);
+                }
+            }
+        }
+
+        bool DevicePresence::isEmptyResourcePresence() const
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "isEmptyResourcePresence()");
+            return resourcePresenceList.empty();
+        }
+
+        void DevicePresence::subscribeCB(OCStackResult ret,
+                const unsigned int seq, const std::string & hostAddress)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "subscribeCB()");
+            OC_LOG_V(DEBUG, BROKER_TAG, "Received presence CB from: %s",hostAddress.c_str());
+            OC_LOG_V(DEBUG, BROKER_TAG, "In subscribeCB: %d",ret);
+
+            if(isRunningTimeOut)
+            {
+                std::unique_lock<std::mutex> lock(timeoutMutex);
+                condition.wait(lock);
+            }
+            presenceTimer.cancel(presenceTimerHandle);
+
+            switch(ret)
+            {
+                case OC_STACK_OK:
+                case OC_STACK_RESOURCE_CREATED:
+                case OC_STACK_CONTINUE:
+                {
+                    OC_LOG_V(DEBUG, BROKER_TAG, "SEQ# %d",seq);
+                    state = DEVICE_STATE::ALIVE;
+                    OC_LOG_V(DEBUG, BROKER_TAG, "device state : %d",
+                            (int)(state.load(boost::memory_order_consume)));
+                    changeAllPresenceMode(BROKER_MODE::DEVICE_PRESENCE_MODE);
+                    presenceTimerHandle
+                    = presenceTimer.post(BROKER_DEVICE_PRESENCE_TIMEROUT, pTimeoutCB);
+                    break;
+                }
+                case OC_STACK_INVALID_REQUEST_HANDLE:
+                case OC_STACK_RESOURCE_DELETED:
+                case OC_STACK_TIMEOUT:
+                case OC_STACK_COMM_ERROR:
+                case OC_STACK_PRESENCE_STOPPED:
+                case OC_STACK_PRESENCE_TIMEOUT:
+                case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+                {
+                    state = DEVICE_STATE::LOST_SIGNAL;
+                    changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
+                    break;
+                }
+                default:
+                {
+                    OC_LOG_V(DEBUG, BROKER_TAG, "Presence Lost Signal because unknown type");
+                    state = DEVICE_STATE::LOST_SIGNAL;
+                    changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
+                    break;
+                }
+            }
+        }
+
+        void DevicePresence::timeOutCB(TimerID /*id*/)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"timeOutCB()");
+            std::unique_lock<std::mutex> lock(timeoutMutex);
+            isRunningTimeOut = true;
+
+            OC_LOG_V(DEBUG, BROKER_TAG,
+                    "Timeout execution. will be discard after receiving cb message");
+            state = DEVICE_STATE::LOST_SIGNAL;
+            changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
+
+            isRunningTimeOut = false;
+            condition.notify_all();
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceBroker/src/ResourceBroker.cpp b/service/resource-encapsulation/src/resourceBroker/src/ResourceBroker.cpp
new file mode 100644 (file)
index 0000000..0332bcd
--- /dev/null
@@ -0,0 +1,239 @@
+//******************************************************************
+//
+// 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 <time.h>
+
+#include "BrokerTypes.h"
+#include "ResourceBroker.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourceBroker * ResourceBroker::s_instance = NULL;
+        std::mutex ResourceBroker::s_mutexForCreation;
+        std::unique_ptr<PresenceList>  ResourceBroker::s_presenceList(nullptr);
+        std::unique_ptr<BrokerIDMap> ResourceBroker::s_brokerIDMap(nullptr);
+
+        ResourceBroker::~ResourceBroker()
+        {
+            if(s_presenceList != nullptr)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "clear the ResourcePresenceList.");
+                s_presenceList->erase(s_presenceList->begin(), s_presenceList->end());
+                s_presenceList->clear();
+            }
+            if(s_brokerIDMap != nullptr)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "clear the brokerIDMap.");
+                s_brokerIDMap->erase(s_brokerIDMap->begin(), s_brokerIDMap->end());
+                s_brokerIDMap->clear();
+            }
+        }
+
+        ResourceBroker * ResourceBroker::getInstance()
+        {
+            if (!s_instance)
+            {
+                s_mutexForCreation.lock();
+                if (!s_instance)
+                {
+                    s_instance = new ResourceBroker();
+                    s_instance->initializeResourceBroker();
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        BrokerID ResourceBroker::hostResource(PrimitiveResourcePtr pResource, BrokerCB cb)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "hostResource().");
+            if(pResource == nullptr || cb == nullptr || cb == NULL)
+            {
+                throw InvalidParameterException("[hostResource] input parameter(PrimitiveResource or BrokerCB) is Invalid");
+            }
+
+            BrokerID retID = generateBrokerID();
+
+            ResourcePresencePtr presenceItem = findResourcePresence(pResource);
+            if(presenceItem == nullptr)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "Not found any Handled Resource.");
+                OC_LOG_V(DEBUG, BROKER_TAG, "Create New Resource Presence Handler.");
+
+                try
+                {
+                    OC_LOG_V(DEBUG, BROKER_TAG, "create the ResourcePresence.");
+                    presenceItem.reset(new ResourcePresence());
+                    presenceItem->initializeResourcePresence(pResource);
+                }catch(PlatformException &e)
+                {
+                    throw FailedSubscribePresenceException(e.getReasonCode());
+                }
+                if(s_presenceList != nullptr)
+                {
+                    OC_LOG_V(DEBUG, BROKER_TAG, "push the ResourcePresence in presenceList.");
+                    s_presenceList->push_back(presenceItem);
+                }
+            }
+            OC_LOG_V(DEBUG, BROKER_TAG, "add the BrokerRequester in ResourcePresence.");
+            presenceItem->addBrokerRequester(retID, cb);
+
+            BrokerCBResourcePair pair(presenceItem, cb);
+            s_brokerIDMap->insert(std::pair<BrokerID, BrokerCBResourcePair>
+                (retID, BrokerCBResourcePair(presenceItem, cb)));
+
+            return retID;
+        }
+
+        void ResourceBroker::cancelHostResource(BrokerID brokerId)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"cancelHostResource().");
+            if(brokerId == 0)
+            {
+                // input parameter is wrong.
+                // hostResource never return value 0;
+                OC_LOG_V(DEBUG,BROKER_TAG,"brokerId is zero.");
+                throw InvalidParameterException("[cancelHostResource] brokerId is invalid.");
+            }
+
+            BrokerIDMap::iterator it = s_brokerIDMap->find(brokerId);
+            if(it == s_brokerIDMap->end())
+            {
+                // not found requested brokerId in BrokerMap;
+                OC_LOG_V(DEBUG,BROKER_TAG,"brokerId is not found in brokerIDMap.");
+                throw InvalidParameterException("[cancelHostResource] brokerId is not found in brokerIDMap.");
+            }
+            else
+            {
+                ResourcePresencePtr presenceItem = it->second.pResource;
+                presenceItem->removeBrokerRequester(brokerId);
+                s_brokerIDMap->erase(brokerId);
+
+                if(presenceItem->isEmptyRequester())
+                {
+                    OC_LOG_V(DEBUG,BROKER_TAG,"remove resourcePresence in presenceList because it is not including any requester info.");
+                    s_presenceList->remove(presenceItem);
+                }
+            }
+        }
+
+        BROKER_STATE ResourceBroker::getResourceState(BrokerID brokerId)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"getResourceState().");
+            if(brokerId == 0)
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"brokerId is zero.");
+                throw InvalidParameterException("[getResourceState] input BrokerID is Invalid");
+            }
+
+            BROKER_STATE retState = BROKER_STATE::NONE;
+
+            BrokerIDMap::iterator it = s_brokerIDMap->find(brokerId);
+            if(it == s_brokerIDMap->end())
+            {
+                // not found requested brokerId in BrokerMap;
+                OC_LOG_V(DEBUG,BROKER_TAG,"brokerId is not found in brokerIDMap.");
+                throw InvalidParameterException("[getResourceState] input BrokerID is unknown ID");
+            }
+            else
+            {
+                ResourcePresencePtr foundResource = it->second.pResource;
+                retState = foundResource->getResourceState();
+            }
+
+            return retState;
+        }
+
+        BROKER_STATE ResourceBroker::getResourceState(PrimitiveResourcePtr pResource)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"getResourceState().");
+            if(pResource == nullptr)
+            {
+                throw InvalidParameterException("[getResourceState] input PrimitiveResource is Invalid");
+            }
+
+            BROKER_STATE retState = BROKER_STATE::NONE;
+
+            ResourcePresencePtr foundResource = findResourcePresence(pResource);
+            if(foundResource != nullptr)
+            {
+                retState = foundResource->getResourceState();
+            }
+
+            return retState;
+        }
+
+        void ResourceBroker::initializeResourceBroker()
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"initializeResourceBroker().");
+            if(s_presenceList == nullptr)
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"create the presenceList.");
+                s_presenceList = std::unique_ptr<PresenceList>(new PresenceList);
+            }
+            if(s_brokerIDMap == nullptr)
+            {
+                OC_LOG_V(DEBUG,BROKER_TAG,"create the brokerIDMap.");
+                s_brokerIDMap = std::unique_ptr<BrokerIDMap>(new BrokerIDMap);
+            }
+        }
+
+        ResourcePresencePtr ResourceBroker::findResourcePresence(PrimitiveResourcePtr pResource)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"findResourcePresence().");
+            ResourcePresencePtr retResource(nullptr);
+
+            if(s_presenceList->empty() != true)
+            {
+                for(auto & it : * s_presenceList)
+                {
+                    PrimitiveResourcePtr temp = it->getPrimitiveResource();
+                    if(temp == pResource)
+                    {
+                        retResource = it;
+                        break;
+                    }
+                }
+            }
+
+            return retResource;
+        }
+
+        BrokerID ResourceBroker::generateBrokerID()
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"generateBrokerID().");
+            BrokerID retID = 0;
+            srand(time(NULL));
+
+            while(1)
+            {
+                if(retID != 0 && s_brokerIDMap->find(retID) == s_brokerIDMap->end())
+                {
+                    break;
+                }
+                retID = (unsigned int)rand();
+            }
+
+            return retID;
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceBroker/src/ResourcePresence.cpp b/service/resource-encapsulation/src/resourceBroker/src/ResourcePresence.cpp
new file mode 100644 (file)
index 0000000..e6ab0ef
--- /dev/null
@@ -0,0 +1,327 @@
+//******************************************************************
+//
+// 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 "ResourcePresence.h"
+
+#include <bits/atomic_base.h>
+#include <bits/shared_ptr_base.h>
+#include <time.h>
+#include <unistd.h>
+#include <cstdbool>
+#include <exception>
+#include <iostream>
+#include <memory>
+
+#include "PrimitiveResource.h"
+#include "DeviceAssociation.h"
+#include "DevicePresence.h"
+
+namespace
+{
+using namespace OIC::Service;
+
+    void getCallback(const HeaderOptions &hos, const ResponseStatement& rep,
+            int eCode, std::weak_ptr<ResourcePresence> this_ptr)
+    {
+        OC_LOG_V(DEBUG,BROKER_TAG,"getCallback().\n");
+        std::shared_ptr<ResourcePresence> Ptr = this_ptr.lock();
+        if(Ptr)
+        {
+            Ptr->getCB(hos, rep, eCode);
+        }
+    }
+    void timeOutCallback(unsigned int msg, std::weak_ptr<ResourcePresence> this_ptr)
+    {
+        OC_LOG_V(DEBUG,BROKER_TAG,"timeOutCallback().\n");
+        std::shared_ptr<ResourcePresence> Ptr = this_ptr.lock();
+        if(Ptr)
+        {
+            Ptr->timeOutCB(msg);
+        }
+    }
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourcePresence::ResourcePresence()
+        : requesterList(nullptr), primitiveResource(nullptr),
+          state(BROKER_STATE::REQUESTED), mode(BROKER_MODE::NON_PRESENCE_MODE),
+          isWithinTime(true), receivedTime(0L), timeoutHandle(0)
+        {
+        }
+
+        void ResourcePresence::initializeResourcePresence(PrimitiveResourcePtr pResource)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"initializeResourcePresence().\n");
+            pGetCB = std::bind(getCallback, std::placeholders::_1, std::placeholders::_2,
+                    std::placeholders::_3, std::weak_ptr<ResourcePresence>(shared_from_this()));
+            pTimeoutCB = std::bind(timeOutCallback, std::placeholders::_1,
+                    std::weak_ptr<ResourcePresence>(shared_from_this()));
+            pPollingCB = std::bind(&ResourcePresence::pollingCB, this, std::placeholders::_1);
+
+            primitiveResource = pResource;
+            requesterList
+            = std::unique_ptr<std::list<BrokerRequesterInfoPtr>>
+            (new std::list<BrokerRequesterInfoPtr>);
+
+            timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND, pTimeoutCB);
+            OC_LOG_V(DEBUG,BROKER_TAG,"initializeResourcePresence::requestGet.\n");
+            primitiveResource->requestGet(pGetCB);
+
+            registerDevicePresence();
+        }
+
+
+        ResourcePresence::~ResourcePresence()
+        {
+            std::string deviceAddress = primitiveResource->getHost();
+
+            DevicePresencePtr foundDevice
+            = DeviceAssociation::getInstance()->findDevice(deviceAddress);
+
+            if(foundDevice != nullptr)
+            {
+                foundDevice->removePresenceResource(this);
+
+                if(foundDevice->isEmptyResourcePresence())
+                {
+                    DeviceAssociation::getInstance()->removeDevice(foundDevice);
+                }
+            }
+
+            requesterList->clear();
+
+            state = BROKER_STATE::DESTROYED;
+        }
+
+        void ResourcePresence::addBrokerRequester(BrokerID _id, BrokerCB _cb)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"addBrokerRequester().\n");
+            requesterList->push_back(
+                    std::make_shared<BrokerRequesterInfo>(BrokerRequesterInfo(_id, _cb)));
+        }
+
+        void ResourcePresence::removeAllBrokerRequester()
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"removeAllBrokerRequester().\n");
+            if(requesterList != nullptr)
+            {
+                requesterList->erase(requesterList->begin(), requesterList->end());
+            }
+        }
+
+        void ResourcePresence::removeBrokerRequester(BrokerID _id)
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"removeBrokerRequester().\n");
+            std::list<BrokerRequesterInfoPtr>::iterator iter = requesterList->begin();
+            for(; iter != requesterList->end(); ++iter)
+            {
+                if(iter->get()->brokerId == _id)
+                {
+                    OC_LOG_V(DEBUG,BROKER_TAG,"find broker-id in requesterList.\n");
+                    requesterList->erase(iter);
+                    break;
+                }
+            }
+        }
+
+        bool ResourcePresence::isEmptyRequester() const
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"isEmptyRequester().\n");
+            return (requesterList!=nullptr)?requesterList->empty():true;
+        }
+
+        int ResourcePresence::requesterListSize() const {
+            OC_LOG_V(DEBUG,BROKER_TAG,"requesterListSize().\n");
+            return (requesterList!=nullptr)?requesterList->size():0;
+        }
+
+        void ResourcePresence::requestResourceState() const
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"requestResourceState().\n");
+            primitiveResource->requestGet(pGetCB);
+            OC_LOG_V(DEBUG, BROKER_TAG, "Request Get\n");
+        }
+
+        void ResourcePresence::registerDevicePresence()
+        {
+            OC_LOG_V(DEBUG,BROKER_TAG,"registerDevicePresence().\n");
+            std::string deviceAddress = primitiveResource->getHost();
+
+            DevicePresencePtr foundDevice
+            = DeviceAssociation::getInstance()->findDevice(deviceAddress);
+
+            if(foundDevice == nullptr)
+            {
+                try
+                {
+                    foundDevice.reset(new DevicePresence());
+                    foundDevice->initializeDevicePresence(primitiveResource);
+                }catch(...)
+                {
+                    throw;
+                }
+                DeviceAssociation::getInstance()->addDevice(foundDevice);
+            }
+            foundDevice->addPresenceResource(this);
+        }
+
+        void ResourcePresence::executeAllBrokerCB(BROKER_STATE changedState)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "executeAllBrokerCB().\n");
+            if(state != changedState)
+            {
+                setResourcestate(changedState);
+                if(requesterList->empty() != true)
+                {
+                    std::list<BrokerRequesterInfoPtr> list = * requesterList;
+                    for(BrokerRequesterInfoPtr item : list)
+                    {
+                        item->brokerCB(state);
+                    }
+                }
+            }
+        }
+
+        void ResourcePresence::setResourcestate(BROKER_STATE _state)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "setResourcestate().\n");
+            this->state = _state;
+        }
+
+        void ResourcePresence::timeOutCB(unsigned int /*msg*/)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "timeOutCB()");
+            OC_LOG_V(DEBUG, BROKER_TAG, "waiting for terminate getCB\n");
+            std::unique_lock<std::mutex> lock(cbMutex);
+
+            time_t currentTime;
+            time(&currentTime);
+            currentTime += 0L;
+
+            if((receivedTime.load(boost::memory_order_consume) == 0) ||
+              ((receivedTime + BROKER_SAFE_SECOND) > currentTime ))
+            {
+                this->isWithinTime = true;
+                return;
+            }
+            this->isWithinTime = false;
+            OC_LOG_V(DEBUG, BROKER_TAG,
+                    "Timeout execution. will be discard after receiving cb message.\n");
+
+            executeAllBrokerCB(BROKER_STATE::LOST_SIGNAL);
+            pollingCB();
+        }
+
+        void ResourcePresence::pollingCB(unsigned int /*msg*/)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "pollingCB().\n");
+            if(this->requesterList->size() != 0)
+            {
+                this->requestResourceState();
+                timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND,pTimeoutCB);
+            }
+        }
+
+        void ResourcePresence::getCB(const HeaderOptions & /*hos*/,
+                const ResponseStatement & /*rep*/, int eCode)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "getCB().\n");
+            OC_LOG_V(DEBUG, BROKER_TAG, "waiting for terminate TimeoutCB.\n");
+            std::unique_lock<std::mutex> lock(cbMutex);
+
+            time_t currentTime;
+            time(&currentTime);
+            receivedTime = currentTime;
+
+            verifiedGetResponse(eCode);
+
+            if(isWithinTime)
+            {
+                expiryTimer.cancel(timeoutHandle);
+                isWithinTime = true;
+            }
+
+            if(mode == BROKER_MODE::NON_PRESENCE_MODE)
+            {
+                expiryTimer.post(BROKER_SAFE_MILLISECOND,pPollingCB);
+            }
+
+        }
+
+        void ResourcePresence::verifiedGetResponse(int eCode)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "verifiedGetResponse().\n");
+            BROKER_STATE verifiedState = BROKER_STATE::NONE;
+            switch(eCode)
+            {
+            case OC_STACK_OK:
+            case OC_STACK_CONTINUE:
+                verifiedState = BROKER_STATE::ALIVE;
+                break;
+
+            case OC_STACK_RESOURCE_DELETED:
+                verifiedState = BROKER_STATE::DESTROYED;
+                break;
+
+            case OC_STACK_INVALID_REQUEST_HANDLE:
+            case OC_STACK_TIMEOUT:
+            case OC_STACK_COMM_ERROR:
+            case OC_STACK_PRESENCE_STOPPED:
+            case OC_STACK_PRESENCE_TIMEOUT:
+            default:
+                verifiedState = BROKER_STATE::LOST_SIGNAL;
+                break;
+            }
+
+            executeAllBrokerCB(verifiedState);
+            OC_LOG_V(DEBUG, BROKER_TAG, "resource state : %d",(int)state);
+        }
+
+        const PrimitiveResourcePtr ResourcePresence::getPrimitiveResource() const
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "getPrimitiveResource()\n");
+            return primitiveResource;
+        }
+
+        BROKER_STATE ResourcePresence::getResourceState() const
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "getResourceState()\n");
+            return state;
+        }
+
+        void ResourcePresence::changePresenceMode(BROKER_MODE newMode)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "changePresenceMode()\n");
+            if(newMode != mode)
+            {
+                expiryTimer.cancel(timeoutHandle);
+                if(newMode == BROKER_MODE::NON_PRESENCE_MODE)
+                {
+                    timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND,pTimeoutCB);
+                    requestResourceState();
+                }
+                mode = newMode;
+            }
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceBroker/unittest/DeviceAssociationUnitTest.cpp b/service/resource-encapsulation/src/resourceBroker/unittest/DeviceAssociationUnitTest.cpp
new file mode 100644 (file)
index 0000000..f1296ed
--- /dev/null
@@ -0,0 +1,107 @@
+//******************************************************************
+//
+// 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 "gtest/gtest.h"
+#include "HippoMocks/hippomocks.h"
+
+#include "OCPlatform.h"
+
+#include "DevicePresence.h"
+#include "DeviceAssociation.h"
+#include "ResourcePresence.h"
+#include "PrimitiveResource.h"
+#include "ResponseStatement.h"
+#include "UnitTestHelper.h"
+
+using namespace testing;
+using namespace OIC::Service;
+using namespace OC;
+
+#define STRING_VALUE "10.242.34.235"
+
+typedef OCStackResult (*subscribePresenceSig1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+
+class DeviceAssociationTest : public TestWithMock
+{
+public:
+
+    DeviceAssociation * instance;
+    DevicePresencePtr device;
+    PrimitiveResource::Ptr pResource;
+protected:
+
+    void setMockingFunc()
+    {
+        mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+        mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return(STRING_VALUE);
+        mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_OK);
+    }
+
+    void SetAssociationDevice()
+    {
+        setMockingFunc();
+        device->initializeDevicePresence(pResource);
+        instance->addDevice(device);
+    }
+
+    void SetUp() 
+    {
+        TestWithMock::SetUp();
+        instance = DeviceAssociation::getInstance();
+        device = (DevicePresencePtr)new DevicePresence();
+        pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource*){});
+    }
+
+    void TearDown() 
+    {
+        TestWithMock::TearDown();
+        device.reset();
+        pResource.reset();
+
+    }
+};
+
+TEST_F(DeviceAssociationTest,findDevice_ReturnNormalValueIfNormalParam)
+{
+
+    SetAssociationDevice();
+    ASSERT_NE(nullptr,instance->findDevice(pResource->getHost()));
+
+
+}
+
+TEST_F(DeviceAssociationTest,addDevice_NormalHandlingIfNormalParam)
+{
+
+    SetAssociationDevice();
+    ASSERT_FALSE(instance->isEmptyDeviceList());
+}
+
+TEST_F(DeviceAssociationTest,removeDevice_NormalHandlingIfNormalParam)
+{
+
+    SetAssociationDevice();
+    instance->removeDevice(device);
+    ASSERT_TRUE(instance->isEmptyDeviceList());
+}
+
diff --git a/service/resource-encapsulation/src/resourceBroker/unittest/DevicePresenceUnitTest.cpp b/service/resource-encapsulation/src/resourceBroker/unittest/DevicePresenceUnitTest.cpp
new file mode 100644 (file)
index 0000000..6d4b3de
--- /dev/null
@@ -0,0 +1,151 @@
+//******************************************************************
+//
+// 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 <unistd.h>
+
+#include "gtest/gtest.h"
+#include "HippoMocks/hippomocks.h"
+
+#include "BrokerTypes.h"
+#include "PrimitiveResource.h"
+#include "ResponseStatement.h"
+#include "OCPlatform.h"
+#include "DevicePresence.h"
+#include "ResourcePresence.h"
+#include "UnitTestHelper.h"
+
+using namespace testing;
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*subscribePresenceSig1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+
+class DevicePresenceTest : public TestWithMock
+{
+public:
+    typedef std::function<void(OCStackResult,const unsigned int, const std::string&)> subscribeCallback;
+    DevicePresence * instance;
+    PrimitiveResource::Ptr pResource;
+    BrokerCB cb;
+    BrokerID id;
+
+protected:
+
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        instance = (DevicePresence*)new DevicePresence();
+        pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource*){});
+        cb = ([](BROKER_STATE)->OCStackResult{return OC_STACK_OK;});
+        id = 0;
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+        pResource.reset();
+        id = 0;
+        cb = nullptr;
+    }
+
+    void MockingFunc()
+    {
+        mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return(std::string());
+        mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_OK);
+    }
+};
+TEST_F(DevicePresenceTest,timeoutCB_TimeOverWhenIsSubscribe)
+{
+   MockingFunc();
+   instance->initializeDevicePresence(pResource);
+   std::cout<<"wait while done timeout device presence\n";
+   sleep((BROKER_DEVICE_PRESENCE_TIMEROUT/1000)+1);
+   ASSERT_EQ(DEVICE_STATE::LOST_SIGNAL,instance->getDeviceState());
+}
+
+TEST_F(DevicePresenceTest,SubscribeCB_NormalHandlingIfMessageOC_STACK_OK)
+{
+   mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return(std::string());
+   mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Do(
+            [](OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, OCConnectivityType, SubscribeCallback callback)->OCStackResult{
+
+        callback(OC_STACK_OK,0,std::string());
+        return OC_STACK_OK;
+
+    }).Return(OC_STACK_OK);
+   instance->initializeDevicePresence(pResource);
+   ASSERT_NE(DEVICE_STATE::LOST_SIGNAL,instance->getDeviceState());
+}
+
+TEST_F(DevicePresenceTest,initializeDevicePresence_NormalHandlingIfNormalResource)
+{
+
+    MockingFunc();
+
+    ASSERT_NO_THROW(instance->initializeDevicePresence(pResource));
+
+}
+
+TEST_F(DevicePresenceTest,initializeDevicePresence_ErrorHandlingIfAbnormalResource)
+{
+
+    MockingFunc();
+    mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(instance->initializeDevicePresence(pResource),PlatformException);
+
+}
+
+TEST_F(DevicePresenceTest,addPresenceResource_NormalHandlingIfNormalResource)
+{
+
+    ResourcePresence * resource = (ResourcePresence *)new ResourcePresence();
+    instance->addPresenceResource(resource);
+
+    ASSERT_FALSE(instance->isEmptyResourcePresence());
+
+}
+
+TEST_F(DevicePresenceTest,isEmptyResourcePresence_NormalHandling)
+{
+
+    MockingFunc();
+
+    ASSERT_TRUE(instance->isEmptyResourcePresence());
+
+}
+
+TEST_F(DevicePresenceTest,getAddress_NormalHandling)
+{
+
+    MockingFunc();
+
+    instance->initializeDevicePresence(pResource);
+    instance->getAddress();
+
+}
+
+TEST_F(DevicePresenceTest,NormalHandlingWhenReceivedCallbackMessage)
+{
+
+    MockingFunc();
+
+}
diff --git a/service/resource-encapsulation/src/resourceBroker/unittest/ResourceBrokerUnitTest.cpp b/service/resource-encapsulation/src/resourceBroker/unittest/ResourceBrokerUnitTest.cpp
new file mode 100644 (file)
index 0000000..2cddd25
--- /dev/null
@@ -0,0 +1,205 @@
+//******************************************************************
+//
+// 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 "gtest/gtest.h"
+#include "HippoMocks/hippomocks.h"
+
+#include "OCPlatform.h"
+#include "PrimitiveResource.h"
+#include "ResponseStatement.h"
+#include "ResourceBroker.h"
+#include "UnitTestHelper.h"
+
+using namespace testing;
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*subscribePresenceSig1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+
+class ResourceBrokerTest : public TestWithMock
+{
+public:
+
+    ResourceBroker * brokerInstance;
+    PrimitiveResource::Ptr pResource;
+    BrokerCB cb;
+    BrokerID id;
+
+protected:
+
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        brokerInstance = ResourceBroker::getInstance();
+        pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource*){});
+        cb = ([](BROKER_STATE)->OCStackResult{return OC_STACK_OK;});
+        id = 0;
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+        pResource.reset();
+        id = 0;
+        cb = nullptr;
+    }
+
+    void MockingFunc()
+    {
+        mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+        mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return(std::string());
+        mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_OK);
+    }
+
+};
+
+TEST_F(ResourceBrokerTest,HostResource_ReturnNormalValueIfNormalParams)
+{
+
+    MockingFunc();
+
+    BrokerID ret = brokerInstance->hostResource(pResource, cb);
+    ASSERT_NE(BrokerID(0), ret);
+
+    brokerInstance->cancelHostResource(ret);
+
+}
+
+TEST_F(ResourceBrokerTest, HostResource_NormalErrorHandlingIfResourceNull)
+{
+
+    ASSERT_THROW(brokerInstance->hostResource(nullptr, cb),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest, HostResource_NormalErrorHandlingIfCbFuncNull)
+{
+
+    ASSERT_THROW(brokerInstance->hostResource(pResource,nullptr),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest,CancelHostResource_NoThrowIfNormalParams)
+{
+
+    MockingFunc();
+
+    BrokerID ret;
+    ret = brokerInstance->hostResource(pResource,cb);
+
+    ASSERT_NO_THROW(brokerInstance->cancelHostResource(ret));
+
+
+}
+
+TEST_F(ResourceBrokerTest,CancelHostResource_NormalErrorHandlingIfAbNormalIdZero)
+{
+
+    id = 0;
+    ASSERT_THROW(brokerInstance->cancelHostResource(id),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest,CancelHostResource_NormalErrorHandlingIfAbNormalIdOutOfRangeValue)
+{
+
+    id = -1;
+    ASSERT_THROW(brokerInstance->cancelHostResource(id),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_ReturnNormalValueIfNormalId)
+{
+
+    MockingFunc();
+
+    BrokerID ret;
+    ret = brokerInstance->hostResource(pResource,cb);
+
+    ASSERT_NE(brokerInstance->getResourceState(ret),BROKER_STATE::NONE);
+
+    brokerInstance->cancelHostResource(ret);
+    TearDown();
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_NormalErrorHandlingIfIdZero)
+{
+
+    id = 0;
+    ASSERT_THROW(brokerInstance->getResourceState(id),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_ReturnNormalValueIfNormalResource)
+{
+
+    MockingFunc();
+
+    BrokerID ret;
+    ret = brokerInstance->hostResource(pResource,cb);
+
+    ASSERT_NE(brokerInstance->getResourceState(pResource),BROKER_STATE::NONE);
+
+    brokerInstance->cancelHostResource(ret);
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_NormalErrorHandlingIfResourceNull)
+{
+
+    ASSERT_THROW(brokerInstance->getResourceState((PrimitiveResource::Ptr)nullptr),ResourceBroker::InvalidParameterException);
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_NormalErrorHandlingIfAbnormalResource)
+{
+
+    MockingFunc();
+
+    PrimitiveResource::Ptr resource[3];
+    BrokerID id[3];
+
+    for(int i=0;i!=3;i++)
+    {
+        resource[i] = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource*){});
+        mocks.OnCall(resource[i].get(), PrimitiveResource::requestGet);
+        mocks.OnCall(resource[i].get(), PrimitiveResource::getHost).Return(std::string());
+        mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_OK);
+        id[i] = brokerInstance->hostResource(resource[i],cb);
+    }
+
+
+    EXPECT_EQ(brokerInstance->getResourceState(pResource),BROKER_STATE::NONE);
+
+    for(int i=0;i!=3;i++)
+    {
+        brokerInstance->cancelHostResource(id[i]);
+    }
+
+}
+
+TEST_F(ResourceBrokerTest,getResourceState_NormalErrorHandlingIfAbnormalId)
+{
+
+    id = -1;
+    ASSERT_THROW(brokerInstance->getResourceState(id),ResourceBroker::InvalidParameterException);
+
+}
diff --git a/service/resource-encapsulation/src/resourceBroker/unittest/ResourcePresenceUnitTest.cpp b/service/resource-encapsulation/src/resourceBroker/unittest/ResourcePresenceUnitTest.cpp
new file mode 100644 (file)
index 0000000..31ca22e
--- /dev/null
@@ -0,0 +1,252 @@
+//******************************************************************
+//
+// 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 <vector>
+#include <unistd.h>
+#include <memory>
+
+#include "gtest/gtest.h"
+#include "HippoMocks/hippomocks.h"
+
+#include "OCResource.h"
+#include "OCPlatform.h"
+
+#include "PrimitiveResource.h"
+#include "BrokerTypes.h"
+#include "ResponseStatement.h"
+#include "RCSResourceAttributes.h"
+#include "ResourcePresence.h"
+#include "UnitTestHelper.h"
+
+using namespace testing;
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*subscribePresenceSig1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+
+class ResourcePresenceTest : public TestWithMock
+{
+public:
+
+    typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int)> GetCallback;
+
+    std::shared_ptr<ResourcePresence> instance;
+    PrimitiveResource::Ptr pResource;
+    BrokerCB cb;
+    BrokerID id;
+
+protected:
+
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        instance.reset(new ResourcePresence());
+        pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource*){});
+        cb = ([](BROKER_STATE)->OCStackResult{return OC_STACK_OK;});
+        id = 0;
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+        instance.reset();
+        pResource.reset();
+        id = 0;
+        cb = nullptr;
+    }
+
+    void MockingFunc()
+    {
+        mocks.OnCall(pResource.get(), PrimitiveResource::requestGet).Do([](GetCallback){});
+        mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return(std::string());
+        mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Return(OC_STACK_OK);
+    }
+
+};
+TEST_F(ResourcePresenceTest,timeoutCB_TimeOverWhenIsRequestGet)
+{
+    MockingFunc();
+    instance->initializeResourcePresence(pResource);
+    std::cout<<"wait while done timeout requestGet\n";
+    BROKER_STATE state;
+    state = instance->getResourceState();
+    sleep((BROKER_DEVICE_PRESENCE_TIMEROUT/1000)+1);
+    ASSERT_EQ(state,instance->getResourceState());
+}
+
+TEST_F(ResourcePresenceTest,initializeResourcePresence_NormalhandlingIfNormalResource)
+{
+    MockingFunc();
+    instance->initializeResourcePresence(pResource);
+    ASSERT_NE(nullptr,instance->getPrimitiveResource());
+}
+
+TEST_F(ResourcePresenceTest,addBrokerRequester_ReturnNormalValueIfNormalParams)
+{
+    MockingFunc();
+    instance->initializeResourcePresence(pResource);
+    id = 1;
+    instance->addBrokerRequester(id,cb);
+    EXPECT_FALSE(instance->isEmptyRequester());
+
+}
+
+TEST_F(ResourcePresenceTest,removeBrokerRequester_NormalHandlingIfNormalId)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+    id = 1;
+    instance->addBrokerRequester(id,cb);
+    id = 2;
+    instance->addBrokerRequester(id,cb);
+
+    instance->removeBrokerRequester(id);
+    ASSERT_EQ(1,instance->requesterListSize());
+
+}
+
+TEST_F(ResourcePresenceTest,removeAllBrokerRequester_NormalHandling)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+    id = 1;
+    instance->addBrokerRequester(id,cb);
+    id = 2;
+    instance->addBrokerRequester(id,cb);
+
+    instance->removeAllBrokerRequester();
+    ASSERT_TRUE(instance->isEmptyRequester());
+
+}
+
+TEST_F(ResourcePresenceTest,removeAllBrokerRequester_ErrorHandlingIfListNull)
+{
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+    instance->removeAllBrokerRequester();
+
+}
+
+TEST_F(ResourcePresenceTest,requestResourceState_NormalHandling)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+
+    ASSERT_NO_THROW(instance->requestResourceState());
+
+}
+
+TEST_F(ResourcePresenceTest,changePresenceMode_NormalHandlingIfNewModeDifferent)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+
+    instance->changePresenceMode(BROKER_MODE::DEVICE_PRESENCE_MODE);
+
+}
+
+TEST_F(ResourcePresenceTest,getResourceState_NormalHandling)
+{
+    MockingFunc();
+    instance->initializeResourcePresence(pResource);
+    ASSERT_EQ(BROKER_STATE::REQUESTED,instance->getResourceState());
+
+}
+
+TEST_F(ResourcePresenceTest,changePresenceMode_NormalHandlingIfNewModeSame)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+
+    instance->changePresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
+
+}
+
+TEST_F(ResourcePresenceTest,getPrimitiveResource_NormalHandling)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+    ASSERT_NE(nullptr,instance->getPrimitiveResource());
+
+}
+
+TEST_F(ResourcePresenceTest,isEmptyRequester_NormalHandling)
+{
+
+    MockingFunc();
+
+    instance->initializeResourcePresence(pResource);
+    id = 1;
+    instance->addBrokerRequester(id,cb);
+    instance->removeAllBrokerRequester();
+    ASSERT_TRUE(instance->isEmptyRequester());
+
+}
+
+TEST_F(ResourcePresenceTest,getCB_NormalHandlingIfMessageOC_STACK_OK)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet).Do(
+                [](GetCallback callback){
+
+        OIC::Service::HeaderOptions op;
+        RCSResourceAttributes attr;
+        OIC::Service::ResponseStatement res(attr);
+
+        callback(op,res,OC_STACK_OK);
+
+    });
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet).Do(
+                                [](GetCallback){
+        std::cout <<"End call requestGetFunc()\n";
+                    });
+    mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return("address1");
+
+    mocks.OnCallFuncOverload(static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Do(
+            [](OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, OCConnectivityType, SubscribeCallback callback)->OCStackResult{
+
+        callback(OC_STACK_OK,0,std::string());
+        return OC_STACK_OK;
+
+    }).Return(OC_STACK_OK);
+
+    instance->initializeResourcePresence(pResource);
+    sleep(3);
+
+}
+
+
+
diff --git a/service/resource-encapsulation/src/resourceBroker/unittest/SConscript b/service/resource-encapsulation/src/resourceBroker/unittest/SConscript
new file mode 100644 (file)
index 0000000..d1371d8
--- /dev/null
@@ -0,0 +1,87 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceBroker Unit Test build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+######################################################################
+#unit test setting 
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+broker_test_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+broker_test_env.AppendUnique(CPPPATH = ['../include'])
+broker_test_env.AppendUnique(CPPPATH = ['../../../include'])
+broker_test_env.AppendUnique(CPPPATH = ['../../common/primitiveResource/include'])
+broker_test_env.AppendUnique(CPPPATH = ['../../common/expiryTimer/include'])
+broker_test_env.AppendUnique(CPPPATH = ['../../common/expiryTimer/src'])
+broker_test_env.AppendUnique(CPPPATH = ['../../common/utils/include'])
+
+broker_test_env.PrependUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+                             gtest_dir + '/include'])
+broker_test_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+broker_test_env.PrependUnique(LIBS = ['rcs_client','rcs_common', 'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', gtest, gtest_main])
+
+if target_os not in ['windows', 'winrt']:
+    broker_test_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os == 'linux':
+    broker_test_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Build Test
+######################################################################
+
+broker_test_src = env.Glob('./*.cpp')
+broker_test = broker_test_env.Program('broker_test', broker_test_src)
+Alias("broker_test", broker_test)
+env.AppendTarget('broker_test')
+
+if env.get('TEST') == '1':
+        target_os = env.get('TARGET_OS')
+        if target_os == 'linux':
+                from tools.scons.RunTest import *
+                run_test(broker_test_env,
+                         '',
+                         'service/resource-encapsulation/src/resourceBroker/unittest/broker_test')
diff --git a/service/resource-encapsulation/src/resourceCache/include/CacheTypes.h b/service/resource-encapsulation/src/resourceCache/include/CacheTypes.h
new file mode 100644 (file)
index 0000000..0f9460e
--- /dev/null
@@ -0,0 +1,92 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RCM_CACHETYPES_H
+#define RCM_CACHETYPES_H
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+#include "logger.h"
+
+#include "PrimitiveResource.h"
+#include "RCSResourceAttributes.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class DataCache;
+
+#define CACHE_TAG  PCF("CACHE")
+#define CACHE_DEFAULT_REPORT_MILLITIME 10000
+#define CACHE_DEFAULT_EXPIRED_MILLITIME 15000
+
+        enum class REPORT_FREQUENCY
+        {
+            NONE = 0,
+            UPTODATE,
+            PERIODICTY
+        };
+
+        struct Report_Info
+        {
+            REPORT_FREQUENCY rf;
+            int reportID;
+            long repeatTime;
+            unsigned int timerID;
+        };
+
+        enum class CACHE_STATE
+        {
+            READY = 0,
+            READY_YET,
+            LOST_SIGNAL,
+            DESTROYED,
+            UPDATING,
+            NONE
+        };
+
+        enum class CACHE_MODE
+        {
+            OBSERVE = 0,
+            FREQUENCY
+        };
+
+        typedef int CacheID;
+
+        typedef std::function<OCStackResult(std::shared_ptr<PrimitiveResource>,
+                                            const RCSResourceAttributes &)> CacheCB;
+        typedef std::map<int, std::pair<Report_Info, CacheCB>> SubscriberInfo;
+        typedef std::pair<int, std::pair<Report_Info, CacheCB>> SubscriberInfoPair;
+
+        typedef OC::OCResource BaseResource;
+        typedef PrimitiveResource::GetCallback GetCB;
+        typedef PrimitiveResource::ObserveCallback ObserveCB;
+
+        typedef std::shared_ptr<DataCache> DataCachePtr;
+        typedef std::shared_ptr<PrimitiveResource> PrimitiveResourcePtr;
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RCM_CACHETYPES_H */
diff --git a/service/resource-encapsulation/src/resourceCache/include/DataCache.h b/service/resource-encapsulation/src/resourceCache/include/DataCache.h
new file mode 100644 (file)
index 0000000..b1429c6
--- /dev/null
@@ -0,0 +1,101 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RCM_DATACACHE_H_
+#define RCM_DATACACHE_H_
+
+#include <list>
+#include <string>
+#include <memory>
+#include <mutex>
+
+#include "CacheTypes.h"
+#include "ExpiryTimer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class DataCache : public std::enable_shared_from_this<DataCache>
+        {
+            public:
+                typedef unsigned int TimerID;
+                typedef std::function<void(TimerID)> TimerCB;
+
+            public:
+                DataCache();
+                ~DataCache();
+
+                void initializeDataCache(PrimitiveResourcePtr pResource);
+
+                CacheID addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime);
+                CacheID deleteSubscriber(CacheID id);
+
+                CACHE_STATE getCacheState() const;
+                const RCSResourceAttributes getCachedData() const;
+                const PrimitiveResourcePtr getPrimitiveResource() const;
+
+                void requestGet();
+                bool isEmptySubscriber() const;
+                bool isCachedData() const;
+
+            private:
+                // resource instance
+                PrimitiveResourcePtr sResource;
+
+                // cached data info
+                RCSResourceAttributes attributes;
+                CACHE_STATE state;
+                CACHE_MODE mode;
+                bool isReady;
+
+                // subscriber info
+                std::unique_ptr<SubscriberInfo> subscriberList;
+                mutable std::mutex m_mutex;
+                mutable std::mutex att_mutex;
+
+                ExpiryTimer networkTimer;
+                ExpiryTimer pollingTimer;
+                TimerID networkTimeOutHandle;
+                TimerID pollingHandle;
+
+                ObserveCB pObserveCB;
+                GetCB pGetCB;
+                TimerCB pTimerCB;
+                TimerCB pPollingCB;
+
+                unsigned int lastSequenceNum;
+
+            public:
+                void onObserve(const HeaderOptions &_hos,
+                               const ResponseStatement &_rep, int _result, int _seq);
+                void onGet(const HeaderOptions &_hos, const ResponseStatement &_rep, int _result);
+            private:
+                void onTimeOut(const unsigned int timerID);
+                void onPollingOut(const unsigned int timerID);
+
+                CacheID generateCacheID();
+                SubscriberInfoPair findSubscriber(CacheID id);
+                void notifyObservers(const RCSResourceAttributes Att);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RCM_DATACACHE_H_ */
diff --git a/service/resource-encapsulation/src/resourceCache/include/ResourceCacheManager.h b/service/resource-encapsulation/src/resourceCache/include/ResourceCacheManager.h
new file mode 100644 (file)
index 0000000..23a3a45
--- /dev/null
@@ -0,0 +1,101 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RCM_RESOURCECACHEMANAGER_H_
+#define RCM_RESOURCECACHEMANAGER_H_
+
+#include <list>
+#include <string>
+#include <mutex>
+#include <map>
+
+#include "CacheTypes.h"
+#include "DataCache.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceCacheManager
+        {
+            public:
+                class InvalidParameterException: public RCSException
+                {
+                    public:
+                        InvalidParameterException(std::string &&what)
+                            : RCSException { std::move(what) } {}
+                };
+                class HasNoCachedDataException: public RCSException
+                {
+                    public:
+                        HasNoCachedDataException(std::string &&what)
+                            : RCSException { std::move(what) } {}
+                };
+
+                static ResourceCacheManager *getInstance();
+
+                // throw InvalidParameterException;
+                CacheID requestResourceCache(
+                    PrimitiveResourcePtr pResource, CacheCB func = NULL,
+                    REPORT_FREQUENCY rf = REPORT_FREQUENCY::NONE, long time = 0l);
+
+                // throw InvalidParameterException;
+                void cancelResourceCache(CacheID id);
+
+                // throw InvalidParameterException;
+                void updateResourceCache(PrimitiveResourcePtr pResource) const;
+                void updateResourceCache(CacheID id) const;
+
+                // throw InvalidParameterException;
+                // throw HasNoCachedDataException;
+                const RCSResourceAttributes getCachedData(PrimitiveResourcePtr pResource) const;
+                const RCSResourceAttributes getCachedData(CacheID id) const;
+
+                // throw InvalidParameterException;
+                CACHE_STATE getResourceCacheState(PrimitiveResourcePtr pResource) const;
+                CACHE_STATE getResourceCacheState(CacheID id) const;
+
+                // throw InvalidParameterException;
+                bool isCachedData(PrimitiveResourcePtr pResource) const;
+                bool isCachedData(CacheID id) const;
+
+            private:
+                static ResourceCacheManager *s_instance;
+                static std::mutex s_mutex;
+                static std::mutex s_mutexForCreation;
+                static std::unique_ptr<std::list<DataCachePtr>> s_cacheDataList;
+                std::map<CacheID, DataCachePtr> cacheIDmap;
+
+                ResourceCacheManager() = default;
+                ~ResourceCacheManager();
+                ResourceCacheManager(const ResourceCacheManager &) = delete;
+                ResourceCacheManager(ResourceCacheManager &&) = delete;
+
+                ResourceCacheManager &operator=(const ResourceCacheManager &) const = delete;
+                ResourceCacheManager &operator=(ResourceCacheManager && ) const = delete;
+
+                static void initializeResourceCacheManager();
+                DataCachePtr findDataCache(PrimitiveResourcePtr pResource) const;
+                DataCachePtr findDataCache(CacheID id) const;
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RCM_RESOURCECACHEMANAGER_H_ */
diff --git a/service/resource-encapsulation/src/resourceCache/src/DataCache.cpp b/service/resource-encapsulation/src/resourceCache/src/DataCache.cpp
new file mode 100644 (file)
index 0000000..e21973c
--- /dev/null
@@ -0,0 +1,346 @@
+//******************************************************************
+//
+// 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 <memory>
+#include <cstdlib>
+#include <functional>
+#include <map>
+#include <utility>
+#include <ctime>
+
+#include "DataCache.h"
+
+#include "ResponseStatement.h"
+#include "RCSResourceAttributes.h"
+#include "ExpiryTimer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        namespace
+        {
+            void verifyObserveCB(
+                const HeaderOptions &_hos, const ResponseStatement &_rep,
+                int _result, int _seq, std::weak_ptr<DataCache> rpPtr)
+            {
+                std::shared_ptr<DataCache> Ptr = rpPtr.lock();
+                if (Ptr)
+                {
+                    Ptr->onObserve(_hos, _rep, _result, _seq);
+                }
+            }
+
+            ObserveCB verifiedObserveCB(std::weak_ptr<DataCache> rpPtr)
+            {
+                return std::bind(verifyObserveCB,
+                                 std::placeholders::_1, std::placeholders::_2,
+                                 std::placeholders::_3, std::placeholders::_4, rpPtr);
+            }
+
+            void verifyGetCB(
+                const HeaderOptions &_hos, const ResponseStatement &_rep,
+                int _result, std::weak_ptr<DataCache> rpPtr)
+            {
+                std::shared_ptr<DataCache> Ptr = rpPtr.lock();
+                if (Ptr)
+                {
+                    Ptr->onGet(_hos, _rep, _result);
+                }
+            }
+
+            GetCB verifiedGetCB(std::weak_ptr<DataCache> rpPtr)
+            {
+                return std::bind(verifyGetCB,
+                                 std::placeholders::_1, std::placeholders::_2,
+                                 std::placeholders::_3, rpPtr);
+            }
+        }
+
+        DataCache::DataCache()
+        {
+            subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
+
+            sResource = nullptr;
+
+            state = CACHE_STATE::READY_YET;
+            mode = CACHE_MODE::FREQUENCY;
+
+            networkTimeOutHandle = 0;
+            pollingHandle = 0;
+            lastSequenceNum = 0;
+            isReady = false;
+        }
+
+        DataCache::~DataCache()
+        {
+            state = CACHE_STATE::DESTROYED;
+
+            if (subscriberList != nullptr)
+            {
+                subscriberList->clear();
+                subscriberList.release();
+            }
+
+            if (mode == CACHE_MODE::OBSERVE)
+            {
+                try
+                {
+                    sResource->cancelObserve();
+                }
+                catch (...)
+                {
+                    // ignore the exception because data cache was released.
+                }
+            }
+        }
+
+        void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
+        {
+            sResource = pResource;
+            pObserveCB = verifiedObserveCB(std::weak_ptr<DataCache>(shared_from_this()));
+            pGetCB = verifiedGetCB(std::weak_ptr<DataCache>(shared_from_this()));
+            pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
+            pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
+
+            sResource->requestGet(pGetCB);
+            if (sResource->isObservable())
+            {
+                sResource->requestObserve(pObserveCB);
+            }
+            networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
+        }
+
+        CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
+        {
+            Report_Info newItem;
+            newItem.rf = rf;
+            newItem.repeatTime = repeatTime;
+            newItem.timerID = 0;
+
+            newItem.reportID = generateCacheID();
+
+            std::lock_guard<std::mutex> lock(m_mutex);
+            if (subscriberList != nullptr)
+            {
+                subscriberList->insert(
+                    std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
+            }
+
+            return newItem.reportID;
+        }
+
+        CacheID DataCache::deleteSubscriber(CacheID id)
+        {
+            CacheID ret = 0;
+
+            SubscriberInfoPair pair = findSubscriber(id);
+
+            std::lock_guard<std::mutex> lock(m_mutex);
+            if (pair.first != 0)
+            {
+                ret = pair.first;
+                subscriberList->erase(pair.first);
+            }
+
+            return ret;
+        }
+
+        SubscriberInfoPair DataCache::findSubscriber(CacheID id)
+        {
+            SubscriberInfoPair ret;
+
+            std::lock_guard<std::mutex> lock(m_mutex);
+            for (auto &i : *subscriberList)
+            {
+                if (i.first == id)
+                {
+                    ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
+                                         (CacheCB)i.second.second));
+                    break;
+                }
+            }
+
+            return ret;
+        }
+
+        const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
+        {
+            return (sResource != nullptr) ? sResource : nullptr;
+        }
+
+        const RCSResourceAttributes DataCache::getCachedData() const
+        {
+            std::lock_guard<std::mutex> lock(att_mutex);
+            if (state != CACHE_STATE::READY)
+            {
+                return RCSResourceAttributes();
+            }
+            return attributes;
+        }
+
+        bool DataCache::isCachedData() const
+        {
+            return isReady;
+        }
+
+        void DataCache::onObserve(const HeaderOptions & /*_hos*/,
+                                  const ResponseStatement &_rep, int _result, int _seq)
+        {
+
+            if (_result != OC_STACK_OK || _rep.getAttributes().empty() || lastSequenceNum > _seq)
+            {
+                return;
+            }
+            else
+            {
+                lastSequenceNum = _seq;
+            }
+
+            if (state != CACHE_STATE::READY)
+            {
+                state = CACHE_STATE::READY;
+                isReady = true;
+            }
+
+            if (mode != CACHE_MODE::OBSERVE)
+            {
+                mode = CACHE_MODE::OBSERVE;
+            }
+
+            networkTimer.cancel(networkTimeOutHandle);
+            networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
+
+            notifyObservers(_rep.getAttributes());
+        }
+
+        void DataCache::onGet(const HeaderOptions & /*_hos*/,
+                              const ResponseStatement &_rep, int _result)
+        {
+            if (_result != OC_STACK_OK || _rep.getAttributes().empty())
+            {
+                return;
+            }
+
+            if (state != CACHE_STATE::READY)
+            {
+                state = CACHE_STATE::READY;
+                isReady = true;
+            }
+
+            if (mode != CACHE_MODE::OBSERVE)
+            {
+                networkTimer.cancel(networkTimeOutHandle);
+                networkTimeOutHandle = networkTimer.post(
+                                           CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
+
+                pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
+            }
+
+            notifyObservers(_rep.getAttributes());
+        }
+
+        void DataCache::notifyObservers(const RCSResourceAttributes Att)
+        {
+            {
+                std::lock_guard<std::mutex> lock(att_mutex);
+                if (attributes == Att)
+                {
+                    return;
+                }
+                attributes = Att;
+            }
+
+            std::lock_guard<std::mutex> lock(m_mutex);
+            for (auto &i : * subscriberList)
+            {
+                if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
+                {
+                    i.second.second(this->sResource, Att);
+                }
+            }
+        }
+
+        CACHE_STATE DataCache::getCacheState() const
+        {
+            return state;
+        }
+
+        void DataCache::onTimeOut(unsigned int /*timerID*/)
+        {
+            if (mode == CACHE_MODE::OBSERVE)
+            {
+                sResource->cancelObserve();
+                mode = CACHE_MODE::FREQUENCY;
+
+                networkTimer.cancel(networkTimeOutHandle);
+                networkTimeOutHandle = networkTimer.post(
+                                           CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
+
+                pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
+                return;
+            }
+
+            state = CACHE_STATE::LOST_SIGNAL;
+        }
+        void DataCache::onPollingOut(const unsigned int /*timerID*/)
+        {
+            if (sResource != nullptr)
+            {
+                mode = CACHE_MODE::FREQUENCY;
+                sResource->requestGet(pGetCB);
+            }
+            return;
+        }
+
+        CacheID DataCache::generateCacheID()
+        {
+            CacheID retID = 0;
+            srand(time(NULL));
+
+            while (1)
+            {
+                if (findSubscriber(retID).first == 0 && retID != 0)
+                {
+                    break;
+                }
+                retID = rand();
+            }
+
+            return retID;
+        }
+
+        void DataCache::requestGet()
+        {
+            state = CACHE_STATE::UPDATING;
+            if (sResource != nullptr)
+            {
+                sResource->requestGet(pGetCB);
+            }
+        }
+
+        bool DataCache::isEmptySubscriber() const
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            return (subscriberList != nullptr) ? subscriberList->empty() : true;
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceCache/src/ResourceCacheManager.cpp b/service/resource-encapsulation/src/resourceCache/src/ResourceCacheManager.cpp
new file mode 100644 (file)
index 0000000..e53608b
--- /dev/null
@@ -0,0 +1,295 @@
+//******************************************************************
+//
+// 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 "ResourceCacheManager.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourceCacheManager *ResourceCacheManager::s_instance = NULL;
+        std::mutex ResourceCacheManager::s_mutexForCreation;
+        std::mutex ResourceCacheManager::s_mutex;
+        std::unique_ptr<std::list<DataCachePtr>> ResourceCacheManager::s_cacheDataList(nullptr);
+
+        ResourceCacheManager::~ResourceCacheManager()
+        {
+            std::lock_guard<std::mutex> lock(s_mutex);
+            if (s_cacheDataList != nullptr)
+            {
+                s_cacheDataList->clear();
+            }
+        }
+
+        ResourceCacheManager *ResourceCacheManager::getInstance()
+        {
+            if (s_instance == nullptr)
+            {
+                s_mutexForCreation.lock();
+                if (s_instance == nullptr)
+                {
+                    s_instance = new ResourceCacheManager();
+                    s_instance->initializeResourceCacheManager();
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        CacheID ResourceCacheManager::requestResourceCache(
+            PrimitiveResourcePtr pResource, CacheCB func,
+            REPORT_FREQUENCY rf, long reportTime)
+        {
+            if (pResource == nullptr)
+            {
+                throw InvalidParameterException {"[requestResourceCache] Primitive Resource is invaild"};
+            }
+
+            CacheID retID = 0;
+
+            if (rf != REPORT_FREQUENCY::NONE)
+            {
+                if (func == NULL || func == nullptr)
+                {
+                    throw InvalidParameterException {"[requestResourceCache] CacheCB is invaild"};
+                }
+                if (!reportTime)
+                {
+                    // default setting
+                    reportTime = CACHE_DEFAULT_REPORT_MILLITIME;
+                }
+            }
+
+            DataCachePtr newHandler = findDataCache(pResource);
+            if (newHandler == nullptr)
+            {
+                std::lock_guard<std::mutex> lock(s_mutex);
+                newHandler.reset(new DataCache());
+                newHandler->initializeDataCache(pResource);
+                s_cacheDataList->push_back(newHandler);
+            }
+            retID = newHandler->addSubscriber(func, rf, reportTime);
+
+            cacheIDmap.insert(std::make_pair(retID, newHandler));
+
+            return retID;
+        }
+
+        void ResourceCacheManager::cancelResourceCache(CacheID id)
+        {
+            if (id == 0 || cacheIDmap.find(id) == cacheIDmap.end())
+            {
+                throw InvalidParameterException {"[cancelResourceCache] CacheID is invaild"};
+            }
+
+            DataCachePtr foundCacheHandler = findDataCache(id);
+            if (foundCacheHandler != nullptr)
+            {
+                CacheID retID = foundCacheHandler->deleteSubscriber(id);
+                if (retID == id)
+                {
+                    cacheIDmap.erase(id);
+                }
+                std::lock_guard<std::mutex> lock(s_mutex);
+                if (foundCacheHandler->isEmptySubscriber())
+                {
+                    s_cacheDataList->remove(foundCacheHandler);
+                }
+            }
+        }
+
+        void ResourceCacheManager::updateResourceCache(PrimitiveResourcePtr pResource) const
+        {
+            if (pResource == nullptr)
+            {
+                throw InvalidParameterException
+                {"[updateResourceCache] Primitive Resource is invaild"};
+            }
+
+            DataCachePtr foundCache = findDataCache(pResource);
+            if (foundCache == nullptr)
+            {
+                throw InvalidParameterException
+                {"[updateResourceCache] Primitive Resource is invaild"};
+            }
+            foundCache->requestGet();
+        }
+
+        void ResourceCacheManager::updateResourceCache(CacheID updateId) const
+        {
+            if (updateId == 0)
+            {
+                throw InvalidParameterException {"[getCachedData] CacheID is NULL"};
+            }
+
+            DataCachePtr foundCache = findDataCache(updateId);
+            if (foundCache == nullptr)
+            {
+                throw InvalidParameterException {"[getCachedData] CacheID is invaild"};
+            }
+            foundCache->requestGet();
+        }
+
+        const RCSResourceAttributes ResourceCacheManager::getCachedData(
+            PrimitiveResourcePtr pResource) const
+        {
+            if (pResource == nullptr)
+            {
+                throw InvalidParameterException {"[getCachedData] Primitive Resource is nullptr"};
+            }
+
+            DataCachePtr handler = findDataCache(pResource);
+            if (handler == nullptr)
+            {
+                throw InvalidParameterException {"[getCachedData] Primitive Resource is invaild"};
+            }
+
+            if (handler->isCachedData() == false)
+            {
+                throw HasNoCachedDataException {"[getCachedData] Cached Data is not stored"};
+            }
+
+            return handler->getCachedData();
+        }
+
+        const RCSResourceAttributes ResourceCacheManager::getCachedData(CacheID id) const
+        {
+            if (id == 0)
+            {
+                throw InvalidParameterException {"[getCachedData] CacheID is NULL"};
+            }
+
+            DataCachePtr handler = findDataCache(id);
+            if (handler == nullptr)
+            {
+                throw InvalidParameterException {"[getCachedData] CacheID is invaild"};
+            }
+
+            if (handler->isCachedData() == false)
+            {
+                throw HasNoCachedDataException {"[getCachedData] Cached Data is not stored"};
+            }
+
+            return handler->getCachedData();
+        }
+
+        CACHE_STATE ResourceCacheManager::getResourceCacheState(
+            PrimitiveResourcePtr pResource) const
+        {
+            if (pResource == nullptr)
+            {
+                throw InvalidParameterException {"[getResourceCacheState] Primitive Resource is nullptr"};
+            }
+
+            DataCachePtr handler = findDataCache(pResource);
+            if (handler == nullptr)
+            {
+                return CACHE_STATE::NONE;
+            }
+            return handler->getCacheState();
+        }
+
+        CACHE_STATE ResourceCacheManager::getResourceCacheState(CacheID id) const
+        {
+            if (id == 0)
+            {
+                throw InvalidParameterException {"[getResourceCacheState] CacheID is NULL"};
+            }
+
+            DataCachePtr handler = findDataCache(id);
+            if (handler == nullptr)
+            {
+                return CACHE_STATE::NONE;
+            }
+            return handler->getCacheState();
+        }
+
+        bool ResourceCacheManager::isCachedData(PrimitiveResourcePtr pResource) const
+        {
+            if (pResource == nullptr)
+            {
+                throw InvalidParameterException {"[isCachedData] Primitive Resource is nullptr"};
+            }
+
+            DataCachePtr handler = findDataCache(pResource);
+            if (handler == nullptr)
+            {
+                throw InvalidParameterException {"[isCachedData] Primitive Resource is invaild"};
+            }
+            return handler->isCachedData();
+        }
+
+        bool ResourceCacheManager::isCachedData(CacheID id) const
+        {
+            if (id == 0)
+            {
+                throw InvalidParameterException {"[isCachedData] CacheID is NULL"};
+            }
+
+            DataCachePtr handler = findDataCache(id);
+            if (handler == nullptr)
+            {
+                throw InvalidParameterException {"[isCachedData] CacheID is invaild"};
+            }
+            return handler->isCachedData();
+        }
+
+        void ResourceCacheManager::initializeResourceCacheManager()
+        {
+            std::lock_guard<std::mutex> lock(s_mutex);
+            if (s_cacheDataList == nullptr)
+            {
+                s_cacheDataList
+                    = std::unique_ptr<std::list<DataCachePtr>>(new std::list<DataCachePtr>);
+            }
+        }
+
+        DataCachePtr ResourceCacheManager::findDataCache(PrimitiveResourcePtr pResource) const
+        {
+            DataCachePtr retHandler = nullptr;
+            std::lock_guard<std::mutex> lock(s_mutex);
+            for (auto &i : * s_cacheDataList)
+            {
+                if (i->getPrimitiveResource()->getUri() == pResource->getUri() &&
+                    i->getPrimitiveResource()->getHost() == pResource->getHost())
+                {
+                    retHandler = i;
+                    break;
+                }
+            }
+            return retHandler;
+        }
+
+        DataCachePtr ResourceCacheManager::findDataCache(CacheID id) const
+        {
+            DataCachePtr retHandler = nullptr;
+            for (auto it : cacheIDmap)
+            {
+                if (it.first == id)
+                {
+                    retHandler = it.second;
+                    break;
+                }
+            }
+
+            return retHandler;
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-encapsulation/src/resourceCache/unittests/DataCacheTest.cpp b/service/resource-encapsulation/src/resourceCache/unittests/DataCacheTest.cpp
new file mode 100644 (file)
index 0000000..41c3e6a
--- /dev/null
@@ -0,0 +1,262 @@
+//******************************************************************
+//
+// 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 <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include "ResourceCacheManager.h"
+#include "DataCache.h"
+#include "RCSResourceAttributes.h"
+#include "ResponseStatement.h"
+#include "UnitTestHelper.h"
+
+using namespace OIC::Service;
+
+class DataCacheTest : public TestWithMock
+{
+    public:
+        typedef std::function <
+        void(const OIC::Service::HeaderOptions &, const OIC::Service::ResponseStatement &,
+             int) > GetCallback;
+
+        typedef std::function <
+        void(const OIC::Service::HeaderOptions &, const OIC::Service::ResponseStatement &, int,
+             int) > ObserveCallback;
+    public:
+        std::shared_ptr<DataCache> cacheHandler;
+        PrimitiveResource::Ptr pResource;
+        CacheCB cb;
+        CacheID id;
+
+    protected:
+        virtual void SetUp()
+        {
+            TestWithMock::SetUp();
+            pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource *) {});
+            cacheHandler.reset(new DataCache());
+            cb = ([](std::shared_ptr<PrimitiveResource >, const RCSResourceAttributes &)->OCStackResult {return OC_STACK_OK;});
+        }
+
+        virtual void TearDown()
+        {
+            cacheHandler.reset();
+            pResource.reset();
+            TestWithMock::TearDown();
+        }
+};
+
+TEST_F(DataCacheTest, initializeDataCache_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+}
+
+TEST_F(DataCacheTest, initializeDataCache_normalCaseObservable)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet).Do(
+        [](GetCallback callback)
+    {
+        OIC::Service::HeaderOptions hos;
+
+        OIC::Service::RCSResourceAttributes attr;
+        OIC::Service::ResponseStatement rep(attr);
+        callback(hos, rep, OC_STACK_OK);
+        return;
+    }
+    );
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestObserve).Do(
+        [](ObserveCallback callback)
+    {
+        OIC::Service::HeaderOptions hos;
+        OIC::Service::RCSResourceAttributes attr;
+        OIC::Service::ResponseStatement rep(attr);
+        int seq;
+        callback(hos, rep, OC_STACK_OK, seq);
+        return;
+    }
+    );
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+}
+
+TEST_F(DataCacheTest, initializeDataCache_normalCaseNonObservable)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet).Do(
+        [](GetCallback callback)
+    {
+        OIC::Service::HeaderOptions hos;
+
+        OIC::Service::RCSResourceAttributes attr;
+        OIC::Service::ResponseStatement rep(attr);
+        callback(hos, rep, OC_STACK_OK);
+        return;
+    }
+    );
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(false);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    sleep(3);
+}
+
+TEST_F(DataCacheTest, initializeDataCache_normalCaseTimeOut)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    sleep(3);
+}
+
+TEST_F(DataCacheTest, addSubscriber_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 1l;
+
+    ASSERT_NE(cacheHandler->addSubscriber(cb, rf, reportTime), 0);
+}
+
+TEST_F(DataCacheTest, deleteSubsciber_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 1l;
+
+    id = cacheHandler->addSubscriber(cb, rf, reportTime);
+
+    ASSERT_NE(cacheHandler->deleteSubscriber(id), 0);
+}
+
+TEST_F(DataCacheTest, getCacheState_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    ASSERT_EQ(cacheHandler->getCacheState(), CACHE_STATE::READY_YET);
+}
+
+TEST_F(DataCacheTest, getCachedData_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    ASSERT_EQ(cacheHandler->getCachedData(), RCSResourceAttributes());
+}
+
+TEST_F(DataCacheTest, getPrimitiveResource_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    ASSERT_EQ(cacheHandler->getPrimitiveResource(), pResource);
+}
+
+TEST_F(DataCacheTest, requestGet_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    cacheHandler->requestGet();
+}
+
+TEST_F(DataCacheTest, isEmptySubscriber_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    ASSERT_EQ(cacheHandler->isEmptySubscriber(), true);
+}
+
+TEST_F(DataCacheTest, requestGet_normalCasetest)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet).Do(
+        [](GetCallback callback)
+    {
+        OIC::Service::HeaderOptions hos;
+        OIC::Service::RCSResourceAttributes attr;
+        OIC::Service::ResponseStatement rep(attr);
+        callback(hos, rep, OC_STACK_OK);
+        return;
+    });
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    cacheHandler->initializeDataCache(pResource);
+
+    cacheHandler->requestGet();
+}
diff --git a/service/resource-encapsulation/src/resourceCache/unittests/ResourceCacheTest.cpp b/service/resource-encapsulation/src/resourceCache/unittests/ResourceCacheTest.cpp
new file mode 100644 (file)
index 0000000..14f3f40
--- /dev/null
@@ -0,0 +1,307 @@
+//******************************************************************
+//
+// 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 <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include "ResourceCacheManager.h"
+#include "UnitTestHelper.h"
+
+using namespace OIC::Service;
+
+class ResourceCacheManagerTest : public TestWithMock
+{
+    public:
+        ResourceCacheManager *cacheInstance;
+        PrimitiveResource::Ptr pResource;
+        CacheCB cb;
+        CacheID id;
+
+    protected:
+        virtual void SetUp()
+        {
+            TestWithMock::SetUp();
+            cacheInstance = ResourceCacheManager::getInstance();
+            pResource = PrimitiveResource::Ptr(mocks.Mock< PrimitiveResource >(), [](PrimitiveResource *) {});
+            cb = ([](std::shared_ptr<PrimitiveResource >, const RCSResourceAttributes &)->OCStackResult {return OC_STACK_OK;});
+        }
+
+        virtual void TearDown()
+        {
+            pResource.reset();
+            TestWithMock::TearDown();
+        }
+};
+
+TEST_F(ResourceCacheManagerTest, requestResourceCache_resourceIsNULL)
+{
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    ASSERT_THROW(cacheInstance->requestResourceCache(NULL, func, rf, reportTime),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, requestResourceCache_cacheCBIsNULL)
+{
+
+    CacheCB func = NULL;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    ASSERT_THROW(cacheInstance->requestResourceCache(pResource, func, rf, reportTime),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, requestResourceCache_reportTimeIsNULL)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf);
+    cacheInstance->cancelResourceCache(id);
+
+    ASSERT_NE(id, 0);
+
+}
+
+TEST_F(ResourceCacheManagerTest, requestResourceCache_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+    cacheInstance->cancelResourceCache(id);
+
+    ASSERT_NE(id, 0);
+}
+
+TEST_F(ResourceCacheManagerTest, cancelResourceCache_cacheIDIsZero)
+{
+
+    ASSERT_THROW(cacheInstance->cancelResourceCache(0),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, cancelResourceCache_normalCase)
+{
+
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.ExpectCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+
+    cacheInstance->cancelResourceCache(id);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCachePrimitiveResource_resourceIsNULL)
+{
+
+    pResource = NULL;
+
+    ASSERT_THROW(cacheInstance->updateResourceCache(pResource),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCachePrimitiveResource_cacheIsNULL)
+{
+
+    ASSERT_THROW(cacheInstance->updateResourceCache(pResource),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCachePrimitiveResource_normalCase)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::getUri).Return("testUri");
+    mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return("testHost");
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+
+    cacheInstance->updateResourceCache(pResource);
+
+    cacheInstance->cancelResourceCache(id);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCacheCacheID_cacheIDIsZero)
+{
+
+    ASSERT_THROW(cacheInstance->updateResourceCache(0),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCacheCacheID_cacheIsNULL)
+{
+
+    ASSERT_THROW(cacheInstance->updateResourceCache(id),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, updateResourceCacheCacheID_normalCase)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::getUri).Return("testUri");
+    mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return("testHost");
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+
+    cacheInstance->updateResourceCache(id);
+
+    cacheInstance->cancelResourceCache(id);
+}
+
+TEST_F(ResourceCacheManagerTest, getCachedDataPrimitiveResource_resourceIsNULL)
+{
+
+    pResource = NULL;
+
+    ASSERT_THROW(cacheInstance->getCachedData(pResource),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getCachedDataPrimitiveResource_handlerIsNULL)
+{
+
+    ASSERT_THROW(cacheInstance->getCachedData(pResource),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getCachedDataCachID_resourceIsNULL)
+{
+
+    ASSERT_THROW(cacheInstance->getCachedData(0), ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getCachedDataCachID_handlerIsNULL)
+{
+
+    ASSERT_THROW(cacheInstance->getCachedData(id), ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStatePrimitiveResource_resourceIsNULL)
+{
+
+    pResource = NULL;
+
+    ASSERT_THROW(cacheInstance->getResourceCacheState(pResource),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStatePrimitiveResource_handlerIsNULL)
+{
+
+    ASSERT_EQ(cacheInstance->getResourceCacheState(pResource), CACHE_STATE::NONE);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStatePrimitiveResource_normalCase)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::getUri).Return("testUri");
+    mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return("testHost");
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+    CACHE_STATE state = cacheInstance->getResourceCacheState(pResource);
+
+    cacheInstance->cancelResourceCache(id);
+
+    ASSERT_EQ(state, CACHE_STATE::READY_YET);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStateCacheID_cacheIDIsZero)
+{
+
+    ASSERT_THROW(cacheInstance->getResourceCacheState(0),
+                 ResourceCacheManager::InvalidParameterException);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStateCacheID_handlerIsNULL)
+{
+
+    id = 1;
+    ASSERT_EQ(cacheInstance->getResourceCacheState(id), CACHE_STATE::NONE);
+}
+
+TEST_F(ResourceCacheManagerTest, getResourceCacheStateCacheID_normalCase)
+{
+
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestGet);
+    mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(true);
+    mocks.OnCall(pResource.get(), PrimitiveResource::requestObserve);
+    mocks.OnCall(pResource.get(), PrimitiveResource::getUri).Return("testUri");
+    mocks.OnCall(pResource.get(), PrimitiveResource::getHost).Return("testHost");
+    mocks.OnCall(pResource.get(), PrimitiveResource::cancelObserve);
+
+    CacheCB func = cb;
+    REPORT_FREQUENCY rf = REPORT_FREQUENCY::UPTODATE;
+    long reportTime = 20l;
+
+    id = cacheInstance->requestResourceCache(pResource, func, rf, reportTime);
+    CACHE_STATE state = cacheInstance->getResourceCacheState(id);
+
+    cacheInstance->cancelResourceCache(id);
+
+    ASSERT_EQ(state, CACHE_STATE::READY_YET);
+}
diff --git a/service/resource-encapsulation/src/resourceCache/unittests/SConscript b/service/resource-encapsulation/src/resourceCache/unittests/SConscript
new file mode 100644 (file)
index 0000000..1561068
--- /dev/null
@@ -0,0 +1,85 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceCache Unit Test build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+    env.AppendUnique(CCFLAGS = ['-Os'])
+    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+######################################################################
+# unit test setting 
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+cache_test_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+cache_test_env.AppendUnique(CPPPATH = ['../include'])
+cache_test_env.AppendUnique(CPPPATH = ['../../../include'])
+cache_test_env.AppendUnique(CPPPATH = ['../../common/primitiveResource/include'])
+cache_test_env.AppendUnique(CPPPATH = ['../../common/expiryTimer/include'])
+cache_test_env.AppendUnique(CPPPATH = ['../../common/expiryTimer/src'])
+cache_test_env.AppendUnique(CPPPATH = ['../../common/utils/include'])
+cache_test_env.PrependUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+                             gtest_dir + '/include'])
+cache_test_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+cache_test_env.PrependUnique(LIBS = ['rcs_client', 'rcs_common', 'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', gtest, gtest_main])
+
+if target_os not in ['windows', 'winrt']:
+    cache_test_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os == 'linux':
+    cache_test_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Build Test
+######################################################################
+cache_test_src = env.Glob('./*.cpp')
+cache_test = cache_test_env.Program('cache_test', cache_test_src)
+Alias("cache_test", cache_test)
+env.AppendTarget('cache_test')
+
+if env.get('TEST') == '1':
+        target_os = env.get('TARGET_OS')
+        if target_os == 'linux':
+                from tools.scons.RunTest import *
+                run_test(cache_test_env,
+                         'cache_test.memcheck',
+                         'service/resource-encapsulation/src/resourceCache/unittests/cache_test')
\ No newline at end of file
diff --git a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp
new file mode 100644 (file)
index 0000000..c51b733
--- /dev/null
@@ -0,0 +1,74 @@
+//******************************************************************
+//
+// 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 "RCSDiscoveryManager.h"
+
+#include "RCSRemoteResourceObject.h"
+#include "PrimitiveResource.h"
+
+#include "ScopeLogger.h"
+
+#define TAG PCF("RCSDiscoveryManager")
+
+using namespace OIC::Service;
+
+namespace
+{
+    void findCallback(std::shared_ptr< PrimitiveResource > primitiveResource,
+            RCSDiscoveryManager::ResourceDiscoveredCallback cb)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        if (!primitiveResource)
+        {
+            OC_LOG(ERROR, TAG, "findCallback : primitiveResource is null.");
+            return;
+        }
+
+        cb(std::make_shared< RCSRemoteResourceObject >(primitiveResource));
+    }
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+        RCSDiscoveryManager* RCSDiscoveryManager::getInstance()
+        {
+            static RCSDiscoveryManager instance;
+            return &instance;
+        }
+
+        void RCSDiscoveryManager::discoverResource(const RCSAddress& address,
+                const std::string& resourceURI, ResourceDiscoveredCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                OC_LOG(ERROR, TAG, "discoverResource NULL Callback");
+                throw InvalidParameterException{ "discoverResource NULL Callback'" };
+            }
+
+            OIC::Service::discoverResource(address, resourceURI,
+                    std::bind(findCallback, std::placeholders::_1, std::move(cb)));
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp b/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp
new file mode 100644 (file)
index 0000000..369ef51
--- /dev/null
@@ -0,0 +1,342 @@
+//******************************************************************
+//
+// 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 "RCSRemoteResourceObject.h"
+
+#include "ResourceBroker.h"
+#include "ResourceCacheManager.h"
+
+#include "ScopeLogger.h"
+
+#define TAG PCF("RCSRemoteResourceObject")
+
+namespace
+{
+    using namespace OIC::Service;
+
+    ResourceState convertBrokerState(BROKER_STATE state)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        switch (state)
+        {
+            case BROKER_STATE::ALIVE:
+                return ResourceState::ALIVE;
+
+            case BROKER_STATE::REQUESTED:
+                return ResourceState::REQUESTED;
+
+            case BROKER_STATE::LOST_SIGNAL:
+                return ResourceState::LOST_SIGNAL;
+
+            case BROKER_STATE::DESTROYED:
+                return ResourceState::DESTROYED;
+
+            case BROKER_STATE::NONE:
+                return ResourceState::NONE;
+        }
+
+        return ResourceState::NONE;
+    }
+
+    CacheState convertCacheState(CACHE_STATE state)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        switch (state)
+        {
+            case CACHE_STATE::READY:
+                return CacheState::READY;
+
+            case CACHE_STATE::READY_YET:
+            case CACHE_STATE::UPDATING:
+                return CacheState::UNREADY;
+
+            case CACHE_STATE::LOST_SIGNAL:
+                return CacheState::LOST_SIGNAL;
+
+            case CACHE_STATE::DESTROYED:
+            case CACHE_STATE::NONE:
+                return CacheState::NONE;
+        }
+
+        return CacheState::NONE;
+    }
+
+    OCStackResult hostingCallback(BROKER_STATE state,
+            RCSRemoteResourceObject::StateChangedCallback onResourceStateChanged)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        onResourceStateChanged(convertBrokerState(state));
+        return OC_STACK_OK;
+    }
+
+    OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >,
+            const RCSResourceAttributes& data,
+            RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        onCacheUpdated(data);
+        return OC_STACK_OK;
+    }
+
+    void setCallback(const HeaderOptions&, const ResponseStatement& response, int,
+            RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        onRemoteAttributesSet(response.getAttributes());
+    }
+
+    void getCallback(const HeaderOptions&, const ResponseStatement& response, int,
+            RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
+    {
+        SCOPE_LOG_F(DEBUG, TAG);
+
+        onRemoteAttributesReceived(response.getAttributes());
+    }
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+        RCSRemoteResourceObject::RCSRemoteResourceObject(
+                std::shared_ptr< PrimitiveResource > pResource) :
+                m_primitiveResource{ pResource },
+                m_cacheId{ },
+                m_brokerId{ }
+        {
+        }
+
+        RCSRemoteResourceObject::~RCSRemoteResourceObject()
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            stopCaching();
+            stopMonitoring();
+        }
+
+        bool RCSRemoteResourceObject::isMonitoring() const
+        {
+            return m_brokerId != 0;
+        }
+
+        bool RCSRemoteResourceObject::isCaching() const
+        {
+            return m_cacheId != 0;
+        }
+
+        bool RCSRemoteResourceObject::isObservable() const
+        {
+            return m_primitiveResource->isObservable();
+        }
+
+        void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw InvalidParameterException{ "startMonitoring : Callback is NULL" };
+            }
+
+            if (isMonitoring())
+            {
+                OC_LOG(DEBUG, TAG, "startMonitoring : already started");
+                throw BadRequestException{ "Monitoring already started." };
+            }
+
+            m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
+                    std::bind(hostingCallback, std::placeholders::_1, std::move(cb)));
+        }
+
+        void RCSRemoteResourceObject::stopMonitoring()
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!isMonitoring())
+            {
+                OC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
+                return;
+            }
+
+            ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
+            m_brokerId = 0;
+        }
+
+        ResourceState RCSRemoteResourceObject::getState() const
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!isMonitoring())
+            {
+                return ResourceState::NONE;
+            }
+
+            return convertBrokerState(
+                    ResourceBroker::getInstance()->getResourceState(m_primitiveResource));
+        }
+
+        void RCSRemoteResourceObject::startCaching()
+        {
+            startCaching({ });
+        }
+
+        void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (isCaching())
+            {
+                OC_LOG(DEBUG, TAG, "startCaching : already Started");
+                throw BadRequestException{ "Caching already started." };
+            }
+
+            if (cb)
+            {
+                m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
+                        m_primitiveResource,
+                        std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
+                                std::move(cb)), REPORT_FREQUENCY::UPTODATE, 0);
+            }
+            else
+            {
+                m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
+                        m_primitiveResource, { }, REPORT_FREQUENCY::NONE, 0);
+            }
+
+            OC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
+        }
+
+        void RCSRemoteResourceObject::stopCaching()
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!isCaching())
+            {
+                OC_LOG(DEBUG, TAG, "Caching already terminated");
+                return;
+            }
+
+            ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
+            m_cacheId = 0;
+        }
+
+        CacheState RCSRemoteResourceObject::getCacheState() const
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!isCaching())
+            {
+                return CacheState::NONE;
+            }
+
+            return convertCacheState(
+                    ResourceCacheManager::getInstance()->getResourceCacheState(m_primitiveResource));
+        }
+
+        bool RCSRemoteResourceObject::isCachedAvailable() const
+        {
+            if (!isCaching())
+            {
+                return false;
+            }
+
+            return ResourceCacheManager::getInstance()->isCachedData(m_cacheId);
+        }
+
+        RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!isCaching())
+            {
+                throw BadRequestException{ "Caching not started." };
+            }
+
+            if (!isCachedAvailable())
+            {
+                throw BadRequestException{ "Cache data is not available." };
+            }
+
+            return ResourceCacheManager::getInstance()->getCachedData(m_primitiveResource);
+        }
+
+        RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
+                const std::string& key) const
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            return getCachedAttributes().at(key);
+        }
+
+        std::string RCSRemoteResourceObject::getUri() const
+        {
+            return m_primitiveResource->getUri();
+        }
+
+        std::string RCSRemoteResourceObject::getAddress() const
+        {
+            return m_primitiveResource->getHost();
+        }
+
+        std::vector< std::string > RCSRemoteResourceObject::getTypes() const
+        {
+            return m_primitiveResource->getTypes();
+        }
+
+        std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const
+        {
+            return m_primitiveResource->getInterfaces();
+        }
+
+        void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw InvalidParameterException{ "getRemoteAttributes : Callback is empty" };
+            }
+
+            m_primitiveResource->requestGet(
+                    std::bind(getCallback, std::placeholders::_1, std::placeholders::_2,
+                            std::placeholders::_3, std::move(cb)));
+        }
+
+        void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
+                RemoteAttributesSetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw InvalidParameterException{ "setRemoteAttributes : Callback is empty" };
+            }
+
+            m_primitiveResource->requestSet(attribute,
+                    std::bind(setCallback, std::placeholders::_1, std::placeholders::_2,
+                            std::placeholders::_3, cb));
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/SConscript b/service/resource-encapsulation/src/resourceContainer/SConscript
new file mode 100644 (file)
index 0000000..926297a
--- /dev/null
@@ -0,0 +1,212 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# resource container build script
+##
+import os
+Import('env')
+import os.path
+
+containerJavaSupport = ARGUMENTS.get('containerJavaSupport',0)
+
+def filtered_glob(env, pattern, omit=[],
+  ondisk=True, source=False, strings=False):
+    return filter(
+      lambda f: os.path.basename(f.path) not in omit,
+      env.Glob(pattern))
+
+env.AddMethod(filtered_glob, "FilteredGlob");
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+resource_container_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+
+if int(containerJavaSupport):
+       try:
+               print 'Java Home: ', os.environ['JAVA_HOME']
+               print 'Java Lib: ', os.environ['JAVA_LIB']
+               resource_container_env.Append(CPPDEFINES={'JAVA_SUPPORT':1})
+       except KeyError:
+               print '''
+       *********************************** Error *************************************
+       * Building resource container without Java support. JAVA_HOME or JAVA_LIB are not set properly 
+       * Please configure JAVA_HOME to point to your Java 7 JDK and 
+       * JAVA_LIB to your folder containing libjvm
+       * Example: export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386
+       *          export JAVA_LIB=/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/server
+       ******************************************************************************* 
+               '''
+               resource_container_env.Append(CPPDEFINES={'JAVA_SUPPORT':0})
+       
+
+resource_container_env.AppendUnique(
+       CPPPATH = [
+               env.get('SRC_DIR')+'/extlibs', 
+               '../../include',
+               'include',
+               'bundle-api/include',
+               'src'           
+       ])
+
+if int(containerJavaSupport):
+       try:
+               resource_container_env.AppendUnique(
+               CPPPATH = [
+                       os.environ['JAVA_HOME']+'/include',
+                       os.environ['JAVA_HOME']+'/include/linux'                
+               ])
+       except KeyError:
+               print ''
+               
+
+if target_os not in ['windows', 'winrt']:
+    resource_container_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    if target_os != 'android':
+        resource_container_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os == 'android':
+    resource_container_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    resource_container_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+       
+try:
+       resource_container_env.AppendUnique(LIBPATH = [os.environ['JAVA_LIB']])
+except KeyError:
+       print ''
+       
+
+resource_container_env.PrependUnique(LIBS = ['rcs_server', 'rcs_common', 'oc','octbstack', 'oc_logger', 'oc_logger_core', 'connectivity_abstraction'])
+resource_container_env.AppendUnique(LIBS = ['dl'])     
+
+if int(containerJavaSupport):
+       try:    
+               print 'Java Lib: ', os.environ['JAVA_LIB']
+               resource_container_env.AppendUnique(LIBS = ['jvm'])             
+       except KeyError:
+               print ''
+
+######################################################################
+# Source files and Targets
+######################################################################
+res_container_src = ['src/BaseActivator.cpp','src/BundleActivator.cpp','src/RCSBundleInfo.cpp', 
+       'src/BundleInfoInternal.cpp', 'src/BundleResource.cpp', 'src/Configuration.cpp', 'src/JavaBundleResource.cpp', 'src/ProtocolBridgeResource.cpp',
+       'src/ProtocolBridgeConnector.cpp', 'src/RCSResourceContainer.cpp', 'src/ResourceContainerBundleAPI.cpp', 'src/ResourceContainerImpl.cpp', 
+       'src/SoftSensorResource.cpp']
+       
+res_container_static = resource_container_env.StaticLibrary('rcs_container', res_container_src)
+res_container_shared = resource_container_env.SharedLibrary('rcs_container', res_container_src)
+
+resource_container_env.InstallTarget([res_container_static,res_container_shared], 'libResContainer')
+
+######################################################################
+# build soft sensor sample bundle
+######################################################################
+
+ss_resource_bundle_env = resource_container_env.Clone()
+ss_resource_bundle_env.AppendUnique(CCFLAGS = ['-fPIC'])
+
+SS_RESOURCE_BUNDLE_DIR = 'examples/SoftSensorSampleBundle/'
+ss_resource_bundle_env.AppendUnique(CPPPATH = [
+               SS_RESOURCE_BUNDLE_DIR + 'include',
+               'include/',
+               '../../include',
+               ])              
+               
+ss_resource_bundle_env.PrependUnique(LIBS = ['rcs_container'])
+
+ss_resource_bundle_src = [ Glob(SS_RESOURCE_BUNDLE_DIR + 'src/*.cpp')]
+
+SoftSensorBundle = ss_resource_bundle_env.SharedLibrary('SoftSensorBundle', ss_resource_bundle_src)
+ss_resource_bundle_env.InstallTarget(SoftSensorBundle, 'libSoftSensorBundle')
+
+######################################################################
+# build hue sample bundle
+######################################################################
+
+conf2 = Configure(lib_env)
+if not conf2.CheckLib('curl'):
+       print '''X
+*********************************** Error *************************************
+* Cannot build hue sample. Please install libcurl.
+* Example (Ubuntu): 
+*      sudo apt-get install libcurl4-openssl-dev
+*      sudo ldconfig
+* Hint: check with pkg-config --libs libcurl and clear scons cache.
+* Skipping hue sample build.
+*******************************************************************************        
+       '''
+else:
+       hue_resource_bundle_env = resource_container_env.Clone()
+       hue_resource_bundle_env.AppendUnique(CCFLAGS = ['-fPIC'])
+       
+       HUE_RESOURCE_BUNDLE_DIR = 'examples/HueSampleBundle/'
+       hue_resource_bundle_env.AppendUnique(CPPPATH = [
+                       HUE_RESOURCE_BUNDLE_DIR + 'include',
+                       'include/'
+                       ])              
+               
+       hue_resource_bundle_env.PrependUnique(LIBS = ['curl', 'rcs_container'])
+               
+       hue_resource_bundle_src = [ Glob(HUE_RESOURCE_BUNDLE_DIR + 'src/*.cpp')]
+       
+       HueBundle = hue_resource_bundle_env.SharedLibrary('HueBundle', hue_resource_bundle_src)
+       hue_resource_bundle_env.InstallTarget(HueBundle, 'libHueBundle')
+       lib_env = conf2.Finish()
+
+######################################################################
+# build resource container unit tests
+######################################################################
+SConscript('unittests/SConscript')
+
+######################################################################
+# Build Container Sample
+######################################################################
+containersample_env = resource_container_env.Clone();
+containersample_env.AppendUnique(LINKFLAGS=["-rdynamic"])
+
+# Copy test configuration
+Command("examples/ResourceContainerConfig.xml","examples/ResourceContainerConfig.xml", Copy("$TARGET", "$SOURCE"))
+Ignore("examples/ResourceContainerConfig.xml", "examples/ResourceContainerConfig.xml")
+
+containersample_env.AppendUnique(LIBS = ['rcs_container'])
+
+containersampleapp_src =  ['examples/ContainerSample.cpp']
+containersampleapp = containersample_env.Program('ContainerSample',containersampleapp_src)
+Alias("containersample", containersampleapp)
+env.AppendTarget('containersample')
+
+######################################################################
+# Build Container Sample Client
+######################################################################
+containersampleclient_env = resource_container_env.Clone();
+
+containersample_env.AppendUnique(LIBS = ['rcs_container'])
+containersampleclient_src =  ['examples/ContainerSampleClient.cpp']
+containersampleclientapp = containersample_env.Program('ContainerSampleClient',containersampleclient_src)
+Alias("containersampleclient", containersampleclientapp)
+env.AppendTarget('containersampleclient')
+
+
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleActivator.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleActivator.h
new file mode 100644 (file)
index 0000000..5a802ad
--- /dev/null
@@ -0,0 +1,93 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLEACTIVATOR_H_
+#define BUNDLEACTIVATOR_H_
+
+#include "ResourceContainerBundleAPI.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    BundleActivator
+        * @brief    This class represents Bundle to be activated by container
+        *
+        */
+        class BundleActivator
+        {
+
+            public:
+
+                /**
+                * Constructor for BundleActivator
+                */
+                BundleActivator();
+
+                /**
+                * Virtual destructor for BundleActivator
+                */
+                virtual ~BundleActivator();
+
+                /**
+                * Activate the Bundle to make bundle work and create bundle resources
+                *
+                * @param resourceContainer - resourceContainer which registered the bundle
+                *
+                * @param bundleId - assigned id for the bundle
+                *
+                * @return void
+                */
+                virtual void activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                            std::string bundleId);
+
+                /**
+                * Deactivate the Bundle to stop working and destroy bundle resources
+                *
+                * @return void
+                */
+                virtual void deactivateBundle();
+
+                /**
+                * Create Bundle Resource instance and register the resource in the container
+                *
+                * @param resourceInfo - information to create bundle resource
+                *
+                * @return void
+                */
+                virtual void createResource(resourceInfo resourceInfo) = 0;
+
+                /**
+                * Destroy Bundle Resource instance and register the resource in the container
+                *
+                * @param pBundleResource - bundle resource to be destroyed
+                *
+                * @return void
+                */
+                virtual void destroyResource(BundleResource *pBundleResource) = 0;
+        };
+    }
+}
+
+#endif /* RESOURCEBUNDLE_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleResource.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/BundleResource.h
new file mode 100644 (file)
index 0000000..27778d2
--- /dev/null
@@ -0,0 +1,121 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLERESOURCE_H_
+#define BUNDLERESOURCE_H_
+
+#include <list>
+#include <string>
+#include <map>
+#include <vector>
+
+#include "NotificationReceiver.h"
+#include "RCSResourceAttributes.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    BundleResource
+        * @brief    This class represents Basic bundle resource template
+        *               to be registered in the container and make resource server
+        *
+        */
+        class BundleResource
+        {
+            public:
+
+                /**
+                * Constructor for BundleResource
+                */
+                BundleResource();
+
+                /**
+                * Virtual destructor for BundleResource
+                */
+                virtual ~BundleResource();
+
+                /**
+                * Return the list of attribute names of the resource
+                *
+                * @return std::list - return list of the attribute names
+                */
+                std::list<std::string> getAttributeNames();
+
+                /**
+                * Initialize attributes of the resource
+                *
+                * @return void
+                */
+                virtual void initAttributes() = 0;
+
+                /**
+                * Register notification receiver(resource container) to notify for the changes of attributes
+                *
+                * @param pNotiReceiver - Notification Receiver to get notification from bundle resource
+                *
+                * @return void
+                */
+                void registerObserver(NotificationReceiver *pNotiReceiver);
+
+                /**
+                * Return all attributes of the resource
+                *
+                * @return RCSResourceAttributes - attributes of the resource
+                */
+                virtual RCSResourceAttributes &getAttributes();
+
+                /**
+                * Execute the logic of bundle to set the value of attribute
+                *
+                * @param key - name of attribute to set
+                *
+                * @param value - value of attribute to set
+                *
+                * @return void
+                */
+                virtual void setAttribute(std::string key, RCSResourceAttributes::Value &&value);
+
+                /**
+                * Execute the logic of bundle to get the value of attribute
+                *
+                * @param key - key of attribute to get
+                *
+                * @return RCSResourceAttributes::Value - return value of the attribute
+                */
+                virtual RCSResourceAttributes::Value getAttribute(const std::string &key);
+
+
+            public:
+                std::string m_bundleId;
+                std::string m_name, m_uri, m_resourceType, m_address;
+                std::map< std::string, std::vector< std::map< std::string, std::string > > > m_mapResourceProperty;
+
+            private:
+                NotificationReceiver *m_pNotiReceiver;
+                RCSResourceAttributes m_resourceAttributes;
+
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/NotificationReceiver.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/NotificationReceiver.h
new file mode 100644 (file)
index 0000000..d4d3515
--- /dev/null
@@ -0,0 +1,63 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef NOTIFICATIONRECEIVER_H_
+#define NOTIFICATIONRECEIVER_H_
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    NotificationReceiver
+        * @brief    This class represents Notification Receiver to get notification
+        *               from bundle resources if there's any changes of attribute state
+        *
+        */
+        class NotificationReceiver
+        {
+            public:
+
+                /**
+                * Constructor for NotificationReceiver
+                */
+                NotificationReceiver() {};
+
+                /**
+                * destructor for NotificationReceiver
+                */
+                ~NotificationReceiver() {};
+
+                /**
+                * Callback method for getting notification from bundle resources
+                *
+                * @param strResourceUri - uri of attribute updated bundle resource
+                *
+                * @return void
+                */
+                virtual void onNotificationReceived(const std::string &strResourceUri) = 0;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeConnector.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeConnector.h
new file mode 100644 (file)
index 0000000..414d688
--- /dev/null
@@ -0,0 +1,70 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef PROTOCOLBRIDGECONNECTOR_H_
+#define PROTOCOLBRIDGECONNECTOR_H_
+
+#include "BundleResource.h"
+#include <map>
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    ProtocolBridgeConnector
+        * @brief    This class represents connector
+        *               to bridge non-IoTivity protocol and IoTivity for Protocol Bridge
+        *
+        */
+        class ProtocolBridgeConnector
+        {
+            public:
+
+                /**
+                * Constructor for ProtocolBridgeConnector
+                */
+                ProtocolBridgeConnector();
+
+                /**
+                * Virtual destructor for ProtocolBridgeConnector
+                */
+                virtual ~ProtocolBridgeConnector();
+
+                /**
+                * Execute the logic needed for connection with different protocol from IoTivity
+                *
+                * @return void
+                */
+                virtual void connect() = 0;
+
+                /**
+                * Execute the logic needed for disconnection with different protocol from IoTivity
+                *
+                * @return void
+                */
+                virtual void disconnect() = 0;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeResource.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ProtocolBridgeResource.h
new file mode 100644 (file)
index 0000000..4174fde
--- /dev/null
@@ -0,0 +1,83 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef PROTOCOLBRIDGERESOURCE_H_
+#define PROTOCOLBRIDGERESOURCE_H_
+
+#include "BundleResource.h"
+#include <map>
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    ProtocolBridgeResource
+        * @brief    This class represents bundle resource template for Protocol Bridge
+        *               to be registered in the container and make resource server
+        *
+        */
+        class ProtocolBridgeResource: public BundleResource
+        {
+            public:
+
+                /**
+                * Constructor for ProtocolBridgeResource
+                */
+                ProtocolBridgeResource();
+
+                /**
+                * Virtual destructor for ProtocolBridgeResource
+                */
+                virtual ~ProtocolBridgeResource();
+
+                /**
+                * Return all attributes of the resource
+                *
+                * @return RCSResourceAttributes - attributes of the resource
+                */
+                virtual RCSResourceAttributes &getAttributes() = 0;
+
+                /**
+                * Execute the logic of bundle to set the value of attribute
+                *
+                * @param key - name of attribute to set
+                *
+                * @param value - value of attribute to set
+                *
+                * @return void
+                */
+                virtual void setAttribute(std::string key, RCSResourceAttributes::Value &&value) = 0;
+
+                /**
+                * Execute the logic of bundle to get the value of attribute
+                *
+                * @param key - key of attribute to get
+                *
+                * @return RCSResourceAttributes::Value - return value of the attribute
+                */
+                virtual RCSResourceAttributes::Value getAttribute(const std::string &key) = 0;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ResourceContainerBundleAPI.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/ResourceContainerBundleAPI.h
new file mode 100644 (file)
index 0000000..7712429
--- /dev/null
@@ -0,0 +1,106 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECONTAINERBUNDLEAPI_H_
+#define RESOURCECONTAINERBUNDLEAPI_H_
+
+#include <unistd.h>
+#include <string.h>
+#include <fstream>
+
+#include "RCSBundleInfo.h"
+#include "Configuration.h"
+#include "NotificationReceiver.h"
+#include "BundleResource.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceContainerBundleAPI: public NotificationReceiver
+        {
+            public:
+
+                /**
+                * Constructor for ResourceContainerBundleAPI
+                */
+                ResourceContainerBundleAPI();
+
+                /**
+                * Virtual destructor for ResourceContainerBundleAPI
+                */
+                virtual ~ResourceContainerBundleAPI();
+
+                /**
+                * Register bundle resource in the container
+                *   and register resource server for bundle resource
+                *
+                * @param resource - bundle resource to register
+                *
+                * @return void
+                */
+                virtual void registerResource(BundleResource *resource) = 0;
+
+                /**
+                * Unregister bundle resource from the container
+                *   and unregister resource server
+                *
+                * @param resource - bundle resource to unregister
+                *
+                * @return void
+                */
+                virtual void unregisterResource(BundleResource *resource) = 0;
+
+                /**
+                * Get Configuration data of certain bundle
+                *
+                * @param [in] bundleId - bundle id to get configuration data
+                *
+                * @param [out] configOutput - returned configuration data
+                *
+                * @return void
+                */
+                virtual void getBundleConfiguration(const std::string &bundleId, configInfo *configOutput) = 0;
+
+                /**
+                * Get the list of Configuration data of resources that certain bundle has
+                *
+                * @param [in] bundleId - bundle id to get configuration data
+                *
+                * @param [out] configOutput - returned resource configuration data vector
+                *
+                * @return void
+                */
+                virtual void getResourceConfiguration(const std::string &bundleId,
+                                                      std::vector< resourceInfo > *configOutput) = 0;
+
+                /**
+                * API for getting an instance of ResourceContainerBundleAPI
+                *
+                * @return ResourceContainerBundleAPI * - return the object pointer of ResourceContainerBundleAPI
+                */
+                static ResourceContainerBundleAPI *getInstance();
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-api/include/SoftSensorResource.h b/service/resource-encapsulation/src/resourceContainer/bundle-api/include/SoftSensorResource.h
new file mode 100644 (file)
index 0000000..bd9d1f0
--- /dev/null
@@ -0,0 +1,99 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SOFTSENSORRESOURCE_H_
+#define SOFTSENSORRESOURCE_H_
+
+#include "BundleResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+        * @class    SoftSensorResource
+        * @brief    This class represents bundle resource for Soft Sensor
+        *               to be registered in the container and make resource server
+        *
+        */
+        class SoftSensorResource: public BundleResource
+        {
+            public:
+                /**
+                * Constructor for SoftSensorResource
+                */
+                SoftSensorResource();
+
+                /**
+                * Virtual destructor for SoftSensorResource
+                */
+                virtual ~SoftSensorResource();
+
+                /**
+                * Initialize input and output attributes for the resource
+                *
+                * @return void
+                */
+                virtual void initAttributes();
+
+                /**
+                * Return all attributes of the resource
+                *
+                * @return RCSResourceAttributes - attributes of the resource
+                */
+                virtual RCSResourceAttributes &getAttributes();
+
+                /**
+                * Execute the logic of bundle to set the value of attribute
+                *
+                * @param key - name of attribute to set
+                *
+                * @param value - value of attribute to set
+                *
+                * @return void
+                */
+                virtual void setAttribute(std::string key, RCSResourceAttributes::Value &&value);
+
+                /**
+                * Execute the logic of bundle to get the value of attribute
+                *
+                * @param key - key of attribute to get
+                *
+                * @return RCSResourceAttributes::Value - return value of the attribute
+                */
+                virtual RCSResourceAttributes::Value getAttribute(const std::string &key);
+
+                /**
+                * SoftSensor logic. Has to be provided by the soft sensor developer.
+                * This function will be executed if an input attribute is updated.
+                *
+                * @return void
+                */
+                virtual void executeLogic() = 0;
+
+
+            public:
+                std::list<std::string> m_inputList;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/pom.xml b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/pom.xml
new file mode 100644 (file)
index 0000000..a1dfceb
--- /dev/null
@@ -0,0 +1,64 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.iotivity.resourcecontainer</groupId>
+  <artifactId>bundle-api</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1</version>
+  <name>resource-container-api</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.maven.plugins</groupId>
+      <artifactId>maven-shade-plugin</artifactId>
+      <version>2.4</version>
+      <type>maven-plugin</type>
+    </dependency>
+  </dependencies>
+  <build>
+       <pluginManagement>
+       <plugins>
+               <plugin>
+                       <groupId>org.apache.maven.plugins</groupId>
+                       <artifactId>maven-assmembly-plugin</artifactId>
+                       <version>2.5.5</version>
+               </plugin>
+       </plugins>            
+      </pluginManagement>
+     <plugins>      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.3</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.5.5</version>  
+        <configuration>
+               <descriptorRefs>
+                       <descriptorRef>jar-with-dependencies</descriptorRef>
+               </descriptorRefs>
+        </configuration>      
+      </plugin> 
+    </plugins>
+  </build>
+  <repositories>
+       <repository>
+               <id>repo1</id>
+               <name>Repo1</name>
+               <url>http://repo1.maven.rog</url>               
+       </repository>
+  </repositories>
+</project>
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BaseActivator.java b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BaseActivator.java
new file mode 100644 (file)
index 0000000..11e3310
--- /dev/null
@@ -0,0 +1,137 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.resourcecontainer.bundle.api;
+
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * The BaseActivator implements the native interface to the resource container. 
+ * It loads the resource container library and provies native methods
+ * that can be used to register and unregister resources.
+ */
+public class BaseActivator implements BundleActivator {
+    private String bundleId;
+    private Vector<BundleResource> bundleResources = new Vector<BundleResource>();
+
+    /**
+     * Creates an instance of the BaseActivator
+     * @param bundleId unique bundle identifier (e.g., oic.bundle.hue)
+     */
+    public BaseActivator(String bundleId) {
+        this.bundleId = bundleId;
+        
+    }
+
+    static {
+        try {
+            System.loadLibrary("ResContainerLib");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Bundle activation needs to be provided by the subclass.
+     */
+    public void activateBundle() {
+
+    }
+
+    /**
+     * Deactivates the bundle and unregisters its resources.
+     */
+    public void deactivateBundle() {
+        System.out.println("Deactivating bundle (Base Activator).");
+        for(BundleResource bundleResource : bundleResources){
+            unregisterResource(bundleResource);
+        }
+    }
+
+    /**
+     * Registers a bundle resource at the resource container.
+     * @param resource bundle resource instance that should be made available as OIC resource 
+     */
+    public void registerResource(BundleResource resource) {
+        bundleResources.add(resource);
+        registerJavaResource(resource, resource.getAttributeKeys(), bundleId,
+                resource.getURI(), resource.getResourceType(),
+                resource.getName());
+    }
+
+    /**
+     * Wrapper to retrieve the resource configuration of the bundle resources.
+     * @return List of resource configurations.     
+     */
+    public List<ResourceConfig> getConfiguredBundleResources() {
+        int configuredResources = getNumberOfConfiguredResources(bundleId);
+
+        Vector<ResourceConfig> configs = new Vector<ResourceConfig>();
+
+        for (int i = 0; i < configuredResources; i++) {
+            String[] resourceParams = getConfiguredResourceParams(bundleId, i);
+            ResourceConfig config = new ResourceConfig(resourceParams);
+            configs.add(config);
+
+        }
+        return configs;
+    }
+
+    /**
+     * Unregisters a resource from the resource container.
+     */
+    public void unregisterResource(BundleResource resource) {
+        bundleResources.remove(resource);
+        unregisterJavaResource(resource, resource.getURI());
+    }
+
+    /**
+     * Native method that calls to the resource container.
+     * @param attributes String array of attribute names
+     * @param bundleId unique bundle identifier
+     * @param uri Uri that should be used to register the resource
+     */
+    private native void registerJavaResource(BundleResource resource,
+            String[] attributes, String bundleId, String uri,
+            String resourceType, String name);
+
+    /**
+     * Native method that calls to the resource container.
+     * @param resource 
+     * @param uri
+     */
+    private native void unregisterJavaResource(BundleResource resource, String uri);
+
+    /**
+     * Native method to retrieve the number of configured resources.
+     * @param bundleId unique bundle identifier
+     */
+    private native int getNumberOfConfiguredResources(String bundleId);
+
+    /**
+     * Native method to retrieve the configured resource parameters.
+     * @param bundleId unique bundle identifier 
+     * @param resId get the resource params for a certain resource
+     */
+    private native String[] getConfiguredResourceParams(String bundleId,
+            int resId);
+
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleActivator.java b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleActivator.java
new file mode 100644 (file)
index 0000000..67d5692
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.resourcecontainer.bundle.api;
+
+import java.util.List;
+
+/**
+ * The BundleActivator interface needs to be implemented. A bundle provider
+ * can directly extend fromt the BaseActivator.
+ */
+public interface BundleActivator {
+    /**
+     * Activates the bundle and creates all resources.
+     */
+    public void activateBundle();
+
+    /**
+     * Deactivates the bundle and destroys all resources.
+     */
+    public void deactivateBundle();
+
+    /**
+     * Registers a single resource instance at the resource container
+     * @param resource Instance of a BundleResource
+     */
+    public void registerResource(BundleResource resource);
+
+    /**
+     * Unregisters a single resource instance at the resource container
+     * @param resource Instance of a BundleResource
+     */
+    public void unregisterResource(BundleResource resource);
+
+    /**
+     * List the configuration of the bundle resources.
+     * @return List of configuration for each resource 
+     */
+    public List<ResourceConfig> getConfiguredBundleResources();
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleResource.java b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/BundleResource.java
new file mode 100644 (file)
index 0000000..68bab81
--- /dev/null
@@ -0,0 +1,130 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.resourcecontainer.bundle.api;
+
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * Basic BundleResource that should be used as a base class
+ * by a bundle resources. A concrete technology has 
+ * to override the setAttribute and getAttribute method
+ * and map the according reads and writes to the technology specific 
+ * messages.
+ */
+public abstract class BundleResource {
+    protected String m_name, m_uri, m_resourceType, m_address;
+
+    protected HashMap<String, String> m_attributes;
+
+    /**
+     * Initialize the internal attribute structure.
+     */
+    protected abstract void initAttributes();
+
+    /**
+     * Set the attribute (map to a send command for the according protocol)
+     * @param key name of the attribute to be set
+     * @param value new value of the attribute
+     */
+    public abstract void setAttribute(String key, String value);
+
+    /**
+     * Retrieve the attribute (map to read command for the according protocol)
+     * @param key name of the attribute to be read
+     * @return Value of the attribute
+     */
+    public abstract String getAttribute(String key);     
+
+    /**
+     * Attribute keys provided through by the bundle resource.
+     * @return Name of attribute keys as string array
+     */
+    public String[] getAttributeKeys() {
+        Set<String> keys = m_attributes.keySet();
+        return keys.toArray(new String[keys.size()]);
+    }
+
+    /**
+     * Setter for the uri property
+     * @param uri URI of the resource
+     */
+    public void setURI(String uri) {
+        this.m_uri = uri;
+    }
+
+    /**
+     * Returns the URI of the resource
+     * @return
+     */
+    public String getURI() {
+        return m_uri;
+    }
+
+    /**
+     * Sets the resource type property
+     * @param resourceType OIC resource type
+     */
+    public void setResourceType(String resourceType) {
+        this.m_resourceType = resourceType;
+    }
+
+    /**
+     * Getter for the resource type
+     * @return OIC resource type
+     */
+    public String getResourceType() {
+        return m_resourceType;
+    }
+
+    /**
+     * Sets the technology specific address information (e.g., ZigBee short or long identifier)    
+     * @param address
+     */
+    public void setAddress(String address) {
+        this.m_address = address;
+    }
+
+    /**
+     * Returns the technology specific address information
+     * @return
+     */
+    public String getAddress() {
+        return m_address;
+    }
+
+    /**
+     * Sets the name property of the resource
+     * @param name
+     */
+    public void setName(String name) {
+        this.m_name = name;
+    }
+
+    /**
+     * Returns the name property of the resource
+     * @return
+     */
+    public String getName() {
+        return m_name;
+    }
+
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ProtocolBridgeConnector.java b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ProtocolBridgeConnector.java
new file mode 100644 (file)
index 0000000..5302846
--- /dev/null
@@ -0,0 +1,38 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.resourcecontainer.bundle.api;
+
+/**
+ * The ProtocolBridgeConnector interface should be implemented 
+ * by a bundle provider and it should be called 
+ * at bundle activation and deactivation.
+ */
+public interface ProtocolBridgeConnector {
+    /**
+     * Connects to a specific protocol (e.g, establishes a communication session)
+     */
+    public void connect();
+
+    /**
+     * Disconnects from a specific protocol
+     */
+    public void disconnect();
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ResourceConfig.java b/service/resource-encapsulation/src/resourceContainer/bundle-java-api/src/main/java/org/iotivity/resourcecontainer/bundle/api/ResourceConfig.java
new file mode 100644 (file)
index 0000000..cf35f4e
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.resourcecontainer.bundle.api;
+
+/**
+ * This class holds the configuration parameters for a single resource instance provided
+ * by the resource bundle.
+ */
+public class ResourceConfig {
+    private String m_name, m_uri, m_resourceType, m_address;
+
+    /**
+     * Empty constructor for resoure config.
+     */
+    public ResourceConfig() {
+
+    }
+
+    /**
+     * Creates a new resource config instance.
+     * @param params Resource parameters as array. 1. Name, 2. URI, 3. Resource Type, 4. Address 
+     */
+    public ResourceConfig(String[] params) {
+        m_name = params[0];
+        m_uri = params[1];
+        m_resourceType = params[2];
+        m_address = params[3];
+    }
+
+    /**
+     * Returns the configured name
+     * @return name property
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Sets the name
+     * @param m_name
+     */
+    public void setName(String m_name) {
+        this.m_name = m_name;
+    }
+
+    /**
+     * Returns the configured URI
+     * @return Configured URI
+     */
+    public String getURI() {
+        return m_uri;
+    }
+
+    /**
+     * Sets the configured URI
+     * @param m_uri Configuration URI
+     */
+    public void setURI(String m_uri) {
+        this.m_uri = m_uri;
+    }
+
+    /**
+     * Returns the configured resource type
+     * @param m_uri configured resource type
+     */
+    public String getResourceType() {
+        return m_resourceType;
+    }
+
+    /**
+     * Sets the configured resource type
+     * @param m_resourceType updates the configured resource type
+     */
+    public void setResourceType(String m_resourceType) {
+        this.m_resourceType = m_resourceType;
+    }
+
+    /**
+     * Returns the configured address
+     * @return Configured address
+     */
+    public String getAddress() {
+        return m_address;
+    }
+
+    /**
+     * Sets the configured address
+     * @param m_address Configured address
+     */
+    public void setAddress(String m_address) {
+        this.m_address = m_address;
+    }
+
+    @Override
+    public String toString() {
+        return "ResourceConfig [m_name=" + m_name + ", m_uri=" + m_uri
+                + ", m_resourceType=" + m_resourceType + ", m_address="
+                + m_address + "]";
+    }
+
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/ContainerSample.cpp b/service/resource-encapsulation/src/resourceContainer/examples/ContainerSample.cpp
new file mode 100644 (file)
index 0000000..9b84abe
--- /dev/null
@@ -0,0 +1,158 @@
+//******************************************************************
+//
+// 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 "RCSResourceContainer.h"
+#include "RCSBundleInfo.h"
+#include "oc_logger.hpp"
+#include <iostream>
+
+using namespace std;
+using namespace OIC::Service;
+using OC::oc_log_stream;
+
+/* Annother way to create a context: */
+auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+
+    return os;
+};
+
+int main()
+{
+    info_logger()->set_module("ContainerTest");
+    info_logger()->set_level(OC_LOG_INFO);
+
+    info_logger() << "Starting container test." << std::flush;
+
+    RCSResourceContainer *container = RCSResourceContainer::getInstance();
+    container->startContainer("examples/ResourceContainerConfig.xml");
+
+    /*so bundle add test*/
+    cout << "++++++++++++++++++++++++++" << endl;
+    cout << "+++ Test for SO Bundle +++" << endl;
+    cout << "++++++++++++++++++++++++++" << endl;
+    cout << "Press enter to add SO bundle " << endl;
+    getchar();
+    std::map<string, string> bundleParams;
+    container->addBundle("oic.bundle.hueSample", "", "libHueBundle.so", bundleParams);
+
+    std::list<RCSBundleInfo *> bundles = container->listBundles();
+    std::list<RCSBundleInfo *>::iterator bundleIt;
+
+    cout << "\t>>> bundle list size : " << bundles.size() << endl;
+    for (bundleIt = bundles.begin(); bundleIt != bundles.end(); bundleIt++)
+    {
+        cout << "\t>>> bundle Id : " << (*bundleIt)->getID().c_str() << endl;
+    }
+
+    cout << "\nPress enter to start SO bundle " << endl;
+    getchar();
+    container->startBundle("oic.bundle.hueSample");
+
+    std::map<string, string> resourceParams;
+    cout << "Press enter to add SO bundle resource " << endl;
+    getchar();
+    resourceParams["resourceType"] = "oic.light.control";
+    resourceParams["address"] = "http://192.168.0.2/api/newdeveloper/lights/1";
+    container->addResourceConfig("oic.bundle.hueSample", "", resourceParams);
+    container->addResourceConfig("oic.bundle.hueSample", "", resourceParams);
+
+    std::list<string> resources = container->listBundleResources("oic.bundle.hueSample");
+    std::list<string>::iterator resourceIt;
+    cout << "\t>>> resource list size : " << resources.size() << endl;
+    for (resourceIt = resources.begin(); resourceIt != resources.end(); resourceIt++)
+    {
+        cout << "\t>>> resource uri : " << (*resourceIt).c_str() << endl;
+    }
+
+    cout << "\nPress enter to remove SO bundle resource " << endl;
+    getchar();
+    container->removeResourceConfig("oic.bundle.hueSample", "/hue/light/1");
+
+    resources = container->listBundleResources("oic.bundle.hueSample");
+    cout << "\t>>> resource list size : " << resources.size() << endl;
+    for (resourceIt = resources.begin(); resourceIt != resources.end(); resourceIt++)
+    {
+        cout << "\t>>> resource uri : " << (*resourceIt).c_str() << endl;
+    }
+
+    cout << "\nPress enter to stop SO Bundle " << endl;
+    getchar();
+    container->stopBundle("oic.bundle.hueSample");
+
+    cout << "Press enter to test remove SO Bundle " << endl;
+    getchar();
+    container->removeBundle("oic.bundle.hueSample");
+
+    bundles = container->listBundles();
+    cout << "\t>>> bundle list size : " << bundles.size() << endl;
+    for (bundleIt = bundles.begin(); bundleIt != bundles.end(); bundleIt++)
+    {
+        cout << "\t>>> bundle Id : " << (*bundleIt)->getID().c_str() << endl;
+    }
+
+#if(JAVA_SUPPORT)
+    /*java bundle add test*/
+    cout << "\n++++++++++++++++++++++++++++" << endl;
+    cout << "+++ Test for JAVA Bundle +++" << endl;
+    cout << "++++++++++++++++++++++++++++" << endl;
+    cout << "Press enter to add java bundle " << endl;
+    getchar();
+    bundleParams["libraryPath"] = ".";
+    bundleParams["activator"] = "org.iotivity.bundle.hue.HueBundleActivator";
+    container->addBundle("oic.bundle.hueJavaSample", "/hueJava",
+                         "../../../../../../../../service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/target/hue-0.1-jar-with-dependencies.jar",
+                         bundleParams);
+
+    bundles = container->listBundles();
+    cout << "\t>>> bundle list size : " << bundles.size() << endl;
+    for (bundleIt = bundles.begin(); bundleIt != bundles.end(); bundleIt++)
+    {
+        cout << "\t>>> bundle Id : " << (*bundleIt)->getID().c_str() << endl;
+    }
+
+    cout << "\nPress enter to start java bundle " << endl;
+    getchar();
+    container->startBundle("oic.bundle.hueJavaSample");
+
+    cout << "Press enter to stop java Bundle " << endl;
+    getchar();
+    container->stopBundle("oic.bundle.hueJavaSample");
+
+    cout << "Press enter to test remove java Bundle " << endl;
+    getchar();
+    container->removeBundle("oic.bundle.hueJavaSample");
+
+    bundles = container->listBundles();
+    cout << "\t>>> bundle list size : " << bundles.size() << endl;
+    for (bundleIt = bundles.begin(); bundleIt != bundles.end(); bundleIt++)
+    {
+        cout << "\t>>> bundle Id : " << (*bundleIt)->getID().c_str() << endl;
+    }
+#endif
+
+    cout << "\nPress enter to stop container " << endl;
+    getchar();
+    container->stopContainer();
+
+    cout << "Container stopped. Bye" << endl;
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/ContainerSampleClient.cpp b/service/resource-encapsulation/src/resourceContainer/examples/ContainerSampleClient.cpp
new file mode 100644 (file)
index 0000000..672713c
--- /dev/null
@@ -0,0 +1,560 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// OCClient.cpp : Defines the entry point for the console application.
+//
+#include <string>
+#include <map>
+#include <cstdlib>
+#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
+
+DiscoveredResourceMap discoveredResources;
+std::shared_ptr<OCResource> curResource;
+std::shared_ptr<OCResource> DISensorResource;
+static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+std::mutex curResourceLock;
+
+class Light
+{
+    public:
+
+        bool m_on_off;
+        int m_color;
+        int m_dim;
+        std::string m_name;
+
+
+        Light() : m_on_off(false), m_color(0), m_dim(0), m_name("")
+        {
+        }
+};
+
+Light mylight;
+
+int observe_count()
+{
+    static int oc = 0;
+    return ++oc;
+}
+
+void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
+               const int &eCode, const int &sequenceNumber)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK)
+        {
+            std::cout << "OBSERVE RESULT:" << std::endl;
+            std::cout << "\tSequenceNumber: " << sequenceNumber << std::endl;
+            rep.getValue("on-off", mylight.m_on_off);
+            rep.getValue("color", mylight.m_color);
+            rep.getValue("dim", mylight.m_dim);
+            rep.getValue("name", mylight.m_name);
+
+            std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
+            std::cout << "\tcolor: " << mylight.m_color << std::endl;
+            std::cout << "\tdim: " << mylight.m_dim << std::endl;
+
+            if (observe_count() > 10)
+            {
+                std::cout << "Cancelling Observe..." << std::endl;
+                OCStackResult result = curResource->cancelObserve();
+
+                std::cout << "Cancel result: " << result << std::endl;
+                sleep(10);
+                std::cout << "DONE" << std::endl;
+                std::exit(0);
+            }
+        }
+        else
+        {
+            std::cout << "onObserve Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
+    }
+
+}
+
+void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
+        {
+            std::cout << "POST request was successful" << std::endl;
+
+            if (rep.hasAttribute("createduri"))
+            {
+                std::cout << "\tUri of the created resource: "
+                          << rep.getValue<std::string>("createduri") << std::endl;
+            }
+            else
+            {
+                rep.getValue("on-off", mylight.m_on_off);
+                rep.getValue("color", mylight.m_color);
+                rep.getValue("dim", mylight.m_dim);
+
+                std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
+                std::cout << "\tcolor: " << mylight.m_color << std::endl;
+                std::cout << "\tdim: " << mylight.m_dim << std::endl;
+            }
+
+            if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
+                std::cout << std::endl << "Observe is used." << std::endl << std::endl;
+            else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
+                std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
+
+            curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
+
+        }
+        else
+        {
+            std::cout << "onPost2 Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPost2" << std::endl;
+    }
+
+}
+
+void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
+        {
+            std::cout << "POST request was successful" << std::endl;
+
+            if (rep.hasAttribute("createduri"))
+            {
+                std::cout << "\tUri of the created resource: "
+                          << rep.getValue<std::string>("createduri") << std::endl;
+            }
+            else
+            {
+                rep.getValue("on-off", mylight.m_on_off);
+                rep.getValue("color", mylight.m_color);
+                rep.getValue("dim", mylight.m_dim);
+
+                std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
+                std::cout << "\tcolor: " << mylight.m_color << std::endl;
+                std::cout << "\tdim: " << mylight.m_dim << std::endl;
+            }
+
+            OCRepresentation rep2;
+
+            std::cout << "Posting light representation..." << std::endl;
+
+            mylight.m_on_off = true;
+
+            rep2.setValue("on-off", mylight.m_on_off);
+
+            curResource->post(rep2, QueryParamsMap(), &onPost2);
+        }
+        else
+        {
+            std::cout << "onPost Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPost" << std::endl;
+    }
+}
+
+// Local function to put a different state for this resource
+void postLightRepresentation(std::shared_ptr<OCResource> resource)
+{
+    if (resource)
+    {
+        OCRepresentation rep;
+
+        std::cout << "Posting light representation..." << std::endl;
+
+        mylight.m_on_off = "false";
+
+        rep.setValue("on-off", mylight.m_on_off);
+
+        // Invoke resource's post API with rep, query map and the callback parameter
+        resource->post(rep, QueryParamsMap(), &onPost);
+    }
+}
+
+// callback handler on PUT request
+void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            /*rep.getValue("on-off", mylight.m_on_off);
+            rep.getValue("dim", mylight.m_dim);
+            rep.getValue("color", mylight.m_color);
+
+            std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
+            std::cout << "\tcolor: " << mylight.m_color << std::endl;
+            std::cout << "\tdim: " << mylight.m_dim << std::endl;*/
+
+            //postLightRepresentation(curResource);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
+    }
+}
+
+void onPutForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
+                      const int eCode)
+{
+    void onGetForDISensor(const HeaderOptions & headerOptions, const OCRepresentation & rep,
+                          const int eCode);
+
+    try
+    {
+        if (eCode == OC_STACK_OK)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            QueryParamsMap test;
+            std::cout << "Sending request to: " << DISensorResource->uri() << std::endl;
+            DISensorResource->get(test, &onGetForDISensor);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
+    }
+}
+
+// Local function to put a different state for this resource
+void putLightRepresentation(std::shared_ptr<OCResource> resource)
+{
+    if (resource)
+    {
+        OCRepresentation rep;
+
+        std::cout << "Putting light representation..." << std::endl;
+
+        mylight.m_on_off = true;
+
+        std::cout << "Sending request to: " << resource->uri() << std::endl;
+        rep.setValue("on-off", mylight.m_on_off);
+
+        // Invoke resource's put API with rep, query map and the callback parameter
+
+        resource->put(rep, QueryParamsMap(), &onPut);
+    }
+}
+
+// Callback handler on GET request
+void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK)
+        {
+            std::cout << "GET request was successful" << std::endl;
+            std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+            std::cout << "Payload: " << rep.getPayload() << std::endl;
+
+            rep.getValue("on-off", mylight.m_on_off);
+            rep.getValue("dim", mylight.m_dim);
+            rep.getValue("color", mylight.m_color);
+
+            std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
+            std::cout << "\tcolor: " << mylight.m_color << std::endl;
+            std::cout << "\tdim: " << mylight.m_dim << std::endl;
+
+            putLightRepresentation(curResource);
+        }
+        else
+        {
+            std::cout << "onGET Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
+    }
+}
+
+void onGetForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
+                      const int eCode)
+{
+    try
+    {
+        if (eCode == OC_STACK_OK)
+        {
+            std::cout << "GET request was successful" << std::endl;
+            std::cout << "Resource URI: " << DISensorResource->uri() << std::endl;
+
+            std::cout << "Payload: " << rep.getPayload() << std::endl;
+
+            std::cout << "\tdiscomfortIndex: " << rep.getValue<std::string>("discomfortIndex") << std::endl;
+        }
+        else
+        {
+            std::cout << "onGET Response error: " << eCode << std::endl;
+        }
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
+    }
+}
+
+// Local function to get representation of light resource
+void getLightRepresentation(std::shared_ptr<OCResource> resource)
+{
+    if (resource)
+    {
+        std::cout << "Getting Light Representation..." << std::endl;
+        // Invoke resource's get API with the callback parameter
+
+        QueryParamsMap test;
+        std::cout << "Sending request to: " << resource->uri() << std::endl;
+        resource->get(test, &onGet);
+    }
+}
+
+// Callback to found resources
+void foundResource(std::shared_ptr<OCResource> resource)
+{
+    std::cout << "In foundResource\n";
+    std::string resourceURI = resource->uri();
+    std::string hostAddress;
+    try
+    {
+        {
+            std::lock_guard<std::mutex> lock(curResourceLock);
+            if (discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end())
+            {
+                std::cout << "Found resource " << resource->uniqueIdentifier() <<
+                          " for the first time on server with ID: " << resource->sid() << std::endl;
+                discoveredResources[resource->uniqueIdentifier()] = resource;
+
+                if (resourceURI.find("/discomfortIndex") != std::string::npos)
+                {
+                    std::cout << "discomfortIndex found !!! " << std::endl;
+
+                    DISensorResource = resource;
+
+                    OCRepresentation rep;
+
+                    rep.setValue("humidity", std::string("30"));
+                    rep.setValue("temperature", std::string("27"));
+
+                    resource->put(rep, QueryParamsMap(), &onPutForDISensor);
+                }
+            }
+            else
+            {
+                std::cout << "Found resource " << resource->uniqueIdentifier() << " again!" << std::endl;
+            }
+
+            if (curResource)
+            {
+                std::cout << "Found another resource, ignoring" << std::endl;
+                return;
+            }
+        }
+
+        // Do some operations with resource object.
+        if (resource)
+        {
+            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;
+
+                if (resourceTypes == "oic.light.control")
+                {
+                    curResource = resource;
+                    // Call a local function which will internally invoke get API on the resource pointer
+                    getLightRepresentation(resource);
+                }
+            }
+
+            // Get the resource interfaces
+            std::cout << "\tList of resource interfaces: " << std::endl;
+            for (auto &resourceInterfaces : resource->getResourceInterfaces())
+            {
+                std::cout << "\t\t" << resourceInterfaces << std::endl;
+            }
+        }
+        else
+        {
+            // Resource is invalid
+            std::cout << "Resource is invalid" << std::endl;
+        }
+
+    }
+    catch (std::exception &e)
+    {
+        std::cerr << "Exception in foundResource: " << e.what() << std::endl;
+    }
+}
+
+void printUsage()
+{
+    std::cout << std::endl;
+    std::cout << "---------------------------------------------------------------------\n";
+    std::cout << "Usage : ContainerSampleClient <ObserveType>" << std::endl;
+    std::cout << "   ObserveType : 1 - Observe" << std::endl;
+    std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
+    std::cout << "---------------------------------------------------------------------\n\n";
+}
+
+void checkObserverValue(int value)
+{
+    if (value == 1)
+    {
+        OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+        std::cout << "<===Setting ObserveType to Observe===>\n\n";
+    }
+    else if (value == 2)
+    {
+        OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
+        std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
+    }
+    else
+    {
+        std::cout << "<===Invalid ObserveType selected."
+                  << " Setting ObserveType to Observe===>\n\n";
+    }
+}
+
+static FILE *client_open(const char *path, const char *mode)
+{
+    return fopen("./oic_svr_db_client.json", mode);
+}
+
+int main(int argc, char *argv[])
+{
+
+    std::ostringstream requestURI;
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    try
+    {
+        printUsage();
+        if (argc == 1)
+        {
+            std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
+        }
+        else if (argc == 2)
+        {
+            checkObserverValue(std::stoi(argv[1]));
+        }
+        else
+        {
+            std::cout << "<===Invalid number of command line arguments===>\n\n";
+            return -1;
+        }
+    }
+    catch (std::exception &)
+    {
+        std::cout << "<===Invalid input arguments===>\n\n";
+        return -1;
+    }
+
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    {
+        OC::ServiceType::InProc,
+        OC::ModeType::Both,
+        "0.0.0.0",
+        0,
+        OC::QualityOfService::LowQos,
+        &ps
+    };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+        // makes it so that all boolean values are printed as 'true/false' in this stream
+        std::cout.setf(std::ios::boolalpha);
+        // Find all resources
+        requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
+
+        OCPlatform::findResource("", requestURI.str(),
+                                 CT_DEFAULT, &foundResource);
+        std::cout << "Finding Resource... " << std::endl;
+
+        // Find resource is done twice so that we discover the original resources a second time.
+        // These resources will have the same uniqueidentifier (yet be different objects), so that
+        // we can verify/show the duplicate-checking code in foundResource(above);
+        OCPlatform::findResource("", requestURI.str(),
+                                 CT_DEFAULT, &foundResource);
+        std::cout << "Finding Resource for second time..." << std::endl;
+
+        // A condition variable will free the mutex it is given, then do a non-
+        // intensive block until 'notify' is called on it.  In this case, since we
+        // don't ever call cv.notify, this should be a non-processor intensive version
+        // of while(true);
+        std::mutex blocker;
+        std::condition_variable cv;
+        std::unique_lock<std::mutex> lock(blocker);
+        cv.wait(lock);
+
+    }
+    catch (OCException &e)
+    {
+        oclog() << "Exception in main: " << e.what();
+    }
+
+    return 0;
+}
+
+
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/pom.xml b/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/pom.xml
new file mode 100644 (file)
index 0000000..2bc318c
--- /dev/null
@@ -0,0 +1,76 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.iotivity.bundles</groupId>
+  <artifactId>hue</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1</version>
+  <name>hue</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+               <groupId>org.apache.httpcomponents</groupId>
+               <artifactId>httpclient</artifactId>
+               <version>4.5</version>
+               <scope>compile</scope>
+    </dependency>
+    <dependency>
+               <groupId>org.iotivity.resourcecontainer</groupId>
+               <artifactId>bundle-api</artifactId>
+               <version>0.1</version>
+               <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugins</groupId>
+      <artifactId>maven-shade-plugin</artifactId>
+      <version>2.4</version>
+      <type>maven-plugin</type>
+    </dependency>
+  </dependencies>
+  <build>
+       <pluginManagement>
+       <plugins>
+               <plugin>
+                       <groupId>org.apache.maven.plugins</groupId>
+                       <artifactId>maven-assmembly-plugin</artifactId>
+                       <version>2.5.5</version>
+               </plugin>
+       </plugins>            
+      </pluginManagement>
+     <plugins>      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.3</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.5.5</version>  
+        <configuration>
+               <descriptorRefs>
+                       <descriptorRef>jar-with-dependencies</descriptorRef>
+               </descriptorRefs>
+        </configuration>      
+      </plugin> 
+    </plugins>
+  </build>
+  <repositories>
+       <repository>
+               <id>repo1</id>
+               <name>Repo1</name>
+               <url>http://repo1.maven.rog</url>               
+       </repository>
+  </repositories>
+</project>
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueBundleActivator.java b/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueBundleActivator.java
new file mode 100644 (file)
index 0000000..7be201f
--- /dev/null
@@ -0,0 +1,40 @@
+package org.iotivity.bundle.hue;
+
+import java.util.List;
+
+import org.iotivity.resourcecontainer.bundle.api.BaseActivator;
+import org.iotivity.resourcecontainer.bundle.api.ResourceConfig;
+
+public class HueBundleActivator extends BaseActivator {
+    private HueConnector connector;
+
+    public HueBundleActivator(String bundleId) {
+        super(bundleId);
+    }
+
+    public void activateBundle() {
+        super.activateBundle();
+        connector = new HueConnector();
+        List<ResourceConfig> resourceConfig = getConfiguredBundleResources();
+
+        for (ResourceConfig config : resourceConfig) {
+
+            HueLightResource hueLightResource = new HueLightResource(connector,
+                    config.getName(), config.getURI(),
+                    config.getResourceType(), config.getAddress());
+            
+            System.out.println("Registration of HueLightresource");
+            registerResource(hueLightResource);
+        }
+    }
+
+    public void deactivateBundle() {
+        System.out.println("Deactivate bundle called.");
+        super.deactivateBundle();
+    }
+
+    // test call
+    public static void main(String[] args) {
+        HueBundleActivator activator = new HueBundleActivator("oic.hue.bundle");
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueConnector.java b/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueConnector.java
new file mode 100644 (file)
index 0000000..d94d575
--- /dev/null
@@ -0,0 +1,70 @@
+package org.iotivity.bundle.hue;
+
+import java.io.IOException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.iotivity.resourcecontainer.bundle.api.ProtocolBridgeConnector;
+
+public class HueConnector implements ProtocolBridgeConnector {
+    public void connect() {
+
+    }
+
+    public void disconnect() {
+
+    }
+
+    public void transmit(String target, String payload) {
+        try {
+            CloseableHttpClient httpclient = HttpClients.createDefault();
+            HttpPost httpPost = new HttpPost(target);
+            // httpPost.setHeader("content-type","application/json");
+            StringEntity stringEntity = new StringEntity(payload,
+                    ContentType.create("application/json", "UTF-8"));
+            httpPost.setEntity(stringEntity);
+
+            CloseableHttpResponse response1;
+            response1 = httpclient.execute(httpPost);
+            // The underlying HTTP connection is still held by the response
+            // object
+            // to allow the response content to be streamed directly from the
+            // network socket.
+            // In order to ensure correct deallocation of system resources
+            // the user MUST call CloseableHttpResponse#close() from a finally
+            // clause.
+            // Please note that if response content is not fully consumed the
+            // underlying
+            // connection cannot be safely re-used and will be shut down and
+            // discarded
+            // by the connection manager.
+            try {
+                HttpEntity entity1 = response1.getEntity();
+                // do something useful with the response body
+                // and ensure it is fully consumed
+                EntityUtils.consume(entity1);
+            } finally {
+                response1.close();
+            }
+
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    public String read(String target) {
+        return "";
+    }
+
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueLightResource.java b/service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/src/main/java/org/iotivity/bundle/hue/HueLightResource.java
new file mode 100644 (file)
index 0000000..32f3fd5
--- /dev/null
@@ -0,0 +1,76 @@
+package org.iotivity.bundle.hue;
+
+import java.util.HashMap;
+
+import org.iotivity.resourcecontainer.bundle.api.BundleResource;
+
+/**
+ * This class maps a Philips Hue light to OIC light resource
+ * 
+ * @author iotivity
+ */
+public class HueLightResource extends BundleResource {
+    private HueConnector m_hueConnector;
+
+    public HueLightResource() {
+        initAttributes();
+        m_resourceType = "oic.light.control";
+       
+    }
+
+    public HueLightResource(HueConnector hueConnector, String name, String uri,
+            String resourceType, String address) {
+        this();
+        this.m_hueConnector = hueConnector;
+        m_name = name;
+        m_uri = uri;
+        m_resourceType = resourceType;
+        m_address = address;        
+    }
+
+    protected void initAttributes() {
+        m_attributes = new HashMap<String, String>();
+        m_attributes.put("on-off", "true");
+        m_attributes.put("color", "0");
+        m_attributes.put("dim", "0");
+    }
+
+    public void setAttribute(String key, String value) {
+        System.out.println("Set attribute called - key: " + key + ", value: "
+                + value + " transmitting now.");
+
+        if ("on-off".equals(value)) {
+            m_hueConnector.transmit(m_address + "/state", "{\"on\":" + value
+                    + "}");
+        }
+
+        if ("dim".equals(value)) {
+            m_hueConnector.transmit(m_address + "/state", "{\"bri\":" + value
+                    + "}");
+        }
+
+        if ("color".equals(value)) {
+            m_hueConnector.transmit(m_address + "/state", "{\"hue\":" + value
+                    + "}");
+        }
+        m_attributes.put(key, value);
+    }
+
+    public String getAttribute(String key) {
+        
+        // map key to hue address
+        // read from Hue gateway, parse resource representation and return
+        // attribute
+        //m_hueConnector.read(m_address);
+        return m_attributes.get(key);
+    }     
+
+    @Override
+    public String toString() {
+        return "HueLightResource [m_hueConnector=" + m_hueConnector
+                + ", m_name=" + m_name + ", m_uri=" + m_uri
+                + ", m_resourceType=" + m_resourceType + ", m_address="
+                + m_address + ", m_attributes=" + m_attributes + "]";
+    }
+
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueConnector.h b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueConnector.h
new file mode 100644 (file)
index 0000000..7a6ed67
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUECONNECTOR_H_
+#define HUECONNECTOR_H_
+
+#include "ProtocolBridgeConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueConnector: public ProtocolBridgeConnector
+        {
+
+        public:
+            HueConnector();
+            virtual ~HueConnector();
+            void connect();
+            void disconnect();
+            std::string transmit(std::string target, std::string data);
+            std::string read(std::string target);
+        };
+    }
+}
+
+#endif /* HUECONNECTOR_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueLight.h b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueLight.h
new file mode 100644 (file)
index 0000000..3390908
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUELIGHT_H_
+#define HUELIGHT_H_
+
+#include "ProtocolBridgeResource.h"
+#include "HueConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueLight: public ProtocolBridgeResource
+        {
+
+        public:
+            HueLight();
+            HueLight(HueConnector* connector, std::string address);
+            virtual ~HueLight();
+            virtual void initAttributes();
+            virtual RCSResourceAttributes& getAttributes();
+
+            virtual void setAttribute(std::string key, RCSResourceAttributes::Value&&);
+
+            virtual RCSResourceAttributes::Value getAttribute(const std::string& key);
+        private:
+            std::string m_address;
+            HueConnector* m_connector;
+        };}
+}
+
+#endif /* HUEGATEWAYCLIENT_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h
new file mode 100644 (file)
index 0000000..c62f367
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUESAMPLEBUNDLEACTIVATOR_H_
+#define HUESAMPLEBUNDLEACTIVATOR_H_
+
+#include "ResourceContainerBundleAPI.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+#include "HueConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueSampleBundleActivator: public BundleActivator
+        {
+            public:
+                HueSampleBundleActivator();
+                ~HueSampleBundleActivator();
+
+                void activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                    std::string bundleId);
+                void deactivateBundle();
+
+                void createResource(resourceInfo resourceInfo);
+                void destroyResource(BundleResource *pBundleResource);
+
+                std::string m_bundleId;
+                ResourceContainerBundleAPI *m_pResourceContainer;
+                std::vector< BundleResource * > m_vecResources;
+            private:
+                HueConnector *m_connector;
+        };
+    }
+}
+
+#endif /* HUESAMPLEBUNDLEACTIVATOR_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp
new file mode 100644 (file)
index 0000000..5a5a956
--- /dev/null
@@ -0,0 +1,152 @@
+//******************************************************************
+//
+// 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 AND PERMISSION NOTICE
+//
+// Copyright (c) 1996 - 2015, Daniel Stenberg, daniel@haxx.se.
+//
+// All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted,
+// provided that the above copyright notice and this permission notice appear in all copies.
+//
+// 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 OF THIRD PARTY RIGHTS. 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.
+//
+// Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the
+// sale, use or other dealings in this Software without prior written authorization of the copyright holder.
+//******************************************************************
+
+#include "HueConnector.h"
+#include <curl/curl.h>
+#include <string.h>
+#include <iostream>
+
+using namespace std;
+using namespace OIC::Service;
+
+HueConnector::HueConnector()
+{
+
+}
+
+HueConnector::~HueConnector()
+{
+
+}
+
+void HueConnector::connect()
+{
+
+}
+
+void HueConnector::disconnect()
+{
+
+}
+
+std::string HueConnector::transmit(std::string target, std::string payload)
+{
+    std::cout << "Transmitting to " << target << " " << payload << endl;
+    CURL *curl;
+    CURLcode res;
+    struct curl_slist *headers = NULL; /* http headers to send with request */
+    /* set content type */
+    headers = curl_slist_append(headers, "Accept: application/json");
+    headers = curl_slist_append(headers, "Content-Type: application/json");
+
+    const char *cstr = payload.c_str();
+
+    curl = curl_easy_init();
+
+    if (curl)
+    {
+        curl_easy_setopt(curl, CURLOPT_URL, target.c_str());
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, cstr);
+        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+
+        /* if we don't provide POSTFIELDSIZE, libcurl will strlen() by
+         itself */
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(cstr));
+
+        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
+        /* Perform the request, res will get the return code */
+        res = curl_easy_perform(curl);
+        /* Check for errors */
+        if (res != CURLE_OK)
+            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+
+        /* always cleanup */
+        curl_easy_cleanup(curl);
+    }
+    return "";
+}
+
+static int writer(char *data, size_t size, size_t nmemb, std::string *buffer_in)
+{
+    buffer_in->append(data, size * nmemb);
+    return size * nmemb;
+}
+
+std::string HueConnector::read(std::string target)
+{
+    std::cout << "Reading from to " << target << endl;
+    CURL *curl;
+    CURLcode res;
+    struct curl_slist *headers = NULL; /* http headers to send with request */
+    /* set content type */
+    headers = curl_slist_append(headers, "Accept: application/json");
+    headers = curl_slist_append(headers, "Content-Type: application/json");
+
+    curl = curl_easy_init();
+
+    if (curl)
+    {
+        curl_easy_setopt(curl, CURLOPT_URL, target.c_str());
+        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
+        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+
+        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
+        std::string response;
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
+
+        /* Perform the request, res will get the return code */
+        res = curl_easy_perform(curl);
+        /* Check for errors */
+        if (res != CURLE_OK)
+        {
+            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+        }
+        else
+        {
+            cout << "Response is: " << response << endl;
+        }
+
+        /* always cleanup */
+        curl_easy_cleanup(curl);
+    }
+    return "";
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp
new file mode 100644 (file)
index 0000000..f378b10
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// 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 "HueLight.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace OIC::Service;
+
+HueLight::HueLight()
+{
+    m_connector = nullptr;
+}
+
+HueLight::HueLight(HueConnector *connector, std::string address)
+{
+    m_address = address;
+    m_connector = connector;
+    initAttributes();
+}
+
+HueLight::~HueLight()
+{
+    m_connector = nullptr;
+}
+
+void HueLight::initAttributes()
+{
+
+    BundleResource::setAttribute("on-off", false);
+    BundleResource::setAttribute("dim", 0);
+    BundleResource::setAttribute("color", 0);
+}
+
+RCSResourceAttributes &HueLight::getAttributes()
+{
+    return BundleResource::getAttributes();
+}
+
+RCSResourceAttributes::Value HueLight::getAttribute(const std::string &key)
+{
+    cout << "HueLight::getAttribute called for " << key <<  " called" << endl;
+    return BundleResource::getAttribute(key);
+}
+
+void HueLight::setAttribute(std::string attributeName, RCSResourceAttributes::Value &&value)
+{
+    cout << "HueLight::setAttribute setting " << attributeName << " to " << value.toString() <<
+         std::endl;
+
+    if (attributeName == "on-off")
+    {
+        m_connector->transmit(this->m_address + "/state", "{\"on\":" + value.toString() + "}");
+    }
+
+    if (attributeName == "dim")
+    {
+        // needs conversion * 2.5
+        m_connector->transmit(this->m_address + "/state", "{\"bri\":" + value.toString() + "}");
+    }
+
+    if (attributeName == "color")
+    {
+        // needs conversion *650
+        m_connector->transmit(this->m_address + "/state", "{\"hue\":" + value.toString()   + "}");
+    }
+
+    BundleResource::setAttribute(attributeName, std::move(value));
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp b/service/resource-encapsulation/src/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp
new file mode 100644 (file)
index 0000000..ab7f40b
--- /dev/null
@@ -0,0 +1,130 @@
+//******************************************************************
+//
+// 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 "HueSampleBundleActivator.h"
+#include "HueLight.h"
+
+#include <algorithm>
+#include <vector>
+
+using namespace OIC::Service;
+
+HueSampleBundleActivator *bundle;
+
+HueSampleBundleActivator::HueSampleBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+    m_connector = nullptr;
+}
+
+HueSampleBundleActivator::~HueSampleBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+    m_connector = nullptr;
+}
+
+void HueSampleBundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+        std::string bundleId)
+{
+
+    m_pResourceContainer = resourceContainer;
+    m_bundleId = bundleId;
+    m_connector = new HueConnector();
+
+    vector< resourceInfo > resourceConfig;
+
+    resourceContainer->getResourceConfiguration(m_bundleId, &resourceConfig);
+
+    for (vector< resourceInfo >::iterator itor = resourceConfig.begin();
+         itor != resourceConfig.end(); itor++)
+    {
+        createResource(*itor);
+    }
+}
+
+void HueSampleBundleActivator::deactivateBundle()
+{
+    std::cout << "HueSampleBundle::deactivateBundle called" << std::endl;
+
+    std::vector<BundleResource *>::iterator itor;
+    for (itor = m_vecResources.begin(); itor != m_vecResources.end();)
+    {
+        destroyResource(*itor);
+    }
+
+    delete m_connector;
+}
+
+void HueSampleBundleActivator::createResource(resourceInfo resourceInfo)
+{
+
+    if (resourceInfo.resourceType == "oic.light.control")
+    {
+        static int lightCount = 1;
+        HueLight *hueLight = new HueLight(m_connector, resourceInfo.address);
+        resourceInfo.uri = "/hue/light/" + std::to_string(lightCount++);
+        std::cout << "Registering resource " << resourceInfo.uri << std::endl;
+        hueLight->m_bundleId = m_bundleId;
+        hueLight->m_uri = resourceInfo.uri;
+        hueLight->m_resourceType = resourceInfo.resourceType;
+        hueLight->m_name = resourceInfo.name;
+
+        m_pResourceContainer->registerResource(hueLight);
+        m_vecResources.push_back(hueLight);
+    }
+}
+
+void HueSampleBundleActivator::destroyResource(BundleResource *pBundleResource)
+{
+    std::cout << "HueSampleBundle::destroyResource called" << pBundleResource->m_uri << std::endl;
+
+    std::vector< BundleResource * >::iterator itor;
+
+    itor = std::find(m_vecResources.begin(), m_vecResources.end(), pBundleResource);
+
+    if (itor != m_vecResources.end())
+    {
+        m_pResourceContainer->unregisterResource(pBundleResource);
+        m_vecResources.erase(itor);
+    }
+}
+
+extern "C" void externalActivateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                       std::string bundleId)
+{
+    bundle = new HueSampleBundleActivator();
+    bundle->activateBundle(resourceContainer, bundleId);
+}
+
+extern "C" void externalDeactivateBundle()
+{
+    bundle->deactivateBundle();
+    delete bundle;
+}
+
+extern "C" void externalCreateResource(resourceInfo resourceInfo)
+{
+    bundle->createResource(resourceInfo);
+}
+
+extern "C" void externalDestroyResource(BundleResource *pBundleResource)
+{
+    bundle->destroyResource(pBundleResource);
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/ResourceContainerConfig.xml b/service/resource-encapsulation/src/resourceContainer/examples/ResourceContainerConfig.xml
new file mode 100644 (file)
index 0000000..2621e42
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<container>      
+    <bundle>
+        <id>oic.bundle.discomfortIndexSensor</id>
+        <path>libSoftSensorBundle.so</path>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>DiscomfortIndexSensor1</name>
+                               <resourceType>oic.softsensor</resourceType>
+                <outputs>
+                  <output>
+                    <name>discomfortIndex</name>
+                    <type>int</type>
+                  </output>
+                </outputs>
+                <inputs>
+                  <input>
+                    <name>humidity</name>
+                    <type>double</type>
+                  </input>
+                                 <input>
+                    <name>temperature</name>
+                    <type>double</type>
+                  </input>
+                </inputs>
+            </resourceInfo>       
+        </resources>
+    </bundle>
+       <bundle>
+        <id>oic.bundle.hueSample</id>
+        <path>libHueBundle.so</path>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>light</name>
+                               <resourceType>oic.light.control</resourceType>
+                <address>http://192.168.0.2/api/newdeveloper/lights/1</address>
+            </resourceInfo>       
+        </resources>
+    </bundle>
+       <!--
+       <bundle>
+        <id>oic.bundle.hueJavaSample</id>       
+               <path>../../../../../../../../service/resource-encapsulation/src/resourceContainer/examples/HueJavaSampleBundle/hue/target/hue-0.1-jar-with-dependencies.jar</path>
+        <libraryPath>.</libraryPath>
+        <uri>/hueJava</uri>
+        <activator>org.iotivity.bundle.hue.HueBundleActivator</activator>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>light</name>
+                <uri>light/1</uri>
+                               <resourceType>oic.light.control</resourceType>
+                <address>http://192.168.0.2/api/newdeveloper/lights/1</address>
+            </resourceInfo>       
+        </resources>
+    </bundle>
+       -->
+</container>
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensor.h b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensor.h
new file mode 100644 (file)
index 0000000..01513a2
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+
+/*
+* DiscomfortIndexSensor.h
+*/
+
+#ifndef DISCOMFORTINDEXSENSOR_H_
+#define DISCOMFORTINDEXSENSOR_H_
+
+/**
+* This header file is included to define _EXPORT_.
+*/
+
+#include "SoftSensorResource.h"
+
+using namespace OIC::Service;
+
+namespace DiscomfortIndexSensorName
+{
+    typedef enum
+    {
+        SUCCESS = 0, ERROR, ALL_DISCOMPORT, HALF_DISCOMPORT, LITTLE_DISCOMPORT, ALL_COMPORT
+    } DIResult;
+
+    class DiscomfortIndexSensor
+    {
+        public:
+            DiscomfortIndexSensor();
+            ~DiscomfortIndexSensor();
+
+            int executeDISensorLogic(std::map<std::string, std::string> *pInputData, std::string *pOutput);
+            DIResult makeDiscomfortIndex();
+
+        private:
+            std::string m_humidity;
+            std::string m_temperature;
+            std::string m_discomfortIndex;
+    };
+};
+
+#endif /* DISCOMFORTINDEXSENSOR_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensorResource.h b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/DiscomfortIndexSensorResource.h
new file mode 100644 (file)
index 0000000..585cbda
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef DISCOMFORTINDEXSENSORRESOURCE_H_
+#define DISCOMFORTINDEXSENSORRESOURCE_H_
+
+#include "SoftSensorResource.h"
+#include "DiscomfortIndexSensor.h"
+
+using namespace DiscomfortIndexSensorName;
+using namespace OIC::Service;
+
+class DiscomfortIndexSensorResource : public SoftSensorResource
+{
+    public:
+        DiscomfortIndexSensorResource();
+        ~DiscomfortIndexSensorResource();
+
+        void initAttributes();
+        virtual RCSResourceAttributes &getAttributes();
+        virtual void setAttribute(std::string key, RCSResourceAttributes::Value &&value);
+        virtual RCSResourceAttributes::Value getAttribute(const std::string &key);
+
+        virtual void executeLogic();
+
+    private:
+        DiscomfortIndexSensor *m_pDiscomfortIndexSensor;
+};
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/SoftSensorBundleActivator.h b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/include/SoftSensorBundleActivator.h
new file mode 100644 (file)
index 0000000..487a654
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SOFTSENSOR_SAMPLEBUNDLE_H_
+#define SOFTSENSOR_SAMPLEBUNDLE_H_
+
+#include "ResourceContainerBundleAPI.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+
+using namespace OIC::Service;
+
+class SoftSensorBundleActivator : public BundleActivator
+{
+    public:
+        SoftSensorBundleActivator();
+        ~SoftSensorBundleActivator();
+
+        void activateBundle(ResourceContainerBundleAPI *resourceContainer, std::string bundleId);
+        void deactivateBundle();
+
+        void createResource(resourceInfo resourceInfo);
+        void destroyResource(BundleResource *pBundleResource);
+
+        std::string m_bundleId;
+        ResourceContainerBundleAPI *m_pResourceContainer;
+        std::vector<BundleResource *> m_vecResources;
+};
+
+#endif /* SOFTSENSOR_SAMPLEBUNDLE_H_ */
  * limitations under the License.
  *
  ******************************************************************/
-#include "oic_string.h"
+/*
+ * SysTimer.h
+ */
 
-#include <string.h>
-#include "oic_malloc.h"
+#ifndef SYSTIMER_H_
+#define SYSTIMER_H_
 
-char *OICStrdup(const char *str)
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+class SysTimer
 {
-    // Allocate memory for original string length and 1 extra byte for '\0'
-    size_t length = strlen(str);
-    char *dup = (char *)OICMalloc(length + 1);
-    if (NULL != dup)
-    {
-        memcpy(dup, str, length + 1);
-    }
-    return dup;
-}
+    public:
+        static std::string MilliSecondAsString();
+        static std::string UTCSecondAsString();
+};
 
+#endif /* SYSTIMER_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensor.cpp b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensor.cpp
new file mode 100644 (file)
index 0000000..1675fbe
--- /dev/null
@@ -0,0 +1,116 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+/**
+ * This file contains the exported symbol.
+ */
+
+#include <iostream>
+
+#include "DiscomfortIndexSensor.h"
+#include "SysTimer.h"
+
+#ifdef __ANDROID__
+#include "OCAndroid.h"
+#endif
+
+using namespace DiscomfortIndexSensorName;
+
+DiscomfortIndexSensor::DiscomfortIndexSensor()
+{
+    m_humidity = "";
+    m_temperature = "";
+    m_discomfortIndex = "";
+}
+
+DiscomfortIndexSensor::~DiscomfortIndexSensor()
+{
+
+}
+
+int DiscomfortIndexSensor::executeDISensorLogic(std::map<std::string, std::string> *pInputData,
+        std::string *pOutput)
+{
+    std::cout << "[DiscomfortIndexSensor] DiscomfortIndexSensor::" << __func__ << " is called."
+              << std::endl;
+
+    DIResult result;
+
+    m_temperature = pInputData->at("temperature");
+    m_humidity = pInputData->at("humidity");
+
+    if ((result = makeDiscomfortIndex()) != SUCCESS)
+    {
+        std::cout << "Error : makeDiscomfortIndex() result = " << result << std::endl;
+        return -1;
+    }
+
+    (*pOutput) = m_discomfortIndex;
+
+    return 0;
+}
+
+/**
+ * Calculation of DiscomfortIndex with TEMP&HUMI.
+ */
+DIResult DiscomfortIndexSensor::makeDiscomfortIndex()
+{
+    int DILevel = (int) ERROR;
+    double dDI = 0.0;
+
+    int t = std::stoi(m_temperature);
+    int h = std::stoi(m_humidity);
+    double F = (9.0 * (double) t) / 5.0 + 32.0;
+
+    // calculation of discomfortIndex
+    dDI = F - (F - 58.0) * (double)((100 - h) * 55) / 10000.0;
+
+    std::cout << "Discomfort level : " << dDI << ", Temperature :" << t << ", Humidity :" << h <<
+              std::endl;
+
+    m_discomfortIndex = std::to_string(DILevel);
+    std::cout << "[result] Discomfort Index : " << m_discomfortIndex << std::endl;
+    if (dDI >= 80.0)
+    {
+        DILevel = (int)ALL_DISCOMPORT;
+        std::cout << "DI : " << DILevel << " : All person discomfort. : " << dDI
+                  << std::endl;
+    }
+    else if (dDI >= 75.0)
+    {
+        DILevel = (int)HALF_DISCOMPORT;
+        std::cout << "DI : " << DILevel << " : Half of person discomfort. : " << dDI
+                  << std::endl;
+    }
+    else if (dDI >= 68.0)
+    {
+        DILevel = (int)LITTLE_DISCOMPORT;
+        std::cout << "DI : " << DILevel << " : A little person discomfort. : " << dDI
+                  << std::endl;
+    }
+    else
+    {
+        DILevel = (int)ALL_COMPORT;
+        std::cout << "DI : " << DILevel << " : All person comfort. : " << dDI
+                  << std::endl;
+    }
+
+    return SUCCESS;
+}
\ No newline at end of file
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensorResource.cpp b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/DiscomfortIndexSensorResource.cpp
new file mode 100644 (file)
index 0000000..de51815
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// 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 "DiscomfortIndexSensorResource.h"
+
+
+DiscomfortIndexSensorResource::DiscomfortIndexSensorResource()
+{
+    m_pDiscomfortIndexSensor = new DiscomfortIndexSensor();
+}
+
+DiscomfortIndexSensorResource::~DiscomfortIndexSensorResource()
+{
+    delete m_pDiscomfortIndexSensor;
+}
+
+void DiscomfortIndexSensorResource::initAttributes()
+{
+    SoftSensorResource::initAttributes();
+}
+
+RCSResourceAttributes &DiscomfortIndexSensorResource::getAttributes()
+{
+    return SoftSensorResource::getAttributes();
+}
+
+void DiscomfortIndexSensorResource::setAttribute(std::string key,
+        RCSResourceAttributes::Value &&value)
+{
+    SoftSensorResource::setAttribute(key, std::move(value));
+}
+
+RCSResourceAttributes::Value DiscomfortIndexSensorResource::getAttribute(const std::string &key)
+{
+    return SoftSensorResource::getAttribute(key);
+}
+
+void DiscomfortIndexSensorResource::executeLogic()
+{
+    std::map<std::string, std::string> mapInputData;
+    std::string strTemp = getAttribute("temperature").toString();
+    std::string strHumid = getAttribute("humidity").toString();
+    std::string strDiscomfortIndex;
+
+    if (!strTemp.empty() && !strHumid.empty())
+    {
+        mapInputData.insert(std::make_pair("temperature", strTemp));
+        mapInputData.insert(std::make_pair("humidity", strHumid));
+
+        m_pDiscomfortIndexSensor->executeDISensorLogic(&mapInputData, &strDiscomfortIndex);
+
+        setAttribute("discomfortIndex", RCSResourceAttributes::Value(strDiscomfortIndex.c_str()));
+    }
+}
\ No newline at end of file
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SoftSensorBundleActivator.cpp b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SoftSensorBundleActivator.cpp
new file mode 100644 (file)
index 0000000..2647188
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// 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 "SoftSensorBundleActivator.h"
+#include "DiscomfortIndexSensorResource.h"
+#include <algorithm>
+
+SoftSensorBundleActivator *bundle;
+
+SoftSensorBundleActivator::SoftSensorBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+}
+
+SoftSensorBundleActivator::~SoftSensorBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+}
+
+void SoftSensorBundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+        std::string bundleId)
+{
+    m_pResourceContainer = resourceContainer;
+    m_bundleId = bundleId;
+
+    std::vector<resourceInfo> resourceConfig;
+
+    resourceContainer->getResourceConfiguration(m_bundleId, &resourceConfig);
+
+    for (vector<resourceInfo>::iterator itor = resourceConfig.begin();
+         itor != resourceConfig.end(); itor++)
+    {
+        createResource(*itor);
+    }
+}
+
+void SoftSensorBundleActivator::deactivateBundle()
+{
+    std::vector<BundleResource *>::iterator itor;
+    for (itor = m_vecResources.begin(); itor != m_vecResources.end();)
+    {
+        destroyResource(*itor);
+    }
+}
+
+void SoftSensorBundleActivator::createResource(resourceInfo resourceInfo)
+{
+    if (resourceInfo.resourceType == "oic.softsensor")
+    {
+        static int discomfortIndexSensorCount = 1;
+
+        // create DISensor resource
+        DiscomfortIndexSensorResource *newResource = new DiscomfortIndexSensorResource();
+
+        newResource->m_bundleId = m_bundleId;
+        newResource->m_uri = "/softsensor/discomfortIndex/" + std::to_string(
+                                 discomfortIndexSensorCount++);
+        newResource->m_resourceType = resourceInfo.resourceType;
+        newResource->m_mapResourceProperty = resourceInfo.resourceProperty;
+
+        newResource->initAttributes();
+
+        m_pResourceContainer->registerResource(newResource);
+        m_vecResources.push_back(newResource);
+    }
+}
+
+void SoftSensorBundleActivator::destroyResource(BundleResource *resource)
+{
+    std::vector <BundleResource *>::iterator itor;
+
+    itor = std::find(m_vecResources.begin(), m_vecResources.end(), resource);
+
+    if (itor != m_vecResources.end())
+    {
+        m_pResourceContainer->unregisterResource(resource);
+        m_vecResources.erase(itor);
+    }
+}
+
+extern "C" void externalActivateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                       std::string bundleId)
+{
+    bundle = new SoftSensorBundleActivator();
+    bundle->activateBundle(resourceContainer, bundleId);
+}
+
+extern "C" void externalDeactivateBundle()
+{
+    bundle->deactivateBundle();
+    delete bundle;
+}
+
+extern "C" void externalCreateResource(resourceInfo resourceInfo)
+{
+    bundle->createResource(resourceInfo);
+}
+
+extern "C" void externalDestroyResource(BundleResource *pBundleResource)
+{
+    bundle->destroyResource(pBundleResource);
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SysTimer.cpp b/service/resource-encapsulation/src/resourceContainer/examples/SoftSensorSampleBundle/src/SysTimer.cpp
new file mode 100644 (file)
index 0000000..032e0fc
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************
+ *
+ * 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 <cstdlib>
+#include <sys/time.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include "SysTimer.h"
+
+#include <stdint.h>
+std::string SysTimer::MilliSecondAsString()
+{
+    std::stringstream ss;
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    long long val = tv.tv_sec * (long long) 1000 + tv.tv_usec / 1000;
+
+    ss << val;
+    std::string strTime = ss.str();
+
+    return strTime;
+}
+
+std::string SysTimer::UTCSecondAsString()
+{
+    std::stringstream ss;
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    unsigned long val = tv.tv_sec;
+
+    ss << val;
+    std::string strTime = ss.str();
+
+    return strTime;
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/include/BundleInfoInternal.h b/service/resource-encapsulation/src/resourceContainer/include/BundleInfoInternal.h
new file mode 100644 (file)
index 0000000..e34c2e3
--- /dev/null
@@ -0,0 +1,117 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLEINFOINTERNAL_H_
+#define BUNDLEINFOINTERNAL_H_
+
+#include <string>
+#include "RCSBundleInfo.h"
+#include "ResourceContainerBundleAPI.h"
+
+#if (JAVA_SUPPORT)
+    #include "jni.h"
+#endif
+
+using namespace std;
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        typedef void activator_t(ResourceContainerBundleAPI *, std::string bundleId);
+        typedef void deactivator_t(void);
+        typedef void resourceCreator_t(resourceInfo resourceInfo);
+        typedef void resourceDestroyer_t(BundleResource *pBundleResource);
+
+        class BundleInfoInternal: public RCSBundleInfo
+        {
+            public:
+                BundleInfoInternal();
+                BundleInfoInternal(RCSBundleInfo *info);
+                virtual ~BundleInfoInternal();
+                void setID(const std::string &id);
+                const std::string &getID();
+                void setPath(const std::string &path);
+                const std::string &getPath();
+                void setVersion(const std::string &version);
+                const std::string &getVersion();
+
+                void setLoaded(bool loaded);
+                bool isLoaded();
+                void setActivated(bool activated);
+                bool isActivated();
+
+                virtual void setLibraryPath(const std::string &libpath);
+                virtual const std::string &getLibraryPath();
+
+                void setActivatorName(const std::string &activatorName);
+                const std::string &getActivatorName();
+
+                void setBundleActivator(activator_t *);
+                activator_t *getBundleActivator();
+
+                void setBundleDeactivator(deactivator_t *);
+                deactivator_t *getBundleDeactivator();
+
+                void setResourceCreator(resourceCreator_t *);
+                resourceCreator_t *getResourceCreator();
+
+                void setResourceDestroyer(resourceDestroyer_t *);
+                resourceDestroyer_t *getResourceDestroyer();
+
+                void setBundleInfo(RCSBundleInfo *bundleInfo);
+
+                void setBundleHandle(void *);
+                void *getBundleHandle();
+
+                void setJavaBundle(bool javaBundle);
+                bool getJavaBundle();
+
+#if (JAVA_SUPPORT)
+                void setJavaBundleActivatorMethod(jmethodID activator);
+                jmethodID getJavaBundleActivatorMethod();
+                void setJavaBundleDeactivatorMethod(jmethodID deactivator);
+                jmethodID getJavaBundleDeactivatorMethod();
+
+                void setJavaBundleActivatorObject(jobject);
+                jobject getJavaBundleActivatorObject();
+#endif
+
+            private:
+                bool m_loaded, m_activated, m_java_bundle;
+                int m_id;
+                activator_t *m_activator;
+                deactivator_t *m_deactivator;
+                resourceCreator_t *m_resourceCreator;
+                resourceDestroyer_t *m_resourceDestroyer;
+                void *m_bundleHandle;
+                string m_activator_name;
+                string m_library_path;
+#if (JAVA_SUPPORT)
+                jmethodID m_java_activator, m_java_deactivator;
+                jobject m_java_activator_object;
+#endif
+
+        };
+    }
+}
+
+#endif /* BUNDLEINFOINTERNAL_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/include/Configuration.h b/service/resource-encapsulation/src/resourceContainer/include/Configuration.h
new file mode 100644 (file)
index 0000000..9f9872c
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef CONFIGURATION_H_
+#define CONFIGURATION_H_
+
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <map>
+
+#include "rapidxml/rapidxml.hpp"
+#include "rapidxml/rapidxml_print.hpp"
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        typedef vector< map< string, string > > configInfo;
+
+        struct resourceInfo
+        {
+            string name;
+            string uri;
+            string resourceType;
+            string address;
+            map< string, vector< map< string, string > > > resourceProperty;
+        };
+
+        class Configuration
+        {
+            public:
+                Configuration();
+                Configuration(string configFile);
+                ~Configuration();
+
+                bool isLoaded();
+                void getConfiguredBundles(configInfo *configOutput);
+                void getBundleConfiguration(string bundleId, configInfo *configOutput);
+                void getResourceConfiguration(string bundleId, vector< resourceInfo > *configOutput);
+
+            private:
+                void getConfigDocument(string pathConfigFile);
+                void getCurrentPath(string *pPath);
+
+                bool m_loaded;
+                string m_pathConfigFile;
+                string m_strConfigData;
+                rapidxml::xml_document< char > m_xmlDoc;
+        };
+    }
+}
+
+#endif /* CONFIGURATION_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/include/JavaBundleResource.h b/service/resource-encapsulation/src/resourceContainer/include/JavaBundleResource.h
new file mode 100644 (file)
index 0000000..54cb40e
--- /dev/null
@@ -0,0 +1,63 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef JAVABUNDLERESOURCE_H_
+#define JAVABUNDLERESOURCE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+#include <jni.h>
+#include "BundleResource.h"
+#include "ResourceContainerImpl.h"
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class JavaBundleResource: public BundleResource
+        {
+        public:
+            JavaBundleResource();
+            JavaBundleResource(JNIEnv *env, jobject obj, jobject bundleResource, string bundleId,
+                    jobjectArray attributes);
+            virtual ~JavaBundleResource();
+
+            virtual RCSResourceAttributes& getAttributes();
+
+            virtual void setAttribute(std::string key, RCSResourceAttributes::Value&&);
+
+            virtual RCSResourceAttributes::Value getAttribute(const std::string& key);
+            virtual void initAttributes();
+        private:
+            // needs to be a GlobalRef
+            jobject bundleResource;
+            jobjectArray attributes;
+            jclass bundleResourceClass;
+            jmethodID attributeSetter;
+            jmethodID attributeGetter;
+            string m_bundleId;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/include/ResourceContainerImpl.h b/service/resource-encapsulation/src/resourceContainer/include/ResourceContainerImpl.h
new file mode 100644 (file)
index 0000000..c9bb210
--- /dev/null
@@ -0,0 +1,130 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECONTAINERIMPL_H_
+#define RESOURCECONTAINERIMPL_H_
+
+
+
+#include "RCSResourceContainer.h"
+#include "ResourceContainerBundleAPI.h"
+#include "BundleInfoInternal.h"
+
+#include "RCSRequest.h"
+#include "RCSResponse.h"
+#include "RCSResourceObject.h"
+
+#if(JAVA_SUPPORT)
+    #include <jni.h>
+#endif
+
+#include <map>
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class ResourceContainerImpl: public RCSResourceContainer, public ResourceContainerBundleAPI
+        {
+            public:
+                ResourceContainerImpl();
+                virtual ~ResourceContainerImpl();
+
+                // methods from ResourceContainer
+                void startContainer(const std::string &configFile);
+                void stopContainer();
+                void activateBundle(RCSBundleInfo *bundleInfo);
+                void deactivateBundle(RCSBundleInfo *bundleInfo);
+                void activateBundle(const std::string &bundleId);
+                void deactivateBundle(const std::string &bundleId);
+                void registerBundle(RCSBundleInfo *bundleinfo);
+                void unregisterBundle(RCSBundleInfo *bundleinfo);
+                void unregisterBundleSo(const std::string &id);
+
+
+                // methods from ResourceContainerBundleAPI
+                void registerResource(BundleResource *resource);
+                void unregisterResource(BundleResource *resource);
+
+                void getBundleConfiguration(const std::string &bundleId, configInfo *configOutput);
+                void getResourceConfiguration(const std::string &bundleId,
+                                              std::vector< resourceInfo > *configOutput);
+
+                RCSGetResponse getRequestHandler(const RCSRequest &request,
+                                                 const RCSResourceAttributes &attributes);
+                RCSSetResponse setRequestHandler(const RCSRequest &request,
+                                                 const RCSResourceAttributes &attributes);
+
+                void onNotificationReceived(const std::string &strResourceUri);
+
+                static ResourceContainerImpl *getImplInstance();
+                static RCSResourceObject::Ptr buildResourceObject(const std::string &strUri, const std::string &strResourceType);
+
+                void startBundle(const std::string &bundleId);
+                void stopBundle(const std::string &bundleId);
+
+                void addBundle(const std::string &bundleId, const std::string &bundleUri, const std::string &bundlePath,
+                               std::map<string, string> params);
+                void removeBundle(const std::string &bundleId);
+
+                std::list<RCSBundleInfo *> listBundles();
+
+                void addResourceConfig(const std::string &bundleId, const std::string &resourceUri, std::map<string, string> params);
+                void removeResourceConfig(const std::string &bundleId, const std::string &resourceUri);
+
+                std::list<string> listBundleResources(const std::string &bundleId);
+
+#if(JAVA_SUPPORT)
+                JavaVM *getJavaVM(string bundleId);
+                void unregisterBundleJava(string id);
+#endif
+
+
+            private:
+                map< std::string, BundleInfoInternal * > m_bundles; // <bundleID, bundleInfo>
+                map< std::string, RCSResourceObject::Ptr > m_mapServers; //<uri, serverPtr>
+                map< std::string, BundleResource * > m_mapResources; //<uri, resourcePtr>
+                map< std::string, list<string> > m_mapBundleResources; //<bundleID, vector<uri>>
+                string m_configFile;
+                Configuration *m_config;
+
+
+                void activateSoBundle(const std::string &bundleId);
+                void deactivateSoBundle(const std::string &bundleId);
+                void addSoBundleResource(const std::string &bundleId, resourceInfo newResourceInfo);
+                void removeSoBundleResource(const std::string &bundleId, const std::string &resourceUri);
+                void registerSoBundle(RCSBundleInfo *bundleInfo);
+
+#if(JAVA_SUPPORT)
+                map<string, JavaVM *> m_bundleVM;
+
+                void registerJavaBundle(RCSBundleInfo *bundleInfo);
+                void activateJavaBundle(string bundleId);
+                void deactivateJavaBundle(string bundleId);
+
+#endif
+
+        };
+    }
+}
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/include/org_iotivity_resourcecontainer_bundle_api_BaseActivator.h b/service/resource-encapsulation/src/resourceContainer/include/org_iotivity_resourcecontainer_bundle_api_BaseActivator.h
new file mode 100644 (file)
index 0000000..b83c4b9
--- /dev/null
@@ -0,0 +1,48 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#if(JAVA_SUPPORT)
+#include <jni.h>
+/* Header for class org_iotivity_resourcecontainer_bundle_api_BaseActivator */
+
+#ifndef _Included_org_iotivity_resourcecontainer_bundle_api_BaseActivator
+#define _Included_org_iotivity_resourcecontainer_bundle_api_BaseActivator
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    registerJavaResource
+ * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_registerJavaResource
+  (JNIEnv *, jobject, jobject, jobjectArray, jstring, jstring, jstring, jstring);
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    unregisterJavaResource
+ * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_unregisterJavaResource
+  (JNIEnv *, jobject, jobject, jstring);
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    getNumberOfConfiguredResources
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_getNumberOfConfiguredResources
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    getConfiguredResourceParams
+ * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_getConfiguredResourceParams
+  (JNIEnv *, jobject, jstring, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/src/BaseActivator.cpp b/service/resource-encapsulation/src/resourceContainer/src/BaseActivator.cpp
new file mode 100644 (file)
index 0000000..992b673
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// 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 "ResourceContainerImpl.h"
+#if(JAVA_SUPPORT)
+    #include <jni.h>
+    #include "org_iotivity_resourcecontainer_bundle_api_BaseActivator.h"
+    #include "JavaBundleResource.h"
+    #include "ResourceContainerImpl.h"
+
+    using namespace OIC::Service;
+
+    std::map< string, JavaBundleResource* > java_resources;
+
+    /*
+     * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+     * Method:    registerJavaResource
+     * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_registerJavaResource
+    (JNIEnv *env, jobject obj, jobject bundleResource, jobjectArray attributes, jstring bundleId, jstring uri, jstring resourceType, jstring res_name)
+    {
+        //return;
+        //static std::map<jobject, JavaBundleResource > javaBundles;
+        const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+        const char *str_uri = env->GetStringUTFChars(uri, 0);
+        const char *str_resourceType = env->GetStringUTFChars(resourceType, 0);
+        const char *str_res_name = env->GetStringUTFChars(res_name, 0);
+
+        JavaBundleResource *javaBundleResource = new JavaBundleResource(env, obj, bundleResource, str_bundleId, attributes);
+        ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+
+        javaBundleResource->m_uri = string(str_uri, strlen(str_uri));
+        javaBundleResource->m_resourceType = string(str_resourceType, strlen(str_resourceType));
+        javaBundleResource->m_name = string(str_res_name, strlen(str_res_name));
+        container->registerResource(javaBundleResource);
+
+        java_resources[str_uri] = javaBundleResource;
+
+    }
+
+    /*
+     * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+     * Method:    unregisterJavaResource
+     * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_unregisterJavaResource
+    (JNIEnv *env, jobject obj, jobject bundleResource, jstring uri)
+    {
+        const char *str_uri = env->GetStringUTFChars(uri, 0);
+
+        if(java_resources[str_uri] != NULL)
+        {
+            ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+            container->unregisterResource(java_resources[str_uri]);
+            java_resources.erase(str_uri);
+        }
+    }
+
+    /*
+     * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+     * Method:    getNumberOfConfiguredResources
+     * Signature: (Ljava/lang/String;)I
+     */
+    JNIEXPORT jint JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_getNumberOfConfiguredResources(
+            JNIEnv *env, jobject obj, jstring bundleId)
+    {
+
+        const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+
+        ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+        vector< resourceInfo > resourceConfig;
+        container->getResourceConfiguration(str_bundleId, &resourceConfig);
+
+        return resourceConfig.size();
+    }
+
+    /*
+     * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+     * Method:    getConfiguredResourceParams
+     * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
+     */
+    JNIEXPORT jobjectArray JNICALL Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_getConfiguredResourceParams(
+            JNIEnv *env, jobject obj, jstring bundleId, jint resourceId)
+    {
+
+        jobjectArray ret;
+        const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+
+        ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+        vector< resourceInfo > resourceConfig;
+        container->getResourceConfiguration(str_bundleId, &resourceConfig);
+        resourceInfo conf = resourceConfig[resourceId];
+        ret = (jobjectArray) env->NewObjectArray(4, env->FindClass("java/lang/String"),
+                env->NewStringUTF(""));
+
+        env->SetObjectArrayElement(ret, 0, env->NewStringUTF(conf.name.c_str()));
+        env->SetObjectArrayElement(ret, 1, env->NewStringUTF(conf.uri.c_str()));
+        env->SetObjectArrayElement(ret, 2, env->NewStringUTF(conf.resourceType.c_str()));
+        env->SetObjectArrayElement(ret, 3, env->NewStringUTF(conf.address.c_str()));
+        return ret;
+    }
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/src/BundleActivator.cpp b/service/resource-encapsulation/src/resourceContainer/src/BundleActivator.cpp
new file mode 100644 (file)
index 0000000..9d0134a
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// 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 "BundleActivator.h"
+#include "RCSResourceContainer.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        BundleActivator::BundleActivator()
+        {
+
+        }
+
+        BundleActivator::~BundleActivator()
+        {
+
+        }
+
+        void BundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                std::string bundleId)
+        {
+
+        }
+
+        void BundleActivator::deactivateBundle()
+        {
+
+        }
+    }
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/src/BundleInfoInternal.cpp b/service/resource-encapsulation/src/resourceContainer/src/BundleInfoInternal.cpp
new file mode 100644 (file)
index 0000000..6adef62
--- /dev/null
@@ -0,0 +1,225 @@
+//******************************************************************
+//
+// 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 "BundleInfoInternal.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        BundleInfoInternal::BundleInfoInternal()
+        {
+            m_activator = nullptr;
+            m_deactivator = nullptr;
+            m_resourceCreator = nullptr;
+            m_resourceDestroyer = nullptr;
+            m_bundleHandle = nullptr;
+
+            m_loaded = false;
+            m_activated = false;
+            m_java_bundle = false;
+            m_id = 0;
+        }
+
+        BundleInfoInternal::~BundleInfoInternal()
+        {
+            m_activator = nullptr;
+            m_deactivator = nullptr;
+            m_resourceCreator = nullptr;
+            m_resourceDestroyer = nullptr;
+            m_bundleHandle = nullptr;
+        }
+
+        void BundleInfoInternal::setID(const std::string &id)
+        {
+            m_ID = id;
+        }
+
+        const std::string &BundleInfoInternal::getID()
+        {
+            return m_ID;
+        }
+
+        void BundleInfoInternal::setPath( const std::string &path)
+        {
+            m_path = path;
+        }
+        const std::string &BundleInfoInternal::getPath()
+        {
+            return m_path;
+        }
+
+        void BundleInfoInternal::setVersion( const std::string &version)
+        {
+            m_version = version;
+        }
+
+        const std::string &BundleInfoInternal::getVersion()
+        {
+            return m_version;
+        }
+
+        void BundleInfoInternal::setLoaded(bool loaded)
+        {
+            m_loaded = loaded;
+        }
+
+        bool BundleInfoInternal::isLoaded()
+        {
+            return m_loaded;
+        }
+
+        void BundleInfoInternal::setActivated(bool activated)
+        {
+            m_activated = activated;
+        }
+
+        bool BundleInfoInternal::isActivated()
+        {
+            return m_activated;
+        }
+
+        void BundleInfoInternal::setBundleActivator(activator_t *activator)
+        {
+            m_activator = activator;
+        }
+
+        activator_t *BundleInfoInternal::getBundleActivator()
+        {
+            return m_activator;
+        }
+
+        void BundleInfoInternal::setBundleDeactivator(deactivator_t *deactivator)
+        {
+            m_deactivator = deactivator;
+        }
+
+        deactivator_t *BundleInfoInternal::getBundleDeactivator()
+        {
+            return m_deactivator;
+        }
+
+        void BundleInfoInternal::setResourceCreator(resourceCreator_t *resourceCreator)
+        {
+            m_resourceCreator = resourceCreator;
+        }
+
+        resourceCreator_t *BundleInfoInternal::getResourceCreator()
+        {
+            return m_resourceCreator;
+        }
+
+        void BundleInfoInternal::setResourceDestroyer(resourceDestroyer_t *resourceDestroyer)
+        {
+            m_resourceDestroyer = resourceDestroyer;
+        }
+
+        resourceDestroyer_t *BundleInfoInternal::getResourceDestroyer()
+        {
+            return m_resourceDestroyer;
+        }
+
+        void BundleInfoInternal::setBundleHandle(void *handle)
+        {
+            m_bundleHandle = handle;
+        }
+
+        void *BundleInfoInternal::getBundleHandle()
+        {
+            return m_bundleHandle;
+        }
+
+        void BundleInfoInternal::setJavaBundle(bool javaBundle)
+        {
+            m_java_bundle = javaBundle;
+        }
+
+        bool BundleInfoInternal::getJavaBundle()
+        {
+            return m_java_bundle;
+        }
+
+        void BundleInfoInternal::setActivatorName( const std::string &activatorName)
+        {
+            m_activator_name = activatorName;
+        }
+
+        const std::string &BundleInfoInternal::getActivatorName()
+        {
+            return m_activator_name;
+        }
+
+        void BundleInfoInternal::setLibraryPath( const std::string &libpath)
+        {
+            m_library_path = libpath;
+        }
+
+        const std::string &BundleInfoInternal::getLibraryPath()
+        {
+            return m_library_path;
+        }
+
+#if (JAVA_SUPPORT)
+        void BundleInfoInternal::setJavaBundleActivatorMethod(jmethodID javaBundleActivator)
+        {
+            m_java_activator = javaBundleActivator;
+        }
+
+        jmethodID BundleInfoInternal::getJavaBundleActivatorMethod()
+        {
+            return m_java_activator;
+        }
+
+        void BundleInfoInternal::setJavaBundleDeactivatorMethod(jmethodID javaBundleActivator)
+        {
+            m_java_deactivator = javaBundleActivator;
+        }
+
+        jmethodID BundleInfoInternal::getJavaBundleDeactivatorMethod()
+        {
+            return m_java_deactivator;
+        }
+
+        void BundleInfoInternal::setJavaBundleActivatorObject(jobject activator_object)
+        {
+            m_java_activator_object = activator_object;
+        }
+
+        jobject BundleInfoInternal::getJavaBundleActivatorObject()
+        {
+            return m_java_activator_object;
+        }
+#endif
+
+        void BundleInfoInternal::setBundleInfo(RCSBundleInfo *bundleInfo)
+        {
+            BundleInfoInternal *source = (BundleInfoInternal *)bundleInfo;
+            m_ID = source->getID();
+            m_path = source->getPath();
+            m_version = source->getVersion();
+            m_loaded = source->isLoaded();
+            m_activated = source->isActivated();
+            m_java_bundle = source->getJavaBundle();
+            m_activator = source->getBundleActivator();
+            m_bundleHandle = source->getBundleHandle();
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/src/BundleResource.cpp b/service/resource-encapsulation/src/resourceContainer/src/BundleResource.cpp
new file mode 100644 (file)
index 0000000..b74f9fc
--- /dev/null
@@ -0,0 +1,73 @@
+//******************************************************************
+//
+// 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 "BundleResource.h"
+#include "Configuration.h"
+#include <list>
+#include <string.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        BundleResource::BundleResource()
+        {
+            m_pNotiReceiver = nullptr;
+        }
+
+        BundleResource::~BundleResource()
+        {
+            m_pNotiReceiver = nullptr;
+        }
+
+        void BundleResource::registerObserver(NotificationReceiver *pNotiReceiver)
+        {
+            m_pNotiReceiver = pNotiReceiver;
+        }
+
+        std::list< string > BundleResource::getAttributeNames()
+        {
+            std::list< string > ret;
+            for (RCSResourceAttributes::iterator it = m_resourceAttributes.begin();
+                 it != m_resourceAttributes.end(); ++it)
+            {
+                ret.push_back(it->key());
+            }
+            return ret;
+        }
+
+        RCSResourceAttributes &BundleResource::getAttributes()
+        {
+            return m_resourceAttributes;
+        }
+
+        void BundleResource::setAttribute(std::string key, RCSResourceAttributes::Value &&value)
+        {
+            m_resourceAttributes[key] = value;
+        }
+
+        RCSResourceAttributes::Value BundleResource::getAttribute(const std::string &key)
+        {
+            cout << "Bundle resource get attribute " << m_resourceAttributes.at(key).toString() << "|" << endl;
+            return m_resourceAttributes.at(key);
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/src/Configuration.cpp b/service/resource-encapsulation/src/resourceContainer/src/Configuration.cpp
new file mode 100644 (file)
index 0000000..22b22e6
--- /dev/null
@@ -0,0 +1,274 @@
+//******************************************************************
+//
+// 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 "Configuration.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        static inline std::string trim_both(const std::string &str)
+        {
+            int npos = str.find_first_not_of(" \t\v\n\r");
+
+            if (npos == -1)
+            {
+                return "";
+            }
+
+            unsigned int n = (unsigned int) npos;
+            std::string tempString = n == std::string::npos ? str : str.substr(n, str.length());
+
+            n = tempString.find_last_not_of(" \t\v\n\r");
+
+            return n == std::string::npos ? tempString : tempString.substr(0, n + 1);
+        }
+
+        Configuration::Configuration()
+        {
+            m_loaded = false;
+        }
+
+        Configuration::Configuration(string configFile)
+        {
+            m_loaded = false;
+
+            m_pathConfigFile.append(configFile);
+
+            getConfigDocument(m_pathConfigFile);
+        }
+
+        Configuration::~Configuration()
+        {
+        }
+
+        bool Configuration::isLoaded()
+        {
+            return m_loaded;
+        }
+
+        void Configuration::getConfiguredBundles(configInfo *configOutput)
+        {
+            rapidxml::xml_node< char > *bundle;
+            rapidxml::xml_node< char > *subItem;
+
+            string strKey, strValue;
+
+            if (m_loaded)
+            {
+                try
+                {
+                    //cout << "Name of first node is: " << m_xmlDoc.first_node()->name() << endl;
+
+                    for (bundle = m_xmlDoc.first_node()->first_node("bundle"); bundle; bundle =
+                            bundle->next_sibling())
+                    {
+                        std::map< std::string, std::string > bundleMap;
+                        //cout << "Bundle: " << bundle->name() << endl;
+                        for (subItem = bundle->first_node(); subItem;
+                                subItem = subItem->next_sibling())
+                        {
+                            strKey = subItem->name();
+                            strValue = subItem->value();
+
+                            if (strlen(subItem->value()) > 0)
+                            {
+                                bundleMap.insert(
+                                        std::make_pair(trim_both(strKey), trim_both(strValue)));
+                                //cout << strKey << " " << strValue << endl;
+                            }
+                        }
+                        configOutput->push_back(bundleMap);
+                    }
+
+                }
+                catch (rapidxml::parse_error &e)
+                {
+                    cout << "xml parsing failed !!" << endl;
+                    cout << e.what() << endl;
+                }
+            }
+        }
+
+        void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
+        {
+            rapidxml::xml_node< char > *bundle;
+
+            string strBundleId, strPath, strVersion;
+
+            if (m_loaded)
+            {
+                try
+                {
+                    std::map< std::string, std::string > bundleConfigMap;
+
+                    // <bundle>
+                    for (bundle = m_xmlDoc.first_node()->first_node("bundle"); bundle; bundle =
+                            bundle->next_sibling())
+                    {
+                        // <id>
+                        strBundleId = bundle->first_node("id")->value();
+
+                        if (!strBundleId.compare(bundleId))
+                        {
+                            bundleConfigMap.insert(std::make_pair("id", trim_both(strBundleId)));
+
+                            // <path>
+                            strPath = bundle->first_node("path")->value();
+                            bundleConfigMap.insert(std::make_pair("path", trim_both(strPath)));
+
+                            // <version>
+                            strVersion = bundle->first_node("version")->value();
+                            bundleConfigMap.insert(
+                                    std::make_pair("version", trim_both(strVersion)));
+
+                            configOutput->push_back(bundleConfigMap);
+
+                            break;
+                        }
+                    }
+                }
+                catch (rapidxml::parse_error &e)
+                {
+                    cout << "xml parsing failed !!" << endl;
+                    cout << e.what() << endl;
+                }
+            }
+        }
+
+        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;
+
+            string strBundleId;
+            string strKey, strValue;
+
+            if (m_loaded)
+            {
+                try
+                {
+                    // <bundle>
+                    for (bundle = m_xmlDoc.first_node()->first_node("bundle"); bundle; bundle =
+                            bundle->next_sibling())
+                    {
+                        // <id>
+                        strBundleId = bundle->first_node("id")->value();
+
+                        if (!strBundleId.compare(bundleId))
+                        {
+                            // <resourceInfo>
+                            for (resource = bundle->first_node("resources")->first_node(
+                                    "resourceInfo"); resource; resource = resource->next_sibling())
+                            {
+                                resourceInfo tempResourceInfo;
+
+                                for (item = resource->first_node(); item; item =
+                                        item->next_sibling())
+                                {
+                                    strKey = item->name();
+                                    strValue = item->value();
+
+                                    if (!strKey.compare("name"))
+                                        tempResourceInfo.name = trim_both(strValue);
+
+                                    else if (!strKey.compare("uri"))
+                                        tempResourceInfo.uri = trim_both(strValue);
+
+                                    else if (!strKey.compare("address"))
+                                        tempResourceInfo.address = trim_both(strValue);
+
+                                    else if (!strKey.compare("resourceType"))
+                                        tempResourceInfo.resourceType = trim_both(strValue);
+
+                                    else
+                                    {
+                                        for (subItem = item->first_node(); subItem; subItem =
+                                                subItem->next_sibling())
+                                        {
+                                            map< string, string > propertyMap;
+
+                                            strKey = subItem->name();
+
+                                            for (subItem2 = subItem->first_node(); subItem2;
+                                                    subItem2 = subItem2->next_sibling())
+                                            {
+                                                string newStrKey = subItem2->name();
+                                                string newStrValue = subItem2->value();
+
+                                                propertyMap[trim_both(newStrKey)] = trim_both(
+                                                        newStrValue);
+                                            }
+
+                                            tempResourceInfo.resourceProperty[trim_both(strKey)].push_back(
+                                                    propertyMap);
+                                        }
+                                    }
+                                }
+                                configOutput->push_back(tempResourceInfo);
+                            }
+                        }
+                    }
+                }
+                catch (rapidxml::parse_error &e)
+                {
+                    std::cout << "xml parsing failed !!" << std::endl;
+                    std::cout << e.what() << std::endl;
+                }
+            }
+        }
+
+        void Configuration::getConfigDocument(std::string pathConfigFile)
+        {
+            std::basic_ifstream< char > xmlFile(pathConfigFile.c_str());
+
+            if (!xmlFile.fail())
+            {
+                xmlFile.seekg(0, std::ios::end);
+                unsigned int size = (unsigned int) xmlFile.tellg();
+                xmlFile.seekg(0);
+
+                std::vector< char > xmlData(size + 1);
+                xmlData[size] = 0;
+
+                xmlFile.read(&xmlData.front(), (std::streamsize) size);
+                xmlFile.close();
+                m_strConfigData = std::string(xmlData.data());
+
+                try
+                {
+                    m_xmlDoc.parse< 0 >((char *) m_strConfigData.c_str());
+                    m_loaded = true;
+                }
+                catch (rapidxml::parse_error &e)
+                {
+                    std::cout << "xml parsing failed !!" << std::endl;
+                    std::cout << e.what() << std::endl;
+                }
+            }
+            else
+            {
+                std::cout << "Configuration File load failed !!" << std::endl;
+            }
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/src/JavaBundleResource.cpp b/service/resource-encapsulation/src/resourceContainer/src/JavaBundleResource.cpp
new file mode 100644 (file)
index 0000000..a799dce
--- /dev/null
@@ -0,0 +1,159 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+#if(JAVA_SUPPORT)
+    #include "JavaBundleResource.h"
+    #include <jni.h>
+    #include <string.h>
+
+    #include <iostream>
+
+    using namespace OIC::Service;
+    using namespace std;
+
+    #include "oc_logger.hpp"
+
+    using OC::oc_log_stream;
+    using namespace OIC::Service;
+
+    auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+    {
+        static OC::oc_log_stream ols(oc_make_ostream_logger);
+        static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+        os->set_level(OC_LOG_INFO);
+        os->set_module("JavaBundleResource");
+        return os;
+    };
+
+    auto error_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+    {
+        static OC::oc_log_stream ols(oc_make_ostream_logger);
+        static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+        os->set_level(OC_LOG_ERROR);
+        os->set_module("JavaBundleResource");
+        return os;
+    };
+
+    JavaBundleResource::JavaBundleResource()
+    {
+
+    }
+
+    void JavaBundleResource::initAttributes()
+    {
+
+    }
+
+    JavaBundleResource::JavaBundleResource(JNIEnv *env, jobject obj, jobject bundleResource,
+            string bundleId, jobjectArray attributes)
+    {
+        int stringCount = env->GetArrayLength(attributes);
+
+        for (int i = 0; i < stringCount; i++)
+        {
+            jstring str = (jstring) env->GetObjectArrayElement(attributes, i);
+            const char *rawString = env->GetStringUTFChars(str, 0);
+            string s(rawString, strlen(rawString));
+            BundleResource::setAttribute(s, "");
+        }
+
+        m_bundleId = bundleId;
+
+        this->bundleResource = env->NewGlobalRef(bundleResource);
+
+        bundleResourceClass = env->GetObjectClass(bundleResource);
+
+        attributeSetter = env->GetMethodID(bundleResourceClass, "setAttribute",
+                "(Ljava/lang/String;Ljava/lang/String;)V");
+
+        attributeGetter = env->GetMethodID(bundleResourceClass, "getAttribute",
+                "(Ljava/lang/String;)Ljava/lang/String;");
+
+    }
+
+    JavaBundleResource::~JavaBundleResource()
+    {
+
+    }
+
+    RCSResourceAttributes& JavaBundleResource::getAttributes(){
+        return BundleResource::getAttributes();
+    }
+
+    RCSResourceAttributes::Value JavaBundleResource::getAttribute(const std::string& attributeName)
+    {
+        JavaVM* vm = ResourceContainerImpl::getImplInstance()->getJavaVM(m_bundleId);
+
+        JNIEnv * env;
+        int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
+
+        if (envStat == JNI_EDETACHED)
+        {
+            if (vm->AttachCurrentThread((void**) &env, NULL) != 0)
+            {
+                error_logger() << "Failed to attach " << endl;
+            }
+        }
+        else if (envStat == JNI_EVERSION)
+        {
+            error_logger() << "Env: version not supported " << endl;
+        }
+
+        jstring attrName = env->NewStringUTF(attributeName.c_str());
+
+        jstring returnString = (jstring) env->CallObjectMethod(bundleResource, attributeGetter,
+                attrName);
+
+        const char *js = env->GetStringUTFChars(returnString, NULL);
+        std::string val(js);
+        RCSResourceAttributes::Value newVal = val;
+        env->ReleaseStringUTFChars(returnString, js);
+        BundleResource::setAttribute(attributeName, newVal.toString());
+        return BundleResource::getAttribute(attributeName);
+    }
+
+    void JavaBundleResource::setAttribute(std::string attributeName, RCSResourceAttributes::Value&& value)
+    {
+        JavaVM* vm = ResourceContainerImpl::getImplInstance()->getJavaVM(m_bundleId);
+
+        JNIEnv * env;
+        int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
+
+        if (envStat == JNI_EDETACHED)
+        {
+            if (vm->AttachCurrentThread((void**) &env, NULL) != 0)
+            {
+                error_logger() << "Failed to attach " << endl;
+            }
+        }
+        else if (envStat == JNI_EVERSION)
+        {
+            error_logger() << "Env: version not supported " << endl;
+        }
+
+        jstring attrName = env->NewStringUTF(attributeName.c_str());
+        jstring val = env->NewStringUTF(value.toString().c_str());
+
+
+        env->CallObjectMethod(bundleResource, attributeSetter, attrName, val);
+        BundleResource::setAttribute(attributeName, std::move(value));
+    }
+#endif
diff --git a/service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeConnector.cpp b/service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeConnector.cpp
new file mode 100644 (file)
index 0000000..f55d8af
--- /dev/null
@@ -0,0 +1,40 @@
+//******************************************************************
+//
+// 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 "ProtocolBridgeConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        ProtocolBridgeConnector::ProtocolBridgeConnector()
+        {
+
+        }
+
+        ProtocolBridgeConnector::~ProtocolBridgeConnector()
+        {
+
+        }
+    }
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeResource.cpp b/service/resource-encapsulation/src/resourceContainer/src/ProtocolBridgeResource.cpp
new file mode 100644 (file)
index 0000000..0e0eed0
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// 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 "ProtocolBridgeResource.h"
+
+using namespace OIC::Service;
+
+namespace OIC{
+    namespace Service{
+        ProtocolBridgeResource::ProtocolBridgeResource()
+        {
+
+        }
+
+        ProtocolBridgeResource::~ProtocolBridgeResource()
+        {
+
+        }
+    }
+}
+
+
diff --git a/service/resource-encapsulation/src/resourceContainer/src/RCSBundleInfo.cpp b/service/resource-encapsulation/src/resourceContainer/src/RCSBundleInfo.cpp
new file mode 100644 (file)
index 0000000..fdcd111
--- /dev/null
@@ -0,0 +1,44 @@
+//******************************************************************
+//
+// 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 "RCSBundleInfo.h"
+#include "BundleInfoInternal.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        RCSBundleInfo::RCSBundleInfo()
+        {
+
+        }
+
+        RCSBundleInfo::~RCSBundleInfo()
+        {
+
+        }
+
+        RCSBundleInfo *RCSBundleInfo::build()
+        {
+            BundleInfoInternal *newBundleInfo = new BundleInfoInternal();
+            return newBundleInfo;
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/src/RCSResourceContainer.cpp b/service/resource-encapsulation/src/resourceContainer/src/RCSResourceContainer.cpp
new file mode 100644 (file)
index 0000000..9830c2b
--- /dev/null
@@ -0,0 +1,42 @@
+//******************************************************************
+//
+// 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 "RCSResourceContainer.h"
+#include "ResourceContainerImpl.h"
+
+namespace OIC{
+    namespace Service{
+        RCSResourceContainer::RCSResourceContainer()
+        {
+
+        }
+
+        RCSResourceContainer::~RCSResourceContainer()
+        {
+
+        }
+
+        RCSResourceContainer *RCSResourceContainer::getInstance()
+        {
+            return (RCSResourceContainer *)ResourceContainerImpl::getImplInstance();
+        }
+    }
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/src/ResourceContainerBundleAPI.cpp b/service/resource-encapsulation/src/resourceContainer/src/ResourceContainerBundleAPI.cpp
new file mode 100644 (file)
index 0000000..ad47a28
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************
+//
+// 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 "ResourceContainerBundleAPI.h"
+#include "ResourceContainerImpl.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        ResourceContainerBundleAPI::ResourceContainerBundleAPI()
+        {
+
+        }
+
+        ResourceContainerBundleAPI::~ResourceContainerBundleAPI()
+        {
+
+        }
+
+        ResourceContainerBundleAPI *ResourceContainerBundleAPI::getInstance()
+        {
+            return (ResourceContainerBundleAPI *)ResourceContainerImpl::getImplInstance();
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/src/ResourceContainerImpl.cpp b/service/resource-encapsulation/src/resourceContainer/src/ResourceContainerImpl.cpp
new file mode 100644 (file)
index 0000000..09d40c3
--- /dev/null
@@ -0,0 +1,858 @@
+//******************************************************************
+//
+// 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 <dlfcn.h>
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+
+#include "ResourceContainerImpl.h"
+#include "BundleActivator.h"
+#include "RCSResourceContainer.h"
+#include "BundleInfoInternal.h"
+#include "logger.h"
+#include "oc_logger.hpp"
+
+using OC::oc_log_stream;
+using namespace OIC::Service;
+
+auto error_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+    os->set_level(OC_LOG_ERROR);
+    os->set_module("ResourceContainerImpl");
+    return os;
+};
+
+auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+    os->set_level(OC_LOG_INFO);
+    os->set_module("ResourceContainerImpl");
+    return os;
+};
+
+using namespace std;
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        ResourceContainerImpl::ResourceContainerImpl()
+        {
+            m_config = nullptr;
+        }
+
+        ResourceContainerImpl::~ResourceContainerImpl()
+        {
+            m_config = nullptr;
+        }
+
+        bool has_suffix(const std::string &str, const std::string &suffix)
+        {
+            return str.size() >= suffix.size()
+                   && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+        }
+
+        void ResourceContainerImpl::startContainer(const std::string &configFile)
+        {
+            info_logger() << "Starting resource container " << endl;
+#if (JAVA_SUPPORT)
+            info_logger() << "Resource container has Java support" << endl;
+#else
+            info_logger() << "Resource container without Java support" << endl;
+#endif
+
+            if (!configFile.empty())
+            {
+                m_config = new Configuration(configFile);
+
+                if (m_config->isLoaded())
+                {
+                    configInfo bundles;
+                    m_config->getConfiguredBundles(&bundles);
+
+                    for (unsigned int i = 0; i < bundles.size(); i++)
+                    {
+                        RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
+                        bundleInfo->setPath(bundles[i]["path"]);
+                        bundleInfo->setVersion(bundles[i]["version"]);
+                        bundleInfo->setID(bundles[i]["id"]);
+                        if (!bundles[i]["activator"].empty())
+                        {
+                            string activatorName = bundles[i]["activator"];
+                            std::replace(activatorName.begin(), activatorName.end(), '.', '/');
+                            ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
+                            ((BundleInfoInternal *) bundleInfo)->setLibraryPath(
+                                bundles[i]["libraryPath"]);
+
+                        }
+                        info_logger() << "Init Bundle:" << bundles[i]["id"] << ";" << bundles[i]["path"]
+                                      << endl;
+                        registerBundle(bundleInfo);
+                        activateBundle(bundleInfo);
+                    }
+                }
+                else
+                {
+                    error_logger() << "Container started with invalid configfile path" << endl;
+                }
+            }
+            else
+            {
+                info_logger() << "No configuration file for the container provided" << endl;
+            }
+        }
+
+        void ResourceContainerImpl::stopContainer()
+        {
+            info_logger() << "Stopping resource container.";
+            for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
+                 it != m_bundles.end(); ++it)
+            {
+                BundleInfoInternal *bundleInfo = it->second;
+                deactivateBundle(bundleInfo);
+                unregisterBundle(bundleInfo);
+            }
+
+            if (!m_mapServers.empty())
+            {
+                map< std::string, RCSResourceObject::Ptr >::iterator itor = m_mapServers.begin();
+
+                while (itor != m_mapServers.end())
+                {
+                    (itor++)->second.reset();
+                }
+
+                m_mapResources.clear();
+                m_mapBundleResources.clear();
+            }
+
+            delete m_config;
+        }
+
+        void ResourceContainerImpl::activateBundle(RCSBundleInfo *bundleInfo)
+        {
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
+
+            if (bundleInfoInternal->isLoaded())
+            {
+                activateBundle(bundleInfo->getID());
+            }
+        }
+
+        void ResourceContainerImpl::deactivateBundle(RCSBundleInfo *bundleInfo)
+        {
+            if (((BundleInfoInternal *) bundleInfo)->isActivated())
+            {
+                deactivateBundle(bundleInfo->getID());
+            }
+        }
+
+        void ResourceContainerImpl::activateBundle(const std::string &id)
+        {
+
+            info_logger() << "Activating bundle: " << m_bundles[id]->getID() << endl;
+
+            if (m_bundles[id]->getJavaBundle())
+            {
+#if(JAVA_SUPPORT)
+                activateJavaBundle(id);
+#endif
+            }
+            else
+            {
+                activateSoBundle(id);
+            }
+
+            info_logger() << "Bundle activated: " << m_bundles[id]->getID() << endl;
+
+        }
+
+        void ResourceContainerImpl::deactivateBundle(const std::string &id)
+        {
+
+            if (m_bundles[id]->getJavaBundle())
+            {
+#if(JAVA_SUPPORT)
+                deactivateJavaBundle(id);
+#endif
+            }
+            else
+            {
+                deactivateSoBundle(id);
+            }
+        }
+
+        // loads the bundle
+        void ResourceContainerImpl::registerBundle(RCSBundleInfo *bundleInfo)
+        {
+            info_logger() << "Registering bundle: " << bundleInfo->getPath() << endl;
+
+            if (has_suffix(bundleInfo->getPath(), ".jar"))
+            {
+#if(JAVA_SUPPORT)
+                ((BundleInfoInternal *) bundleInfo)->setJavaBundle(true);
+                registerJavaBundle(bundleInfo);
+#endif
+            }
+            else
+            {
+                ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
+                registerSoBundle(bundleInfo);
+            }
+        }
+
+        void ResourceContainerImpl::unregisterBundle(RCSBundleInfo *bundleInfo)
+        {
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
+            if (bundleInfoInternal->isLoaded() && !bundleInfoInternal->isActivated())
+            {
+                if (!bundleInfoInternal->getJavaBundle())
+                {
+                    unregisterBundleSo(bundleInfo->getID());
+                }
+                else
+                {
+#if(JAVA_SUPPORT)
+                    unregisterBundleJava(bundleInfo->getID());
+#endif
+                }
+            }
+        }
+
+        void ResourceContainerImpl::unregisterBundleSo(const std::string &id)
+        {
+            void *bundleHandle = m_bundles[id]->getBundleHandle();
+            info_logger() << "Unregister bundle: " << m_bundles[id]->getID() << ", "
+                          << m_bundles[id]->getID() << endl;
+            char *error;
+            dlclose(bundleHandle);
+            if ((error = dlerror()) != NULL)
+            {
+                error_logger() << error << endl;
+            }
+            else
+            {
+                delete m_bundles[id];
+                m_bundles.erase(id);
+            }
+        }
+
+        void ResourceContainerImpl::registerResource(BundleResource *resource)
+        {
+            string strUri = resource->m_uri;
+            string strResourceType = resource->m_resourceType;
+            RCSResourceObject::Ptr server = nullptr;
+
+            info_logger() << "Registration of resource " << strUri << "," << strResourceType << endl;
+
+            if (m_mapResources.find(strUri) == m_mapResources.end())
+            {
+                server = buildResourceObject(strUri, strResourceType);
+
+                if (server != nullptr)
+                {
+                    m_mapServers[strUri] = server;
+                    m_mapResources[strUri] = resource;
+                    m_mapBundleResources[resource->m_bundleId].push_back(strUri);
+
+                    resource->registerObserver(this);
+
+                    server->setGetRequestHandler(
+                        std::bind(&ResourceContainerImpl::getRequestHandler, this,
+                                  std::placeholders::_1, std::placeholders::_2));
+
+                    server->setSetRequestHandler(
+                        std::bind(&ResourceContainerImpl::setRequestHandler, this,
+                                  std::placeholders::_1, std::placeholders::_2));
+
+                    info_logger() << "Registration finished " << strUri << "," << strResourceType
+                                  << endl;
+                }
+            }
+            else
+            {
+                error_logger() << "resource with " << strUri << " already exists." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::unregisterResource(BundleResource *resource)
+        {
+            string strUri = resource->m_uri;
+            string strResourceType = resource->m_resourceType;
+
+            info_logger() << "Unregistration of resource " << resource->m_uri << "," << resource->m_resourceType
+                          << endl;
+
+            if (m_mapServers.find(strUri) != m_mapServers.end())
+            {
+                m_mapServers[strUri].reset();
+
+                m_mapResources.erase(m_mapResources.find(strUri));
+                m_mapBundleResources[resource->m_bundleId].remove(strUri);
+            }
+        }
+
+        void ResourceContainerImpl::getBundleConfiguration(const std::string &bundleId,
+                configInfo *configOutput)
+        {
+            if (m_config)
+            {
+                m_config->getBundleConfiguration(bundleId, (configInfo *) configOutput);
+            }
+        }
+
+        void ResourceContainerImpl::getResourceConfiguration(const std::string &bundleId,
+                std::vector< resourceInfo > *configOutput)
+        {
+            if (m_config)
+            {
+                m_config->getResourceConfiguration(bundleId, configOutput);
+            }
+        }
+
+        RCSGetResponse ResourceContainerImpl::getRequestHandler(const RCSRequest &request,
+                const RCSResourceAttributes &attributes)
+        {
+            RCSResourceAttributes attr;
+
+            if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
+                && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
+            {
+                for (string attrName : m_mapResources[request.getResourceUri()]->getAttributeNames())
+                {
+                    attr[attrName] = m_mapResources[request.getResourceUri()]->getAttribute(
+                                         attrName);
+                }
+            }
+
+            return RCSGetResponse::create(attr);
+        }
+
+        RCSSetResponse ResourceContainerImpl::setRequestHandler(const RCSRequest &request,
+                const RCSResourceAttributes &attributes)
+        {
+            RCSResourceAttributes attr = attributes;
+
+            if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
+                && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
+            {
+                for (string attrName : m_mapResources[request.getResourceUri()]->getAttributeNames())
+                {
+                    if (!attr[attrName].toString().empty())
+                    {
+                        m_mapResources[request.getResourceUri()]->setAttribute(attrName,
+                                attr[attrName].toString());
+                    }
+                }
+            }
+
+            return RCSSetResponse::create(attr);
+        }
+
+        void ResourceContainerImpl::onNotificationReceived(const std::string &strResourceUri)
+        {
+            info_logger() << "ResourceContainerImpl::onNotificationReceived\n\tnotification from "
+                          << strResourceUri << ".\n";
+
+            if (m_mapServers.find(strResourceUri) != m_mapServers.end())
+            {
+                m_mapServers[strResourceUri]->notify();
+            }
+        }
+
+        ResourceContainerImpl *ResourceContainerImpl::getImplInstance()
+        {
+            static ResourceContainerImpl m_instance;
+            return &m_instance;
+        }
+
+        RCSResourceObject::Ptr ResourceContainerImpl::buildResourceObject(const std::string &strUri,
+                const std::string &strResourceType)
+        {
+            return RCSResourceObject::Builder(strUri, strResourceType, "DEFAULT_INTERFACE").setObservable(
+                       true).setDiscoverable(true).build();
+        }
+
+        void ResourceContainerImpl::startBundle(const std::string &bundleId)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+            {
+                if (!m_bundles[bundleId]->isActivated())
+                    activateBundle(m_bundles[bundleId]);
+                else
+                    error_logger() << "Bundle already started" << endl;
+            }
+            else
+            {
+                error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::stopBundle(const std::string &bundleId)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+            {
+                if (m_bundles[bundleId]->isActivated())
+                    deactivateBundle(m_bundles[bundleId]);
+                else
+                    error_logger() << "Bundle not activated" << endl;
+            }
+            else
+            {
+                error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::addBundle(const std::string &bundleId, const std::string &bundleUri,
+                                              const std::string &bundlePath,
+                                              std::map< string, string > params)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+                error_logger() << "BundleId already exist" << endl;
+
+            else
+            {
+                RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
+                bundleInfo->setID(bundleId);
+                bundleInfo->setPath(bundlePath);
+                if (params.find("activator") != params.end())
+                {
+                    string activatorName = params["activator"];
+                    std::replace(activatorName.begin(), activatorName.end(), '.', '/');
+                    ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
+                    ((BundleInfoInternal *) bundleInfo)->setLibraryPath(params["libraryPath"]);
+                }
+
+                info_logger() << "Add Bundle:" << bundleInfo->getID().c_str() << ";"
+                              << bundleInfo->getPath().c_str() << endl;
+
+                registerBundle(bundleInfo);
+            }
+        }
+
+        void ResourceContainerImpl::removeBundle(const std::string &bundleId)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+            {
+                BundleInfoInternal *bundleInfo = m_bundles[bundleId];
+                if (bundleInfo->isActivated())
+                    deactivateBundle(bundleInfo);
+
+                if (bundleInfo->isLoaded())
+                    unregisterBundle(bundleInfo);
+            }
+            else
+            {
+                error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
+                               << endl;
+            }
+        }
+
+        std::list< RCSBundleInfo * > ResourceContainerImpl::listBundles()
+        {
+            std::list< RCSBundleInfo * > ret;
+            for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
+                 it != m_bundles.end(); ++it)
+            {
+                {
+                    RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
+                    ((BundleInfoInternal *) bundleInfo)->setBundleInfo((RCSBundleInfo *) it->second);
+                    ret.push_back(bundleInfo);
+                }
+            }
+            return ret;
+        }
+
+        void ResourceContainerImpl::addResourceConfig(const std::string &bundleId,
+                const std::string &resourceUri,
+                std::map< string, string > params)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+            {
+                if (!m_bundles[bundleId]->getJavaBundle())
+                {
+                    resourceInfo newResourceInfo;
+                    newResourceInfo.uri = resourceUri;
+
+                    if (params.find("name") != params.end())
+                        newResourceInfo.name = params["name"];
+                    if (params.find("resourceType") != params.end())
+                        newResourceInfo.resourceType = params["resourceType"];
+                    if (params.find("address") != params.end())
+                        newResourceInfo.address = params["address"];
+
+                    addSoBundleResource(bundleId, newResourceInfo);
+                }
+            }
+            else
+            {
+                error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
+                               << endl;
+            }
+        }
+
+        void ResourceContainerImpl::removeResourceConfig(const std::string &bundleId,
+                const std::string &resourceUri)
+        {
+            if (m_bundles.find(bundleId) != m_bundles.end())
+            {
+                if (!m_bundles[bundleId]->getJavaBundle())
+                {
+                    removeSoBundleResource(bundleId, resourceUri);
+                }
+            }
+            else
+            {
+                error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
+                               << endl;
+            }
+        }
+
+        std::list< string > ResourceContainerImpl::listBundleResources(const std::string &bundleId)
+        {
+            std::list< string > ret;
+
+            if (m_mapBundleResources.find(bundleId) != m_mapBundleResources.end())
+            {
+                ret = m_mapBundleResources[bundleId];
+            }
+
+            return ret;
+
+        }
+
+        void ResourceContainerImpl::registerSoBundle(RCSBundleInfo *bundleInfo)
+        {
+            char *error;
+
+            activator_t *bundleActivator = NULL;
+            deactivator_t *bundleDeactivator = NULL;
+            resourceCreator_t *resourceCreator = NULL;
+            resourceDestroyer_t *resourceDestroyer = NULL;
+
+            //sstream << bundleInfo.path << std::ends;
+
+            void *bundleHandle = NULL;
+            bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
+
+            if (bundleHandle != NULL)
+            {
+                bundleActivator = (activator_t *) dlsym(bundleHandle, "externalActivateBundle");
+                bundleDeactivator = (deactivator_t *) dlsym(bundleHandle,
+                                    "externalDeactivateBundle");
+                resourceCreator = (resourceCreator_t *) dlsym(bundleHandle,
+                                  "externalCreateResource");
+                resourceDestroyer = (resourceDestroyer_t *) dlsym(bundleHandle,
+                                    "externalDestroyResource");
+
+                if ((error = dlerror()) != NULL)
+                {
+                    error_logger() << error << endl;
+                }
+                else
+                {
+                    ((BundleInfoInternal *) bundleInfo)->setBundleActivator(bundleActivator);
+                    ((BundleInfoInternal *) bundleInfo)->setBundleDeactivator(bundleDeactivator);
+                    ((BundleInfoInternal *) bundleInfo)->setResourceCreator(resourceCreator);
+                    ((BundleInfoInternal *) bundleInfo)->setResourceDestroyer(resourceDestroyer);
+                    ((BundleInfoInternal *) bundleInfo)->setLoaded(true);
+                    ((BundleInfoInternal *) bundleInfo)->setBundleHandle(bundleHandle);
+
+                    m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *) bundleInfo);
+                }
+            }
+            else
+            {
+                if ((error = dlerror()) != NULL)
+                {
+                    error_logger() << error << endl;
+                }
+            }
+        }
+
+        void ResourceContainerImpl::activateSoBundle(const std::string &bundleId)
+        {
+            activator_t *bundleActivator = m_bundles[bundleId]->getBundleActivator();
+
+            if (bundleActivator != NULL)
+            {
+                bundleActivator(this, m_bundles[bundleId]->getID());
+                m_bundles[bundleId]->setActivated(true);
+            }
+            else
+            {
+                //Unload module and return error
+                error_logger() << "Activation unsuccessful." << endl;
+            }
+
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
+            bundleInfoInternal->setActivated(true);
+        }
+
+        void ResourceContainerImpl::deactivateSoBundle(const std::string &id)
+        {
+            deactivator_t *bundleDeactivator = m_bundles[id]->getBundleDeactivator();
+            info_logger() << "De-activating bundle: " << m_bundles[id]->getID() << endl;
+
+            if (bundleDeactivator != NULL)
+            {
+                bundleDeactivator();
+                m_bundles[id]->setActivated(false);
+            }
+            else
+            {
+                //Unload module and return error
+                error_logger() << "De-activation unsuccessful." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::addSoBundleResource(const std::string &bundleId,
+                resourceInfo newResourceInfo)
+        {
+            resourceCreator_t *resourceCreator;
+
+            resourceCreator = m_bundles[bundleId]->getResourceCreator();
+
+            if (resourceCreator != NULL)
+            {
+                resourceCreator(newResourceInfo);
+            }
+            else
+            {
+                error_logger() << "addResource unsuccessful." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::removeSoBundleResource(const std::string &bundleId,
+                const std::string &resourceUri)
+        {
+            if (m_mapResources.find(resourceUri) != m_mapResources.end())
+            {
+                resourceDestroyer_t *resourceDestroyer =
+                    m_bundles[bundleId]->getResourceDestroyer();
+
+                if (resourceDestroyer != NULL)
+                {
+                    resourceDestroyer(m_mapResources[resourceUri]);
+                }
+                else
+                {
+                    error_logger() << "removeResource unsuccessful." << endl;
+                }
+            }
+        }
+
+#if(JAVA_SUPPORT)
+        JavaVM *ResourceContainerImpl::getJavaVM(string bundleId)
+        {
+            return m_bundleVM[bundleId];
+        }
+
+        void ResourceContainerImpl::registerJavaBundle(RCSBundleInfo *bundleInfo)
+        {
+            info_logger() << "Registering Java bundle " << bundleInfo->getID() << endl;
+            JavaVM *jvm;
+            JNIEnv *env;
+            JavaVMInitArgs vm_args;
+            JavaVMOption options[3];
+
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
+
+            if (FILE *file = fopen(bundleInfo->getPath().c_str(), "r"))
+            {
+                fclose(file);
+                info_logger() << "Resource bundle " << bundleInfo->getPath().c_str() << " available." << endl;
+                //return true;
+            }
+            else
+            {
+                error_logger() << "Resource bundle " << bundleInfo->getPath().c_str() << " not available" << endl;
+                return;
+            }
+
+            char optionString[] = "-Djava.compiler=NONE";
+            options[0].optionString = optionString;
+            char classpath[1000];
+            strcpy(classpath, "-Djava.class.path=");
+            strcat(classpath, bundleInfo->getPath().c_str());
+
+            info_logger() << "Configured classpath: " << classpath << "|" << endl;
+
+            options[1].optionString = classpath;
+
+            char libraryPath[1000];
+            strcpy(libraryPath, "-Djava.library.path=");
+            strcat(libraryPath, bundleInfo->getLibraryPath().c_str());
+            options[2].optionString = libraryPath;
+
+            info_logger() << "Configured library path: " << libraryPath << "|" << endl;
+
+            vm_args.version = JNI_VERSION_1_4;
+            vm_args.options = options;
+            vm_args.nOptions = 3;
+            vm_args.ignoreUnrecognized = 1;
+
+            int res;
+            res = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
+
+            if (res < 0)
+            {
+                error_logger() << " cannot create JavaVM." << endl;
+                return;
+            }
+            else
+            {
+                info_logger() << "JVM successfully created " << endl;
+            }
+
+            m_bundleVM.insert(std::pair< string, JavaVM * >(bundleInfo->getID(), jvm));
+
+            const char *className = bundleInfoInternal->getActivatorName().c_str();
+
+            info_logger() << "Looking up class: " << bundleInfoInternal->getActivatorName() << "|" << endl;
+
+            jclass bundleActivatorClass = env->FindClass(className);
+
+            if (bundleActivatorClass == NULL)
+            {
+                error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
+                               << " bundle activator(" << bundleInfoInternal->getActivatorName()
+                               << ") not found " << endl;
+                return;
+            }
+
+            jmethodID activateMethod = env->GetMethodID(bundleActivatorClass, "activateBundle",
+                                       "()V");
+
+            if (activateMethod == NULL)
+            {
+                error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
+                               << " activate bundle method not found " << endl;
+                return;
+            }
+            bundleInfoInternal->setJavaBundleActivatorMethod(activateMethod);
+
+            jmethodID deactivateMethod = env->GetMethodID(bundleActivatorClass, "deactivateBundle",
+                                         "()V");
+
+            if (deactivateMethod == NULL)
+            {
+                error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
+                               << " deactivate bundle method not found " << endl;
+                return;
+            }
+
+            bundleInfoInternal->setJavaBundleDeactivatorMethod(deactivateMethod);
+
+            jmethodID constructor;
+
+            constructor = env->GetMethodID(bundleActivatorClass, "<init>", "(Ljava/lang/String;)V");
+
+            jstring bundleID = env->NewStringUTF(bundleInfoInternal->getID().c_str());
+
+            jobject bundleActivator = env->NewObject(bundleActivatorClass, constructor, bundleID);
+
+            bundleInfoInternal->setJavaBundleActivatorObject(bundleActivator);
+
+            bundleInfoInternal->setLoaded(true);
+
+            m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *)bundleInfo);
+
+            info_logger() << "Bundle registered" << endl;
+        }
+
+        void ResourceContainerImpl::activateJavaBundle(string bundleId)
+        {
+            info_logger() << "Activating java bundle" << endl;
+            JavaVM *vm = getJavaVM(bundleId);
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
+            JNIEnv *env;
+            int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
+
+            if (envStat == JNI_EDETACHED)
+            {
+                if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
+                {
+                    error_logger() << "Failed to attach " << endl;
+                }
+            }
+            else if (envStat == JNI_EVERSION)
+            {
+                error_logger() << "Env: version not supported " << endl;
+            }
+
+            env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
+                                bundleInfoInternal->getJavaBundleActivatorMethod());
+
+            m_bundles[bundleId]->setActivated(true);
+        }
+
+        void ResourceContainerImpl::deactivateJavaBundle(string bundleId)
+        {
+            info_logger() << "Deactivating java bundle" << endl;
+            JavaVM *vm = getJavaVM(bundleId);
+            BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
+            JNIEnv *env;
+            int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
+
+            if (envStat == JNI_EDETACHED)
+            {
+                if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
+                {
+                    error_logger() << "Failed to attach " << endl;
+                }
+            }
+            else if (envStat == JNI_EVERSION)
+            {
+                error_logger() << "Env: version not supported " << endl;
+            }
+
+            env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
+                                bundleInfoInternal->getJavaBundleDeactivatorMethod());
+
+            m_bundles[bundleId]->setActivated(false);
+        }
+
+        void ResourceContainerImpl::unregisterBundleJava(string id)
+        {
+            info_logger() << "Unregister Java bundle: " << m_bundles[id]->getID() << ", "
+                          << m_bundles[id]->getID() << endl;
+
+            info_logger() << "Destroying JVM" << endl;
+            m_bundleVM[id]->DestroyJavaVM();
+
+            delete m_bundles[id];
+            m_bundles.erase(id);
+        }
+#endif
+    }
+
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/src/SoftSensorResource.cpp b/service/resource-encapsulation/src/resourceContainer/src/SoftSensorResource.cpp
new file mode 100644 (file)
index 0000000..7767e11
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// 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 "SoftSensorResource.h"
+#include <algorithm>
+
+using namespace OIC::Service;
+namespace OIC
+{
+    namespace Service
+    {
+        SoftSensorResource::SoftSensorResource()
+        {
+
+        }
+
+        SoftSensorResource::~SoftSensorResource()
+        {
+
+        }
+
+        void SoftSensorResource::initAttributes()
+        {
+            std::vector< std::map< std::string, std::string > >::iterator itor;
+
+            // initialize input attributes
+            for (itor = m_mapResourceProperty["input"].begin(); itor != m_mapResourceProperty["input"].end();
+                 itor++)
+            {
+                m_inputList.push_back((*itor)["name"]);
+                BundleResource::setAttribute((*itor)["name"], nullptr);
+            }
+
+            // initialize output attributes
+            for (itor = m_mapResourceProperty["output"].begin(); itor != m_mapResourceProperty["output"].end();
+                 itor++)
+                BundleResource::setAttribute((*itor)["name"], nullptr);
+        }
+
+        RCSResourceAttributes &SoftSensorResource::getAttributes()
+        {
+            return BundleResource::getAttributes();
+        }
+
+        void SoftSensorResource::setAttribute(std::string key, RCSResourceAttributes::Value &&value)
+        {
+            BundleResource::setAttribute(key, value.toString());
+
+            if (std::find(m_inputList.begin(), m_inputList.end(), key) != m_inputList.end())
+                executeLogic();
+        }
+
+        RCSResourceAttributes::Value SoftSensorResource::getAttribute(const std::string &key)
+        {
+            return BundleResource::getAttribute(key);
+        }
+    }
+}
+
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerInvalidConfig.xml b/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerInvalidConfig.xml
new file mode 100644 (file)
index 0000000..07f42b8
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<container>      
+    <bundle>
+        <id>oic.bundle.test</id>
+        <path>libTestBundle.so</path>
+        <version>1.0.0</version>
+    <!--</bundle>-->
+</container>
\ No newline at end of file
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTest.cpp b/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTest.cpp
new file mode 100644 (file)
index 0000000..f672046
--- /dev/null
@@ -0,0 +1,584 @@
+//******************************************************************
+//
+// 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 <string>
+#include <map>
+#include <vector>
+
+#include <UnitTestHelper.h>
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include "Configuration.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+#include "RCSResourceContainer.h"
+#include "ResourceContainerBundleAPI.h"
+#include "ResourceContainerImpl.h"
+
+#include "RCSResourceObject.h"
+
+using namespace std;
+using namespace testing;
+using namespace OIC::Service;
+
+string CONFIG_FILE = "ResourceContainerTestConfig.xml";
+
+
+/*Fake bundle resource class for testing*/
+class TestBundleResource: public BundleResource
+{
+    public:
+        string getAttribute(string attributeName)
+        {
+            return "test";
+        }
+        ;
+        void setAttribute(string attributeName, string value)
+        {
+        }
+        ;
+        void initAttributes()
+        {
+            BundleResource::setAttribute("attri", "test");
+        }
+        ;
+};
+
+class ResourceContainerTest: public TestWithMock
+{
+
+    public:
+        RCSResourceContainer *m_pResourceContainer;
+
+    protected:
+        void SetUp()
+        {
+            TestWithMock::SetUp();
+            m_pResourceContainer = RCSResourceContainer::getInstance();
+        }
+};
+
+TEST_F(ResourceContainerTest, BundleRegisteredWhenContainerStartedWithValidConfigFile)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+
+    EXPECT_GT(m_pResourceContainer->listBundles().size(), (unsigned int) 0);
+    EXPECT_STREQ("oic.bundle.test",
+                 (*m_pResourceContainer->listBundles().begin())->getID().c_str());
+    EXPECT_STREQ("libTestBundle.so",
+                 (*m_pResourceContainer->listBundles().begin())->getPath().c_str());
+    EXPECT_STREQ("1.0.0", (*m_pResourceContainer->listBundles().begin())->getVersion().c_str());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, BundleLoadedWhenContainerStartedWithValidConfigFile)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+
+    EXPECT_GT(m_pResourceContainer->listBundles().size(), (unsigned int) 0);
+    EXPECT_TRUE(((BundleInfoInternal *)(*m_pResourceContainer->listBundles().begin()))->isLoaded());
+    EXPECT_NE(nullptr,
+              ((BundleInfoInternal *)( *m_pResourceContainer->listBundles().begin()))->getBundleHandle());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, BundleActivatedWhenContainerStartedWithValidConfigFile)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+
+    EXPECT_GT(m_pResourceContainer->listBundles().size(), (unsigned int) 0);
+    EXPECT_TRUE(
+        ((BundleInfoInternal *)(*m_pResourceContainer->listBundles().begin()))->isActivated());
+    EXPECT_NE(nullptr,
+              ((BundleInfoInternal *)( *m_pResourceContainer->listBundles().begin()))->getBundleActivator());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, BundleNotRegisteredWhenContainerStartedWithInvalidConfigFile)
+{
+    m_pResourceContainer->startContainer("invalidConfig");
+
+    EXPECT_EQ((unsigned int) 0, m_pResourceContainer->listBundles().size());
+}
+
+TEST_F(ResourceContainerTest, BundleNotRegisteredWhenContainerStartedWithEmptyConfigFile)
+{
+    m_pResourceContainer->startContainer("");
+
+    EXPECT_EQ((unsigned int) 0, m_pResourceContainer->listBundles().size());
+}
+
+TEST_F(ResourceContainerTest, BundleUnregisteredWhenContainerStopped)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+    m_pResourceContainer->stopContainer();
+
+    EXPECT_EQ((unsigned int) 0, m_pResourceContainer->listBundles().size());
+}
+
+TEST_F(ResourceContainerTest, BundleStoppedWithStartBundleAPI)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+    m_pResourceContainer->stopBundle("oic.bundle.test");
+
+    EXPECT_FALSE(
+        ((BundleInfoInternal *)(*m_pResourceContainer->listBundles().begin()))->isActivated());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, BundleStartedWithStartBundleAPI)
+{
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+    m_pResourceContainer->stopBundle("oic.bundle.test");
+    m_pResourceContainer->startBundle("oic.bundle.test");
+
+    EXPECT_TRUE(
+        ((BundleInfoInternal *)(*m_pResourceContainer->listBundles().begin()))->isActivated());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, AddNewSoBundleToContainer)
+{
+    std::map<string, string> bundleParams;
+    std::list<RCSBundleInfo *> bundles;
+
+    bundles = m_pResourceContainer->listBundles();
+    m_pResourceContainer->addBundle("oic.bundle.test", "", "libTestBundle.so", bundleParams);
+
+    EXPECT_EQ(bundles.size() + 1, m_pResourceContainer->listBundles().size());
+    EXPECT_TRUE(((BundleInfoInternal *)(*m_pResourceContainer->listBundles().begin()))->isLoaded());
+}
+
+TEST_F(ResourceContainerTest, RemoveSoBundleFromContainer)
+{
+    std::map<string, string> bundleParams;
+    std::list<RCSBundleInfo *> bundles;
+
+    bundles = m_pResourceContainer->listBundles();
+    m_pResourceContainer->removeBundle("oic.bundle.test");
+
+    EXPECT_EQ(bundles.size() - 1, m_pResourceContainer->listBundles().size());
+}
+
+TEST_F(ResourceContainerTest, AddBundleAlreadyRegistered)
+{
+    std::map<string, string> bundleParams;
+    std::list<RCSBundleInfo *> bundles;
+
+    m_pResourceContainer->addBundle("oic.bundle.test", "", "libTestBundle.so", bundleParams);
+    bundles = m_pResourceContainer->listBundles();
+    m_pResourceContainer->addBundle("oic.bundle.test", "", "libTestBundle.so", bundleParams);
+
+    EXPECT_EQ(bundles.size(), m_pResourceContainer->listBundles().size());
+}
+
+TEST_F(ResourceContainerTest, AddAndRemoveSoBundleResource)
+{
+    std::list<string> resources;
+    std::map<string, string> resourceParams;
+    resourceParams["resourceType"] = "oic.test";
+
+    m_pResourceContainer->startContainer(CONFIG_FILE);
+    resources = m_pResourceContainer->listBundleResources("oic.bundle.test");
+
+    m_pResourceContainer->addResourceConfig("oic.bundle.test", "/test_resource", resourceParams);
+
+    EXPECT_EQ(resources.size() + 1,
+              m_pResourceContainer->listBundleResources("oic.bundle.test").size());
+
+    m_pResourceContainer->removeResourceConfig("oic.bundle.test", "/test_resource");
+
+    EXPECT_EQ(resources.size(), m_pResourceContainer->listBundleResources("oic.bundle.test").size());
+
+    m_pResourceContainer->stopContainer();
+}
+
+TEST_F(ResourceContainerTest, TryAddingSoBundleResourceToNotRegisteredBundle)
+{
+    std::map<string, string> resourceParams;
+
+    mocks.NeverCallFunc(ResourceContainerImpl::buildResourceObject);
+
+    m_pResourceContainer->addResourceConfig("unvalidBundleId", "", resourceParams);
+}
+
+class ResourceContainerBundleAPITest: public TestWithMock
+{
+
+    public:
+        RCSResourceObject *m_pResourceObject;
+        ResourceContainerBundleAPI *m_pResourceContainer;
+        TestBundleResource *m_pBundleResource;
+
+    protected:
+        void SetUp()
+        {
+            TestWithMock::SetUp();
+            m_pResourceObject = mocks.Mock<RCSResourceObject>();
+            m_pResourceContainer = ResourceContainerBundleAPI::getInstance();
+
+            m_pBundleResource = new TestBundleResource();
+            m_pBundleResource->m_bundleId = "oic.bundle.test";
+            m_pBundleResource->m_uri = "/test_resource";
+            m_pBundleResource->m_resourceType = "oic.test";
+        }
+};
+
+TEST_F(ResourceContainerBundleAPITest, ResourceServerCreatedWhenRegisterResourceCalled)
+{
+    m_pBundleResource = new TestBundleResource();
+    m_pBundleResource->m_bundleId = "oic.bundle.test";
+    m_pBundleResource->m_uri = "/test_resource/test";
+    m_pBundleResource->m_resourceType = "oic.test";
+
+    mocks.ExpectCallFunc(ResourceContainerImpl::buildResourceObject).With(m_pBundleResource->m_uri,
+            m_pBundleResource->m_resourceType).Return(nullptr);
+
+    m_pResourceContainer->registerResource(m_pBundleResource);
+}
+
+TEST_F(ResourceContainerBundleAPITest, RequestHandlerForResourceServerSetWhenRegisterResourceCalled)
+{
+    mocks.OnCallFunc(ResourceContainerImpl::buildResourceObject).Return(
+        RCSResourceObject::Ptr(m_pResourceObject, [](RCSResourceObject *)
+    {}));
+
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setGetRequestHandler);
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setSetRequestHandler);
+
+    m_pResourceContainer->registerResource(m_pBundleResource);
+
+    m_pResourceContainer->unregisterResource(m_pBundleResource);
+}
+
+TEST_F(ResourceContainerBundleAPITest, BundleResourceUnregisteredWhenUnregisterResourceCalled)
+{
+    mocks.OnCallFunc(ResourceContainerImpl::buildResourceObject).Return(
+        RCSResourceObject::Ptr(m_pResourceObject, [](RCSResourceObject *)
+    {}));
+
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setGetRequestHandler);
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setSetRequestHandler);
+
+    m_pResourceContainer->registerResource(m_pBundleResource);
+    m_pResourceContainer->unregisterResource(m_pBundleResource);
+
+    EXPECT_EQ((unsigned int) 0,
+              ((ResourceContainerImpl *)m_pResourceContainer)->listBundleResources(
+                  m_pBundleResource->m_bundleId).size());
+}
+
+TEST_F(ResourceContainerBundleAPITest,
+       ServerNotifiesToObserversWhenNotificationReceivedFromResource)
+{
+    mocks.OnCallFunc(ResourceContainerImpl::buildResourceObject).Return(
+        RCSResourceObject::Ptr(m_pResourceObject, [](RCSResourceObject *)
+    {}));
+
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setGetRequestHandler);
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::setSetRequestHandler);
+
+    m_pResourceContainer->registerResource(m_pBundleResource);
+
+    mocks.ExpectCall(m_pResourceObject, RCSResourceObject::notify);
+
+    m_pResourceContainer->onNotificationReceived(m_pBundleResource->m_uri);
+
+    m_pResourceContainer->unregisterResource(m_pBundleResource);
+}
+
+TEST_F(ResourceContainerBundleAPITest, BundleConfigurationParsedWithValidBundleId)
+{
+    configInfo bundle;
+    map< string, string > results;
+
+    ((ResourceContainerImpl *)m_pResourceContainer)->startContainer(CONFIG_FILE);
+    m_pResourceContainer->getBundleConfiguration("oic.bundle.test", &bundle);
+
+    results = *bundle.begin();
+
+    EXPECT_STREQ("oic.bundle.test", results["id"].c_str());
+    EXPECT_STREQ("libTestBundle.so", results["path"].c_str());
+    EXPECT_STREQ("1.0.0", results["version"].c_str());
+
+    ((ResourceContainerImpl *)m_pResourceContainer)->stopContainer();
+}
+
+TEST_F(ResourceContainerBundleAPITest, BundleResourceConfigurationListParsed)
+{
+    vector< resourceInfo > resourceConfig;
+    resourceInfo result;
+
+    ((ResourceContainerImpl *)m_pResourceContainer)->startContainer(CONFIG_FILE);
+    m_pResourceContainer->getResourceConfiguration("oic.bundle.test", &resourceConfig);
+
+    result = *resourceConfig.begin();
+
+    EXPECT_STREQ("test_resource", result.name.c_str());
+    EXPECT_STREQ("oic.test", result.resourceType.c_str());
+
+    ((ResourceContainerImpl *)m_pResourceContainer)->stopContainer();
+}
+
+class ResourceContainerImplTest: public TestWithMock
+{
+
+    public:
+        ResourceContainerImpl *m_pResourceContainer;
+        RCSBundleInfo *m_pBundleInfo;
+
+    protected:
+        void SetUp()
+        {
+            TestWithMock::SetUp();
+            m_pResourceContainer = ResourceContainerImpl::getImplInstance();
+            m_pBundleInfo = RCSBundleInfo::build();
+        }
+};
+
+TEST_F(ResourceContainerImplTest, SoBundleLoadedWhenRegisteredWithRegisterBundleAPI)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath(".");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+
+    EXPECT_NE(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleHandle());
+}
+
+#if (JAVA_SUPPORT_TEST)
+TEST_F(ResourceContainerImplTest, JavaBundleLoadedWhenRegisteredWithRegisterBundleAPIWrongPath)
+{
+    m_pBundleInfo->setPath("wrong_path.jar");
+    m_pBundleInfo->setActivatorName("org/iotivity/bundle/hue/HueBundleActivator");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setID("oic.bundle.java.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    EXPECT_FALSE(((BundleInfoInternal *)m_pBundleInfo)->isLoaded());
+}
+
+TEST_F(ResourceContainerImplTest, JavaBundleTest)
+{
+    m_pBundleInfo->setPath("TestBundleJava/hue-0.1-jar-with-dependencies.jar");
+    m_pBundleInfo->setActivatorName("org/iotivity/bundle/hue/HueBundleActivator");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setID("oic.bundle.java.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    EXPECT_TRUE(((BundleInfoInternal *)m_pBundleInfo)->isLoaded());
+
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+    EXPECT_TRUE(((BundleInfoInternal *) m_pBundleInfo)->isActivated());
+
+    m_pResourceContainer->deactivateBundle(m_pBundleInfo);
+    EXPECT_FALSE(((BundleInfoInternal *) m_pBundleInfo)->isActivated());
+}
+#endif
+
+TEST_F(ResourceContainerImplTest, BundleNotRegisteredIfBundlePathIsInvalid)
+{
+    m_pBundleInfo->setPath("");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+
+    EXPECT_EQ(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleHandle());
+
+}
+
+TEST_F(ResourceContainerImplTest, SoBundleActivatedWithValidBundleInfo)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+
+    EXPECT_NE(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleActivator());
+}
+
+TEST_F(ResourceContainerImplTest, BundleNotActivatedWhenNotRegistered)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+
+    EXPECT_EQ(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleActivator());
+}
+
+TEST_F(ResourceContainerImplTest, SoBundleActivatedWithBundleID)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    m_pResourceContainer->activateBundle(m_pBundleInfo->getID());
+
+    EXPECT_NE(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleActivator());
+    EXPECT_TRUE(((BundleInfoInternal *)m_pBundleInfo)->isActivated());
+}
+
+TEST_F(ResourceContainerImplTest, BundleDeactivatedWithBundleInfo)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+    m_pResourceContainer->deactivateBundle(m_pBundleInfo);
+
+    EXPECT_NE(nullptr, ((BundleInfoInternal *)m_pBundleInfo)->getBundleDeactivator());
+    EXPECT_FALSE(((BundleInfoInternal *)m_pBundleInfo)->isActivated());
+}
+
+TEST_F(ResourceContainerImplTest, BundleDeactivatedWithBundleInfoJava)
+{
+    m_pBundleInfo->setPath("TestBundle/hue-0.1-jar-with-dependencies.jar");
+    m_pBundleInfo->setActivatorName("org/iotivity/bundle/hue/HueBundleActivator");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setID("oic.bundle.java.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+    m_pResourceContainer->deactivateBundle(m_pBundleInfo);
+    EXPECT_FALSE(((BundleInfoInternal *) m_pBundleInfo)->isActivated());
+}
+
+TEST_F(ResourceContainerImplTest, SoBundleDeactivatedWithBundleID)
+{
+    m_pBundleInfo->setPath("libTestBundle.so");
+    m_pBundleInfo->setVersion("1.0");
+    m_pBundleInfo->setLibraryPath("../.");
+    m_pBundleInfo->setID("oic.bundle.test");
+
+    m_pResourceContainer->registerBundle(m_pBundleInfo);
+    m_pResourceContainer->activateBundle(m_pBundleInfo);
+
+    m_pResourceContainer->deactivateBundle(m_pBundleInfo->getID());
+
+    EXPECT_FALSE(((BundleInfoInternal *)m_pBundleInfo)->isActivated());
+}
+
+/* Test for Configuration */
+TEST(ConfigurationTest, ConfigFileLoadedWithValidPath)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    EXPECT_TRUE(config->isLoaded());
+}
+
+TEST(ConfigurationTest, ConfigFileNotLoadedWithInvalidPath)
+{
+    Configuration *config = new Configuration("InvalidPath");
+
+    EXPECT_FALSE(config->isLoaded());
+}
+
+TEST(ConfigurationTest, BundleConfigurationListParsed)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    configInfo bundles;
+    map< string, string > results;
+
+    config->getConfiguredBundles(&bundles);
+
+    results = *bundles.begin();
+
+    EXPECT_STREQ("oic.bundle.test", results["id"].c_str());
+    EXPECT_STREQ("libTestBundle.so", results["path"].c_str());
+    EXPECT_STREQ("1.0.0", results["version"].c_str());
+}
+
+TEST(ConfigurationTest, BundleConfigurationParsedWithValidBundleId)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    configInfo bundle;
+    map< string, string > results;
+
+    config->getBundleConfiguration("oic.bundle.test", &bundle);
+
+    results = *bundle.begin();
+
+    EXPECT_STREQ("oic.bundle.test", results["id"].c_str());
+    EXPECT_STREQ("libTestBundle.so", results["path"].c_str());
+    EXPECT_STREQ("1.0.0", results["version"].c_str());
+}
+
+TEST(ConfigurationTest, BundleConfigurationNotParsedWithInvalidBundleId)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    configInfo bundles;
+    config->getBundleConfiguration("test", &bundles);
+
+    EXPECT_TRUE(bundles.empty());
+}
+
+TEST(ConfigurationTest, BundleResourceConfigurationListParsed)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    vector< resourceInfo > resourceConfig;
+    resourceInfo result;
+
+    config->getResourceConfiguration("oic.bundle.test", &resourceConfig);
+
+    result = *resourceConfig.begin();
+
+    EXPECT_STREQ("test_resource", result.name.c_str());
+    EXPECT_STREQ("oic.test", result.resourceType.c_str());
+}
+
+TEST(ConfigurationTest, BundleResourceConfigurationNotParsedWithInvalidBundleId)
+{
+    Configuration *config = new Configuration(CONFIG_FILE);
+
+    configInfo bundles;
+    vector< resourceInfo > resourceConfig;
+    config->getResourceConfiguration("test", &resourceConfig);
+
+    EXPECT_TRUE(bundles.empty());
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTestConfig.xml b/service/resource-encapsulation/src/resourceContainer/unittests/ResourceContainerTestConfig.xml
new file mode 100644 (file)
index 0000000..d7e4671
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<container>      
+    <bundle>
+        <id>oic.bundle.test</id>
+        <path>libTestBundle.so</path>
+        <libraryPath>.</libraryPath>
+        <version>1.0.0</version>
+               <resources>
+                       <resourceInfo>
+                               <name>test_resource</name>
+                               <resourceType>oic.test</resourceType>
+                       </resourceInfo>   
+               </resources>
+    </bundle>
+</container>
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/SConscript b/service/resource-encapsulation/src/resourceContainer/unittests/SConscript
new file mode 100644 (file)
index 0000000..7e5d510
--- /dev/null
@@ -0,0 +1,182 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceContainer (rcs_container) Unit Test build script
+##
+import os
+Import('env')
+
+import os.path
+
+containerJavaSupport = ARGUMENTS.get('containerJavaSupport',0)
+
+def filtered_glob(env, pattern, omit=[],
+  ondisk=True, source=False, strings=False):
+    return filter(
+      lambda f: os.path.basename(f.path) not in omit,
+      env.Glob(pattern))
+
+env.AddMethod(filtered_glob, "FilteredGlob");
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+       
+       
+
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+container_gtest_env = lib_env.Clone()
+
+if int(containerJavaSupport):
+       try:
+               print 'Java Home: ', os.environ['JAVA_HOME']
+               print 'Java Lib: ', os.environ['JAVA_LIB']
+               container_gtest_env.Append(CPPDEFINES={'JAVA_SUPPORT_TEST':1})
+       except KeyError:
+               print '''
+       *********************************** Error *************************************
+       * Building resource container without Java support. JAVA_HOME or JAVA_LIB are not set properly 
+       * Please configure JAVA_HOME to point to your Java 7 JDK and 
+       * JAVA_LIB to your folder containing libjvm
+       * Example: export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386
+       *          export JAVA_LIB=/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/server/
+       ******************************************************************************* 
+               '''
+               container_gtest_env.Append(CPPDEFINES={'JAVA_SUPPORT_TEST':0})
+       
+
+target_os = env.get('TARGET_OS')
+
+######################### unit test setting ##########################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+######################################################################
+
+
+######################################################################
+# Build flags
+######################################################################
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+container_gtest_env.AppendUnique(
+       CPPPATH = [
+               env.get('SRC_DIR')+'/extlibs', 
+               '../include',
+               '../../../include',
+               '../include/internal',
+               '../../common/utils/include',
+               '../bundle-api/include'         
+       ])
+
+if int(containerJavaSupport):  
+       try:
+               container_gtest_env.AppendUnique(
+               CPPPATH = [
+                       os.environ['JAVA_HOME']+'/include',
+                       os.environ['JAVA_HOME']+'/include/linux'                
+               ])
+       except KeyError:
+               print ''
+
+if target_os not in ['windows', 'winrt']:
+       container_gtest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+       if target_os != 'android':
+               container_gtest_env.AppendUnique(CXXFLAGS = ['-pthread'])
+               container_gtest_env.AppendUnique(LIBS = ['pthread'])
+
+if target_os == 'android':
+    container_gtest_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    container_gtest_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+
+container_gtest_env.PrependUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+                             gtest_dir + '/include'])
+                       
+if int(containerJavaSupport):
+       try:
+               container_gtest_env.AppendUnique(LIBPATH = [os.environ['JAVA_LIB']])
+       except KeyError:
+               print ''
+
+container_gtest_env.AppendUnique(CCFLAGS = ['-Wnoexcept'])     
+
+container_gtest_env.PrependUnique(LIBS = ['rcs_container', 'rcs_server', 'rcs_common', 'oc','octbstack', 'oc_logger', 'oc_logger_core', 'connectivity_abstraction', gtest, gtest_main])
+
+container_gtest_env.AppendUnique(LIBS = ['dl'])
+
+if int(containerJavaSupport):
+       try:    
+               print 'Java Lib: ', os.environ['JAVA_LIB']
+               container_gtest_env.AppendUnique(LIBS = ['jvm'])                
+       except KeyError:
+               print ''
+
+######################################################################
+# build test bundle
+######################################################################
+test_bundle_env = container_gtest_env.Clone()
+test_bundle_env.AppendUnique(CCFLAGS = ['-fPIC'])
+
+TEST_BUNDLE_DIR = 'TestBundle/'
+test_bundle_env.AppendUnique(CPPPATH = [
+               TEST_BUNDLE_DIR + 'include',
+               '../include/'
+               ])              
+
+test_bundle_src = [ Glob(TEST_BUNDLE_DIR + 'src/*.cpp'), Glob('src/*.cpp')]
+
+TestBundle = test_bundle_env.SharedLibrary('TestBundle', test_bundle_src)
+test_bundle_env.InstallTarget(TestBundle, 'libTestBundle')
+
+
+######################################################################
+# Build Test
+######################################################################
+container_gtest_src = env.Glob('./*.cpp')
+
+container_test = container_gtest_env.Program('container_test', container_gtest_src)
+Alias("container_test", container_test)
+env.AppendTarget('container_test')
+
+# Copy test configuration
+Command("./ResourceContainerTestConfig.xml","./ResourceContainerTestConfig.xml", Copy("$TARGET", "$SOURCE"))
+Ignore("./ResourceContainerTestConfig.xml", "./ResourceContainerTestConfig.xml")
+Command("./ResourceContainerInvalidConfig.xml","./ResourceContainerInvalidConfig.xml", Copy("$TARGET", "$SOURCE"))
+Ignore("./ResourceContainerInvalidConfig.xml", "./ResourceContainerInvalidConfig.xml")
+Command("./TestBundleJava/hue-0.1-jar-with-dependencies.jar","./TestBundleJava/hue-0.1-jar-with-dependencies.jar", Copy("$TARGET", "$SOURCE"))
+Ignore("./TestBundleJava/hue-0.1-jar-with-dependencies.jar", "./TestBundleJava/hue-0.1-jar-with-dependencies.jar")
+
+if env.get('TEST') == '1':
+       target_os = env.get('TARGET_OS')
+       if target_os == 'linux':
+               from tools.scons.RunTest import *
+               run_test(container_gtest_env,
+                       '',
+                       'service/resource-encapsulation/src/resourceContainer/unittests/container_test')
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/include/TestBundleActivator.h b/service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/include/TestBundleActivator.h
new file mode 100644 (file)
index 0000000..5a2e254
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef TESTBUNDLE_H_
+#define TESTBUNDLE_H_
+
+#include <vector>
+
+#include "ResourceContainerBundleAPI.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+
+using namespace OIC::Service;
+
+class TestBundleActivator : public BundleActivator
+{
+    public:
+        TestBundleActivator();
+        ~TestBundleActivator();
+
+        void activateBundle(ResourceContainerBundleAPI *resourceContainer, std::string bundleId);
+        void deactivateBundle();
+
+        void createResource(resourceInfo resourceInfo);
+        void destroyResource(BundleResource *pBundleResource);
+
+        ResourceContainerBundleAPI *m_pResourceContainer;
+        std::string m_bundleId;
+        BundleResource *m_pTestResource;
+};
+
+/*Fake bundle resource class for testing*/
+class TestBundleResource : public BundleResource
+{
+    public:
+        void initAttributes() { };
+};
+
+#endif /* TESTBUNDLE_H_ */
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/src/TestBundleActivator.cpp b/service/resource-encapsulation/src/resourceContainer/unittests/TestBundle/src/TestBundleActivator.cpp
new file mode 100644 (file)
index 0000000..47b1afa
--- /dev/null
@@ -0,0 +1,92 @@
+//******************************************************************
+//
+// 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 "TestBundleActivator.h"
+
+TestBundleActivator *bundle;
+
+TestBundleActivator::TestBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+    m_pTestResource = nullptr;
+}
+
+TestBundleActivator::~TestBundleActivator()
+{
+    m_pResourceContainer = nullptr;
+    m_pTestResource = nullptr;
+}
+
+void TestBundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+        std::string bundleId)
+{
+    std::cout << "TestBundleActivator::activateBundle .. " << std::endl;
+    m_pResourceContainer = resourceContainer;
+    m_bundleId = bundleId;
+}
+
+void TestBundleActivator::deactivateBundle()
+{
+    std::cout << "TestBundleActivator::deactivateBundle .. " << std::endl;
+    m_pResourceContainer = nullptr;
+}
+
+void TestBundleActivator::createResource(resourceInfo resourceInfo)
+{
+    std::cout << "TestBundleActivator::createResource .. " << std::endl;
+
+    TestBundleResource *m_pTestResource = new TestBundleResource();
+
+    m_pTestResource->m_bundleId = m_bundleId;
+    m_pTestResource->m_uri = resourceInfo.uri;
+    m_pTestResource->m_resourceType = resourceInfo.resourceType;
+
+    m_pResourceContainer->registerResource(m_pTestResource);
+}
+
+void TestBundleActivator::destroyResource(BundleResource *pBundleResource)
+{
+    std::cout << "TestBundleActivator::destroyResource .. " << std::endl;
+
+    m_pResourceContainer->unregisterResource(pBundleResource);
+}
+
+extern "C" void externalActivateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                       std::string bundleId)
+{
+    bundle = new TestBundleActivator();
+    bundle->activateBundle(resourceContainer, bundleId);
+}
+
+extern "C" void externalDeactivateBundle()
+{
+    bundle->deactivateBundle();
+    delete bundle;
+}
+
+extern "C" void externalCreateResource(resourceInfo resourceInfo)
+{
+    bundle->createResource(resourceInfo);
+}
+
+extern "C" void externalDestroyResource(BundleResource *pBundleResource)
+{
+    bundle->destroyResource(pBundleResource);
+}
diff --git a/service/resource-encapsulation/src/resourceContainer/unittests/TestBundleJava/hue-0.1-jar-with-dependencies.jar b/service/resource-encapsulation/src/resourceContainer/unittests/TestBundleJava/hue-0.1-jar-with-dependencies.jar
new file mode 100644 (file)
index 0000000..f716b43
Binary files /dev/null and b/service/resource-encapsulation/src/resourceContainer/unittests/TestBundleJava/hue-0.1-jar-with-dependencies.jar differ
diff --git a/service/resource-encapsulation/src/serverBuilder/SConscript b/service/resource-encapsulation/src/serverBuilder/SConscript
new file mode 100755 (executable)
index 0000000..0e20ef6
--- /dev/null
@@ -0,0 +1,114 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# rcs_server (Server Builder) project build script
+##
+import os
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+src_dir = lib_env.get('SRC_DIR')
+
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+server_builder_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+release = env.get('RELEASE')
+
+######################################################################
+# Build flags
+######################################################################
+server_builder_env.AppendUnique(CPPPATH = [
+    '../common/primitiveResource/include',
+    '../../include',
+    ])
+
+server_builder_env.AppendUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs', 'include'])
+
+if target_os not in ['windows', 'winrt']:
+    server_builder_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    if target_os != 'android':
+        server_builder_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os == 'android':
+    server_builder_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    server_builder_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+
+server_builder_env.AppendUnique(LIBS = ['dl'])
+
+if not release:
+    server_builder_env.AppendUnique(CXXFLAGS = ['--coverage'])
+    server_builder_env.PrependUnique(LIBS = ['gcov'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+server_builder_src = env.Glob('src/*.cpp')
+
+server_builder_static = server_builder_env.StaticLibrary('rcs_server', server_builder_src)
+server_builder_shared = server_builder_env.SharedLibrary('rcs_server', server_builder_src)
+
+server_builder_env.InstallTarget([server_builder_static, server_builder_shared], 'rcs_server')
+
+######################################################################
+# Build Test
+######################################################################
+server_builder_test_env = server_builder_env.Clone();
+
+server_builder_test_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+server_builder_test_env.AppendUnique(CPPPATH = [
+    env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+    gtest_dir + '/include',
+    '../common/utils/include'
+    ])
+
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+server_builder_test_env.PrependUnique(LIBS = [
+    'rcs_server',
+    'rcs_common',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    gtest,
+    gtest_main,
+    'pthread',
+    ])
+
+server_builder_test_src = env.Glob('unittests/*.cpp')
+
+server_builder_test = server_builder_test_env.Program('rcs_server_test', server_builder_test_src)
+Alias("rcs_server_test", server_builder_test)
+env.AppendTarget('rcs_server_test')
+
+if env.get('TEST') == '1':
+    target_os = env.get('TARGET_OS')
+    if target_os == 'linux':
+        from tools.scons.RunTest import *
+        run_test(server_builder_test_env, '',
+                'service/resource-encapsulation/src/serverBuilder/rcs_server_test')
diff --git a/service/resource-encapsulation/src/serverBuilder/include/RequestHandler.h b/service/resource-encapsulation/src/serverBuilder/include/RequestHandler.h
new file mode 100644 (file)
index 0000000..0a03f4f
--- /dev/null
@@ -0,0 +1,103 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SERVERBUILDER_REQUESTHANDLER_H
+#define SERVERBUILDER_REQUESTHANDLER_H
+
+#include <RCSResponse.h>
+#include <ResourceAttributesUtils.h>
+
+namespace OC
+{
+    class OCResourceResponse;
+    class OCRepresentation;
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class RCSResourceObject;
+
+        class RequestHandler
+        {
+        private:
+            typedef std::function< std::shared_ptr< OC::OCResourceResponse >(RCSResourceObject&) >
+                        BuildResponseHolder;
+
+        public:
+            typedef std::shared_ptr< RequestHandler > Pre;
+
+            static constexpr int DEFAULT_ERROR_CODE = 200;
+            static constexpr OCEntityHandlerResult DEFAULT_RESULT = OC_EH_OK;
+
+            RequestHandler();
+
+            RequestHandler(const RequestHandler&) = delete;
+            RequestHandler(RequestHandler&&) = default;
+
+            RequestHandler(const OCEntityHandlerResult& result, int errorCode);
+
+            RequestHandler(const RCSResourceAttributes&,
+                    const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE);
+
+            RequestHandler(RCSResourceAttributes&&,
+                    const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE);
+
+
+            virtual ~RequestHandler() { };
+
+            std::shared_ptr< OC::OCResourceResponse > buildResponse(RCSResourceObject&);
+
+        private:
+            const BuildResponseHolder m_holder;
+        };
+
+        class SetRequestHandler: public RequestHandler
+        {
+        public:
+            typedef std::shared_ptr< SetRequestHandler > Ptr;
+
+            SetRequestHandler(const SetRequestHandler&) = delete;
+            SetRequestHandler(SetRequestHandler&&) = default;
+
+            SetRequestHandler();
+
+            SetRequestHandler(const OCEntityHandlerResult& result, int errorCode);
+
+            SetRequestHandler(const RCSResourceAttributes&,
+                    const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE);
+
+            SetRequestHandler(RCSResourceAttributes&&,
+                    const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE);
+
+            AttrKeyValuePairs applyAcceptanceMethod(RCSSetResponse::AcceptanceMethod,
+                    RCSResourceObject&, const RCSResourceAttributes&) const;
+        };
+
+    }
+}
+
+#endif // SERVERBUILDER_REQUESTHANDLER_H
diff --git a/service/resource-encapsulation/src/serverBuilder/src/RCSRequest.cpp b/service/resource-encapsulation/src/serverBuilder/src/RCSRequest.cpp
new file mode 100644 (file)
index 0000000..378e5ed
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// 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 <RCSRequest.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RCSRequest::RCSRequest(const std::string& resourceUri) :
+                m_resourceUri{ resourceUri }
+        {
+        }
+
+        std::string RCSRequest::getResourceUri() const
+        {
+            return m_resourceUri;
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp b/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp
new file mode 100755 (executable)
index 0000000..1d3a0cb
--- /dev/null
@@ -0,0 +1,596 @@
+//******************************************************************
+//
+// 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 <RCSResourceObject.h>
+
+#include <string>
+#include <functional>
+#include <vector>
+
+#include <RequestHandler.h>
+#include <AssertUtils.h>
+#include <ResourceAttributesConverter.h>
+
+#include <logger.h>
+#include <OCPlatform.h>
+
+namespace
+{
+    using namespace OIC::Service;
+
+    constexpr char LOG_TAG[]{ "RCSResourceObject" };
+
+    inline bool hasProperty(uint8_t base, uint8_t target)
+    {
+        return (base & target) == target;
+    }
+
+    inline uint8_t makePropertyFlags(uint8_t base, uint8_t target, bool add)
+    {
+        if (add)
+        {
+            return base | target;
+        }
+
+        return base & ~target;
+    }
+
+    template <typename RESPONSE>
+    OCEntityHandlerResult sendResponse(RCSResourceObject& resource,
+            std::shared_ptr< OC::OCResourceRequest > ocRequest, RESPONSE&& response)
+    {
+        auto ocResponse = response.getHandler()->buildResponse(resource);
+        ocResponse->setRequestHandle(ocRequest->getRequestHandle());
+        ocResponse->setResourceHandle(ocRequest->getResourceHandle());
+
+        try
+        {
+            if (OC::OCPlatform::sendResponse(ocResponse) == OC_STACK_OK)
+            {
+                return OC_EH_OK;
+            }
+        }
+        catch (const OC::OCException& e)
+        {
+            OC_LOG(WARNING, LOG_TAG, e.what());
+        }
+
+        return OC_EH_ERROR;
+    }
+
+    RCSResourceAttributes getAttributesFromOCRequest(
+            std::shared_ptr< OC::OCResourceRequest > request)
+    {
+        return ResourceAttributesConverter::fromOCRepresentation(
+                request->getResourceRepresentation());
+    }
+
+    template< typename HANDLER, typename RESPONSE =
+            typename std::decay<HANDLER>::type::result_type >
+    RESPONSE invokeHandler(RCSResourceAttributes& attrs,
+            std::shared_ptr< OC::OCResourceRequest > ocRequest, HANDLER&& handler)
+    {
+        if (handler)
+        {
+            return handler(RCSRequest{ ocRequest->getResourceUri() }, attrs);
+        }
+
+        return RESPONSE::defaultAction();
+    }
+
+    typedef void (RCSResourceObject::* AutoNotifyFunc)
+            (bool, RCSResourceObject::AutoNotifyPolicy) const;
+
+    std::function <void ()> createAutoNotifyInvoker(AutoNotifyFunc autoNotifyFunc,
+            const RCSResourceObject& resourceObject, const RCSResourceAttributes& resourceAttributes,
+            RCSResourceObject::AutoNotifyPolicy autoNotifyPolicy)
+    {
+        if(autoNotifyPolicy == RCSResourceObject::AutoNotifyPolicy::UPDATED)
+        {
+            auto&& compareAttributesFunc =
+                    std::bind(std::not_equal_to<RCSResourceAttributes>(),
+                                resourceAttributes,
+                                std::cref(resourceAttributes));
+            return std::bind(autoNotifyFunc,
+                    &resourceObject, std::move(compareAttributesFunc), autoNotifyPolicy);
+        }
+        else if(autoNotifyPolicy == RCSResourceObject::AutoNotifyPolicy::ALWAYS)
+        {
+            return std::bind(autoNotifyFunc,
+                    &resourceObject, true, autoNotifyPolicy);
+        }
+        return {};
+    }
+} // unnamed namespace
+
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RCSResourceObject::Builder::Builder(const std::string& uri, const std::string& type,
+                const std::string& interface) :
+                m_uri{ uri },
+                m_type{ type },
+                m_interface{ interface },
+                m_properties{ OC_DISCOVERABLE | OC_OBSERVABLE },
+                m_resourceAttributes{ }
+        {
+        }
+
+        RCSResourceObject::Builder& RCSResourceObject::Builder::setDiscoverable(
+                bool discoverable)
+        {
+            m_properties = ::makePropertyFlags(m_properties, OC_DISCOVERABLE, discoverable);
+            return *this;
+        }
+
+        RCSResourceObject::Builder& RCSResourceObject::Builder::setObservable(
+                bool observable)
+        {
+            m_properties = ::makePropertyFlags(m_properties, OC_OBSERVABLE, observable);
+            return *this;
+        }
+
+        RCSResourceObject::Builder& RCSResourceObject::Builder::setAttributes(
+                const RCSResourceAttributes& attrs)
+        {
+            m_resourceAttributes = attrs;
+            return *this;
+        }
+
+        RCSResourceObject::Builder& RCSResourceObject::Builder::setAttributes(
+                RCSResourceAttributes&& attrs)
+        {
+            m_resourceAttributes = std::move(attrs);
+            return *this;
+        }
+
+        RCSResourceObject::Ptr RCSResourceObject::Builder::build()
+        {
+            OCResourceHandle handle{ nullptr };
+
+            RCSResourceObject::Ptr server {
+                new RCSResourceObject{ m_properties, std::move(m_resourceAttributes) } };
+
+            OC::EntityHandler entityHandler{ std::bind(&RCSResourceObject::entityHandler,
+                    server.get(), std::placeholders::_1) };
+
+            typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&,
+                    const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+
+            invokeOCFunc(static_cast<RegisterResource>(OC::OCPlatform::registerResource),
+                    handle, m_uri, m_type, m_interface, entityHandler, m_properties);
+
+            server->m_resourceHandle = handle;
+
+            return server;
+        }
+
+
+        RCSResourceObject::RCSResourceObject(uint8_t properties, RCSResourceAttributes&& attrs) :
+                m_properties { properties },
+                m_resourceHandle{ },
+                m_resourceAttributes{ std::move(attrs) },
+                m_getRequestHandler{ },
+                m_setRequestHandler{ },
+                m_autoNotifyPolicy { AutoNotifyPolicy::UPDATED },
+                m_setRequestHandlerPolicy { SetRequestHandlerPolicy::NEVER },
+                m_keyAttributesUpdatedListeners{ },
+                m_lockOwner{ },
+                m_mutex{ },
+                m_mutexKeyAttributeUpdate{ }
+        {
+        }
+
+        RCSResourceObject::~RCSResourceObject()
+        {
+            if (m_resourceHandle)
+            {
+                try
+                {
+                    OC::OCPlatform::unregisterResource(m_resourceHandle);
+                }
+                catch (...)
+                {
+                    OC_LOG(WARNING, LOG_TAG, "Failed to unregister resource.");
+                }
+            }
+        }
+
+        template< typename K, typename V >
+        void RCSResourceObject::setAttributeInternal(K&& key, V&& value)
+        {
+            bool needToNotify = false;
+            bool valueUpdated = false;
+
+            {
+                WeakGuard lock(*this);
+
+                if (lock.hasLocked())
+                {
+                    needToNotify = true;
+                    valueUpdated = testValueUpdated(key, value);
+                }
+
+                m_resourceAttributes[std::forward< K >(key)] = std::forward< V >(value);
+            }
+
+            if (needToNotify) autoNotify(valueUpdated);
+        }
+        void RCSResourceObject::setAttribute(const std::string& key,
+                const RCSResourceAttributes::Value& value)
+        {
+            setAttributeInternal(key, value);
+        }
+
+        void RCSResourceObject::setAttribute(const std::string& key,
+                RCSResourceAttributes::Value&& value)
+        {
+            setAttributeInternal(key, std::move(value));
+        }
+
+        void RCSResourceObject::setAttribute(std::string&& key,
+                const RCSResourceAttributes::Value& value)
+        {
+            setAttributeInternal(std::move(key), value);
+        }
+
+        void RCSResourceObject::setAttribute(std::string&& key,
+                RCSResourceAttributes::Value&& value)
+        {
+            setAttributeInternal(std::move(key), std::move(value));
+        }
+
+        RCSResourceAttributes::Value RCSResourceObject::getAttributeValue(
+                const std::string& key) const
+        {
+            WeakGuard lock(*this);
+            return m_resourceAttributes.at(key);
+        }
+
+        bool RCSResourceObject::removeAttribute(const std::string& key)
+        {
+            bool needToNotify = false;
+            bool erased = false;
+            {
+                WeakGuard lock(*this);
+
+                if (m_resourceAttributes.erase(key))
+                {
+                    erased = true;
+                    needToNotify = lock.hasLocked();
+                }
+            }
+
+            if (needToNotify) autoNotify(true);
+
+            return erased;
+        }
+
+        bool RCSResourceObject::containsAttribute(const std::string& key) const
+        {
+            WeakGuard lock(*this);
+            return m_resourceAttributes.contains(key);
+        }
+
+        RCSResourceAttributes& RCSResourceObject::getAttributes()
+        {
+            expectOwnLock();
+            return m_resourceAttributes;
+        }
+
+        const RCSResourceAttributes& RCSResourceObject::getAttributes() const
+        {
+            expectOwnLock();
+            return m_resourceAttributes;
+        }
+
+        void RCSResourceObject::expectOwnLock() const
+        {
+            if (m_lockOwner != std::this_thread::get_id())
+            {
+                throw NoLockException{ "Must acquire the lock first using LockGuard." };
+            }
+        }
+
+        bool RCSResourceObject::isObservable() const
+        {
+            return ::hasProperty(m_properties, OC_OBSERVABLE);
+        }
+
+        bool RCSResourceObject::isDiscoverable() const
+        {
+            return ::hasProperty(m_properties, OC_DISCOVERABLE);
+        }
+
+        void RCSResourceObject::setGetRequestHandler(GetRequestHandler h)
+        {
+            m_getRequestHandler = std::move(h);
+        }
+
+        void RCSResourceObject::setSetRequestHandler(SetRequestHandler h)
+        {
+            m_setRequestHandler = std::move(h);
+        }
+
+        void RCSResourceObject::notify() const
+        {
+            typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle);
+
+            invokeOCFuncWithResultExpect({ OC_STACK_OK, OC_STACK_NO_OBSERVERS },
+                    static_cast< NotifyAllObservers >(OC::OCPlatform::notifyAllObservers),
+                    m_resourceHandle);
+        }
+
+        void RCSResourceObject::addAttributeUpdatedListener(const std::string& key,
+                AttributeUpdatedListener h)
+        {
+            std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+            m_keyAttributesUpdatedListeners[key] = std::move(h);
+        }
+
+        void RCSResourceObject::addAttributeUpdatedListener(std::string&& key,
+                AttributeUpdatedListener h)
+        {
+           std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+           m_keyAttributesUpdatedListeners[std::move(key)] = std::move(h);
+        }
+
+        bool RCSResourceObject::removeAttributeUpdatedListener(const std::string& key)
+        {
+           std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+
+           return m_keyAttributesUpdatedListeners.erase(key) != 0;
+        }
+
+        bool RCSResourceObject::testValueUpdated(const std::string& key,
+                const RCSResourceAttributes::Value& value) const
+        {
+            return m_resourceAttributes.contains(key) == false
+                    || m_resourceAttributes.at(key) != value;
+        }
+
+        void RCSResourceObject::setAutoNotifyPolicy(AutoNotifyPolicy policy)
+        {
+            m_autoNotifyPolicy = policy;
+        }
+
+        RCSResourceObject::AutoNotifyPolicy RCSResourceObject::getAutoNotifyPolicy() const
+        {
+            return m_autoNotifyPolicy;
+        }
+
+        void RCSResourceObject::setSetRequestHandlerPolicy(SetRequestHandlerPolicy policy)
+        {
+            m_setRequestHandlerPolicy = policy;
+        }
+
+        auto RCSResourceObject::getSetRequestHandlerPolicy() const -> SetRequestHandlerPolicy
+        {
+            return m_setRequestHandlerPolicy;
+        }
+
+        void RCSResourceObject::autoNotify(bool isAttributesChanged) const
+        {
+            autoNotify(isAttributesChanged, m_autoNotifyPolicy);
+        }
+
+        void RCSResourceObject::autoNotify(
+                        bool isAttributesChanged, AutoNotifyPolicy autoNotifyPolicy) const
+        {
+            if(autoNotifyPolicy == AutoNotifyPolicy::NEVER) return;
+            if(autoNotifyPolicy == AutoNotifyPolicy::UPDATED &&
+                    isAttributesChanged == false) return;
+
+            notify();
+        }
+
+        OCEntityHandlerResult RCSResourceObject::entityHandler(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            if (!request)
+            {
+                return OC_EH_ERROR;
+            }
+
+            try
+            {
+                if (request->getRequestHandlerFlag() & OC::RequestHandlerFlag::RequestFlag)
+                {
+                    return handleRequest(request);
+                }
+
+                if (request->getRequestHandlerFlag() & OC::RequestHandlerFlag::ObserverFlag)
+                {
+                    return handleObserve(request);
+                }
+            }
+            catch (const std::exception& e)
+            {
+                OC_LOG_V(WARNING, LOG_TAG, "Failed to handle request : %s", e.what());
+                throw;
+            }
+            catch (...)
+            {
+                OC_LOG(WARNING, LOG_TAG, "Failed to handle request.");
+                throw;
+            }
+
+            return OC_EH_ERROR;
+        }
+
+        OCEntityHandlerResult RCSResourceObject::handleRequest(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            assert(request != nullptr);
+
+            if (request->getRequestType() == "GET")
+            {
+                return handleRequestGet(request);
+            }
+
+            if (request->getRequestType() == "PUT")
+            {
+                return handleRequestSet(request);
+            }
+
+            return OC_EH_ERROR;
+        }
+
+        OCEntityHandlerResult RCSResourceObject::handleRequestGet(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            assert(request != nullptr);
+
+            auto attrs = getAttributesFromOCRequest(request);
+
+            return sendResponse(*this, request, invokeHandler(attrs, request, m_getRequestHandler));
+        }
+
+        OCEntityHandlerResult RCSResourceObject::handleRequestSet(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            assert(request != nullptr);
+
+            auto attrs = getAttributesFromOCRequest(request);
+            auto response = invokeHandler(attrs, request, m_setRequestHandler);
+            auto requestHandler = response.getHandler();
+
+            assert(requestHandler != nullptr);
+
+            AttrKeyValuePairs replaced = requestHandler->applyAcceptanceMethod(
+                    response.getAcceptanceMethod(), *this, attrs);
+
+            for (const auto& it : replaced)
+            {
+                std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+
+                auto keyAttribute = m_keyAttributesUpdatedListeners.find(it.first);
+                if(keyAttribute != m_keyAttributesUpdatedListeners.end())
+                {
+                    keyAttribute-> second(it.second, attrs[it.first]);
+                }
+            }
+
+            autoNotify(!replaced.empty(), m_autoNotifyPolicy);
+            return sendResponse(*this, request, response);
+        }
+
+        OCEntityHandlerResult RCSResourceObject::handleObserve(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            assert(request != nullptr);
+
+            if (!isObservable())
+            {
+                return OC_EH_ERROR;
+            }
+
+            return OC_EH_OK;
+        }
+
+        RCSResourceObject::LockGuard::LockGuard(const RCSResourceObject::Ptr ptr) :
+                m_resourceObject(*ptr),
+                m_autoNotifyPolicy{ ptr->getAutoNotifyPolicy() },
+                m_isOwningLock{ false }
+        {
+            init();
+        }
+
+        RCSResourceObject::LockGuard::LockGuard(
+                const RCSResourceObject& serverResource) :
+                m_resourceObject(serverResource),
+                m_autoNotifyPolicy{ serverResource.getAutoNotifyPolicy() },
+                m_isOwningLock{ false }
+        {
+            init();
+        }
+
+        RCSResourceObject::LockGuard::LockGuard(
+                const RCSResourceObject::Ptr ptr, AutoNotifyPolicy autoNotifyPolicy) :
+                m_resourceObject(*ptr),
+                m_autoNotifyPolicy { autoNotifyPolicy },
+                m_isOwningLock{ false }
+        {
+            init();
+        }
+
+        RCSResourceObject::LockGuard::LockGuard(
+                const RCSResourceObject& resourceObject, AutoNotifyPolicy autoNotifyPolicy) :
+                m_resourceObject(resourceObject),
+                m_autoNotifyPolicy { autoNotifyPolicy },
+                m_isOwningLock{ false }
+        {
+            init();
+        }
+
+        RCSResourceObject::LockGuard::~LockGuard()
+        {
+            if (m_autoNotifyFunc) m_autoNotifyFunc();
+
+            if (m_isOwningLock)
+            {
+                m_resourceObject.m_lockOwner = std::thread::id{ };
+                m_resourceObject.m_mutex.unlock();
+            }
+        }
+
+        void RCSResourceObject::LockGuard::init()
+        {
+            if (m_resourceObject.m_lockOwner != std::this_thread::get_id())
+            {
+                m_resourceObject.m_mutex.lock();
+                m_resourceObject.m_lockOwner = std::this_thread::get_id();
+                m_isOwningLock = true;
+            }
+            m_autoNotifyFunc = ::createAutoNotifyInvoker(&RCSResourceObject::autoNotify,
+                    m_resourceObject, m_resourceObject.m_resourceAttributes, m_autoNotifyPolicy);
+        }
+
+        RCSResourceObject::WeakGuard::WeakGuard(
+                const RCSResourceObject& resourceObject) :
+                m_isOwningLock{ false },
+                m_resourceObject(resourceObject)
+        {
+            if (resourceObject.m_lockOwner != std::this_thread::get_id())
+            {
+                m_resourceObject.m_mutex.lock();
+                m_resourceObject.m_lockOwner = std::this_thread::get_id();
+                m_isOwningLock = true;
+            }
+        }
+
+        RCSResourceObject::WeakGuard::~WeakGuard()
+        {
+            if (m_isOwningLock)
+            {
+                m_resourceObject.m_lockOwner = std::thread::id{ };
+                m_resourceObject.m_mutex.unlock();
+            }
+        }
+
+        bool RCSResourceObject::WeakGuard::hasLocked() const
+        {
+            return m_isOwningLock;
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/serverBuilder/src/RCSResponse.cpp b/service/resource-encapsulation/src/serverBuilder/src/RCSResponse.cpp
new file mode 100644 (file)
index 0000000..4151338
--- /dev/null
@@ -0,0 +1,167 @@
+//******************************************************************
+//
+// 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 <RCSResponse.h>
+
+#include <RequestHandler.h>
+
+#include <cassert>
+
+namespace OIC
+{
+    namespace Service
+    {
+        RCSGetResponse RCSGetResponse::defaultAction()
+        {
+            static RCSGetResponse defaultRes { std::make_shared< RequestHandler >() };
+
+            return defaultRes;
+        }
+
+        RCSGetResponse RCSGetResponse::create(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return RCSGetResponse {
+                std::make_shared< RequestHandler >( result, errorCode) };
+        }
+
+        RCSGetResponse RCSGetResponse::create(const RCSResourceAttributes& attrs)
+        {
+            return RCSGetResponse { std::make_shared< RequestHandler >(attrs) };
+        }
+
+        RCSGetResponse RCSGetResponse::create(const RCSResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return RCSGetResponse {
+                std::make_shared< RequestHandler >(attrs, result, errorCode) };
+        }
+
+        RCSGetResponse RCSGetResponse::create(RCSResourceAttributes&& result)
+        {
+            return RCSGetResponse {
+                std::make_shared< RequestHandler >(std::move(result)) };
+        }
+
+        RCSGetResponse RCSGetResponse::create(RCSResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return RCSGetResponse { std::make_shared< RequestHandler >(
+                std::move(attrs), result, errorCode) };
+        }
+
+        RCSGetResponse::RCSGetResponse(std::shared_ptr< RequestHandler >&& handler) :
+                m_handler{ std::move(handler) }
+        {
+            assert(m_handler);
+        }
+
+        RequestHandler* RCSGetResponse::getHandler() const
+        {
+            return m_handler.get();
+        }
+
+
+        RCSSetResponse RCSSetResponse::defaultAction()
+        {
+            return std::make_shared< SetRequestHandler >();
+        }
+
+        RCSSetResponse RCSSetResponse::accept()
+        {
+            return defaultAction().setAcceptanceMethod(AcceptanceMethod::ACCEPT);
+        }
+
+        RCSSetResponse RCSSetResponse::accept(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return create(result, errorCode).setAcceptanceMethod(AcceptanceMethod::ACCEPT);
+        }
+
+        RCSSetResponse RCSSetResponse::ignore()
+        {
+            return defaultAction().setAcceptanceMethod(AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse RCSSetResponse::ignore(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return create(result, errorCode).setAcceptanceMethod(AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse RCSSetResponse::create(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return std::make_shared< SetRequestHandler >(result, errorCode);
+        }
+
+        RCSSetResponse RCSSetResponse::create(const RCSResourceAttributes& attrs)
+        {
+            return std::make_shared< SetRequestHandler >(attrs);
+        }
+
+        RCSSetResponse RCSSetResponse::create(const RCSResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return std::make_shared< SetRequestHandler >(attrs, result, errorCode);
+        }
+
+        RCSSetResponse RCSSetResponse::create(RCSResourceAttributes&& result)
+        {
+            return std::make_shared< SetRequestHandler >(std::move(result));
+        }
+
+        RCSSetResponse RCSSetResponse::create(RCSResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return std::make_shared< SetRequestHandler >(std::move(attrs), result, errorCode);
+        }
+
+        RCSSetResponse::RCSSetResponse(std::shared_ptr< SetRequestHandler >&& handler) :
+                m_acceptanceMethod { AcceptanceMethod::DEFAULT },
+                m_handler{ std::move(handler) }
+        {
+        }
+
+        RCSSetResponse::RCSSetResponse(std::shared_ptr< SetRequestHandler >&& handler,
+                AcceptanceMethod method) :
+                m_acceptanceMethod{ method },
+                m_handler{ std::move(handler) }
+        {
+            assert(m_handler);
+        }
+
+        SetRequestHandler* RCSSetResponse::getHandler() const
+        {
+            return m_handler.get();
+        }
+
+        auto RCSSetResponse::getAcceptanceMethod() const -> AcceptanceMethod
+        {
+            return m_acceptanceMethod;
+        }
+
+        RCSSetResponse& RCSSetResponse::setAcceptanceMethod(AcceptanceMethod method)
+        {
+            m_acceptanceMethod = method;
+            return *this;
+        }
+    }
+}
diff --git a/service/resource-encapsulation/src/serverBuilder/src/RequestHandler.cpp b/service/resource-encapsulation/src/serverBuilder/src/RequestHandler.cpp
new file mode 100644 (file)
index 0000000..b80985b
--- /dev/null
@@ -0,0 +1,181 @@
+//******************************************************************
+//
+// 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 <RequestHandler.h>
+
+#include <OCResourceResponse.h>
+#include <ResourceAttributesConverter.h>
+#include <RCSResourceObject.h>
+
+namespace
+{
+    using namespace OIC::Service;
+
+    typedef std::function< OC::OCRepresentation(RCSResourceObject&) > OCRepresentationGetter;
+
+    OC::OCRepresentation getOCRepresentationFromResource(RCSResourceObject& resource)
+    {
+        RCSResourceObject::LockGuard lock{ resource, RCSResourceObject::AutoNotifyPolicy::NEVER };
+        return ResourceAttributesConverter::toOCRepresentation(resource.getAttributes());
+    }
+
+    OC::OCRepresentation getOCRepresentation(const RCSResourceAttributes& attrs)
+    {
+        return ResourceAttributesConverter::toOCRepresentation(attrs);
+    }
+
+    template< typename T >
+    OCRepresentationGetter wrapGetOCRepresentation(T&& attrs)
+    {
+        return std::bind(getOCRepresentation, std::forward<T>(attrs));
+    }
+
+    std::shared_ptr< OC::OCResourceResponse > doBuildResponse(RCSResourceObject& resource,
+            const OCEntityHandlerResult result, int errorCode, OCRepresentationGetter ocRepGetter)
+    {
+        auto response = std::make_shared< OC::OCResourceResponse >();
+
+        response->setResponseResult(result);
+        response->setErrorCode(errorCode);
+        response->setResourceRepresentation(ocRepGetter(resource));
+
+        return response;
+    }
+
+    AttrKeyValuePairs applyAcceptMethod(RCSResourceObject& resource,
+            const RCSResourceAttributes& requestAttrs)
+    {
+        RCSResourceObject::LockGuard lock(resource, RCSResourceObject::AutoNotifyPolicy::NEVER);
+
+        return replaceAttributes(resource.getAttributes(), requestAttrs);
+    }
+
+    AttrKeyValuePairs applyDefaultMethod(RCSResourceObject& resource,
+            const RCSResourceAttributes& requestAttrs)
+    {
+        RCSResourceObject::LockGuard lock(resource, RCSResourceObject::AutoNotifyPolicy::NEVER);
+
+        if (resource.getSetRequestHandlerPolicy()
+            != RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE
+            && !acceptableAttributes(resource.getAttributes(), requestAttrs))
+        {
+            return AttrKeyValuePairs{ };
+        }
+
+        return replaceAttributes(resource.getAttributes(), requestAttrs);
+    }
+
+    AttrKeyValuePairs applyIgnoreMethod(RCSResourceObject&, const RCSResourceAttributes&)
+    {
+        return AttrKeyValuePairs();
+    }
+
+    auto getApplyAcceptanceFunc(RCSSetResponse::AcceptanceMethod method) ->
+            std::function<AttrKeyValuePairs(RCSResourceObject&, const RCSResourceAttributes&)>
+    {
+        switch (method)
+        {
+            case RCSSetResponse::AcceptanceMethod::DEFAULT:
+                return applyDefaultMethod;
+
+            case RCSSetResponse::AcceptanceMethod::ACCEPT:
+                return applyAcceptMethod;
+
+            case RCSSetResponse::AcceptanceMethod::IGNORE:
+                return applyIgnoreMethod;
+        }
+
+        return applyIgnoreMethod;
+    }
+
+} // unnamed namespace
+
+namespace OIC
+{
+    namespace Service
+    {
+        constexpr int RequestHandler::DEFAULT_ERROR_CODE;
+        constexpr OCEntityHandlerResult RequestHandler::DEFAULT_RESULT;
+
+        RequestHandler::RequestHandler() :
+                m_holder{ std::bind(doBuildResponse, std::placeholders::_1, DEFAULT_RESULT,
+                        DEFAULT_ERROR_CODE, getOCRepresentationFromResource) }
+        {
+        }
+
+        RequestHandler::RequestHandler(const OCEntityHandlerResult& result, int errorCode) :
+                m_holder{ std::bind(doBuildResponse, std::placeholders::_1, result, errorCode,
+                        getOCRepresentationFromResource) }
+        {
+        }
+
+        RequestHandler::RequestHandler(const RCSResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode) :
+                m_holder{ std::bind(doBuildResponse, std::placeholders::_1, result, errorCode,
+                        wrapGetOCRepresentation(attrs)) }
+        {
+        }
+
+        RequestHandler::RequestHandler(RCSResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode) :
+                m_holder{ std::bind(doBuildResponse, std::placeholders::_1, result, errorCode,
+                        wrapGetOCRepresentation(std::move(attrs))) }
+        {
+        }
+
+        std::shared_ptr< OC::OCResourceResponse > RequestHandler::buildResponse(
+                RCSResourceObject& resource)
+        {
+            return m_holder(resource);
+        }
+
+
+        SetRequestHandler::SetRequestHandler() :
+                RequestHandler{ }
+        {
+        }
+
+        SetRequestHandler::SetRequestHandler(const OCEntityHandlerResult& result, int errorCode) :
+                RequestHandler{ result, errorCode }
+        {
+        }
+
+
+        SetRequestHandler::SetRequestHandler(const RCSResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode) :
+                RequestHandler{ attrs, result, errorCode }
+        {
+        }
+
+        SetRequestHandler::SetRequestHandler(RCSResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode) :
+                RequestHandler{ std::move(attrs), result, errorCode }
+        {
+        }
+
+        AttrKeyValuePairs SetRequestHandler::applyAcceptanceMethod(
+                RCSSetResponse::AcceptanceMethod method, RCSResourceObject& resource,
+                const RCSResourceAttributes& requestAttrs) const
+        {
+            return getApplyAcceptanceFunc(method)(resource, requestAttrs);
+        }
+
+    }
+}
diff --git a/service/resource-encapsulation/src/serverBuilder/unittests/RCSResourceObjectTest.cpp b/service/resource-encapsulation/src/serverBuilder/unittests/RCSResourceObjectTest.cpp
new file mode 100755 (executable)
index 0000000..33cfaa6
--- /dev/null
@@ -0,0 +1,665 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <RCSResourceObject.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+using namespace std::placeholders;
+
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*registerResource)(OCResourceHandle&, string&, const string&, const string&,
+                           EntityHandler, uint8_t );
+
+typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle);
+
+constexpr char RESOURCE_URI[]{ "a/test" };
+constexpr char RESOURCE_TYPE[]{ "resourceType" };
+constexpr char KEY[]{ "key" };
+constexpr int value{ 100 };
+
+TEST(ResourceObjectBuilderCreateTest, ThrowIfUriIsInvalid)
+{
+    ASSERT_THROW(RCSResourceObject::Builder("", "", "").build(), PlatformException);
+}
+
+class ResourceObjectBuilderTest: public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        mocks.OnCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(ResourceObjectBuilderTest, RegisterResourceWhenCallCreate)
+{
+    mocks.ExpectCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource))
+            .Return(OC_STACK_OK);
+
+    RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
+}
+
+TEST_F(ResourceObjectBuilderTest, ResourceServerHasPropertiesSetByBuilder)
+{
+    auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
+            setDiscoverable(false).setObservable(true).build();
+
+    EXPECT_FALSE(serverResource->isDiscoverable());
+    EXPECT_TRUE(serverResource->isObservable());
+}
+
+TEST_F(ResourceObjectBuilderTest, ResourceServerHasAttrsSetByBuilder)
+{
+    RCSResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
+            setAttributes(attrs).build();
+
+    RCSResourceObject::LockGuard lock{ serverResource, RCSResourceObject::AutoNotifyPolicy::NEVER };
+    EXPECT_EQ(attrs, serverResource->getAttributes());
+}
+
+
+class ResourceObjectTest: public TestWithMock
+{
+public:
+    RCSResourceObject::Ptr server;
+
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        initMocks();
+
+        server = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
+
+        initResourceObject();
+    }
+
+    virtual void initMocks()
+    {
+        mocks.OnCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource)).
+                Return(OC_STACK_OK);
+
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+    }
+
+    virtual void initResourceObject() {
+        server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
+    }
+};
+
+TEST_F(ResourceObjectTest, AccessAttributesWithLock)
+{
+    {
+        RCSResourceObject::LockGuard lock{ server };
+        auto& attr = server->getAttributes();
+        attr[KEY] = value;
+    }
+
+    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+}
+
+TEST_F(ResourceObjectTest, ThrowIfTryToAccessAttributesWithoutGuard)
+{
+    ASSERT_THROW(server->getAttributes(), NoLockException);
+}
+
+TEST_F(ResourceObjectTest, SettingAttributesWithinGuardDoesntCauseDeadLock)
+{
+    {
+        RCSResourceObject::LockGuard guard{ server };
+        server->setAttribute(KEY, value);
+    }
+
+    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+}
+
+
+class AutoNotifyTest: public ResourceObjectTest
+{
+protected:
+    void initMocks()
+    {
+        mocks.OnCallFuncOverload(static_cast< NotifyAllObservers >(
+                OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+    }
+
+    virtual void initResourceObject() {
+        // intended blank
+    }
+};
+
+TEST_F(AutoNotifyTest, DefalutAutoNotifyPolicyIsUpdated)
+{
+    ASSERT_EQ(RCSResourceObject::AutoNotifyPolicy::UPDATED, server->getAutoNotifyPolicy());
+}
+
+TEST_F(AutoNotifyTest, AutoNotifyPolicyCanBeSet)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
+
+    ASSERT_EQ(RCSResourceObject::AutoNotifyPolicy::NEVER, server->getAutoNotifyPolicy());
+}
+
+TEST_F(AutoNotifyTest, WithUpdatedPolicy_NeverBeNotifiedIfAttributeIsNotChanged)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    server->setAttribute(KEY, value);
+
+    mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers));
+
+    server->setAttribute(KEY, value);
+}
+
+TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfAttributeIsChanged)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    server->setAttribute(KEY, value);
+
+    mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    server->setAttribute(KEY, value + 1);
+}
+
+TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfValueIsAdded)
+{
+    constexpr char newKey[]{ "newKey" };
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+
+    mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    server->setAttribute(newKey, value);
+}
+
+TEST_F(AutoNotifyTest, WithNeverPolicy_NeverBeNotifiedEvenIfAttributeIsChanged)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
+
+    mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers));
+
+    RCSResourceObject::LockGuard lock{ server };
+    server->setAttribute(KEY, value);
+}
+
+TEST_F(AutoNotifyTest, WithUpdatePolicy_WillBeNotifiedIfAttributeIsDeleted)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    server->setAttribute(KEY, value);
+
+    mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    server->removeAttribute(KEY);
+}
+
+class AutoNotifyWithGuardTest: public AutoNotifyTest
+{
+};
+
+TEST_F(AutoNotifyWithGuardTest, GuardFollowsServerPolicyByDefault)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+
+    mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    RCSResourceObject::LockGuard guard{ server };
+    server->setAttribute(KEY, value);
+}
+
+TEST_F(AutoNotifyWithGuardTest, GuardCanOverridePolicy)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::ALWAYS);
+
+    mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers));
+
+    RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::NEVER };
+    server->getAttributes()[KEY] = value;
+}
+
+TEST_F(AutoNotifyWithGuardTest, GuardInvokesNotifyWhenDestroyed)
+{
+    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
+
+    mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
+            OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    {
+        RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::ALWAYS };
+        server->setAttribute(KEY, value);
+    }
+
+    mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
+               OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
+
+    server->setAttribute(KEY, value);
+}
+
+
+
+class ResourceObjectHandlingRequestTest: public ResourceObjectTest
+{
+public:
+    EntityHandler handler;
+
+    static constexpr OCRequestHandle fakeRequestHandle =
+            reinterpret_cast<OCRequestHandle>(0x1234);
+    static constexpr OCResourceHandle fakeResourceHandle =
+            reinterpret_cast<OCResourceHandle>(0x4321);
+
+public:
+    OCResourceRequest::Ptr createRequest(OCMethod method = OC_REST_GET, OCRepresentation ocRep =
+            OCRepresentation{})
+    {
+        auto request = make_shared<OCResourceRequest>();
+
+        OCEntityHandlerRequest ocEntityHandlerRequest { 0 };
+        OC::MessageContainer mc;
+
+        mc.addRepresentation(ocRep);
+
+        ocEntityHandlerRequest.requestHandle = fakeRequestHandle;
+        ocEntityHandlerRequest.resource = fakeResourceHandle;
+        ocEntityHandlerRequest.method = method;
+        ocEntityHandlerRequest.payload = reinterpret_cast<OCPayload*>(mc.getPayload());
+
+        formResourceRequest(OC_REQUEST_FLAG, &ocEntityHandlerRequest, request);
+
+        return request;
+    }
+
+protected:
+    OCStackResult registerResourceFake(OCResourceHandle&, string&, const string&,
+            const string&, EntityHandler handler, uint8_t)
+    {
+        this->handler = handler;
+        return OC_STACK_OK;
+    }
+
+    void initMocks()
+    {
+        mocks.OnCallFuncOverload(
+            static_cast<registerResource>(OCPlatform::registerResource)).Do(
+                    bind(&ResourceObjectHandlingRequestTest::registerResourceFake,
+                            this, _1, _2, _3, _4, _5, _6));
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(ResourceObjectHandlingRequestTest, CallSendResponseWhenReceiveRequest)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, ReturnErrorCodeWhenSendResponseFailed)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_ERROR);
+
+    ASSERT_EQ(OC_EH_ERROR, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithSameHandlesPassedByRequest)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return response->getRequestHandle() == fakeRequestHandle &&
+                        response->getResourceHandle() == fakeResourceHandle;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithRCSResponseResults)
+{
+    constexpr int errorCode{ 1999 };
+    constexpr OCEntityHandlerResult result{ OC_EH_SLOW };
+
+    server->setGetRequestHandler(
+            [](const RCSRequest&, RCSResourceAttributes&) -> RCSGetResponse
+            {
+                return RCSGetResponse::create(result, errorCode);
+            }
+    );
+
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return response->getErrorCode() == errorCode &&
+                        response->getResponseResult() == result;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrsAndResults)
+{
+    constexpr int errorCode{ 1999 };
+    constexpr OCEntityHandlerResult result{ OC_EH_SLOW };
+    constexpr char value[]{ "value" };
+
+    server->setSetRequestHandler(
+            [](const RCSRequest&, RCSResourceAttributes&) -> RCSSetResponse
+            {
+                RCSResourceAttributes attrs;
+                attrs[KEY] = value;
+                return RCSSetResponse::create(attrs, result, errorCode);
+            }
+    );
+
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return value == response->getResourceRepresentation()[KEY].getValue<std::string>()
+                        && response->getErrorCode() == errorCode
+                        && response->getResponseResult() == result;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest(OC_REST_PUT)));
+}
+
+
+class SetRequestHandlerPolicyTest: public ResourceObjectHandlingRequestTest
+{
+public:
+    typedef OCStackResult (*SendResponse)(std::shared_ptr<OCResourceResponse>);
+
+public:
+    OCRepresentation createOCRepresentation()
+    {
+        OCRepresentation ocRep;
+
+        vector<string> interface{"oic.if.baseline"};
+        vector<string> type{"core.light"};
+
+        ocRep.setUri(RESOURCE_URI);
+        ocRep.setResourceInterfaces(interface);
+        ocRep.setResourceTypes(type);
+
+        return ocRep;
+    }
+
+    void initMocks()
+    {
+        ResourceObjectHandlingRequestTest::initMocks();
+        mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(SetRequestHandlerPolicyTest, DefalutSetRequestHandlerPolicyIsNever)
+{
+    ASSERT_EQ(RCSResourceObject::SetRequestHandlerPolicy::NEVER,
+                server->getSetRequestHandlerPolicy());
+}
+
+TEST_F(SetRequestHandlerPolicyTest, SetRequestHandlerPolicyCanBeSet)
+{
+    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
+
+    ASSERT_EQ(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE,
+                server->getSetRequestHandlerPolicy());
+}
+
+TEST_F(SetRequestHandlerPolicyTest, WithNeverPolicy_NotAddedIfReceivedNewKeyValuePair)
+{
+    OCRepresentation ocRep = createOCRepresentation();
+    ocRep.setValue("NewKey", value);
+    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
+
+    handler(createRequest(OC_REST_PUT, ocRep));
+
+    RCSResourceObject::LockGuard guard{ server };
+    ASSERT_FALSE((server->getAttributes()).contains("NewKey"));
+}
+
+TEST_F(SetRequestHandlerPolicyTest, WithAcceptancePolicy_WillBeAddedIfReceivedNewKeyValuePair)
+{
+    OCRepresentation ocRep = createOCRepresentation();
+    ocRep.setValue("NewKey", value);
+    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
+
+    handler(createRequest(OC_REST_PUT, ocRep));
+
+    RCSResourceObject::LockGuard guard{ server };
+    ASSERT_TRUE((server->getAttributes()).contains("NewKey"));
+}
+
+
+class ResourceObjectSynchronizationTest: public ResourceObjectHandlingRequestTest
+{
+public:
+
+    static void withLock(RCSResourceObject::Ptr serverResource, int count)
+    {
+        for (int i=0; i<count; ++i)
+        {
+            RCSResourceObject::LockGuard lock{ serverResource };
+
+            auto& attrs = serverResource->getAttributes();
+
+            attrs[KEY] = attrs[KEY].get<int>() + 1;
+        }
+    }
+
+    static void withSetter(RCSResourceObject::Ptr serverResource, int count)
+    {
+        for (int i=0; i<count; ++i)
+        {
+            RCSResourceObject::LockGuard lock{ serverResource };
+
+            serverResource->setAttribute(KEY, serverResource->getAttribute<int>(KEY) + 1);
+        }
+    }
+};
+
+TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResource)
+{
+    int expected { 0 };
+    vector<thread> threads;
+
+    server->setAttribute(KEY, 0);
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread { withLock, server, count });
+        expected += count;
+    }
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread { withSetter, server, count });
+        expected +=count;
+    }
+
+    for (auto& t : threads)
+    {
+        t.join();
+    }
+
+    ASSERT_EQ(expected, server->getAttribute<int>(KEY));
+}
+
+TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResourceWithRequests)
+{
+    int expected { 0 };
+    vector<thread> threads;
+
+    mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+
+    server->setAttribute(KEY, 0);
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread{ withLock, server, count });
+        expected += count;
+    }
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread{ withSetter, server, count });
+        expected +=count;
+    }
+
+    threads.push_back(thread{
+        [this]()
+        {
+            for (int i=0; i<10000; ++i)
+            {
+                if (i % 5 == 0) handler(createRequest(OC_REST_OBSERVE));
+                handler(createRequest((i & 1) ? OC_REST_GET : OC_REST_PUT));
+            }
+        }
+    });
+
+    for (auto& t : threads)
+    {
+        t.join();
+    }
+
+    ASSERT_EQ(expected, server->getAttribute<int>(KEY));
+}
+
+
+class AttributeUpdatedListenerTest: public ResourceObjectHandlingRequestTest
+{
+public:
+    typedef OCStackResult (*SendResponse)(std::shared_ptr<OCResourceResponse>);
+
+public:
+    OCRepresentation createOCRepresentation(void)
+    {
+        OCRepresentation ocRep;
+
+        vector<string> interface{"oic.if.baseline"};
+        vector<string> type{"core.light"};
+
+        ocRep.setUri(RESOURCE_URI);
+        ocRep.setResourceInterfaces(interface);
+        ocRep.setResourceTypes(type);
+        ocRep[KEY] = value;
+
+        return ocRep;
+    }
+
+    void initMocks()
+    {
+        ResourceObjectHandlingRequestTest::initMocks();
+        mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+    }
+};
+
+class FunctionsForAttributeUpdatedListener
+{
+public:
+    virtual void fCalled(const OIC::Service::RCSResourceAttributes::Value&,
+        const OIC::Service::RCSResourceAttributes::Value&)=0;
+    virtual void fNotCalled(const OIC::Service::RCSResourceAttributes::Value&,
+        const OIC::Service::RCSResourceAttributes::Value&)=0;
+};
+
+TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAddedFunction)
+{
+    FunctionsForAttributeUpdatedListener *ptrMock =
+        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+
+    server->setAttribute(KEY, 0);
+
+    mocks.ExpectCall(ptrMock, FunctionsForAttributeUpdatedListener::fCalled);
+
+    server->addAttributeUpdatedListener(KEY,
+        (std::bind(&FunctionsForAttributeUpdatedListener::fCalled, ptrMock, _1, _2)));
+
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
+}
+
+TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAccordingToLastAddedFunction)
+{
+    FunctionsForAttributeUpdatedListener *ptrMock =
+        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+
+    string duplicateKEY(KEY);
+    server->setAttribute(KEY, 0);
+
+    mocks.ExpectCall(ptrMock, FunctionsForAttributeUpdatedListener::fCalled);
+    mocks.NeverCall(ptrMock, FunctionsForAttributeUpdatedListener::fNotCalled);
+
+    server->addAttributeUpdatedListener(duplicateKEY,
+        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
+    server->addAttributeUpdatedListener(KEY,
+        (std::bind(&FunctionsForAttributeUpdatedListener::fCalled, ptrMock, _1, _2)));
+
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
+}
+
+TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsNotAdded)
+{
+    ASSERT_FALSE(server->removeAttributeUpdatedListener(KEY));
+}
+
+TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsAdded)
+{
+    FunctionsForAttributeUpdatedListener *ptrMock =
+        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+
+    server->addAttributeUpdatedListener(KEY,
+        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
+
+    ASSERT_TRUE(server->removeAttributeUpdatedListener(KEY));
+}
+
+TEST_F(AttributeUpdatedListenerTest, RemoveListenerNeverRunsRemovedFunc)
+{
+    FunctionsForAttributeUpdatedListener *ptrMock =
+        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+
+    mocks.NeverCall(ptrMock, FunctionsForAttributeUpdatedListener::fNotCalled);
+
+    server->setAttribute(KEY, 0);
+    server->addAttributeUpdatedListener(KEY,
+        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
+    server->removeAttributeUpdatedListener(KEY);
+
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
+}
+
+
+
diff --git a/service/resource-encapsulation/src/serverBuilder/unittests/RCSResponseTest.cpp b/service/resource-encapsulation/src/serverBuilder/unittests/RCSResponseTest.cpp
new file mode 100644 (file)
index 0000000..16c7bb5
--- /dev/null
@@ -0,0 +1,198 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <RCSResponse.h>
+#include <RCSResourceObject.h>
+
+#include <RequestHandler.h>
+#include <ResourceAttributesConverter.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*registerResourceSig)(OCResourceHandle&,
+                       string&,
+                       const string&,
+                       const string&,
+                       EntityHandler,
+                       uint8_t );
+
+static constexpr char KEY[] = "key";
+
+
+void EXPECT_RESPONSE(shared_ptr< OCResourceResponse > ocResponse,
+        const OCEntityHandlerResult& result, int errorCode, const RCSResourceAttributes& attrs)
+{
+    EXPECT_EQ(ocResponse->getResponseResult(), result);
+    EXPECT_EQ(ocResponse->getErrorCode(), errorCode);
+    EXPECT_EQ(ResourceAttributesConverter::fromOCRepresentation(
+                    ocResponse->getResourceRepresentation()), attrs);
+}
+
+
+class RCSResponseTest: public TestWithMock
+{
+public:
+    template< typename T >
+    shared_ptr< OCResourceResponse > buildResponse(const T& response)
+    {
+        RCSResourceObject::Ptr server =
+                RCSResourceObject::Builder("a/test", "", "").build();
+
+        return response.getHandler()->buildResponse(*server);
+    }
+
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        mocks.OnCallFuncOverload(static_cast< registerResourceSig >(OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(RCSResponseTest, GetDefaultActionHasEmptyAttrs)
+{
+    EXPECT_RESPONSE(buildResponse(RCSGetResponse::defaultAction()),
+            RequestHandler::DEFAULT_RESULT, RequestHandler::DEFAULT_ERROR_CODE,
+            RCSResourceAttributes());
+}
+
+TEST_F(RCSResponseTest, GetResponseHasResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    EXPECT_RESPONSE(buildResponse(RCSGetResponse::create(result, errorCode)),
+            result, errorCode, RCSResourceAttributes());
+}
+
+TEST_F(RCSResponseTest, GetResponseHasAttrsAndResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    RCSResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    EXPECT_RESPONSE(buildResponse(RCSGetResponse::create(attrs, result, errorCode)),
+            result, errorCode, attrs);
+}
+
+TEST_F(RCSResponseTest, GetResponseCanMoveAttrs)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    RCSResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    RCSResourceAttributes attrsClone;
+    attrsClone[KEY] = 100;
+
+    EXPECT_RESPONSE(
+            buildResponse(RCSGetResponse::create(std::move(attrs), result, errorCode)),
+            result, errorCode, attrsClone);
+
+    EXPECT_TRUE(attrs.empty());
+}
+
+TEST_F(RCSResponseTest, SetDefaultActionHasEmptyAttrs)
+{
+    EXPECT_RESPONSE(buildResponse(RCSSetResponse::defaultAction()),
+            RequestHandler::DEFAULT_RESULT, RequestHandler::DEFAULT_ERROR_CODE,
+            RCSResourceAttributes());
+}
+
+TEST_F(RCSResponseTest, SetResponseHasResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    EXPECT_RESPONSE(buildResponse(RCSSetResponse::create(result, errorCode)),
+            result, errorCode, RCSResourceAttributes());
+}
+
+TEST_F(RCSResponseTest, SetResponseHasAttrsAndResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    RCSResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    EXPECT_RESPONSE(buildResponse(RCSSetResponse::create(attrs, result, errorCode)),
+            result, errorCode, attrs);
+}
+
+TEST_F(RCSResponseTest, SetResponseCanMoveAttrs)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    RCSResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    RCSResourceAttributes attrsClone;
+    attrsClone[KEY] = 100;
+
+    EXPECT_RESPONSE(
+            buildResponse(RCSSetResponse::create(std::move(attrs), result, errorCode)),
+            result, errorCode, attrsClone);
+
+    EXPECT_TRUE(attrs.empty());
+}
+
+
+TEST_F(RCSResponseTest, DefaultSetResponseHasDefaultMethod)
+{
+    EXPECT_EQ(RCSSetResponse::AcceptanceMethod::DEFAULT,
+            RCSSetResponse::defaultAction().getAcceptanceMethod());
+}
+
+TEST_F(RCSResponseTest, AcceptSetResponseHasAcceptMethod)
+{
+    EXPECT_EQ(RCSSetResponse::AcceptanceMethod::ACCEPT,
+            RCSSetResponse::accept().getAcceptanceMethod());
+}
+
+TEST_F(RCSResponseTest, IgnoreSetResponseHasIgnoreMethod)
+{
+    EXPECT_EQ(RCSSetResponse::AcceptanceMethod::IGNORE,
+            RCSSetResponse::ignore().getAcceptanceMethod());
+}
+
+TEST_F(RCSResponseTest, SetResponseHasMethodSetBySetter)
+{
+    RCSSetResponse::AcceptanceMethod method = RCSSetResponse::AcceptanceMethod::ACCEPT;
+    RCSSetResponse response =
+            RCSSetResponse::defaultAction().setAcceptanceMethod(method);
+
+    EXPECT_EQ(method, response.getAcceptanceMethod());
+}
diff --git a/service/resource-encapsulation/src/serverBuilder/unittests/RequestHandlerTest.cpp b/service/resource-encapsulation/src/serverBuilder/unittests/RequestHandlerTest.cpp
new file mode 100644 (file)
index 0000000..9761f3d
--- /dev/null
@@ -0,0 +1,181 @@
+//******************************************************************
+//
+// 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 <UnitTestHelper.h>
+
+#include <RequestHandler.h>
+#include <RCSResourceObject.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+
+using namespace OIC::Service;
+
+constexpr char EXISTING[]{ "ext" };
+constexpr int ORIGIN_VALUE{ 100 };
+
+constexpr int NEW_VALUE{ 1 };
+
+typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&,
+        const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+
+class RequestHandlerTest: public TestWithMock
+{
+public:
+    RCSResourceObject::Ptr server;
+
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        mocks.OnCallFuncOverload(static_cast<RegisterResource>(OC::OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+
+        mocks.OnCallFunc(OC::OCPlatform::unregisterResource).Return(OC_STACK_OK);
+
+        server = RCSResourceObject::Builder("a/test", "resourceType", "").build();
+
+        server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
+        server->setAttribute(EXISTING, ORIGIN_VALUE);
+    }
+};
+
+TEST_F(RequestHandlerTest, ResponseHasSameValuesPassedToHandlerConstructor)
+{
+    RequestHandler handler{ OC_EH_ERROR, -1000 };
+
+    auto response = handler.buildResponse(*server);
+
+    ASSERT_EQ(OC_EH_ERROR, response->getResponseResult());
+    ASSERT_EQ(-1000, response->getErrorCode());
+}
+
+TEST_F(RequestHandlerTest, ResponseHasSameAttrsWithServerAttrs)
+{
+    RequestHandler handler{};
+
+    auto response = handler.buildResponse(*server);
+
+    ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[EXISTING].getValue<int>());
+}
+
+TEST_F(RequestHandlerTest, ResponseHasAttrsSetByCustomAttrRequestHandler)
+{
+    constexpr char key[] { "key" };
+    constexpr int newValue{ 100 };
+
+    RCSResourceAttributes attrs;
+    attrs[key] = newValue;
+    RequestHandler handler{ attrs };
+
+    auto response = handler.buildResponse(*server);
+
+    ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[key].getValue<int>());
+}
+
+
+
+class SetRequestHandlerAcceptanceTest: public RequestHandlerTest
+{
+public:
+    SetRequestHandler::Ptr setRequestHandler;
+
+    RCSResourceAttributes requestAttrs;
+
+protected:
+    void SetUp()
+    {
+        RequestHandlerTest::SetUp();
+
+        setRequestHandler = make_shared< SetRequestHandler >();
+
+        requestAttrs[EXISTING] = NEW_VALUE;
+    }
+};
+
+TEST_F(SetRequestHandlerAcceptanceTest, NothingReplacedWithIgnoreMethod)
+{
+    auto replaced = setRequestHandler->applyAcceptanceMethod(
+            RCSSetResponse::AcceptanceMethod::IGNORE, *server, requestAttrs);
+
+    ASSERT_TRUE(replaced.empty());
+}
+
+
+TEST_F(SetRequestHandlerAcceptanceTest, NewValueApplyedWithAcceptMethod)
+{
+    setRequestHandler->applyAcceptanceMethod(
+            RCSSetResponse::AcceptanceMethod::ACCEPT, *server, requestAttrs);
+
+    ASSERT_EQ(NEW_VALUE, server->getAttribute<int>(EXISTING));
+}
+
+TEST_F(SetRequestHandlerAcceptanceTest, ReturnedAttrPairsHaveOldValue)
+{
+    auto replaced = setRequestHandler->applyAcceptanceMethod(
+            RCSSetResponse::AcceptanceMethod::ACCEPT, *server, requestAttrs);
+
+    ASSERT_EQ(ORIGIN_VALUE, replaced[0].second);
+}
+
+TEST_F(SetRequestHandlerAcceptanceTest, NothingHappenedWithEmptyAttrs)
+{
+    setRequestHandler->applyAcceptanceMethod(
+            RCSSetResponse::AcceptanceMethod::ACCEPT, *server, RCSResourceAttributes{ });
+
+    ASSERT_EQ(ORIGIN_VALUE, server->getAttribute<int>(EXISTING));
+}
+
+TEST_F(SetRequestHandlerAcceptanceTest, EverythingAppliedIfMethodIsAccept)
+{
+    requestAttrs[EXISTING] = "";
+
+    auto replaced = setRequestHandler->applyAcceptanceMethod(
+             RCSSetResponse::AcceptanceMethod::ACCEPT, *server, requestAttrs);
+
+     ASSERT_EQ(ORIGIN_VALUE, replaced[0].second);
+}
+
+
+TEST_F(SetRequestHandlerAcceptanceTest, NoReplaceIfMethodIsDefaultAndTypeMismatch)
+{
+    requestAttrs[EXISTING] = "";
+
+    auto replaced = setRequestHandler->applyAcceptanceMethod(
+             RCSSetResponse::AcceptanceMethod::DEFAULT, *server, requestAttrs);
+
+     ASSERT_TRUE(replaced.empty());
+}
+
+TEST_F(SetRequestHandlerAcceptanceTest, NoReplacefMethodIsDefaultAndRequestAttrsHasUnknownKey)
+{
+    constexpr char unknownKey[]{ "???" };
+
+    requestAttrs[EXISTING] = ORIGIN_VALUE;
+    requestAttrs[unknownKey] = ORIGIN_VALUE;
+
+
+    auto replaced = setRequestHandler->applyAcceptanceMethod(
+             RCSSetResponse::AcceptanceMethod::DEFAULT, *server, requestAttrs);
+
+     ASSERT_TRUE(replaced.empty());
+}
diff --git a/service/resource-encapsulation/unittests/ResourceClientTest.cpp b/service/resource-encapsulation/unittests/ResourceClientTest.cpp
new file mode 100644 (file)
index 0000000..c51d1a5
--- /dev/null
@@ -0,0 +1,347 @@
+//******************************************************************
+//
+// 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 "UnitTestHelper.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSDiscoveryManager.h"
+#include "RCSResourceObject.h"
+#include "PrimitiveResource.h"
+#include <condition_variable>
+
+#include <mutex>
+
+using namespace OIC::Service;
+using namespace OC;
+
+constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
+constexpr char RESOURCETYPE[]{ "Resource.Hosting" };
+constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
+
+constexpr char ATTR_KEY[]{ "Temperature" };
+constexpr int ATTR_VALUE{ 0 };
+
+constexpr int DEFAULT_WAITING_TIME_IN_MILLIS = 3000;
+
+void getRemoteAttributesCallback(const RCSResourceAttributes&) {}
+void setRemoteAttributesCallback(const RCSResourceAttributes&) {}
+void resourceStateChanged(ResourceState) { }
+void cacheUpdatedCallback(const RCSResourceAttributes&) {}
+
+class RemoteResourceObjectTest: public TestWithMock
+{
+public:
+    RCSResourceObject::Ptr server;
+    RCSRemoteResourceObject::Ptr object;
+    std::shared_ptr< bool > finished;
+
+public:
+    void Proceed()
+    {
+        cond.notify_all();
+    }
+
+    void Wait(int waitingTime = DEFAULT_WAITING_TIME_IN_MILLIS)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        finished = std::make_shared< bool >(false);
+
+        CreateResource();
+
+        WaitUntilDiscovered();
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+
+        // This method is to make sure objects disposed.
+        WaitForPtrBeingUnique();
+
+        *finished = true;
+    }
+
+private:
+    void CreateResource()
+    {
+        server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
+        server->setAttribute(ATTR_KEY, ATTR_VALUE);
+    }
+
+    bool checkObject()
+    {
+        std::lock_guard<std::mutex> lock{ mutexForObject };
+        return object == nullptr;
+    }
+
+    void WaitUntilDiscovered()
+    {
+        while (checkObject())
+        {
+            RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(),
+                    "/oic/res?rt=Resource.Hosting", std::bind(resourceDiscovered, this, finished,
+                            std::placeholders::_1));
+
+            Wait(1000);
+        }
+    }
+
+    void WaitForPtrBeingUnique()
+    {
+        while((object && !object.unique()) || (server && !server.unique()))
+        {
+            std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
+        }
+    }
+
+    // This callback is to protect crash from crashes caused by delayed callbacks
+    static void resourceDiscovered(RemoteResourceObjectTest* test,
+            std::shared_ptr< bool > finished, RCSRemoteResourceObject::Ptr resourceObject)
+    {
+        if (*finished) return;
+
+        {
+            std::lock_guard< std::mutex > lock{ test->mutexForObject };
+
+            if (test->object) return;
+
+            test->object = resourceObject;
+        }
+
+        test->Proceed();
+    }
+
+private:
+    std::condition_variable cond;
+    std::mutex mutex;
+    std::mutex mutexForObject;
+};
+
+TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction)
+{
+    ASSERT_THROW(object->getRemoteAttributes({ }), InvalidParameterException);
+}
+
+TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer)
+{
+    mocks.ExpectCallFunc(getRemoteAttributesCallback).Match(
+            [this](const RCSResourceAttributes& attrs)
+            {
+                RCSResourceObject::LockGuard lock{ server };
+                return attrs == server->getAttributes();
+            }
+    ).Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    object->getRemoteAttributes(getRemoteAttributesCallback);
+
+    Wait();
+}
+
+TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction)
+{
+    ASSERT_THROW(object->setRemoteAttributes({ }, { }), InvalidParameterException);
+}
+
+TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer)
+{
+    constexpr int newValue = ATTR_VALUE + 1;
+    RCSResourceAttributes newAttrs;
+    newAttrs[ATTR_KEY] = newValue;
+
+    mocks.ExpectCallFunc(setRemoteAttributesCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback);
+    Wait();
+
+    ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY));
+}
+
+TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault)
+{
+    ASSERT_FALSE(object->isMonitoring());
+}
+
+TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty)
+{
+    ASSERT_THROW(object->startMonitoring({ }), InvalidParameterException);
+}
+
+TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring)
+{
+    object->startMonitoring(resourceStateChanged);
+
+    ASSERT_TRUE(object->isMonitoring());
+}
+
+TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain)
+{
+    object->startMonitoring(resourceStateChanged);
+
+    ASSERT_THROW(object->startMonitoring(resourceStateChanged), BadRequestException);
+}
+
+TEST_F(RemoteResourceObjectTest, DefaultStateIsNone)
+{
+    ASSERT_EQ(ResourceState::NONE, object->getState());
+}
+
+TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault)
+{
+    ASSERT_FALSE(object->isCaching());
+}
+
+TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching)
+{
+    object->startCaching(cacheUpdatedCallback);
+
+    ASSERT_TRUE(object->isCaching());
+}
+
+TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain)
+{
+    object->startCaching(cacheUpdatedCallback);
+
+    ASSERT_THROW(object->startCaching(), BadRequestException);
+}
+
+TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone)
+{
+    ASSERT_EQ(CacheState::NONE, object->getCacheState());
+}
+
+TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
+{
+    object->startCaching();
+
+    ASSERT_EQ(CacheState::UNREADY, object->getCacheState());
+}
+
+TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
+{
+    mocks.ExpectCallFunc(cacheUpdatedCallback).
+                Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    ASSERT_EQ(CacheState::READY, object->getCacheState());
+}
+
+TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
+{
+    mocks.ExpectCallFunc(cacheUpdatedCallback).
+                Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    ASSERT_TRUE(object->isCachedAvailable());
+}
+
+TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
+{
+    mocks.OnCallFunc(cacheUpdatedCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    mocks.ExpectCallFunc(cacheUpdatedCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
+
+    Wait();
+}
+
+TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes)
+{
+    constexpr int newValue = ATTR_VALUE + 1;
+
+    mocks.OnCallFunc(cacheUpdatedCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    mocks.ExpectCallFunc(cacheUpdatedCallback).
+            Match([this](const RCSResourceAttributes& attrs){
+                return attrs.at(ATTR_KEY) == newValue;
+            }).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+
+    server->setAttribute(ATTR_KEY, newValue);
+
+    Wait();
+}
+
+TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
+{
+    ASSERT_THROW(object->getCachedAttributes(), BadRequestException);
+}
+
+TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
+{
+    mocks.OnCallFunc(cacheUpdatedCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    RCSResourceObject::LockGuard lock{ server };
+
+    ASSERT_EQ(object->getCachedAttributes(), server->getAttributes());
+}
+
+TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
+{
+    ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), BadRequestException);
+}
+
+TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
+{
+    mocks.OnCallFunc(cacheUpdatedCallback).
+            Do([this](const RCSResourceAttributes&){ Proceed(); });
+    object->startCaching(cacheUpdatedCallback);
+    Wait();
+
+    ASSERT_THROW(object->getCachedAttribute(""), InvalidKeyException);
+}
+
+TEST_F(RemoteResourceObjectTest, HasSameUriWithServer)
+{
+    EXPECT_EQ(RESOURCEURI, object->getUri());
+}
+
+TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer)
+{
+    EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]);
+}
+
+TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer)
+{
+    EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]);
+}
+
diff --git a/service/resource-encapsulation/unittests/SConscript b/service/resource-encapsulation/unittests/SConscript
new file mode 100755 (executable)
index 0000000..ddea23a
--- /dev/null
@@ -0,0 +1,109 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceClient Unit Test build script
+##
+import os
+Import('env')
+
+if env.get('RELEASE'):
+        env.AppendUnique(CCFLAGS = ['-Os'])
+        env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+        env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+        env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+target_os = env.get('TARGET_OS')
+if target_os == 'linux':
+        # Verify that 'google unit test' library is installed.  If not,
+        # get it and install it
+        SConscript(env.get('SRC_DIR') + '/extlibs/gtest/SConscript')
+
+        # Verify that 'hippomocks' mocking code is installed.  If not,
+        # get it and install it
+        SConscript(env.get('SRC_DIR') + '/extlibs/hippomocks.scons')
+
+ResourceClient_gtest_env = lib_env.Clone()
+
+######################################################################
+#unit test setting
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+######################################################################
+# Build flags
+######################################################################
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+ResourceClient_gtest_env.AppendUnique(
+        CPPPATH = [
+                src_dir + '/extlibs/hippomocks-master', 
+                src_dir + '/extlibs/gtest/gtest-1.7.0/include',
+                '../include',
+                '../src/common/utils/include',
+                '../src/serverBuilder/include',
+                '../src/common/primitiveResource/include',
+                '../src/common/include/expiryTimer'
+        ])
+
+if target_os not in ['windows', 'winrt']:
+        ResourceClient_gtest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+        if target_os != 'android':
+                ResourceClient_gtest_env.AppendUnique(CXXFLAGS = ['-pthread'])
+                ResourceClient_gtest_env.AppendUnique(LIBS = ['pthread'])
+
+ResourceClient_gtest_env.PrependUnique(LIBS = [
+    'rcs_client',
+    'rcs_server',
+    'rcs_common',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'oc_logger_core',
+    'connectivity_abstraction',
+    gtest,
+    gtest_main])
+
+ResourceClient_gtest_env.AppendUnique(LIBS = ['dl'])   
+
+######################################################################
+# Build Test
+######################################################################
+ResourceClient_gtest_src = env.Glob('./*.cpp')
+
+ResourceClient_test = ResourceClient_gtest_env.Program('ResourceClientTest', ResourceClient_gtest_src)
+Alias("ResourceClientTest", ResourceClient_test)
+env.AppendTarget('ResourceClient_test')
+
+if env.get('TEST') == '1':
+    target_os = env.get('TARGET_OS')
+    if target_os == 'linux':
+        from tools.scons.RunTest import *
+        run_test(ResourceClient_gtest_env, '',
+                'service/resource-encapsulation/unittests/ResourceClientTest')
\ No newline at end of file
index 1a645ef..fe54d61 100644 (file)
@@ -70,6 +70,7 @@ libssmsdk = sdk_env.StaticLibrary(
                source = [ssm_sdk_cpp_src]
                )
 sdk_env.InstallTarget(libssmsdk, 'libSSMCORE')
+sdk_env.UserInstallTargetLib(libssmsdk, 'libSSMCORE')
 
 ######################################################################
 # build DiscomfortIndexSensor plugin
@@ -87,6 +88,7 @@ DiscomfortIndexSensor_src = [ Glob(DISCOMFORTINDEXSENSOR_DIR + 'src/*.cpp')]
 
 DiscomfortIndexSensor = DiscomfortIndexSensor_env.SharedLibrary('DiscomfortIndexSensor', DiscomfortIndexSensor_src)
 DiscomfortIndexSensor_env.InstallTarget(DiscomfortIndexSensor, 'libDiscomfortIndexSensor')
+DiscomfortIndexSensor_env.UserInstallTargetLib(DiscomfortIndexSensor, 'libDiscomfortIndexSensor')
 
 
 
@@ -107,6 +109,7 @@ BMISensor_src = [ Glob(BMISENSOR_DIR + 'src/*.cpp')]
 
 BMISensor = BMISensor_env.SharedLibrary('BMISensor', BMISensor_src)
 BMISensor_env.InstallTarget(BMISensor, 'libBMISensor')
+BMISensor_env.UserInstallTargetLib(BMISensor, 'libBMISensor')
 
 
 
@@ -162,6 +165,7 @@ shared_libssmcore = ssmcore_env.SharedLibrary(
                )
 
 ssmcore_env.InstallTarget([shared_libssmcore, static_libssmcore], 'libSSMCORE')
+ssmcore_env.UserInstallTargetLib([shared_libssmcore, static_libssmcore], 'libSSMCORE')
 
 #######################################################################
 ## build SampleApp
index 7399891..4392b8f 100644 (file)
@@ -137,13 +137,14 @@ SSMRESULT CQueryEngine::processQueryResult(int userTriggerId,
 
         for (unsigned int j = 0; j < (result_model_data_id)[i].dataId.size(); j++)
         {
-            CModelData *pModelData = new CModelData();
+            CModelData *pModelData = NULL;
             IContextModel       *pCM = NULL;
             ModelPropertyVec    modelPropertyVec;
 
             SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel((result_model_data_id)[i].modelName,
                                &pCM));
             SSM_CLEANUP_ASSERT(pCM->getModelData((result_model_data_id)[i].dataId[j], &modelPropertyVec));
+            pModelData = new CModelData();
             pModelData->setDataId((result_model_data_id)[i].dataId[j]);
             for (ModelPropertyVec::iterator itor = modelPropertyVec.begin();
                  itor != modelPropertyVec.end(); ++itor)
@@ -162,6 +163,7 @@ SSMRESULT CQueryEngine::processQueryResult(int userTriggerId,
     pData[0] = EVENT_TYPE_OUTER;
     pData[1] = userTriggerId;
     pData[2] = reinterpret_cast<intptr_t>(pDataReader);
+    pDataReader = NULL;
 
     m_pTasker->addTask(this, (void *)pData);
 
@@ -169,6 +171,7 @@ SSMRESULT CQueryEngine::processQueryResult(int userTriggerId,
 
 CLEANUP:
     m_mtxQueries.unlock();
+    SAFE_DELETE(pDataReader);
     SAFE_RELEASE(temp_contextmodel);
     SAFE_RELEASE(temp_contextmodel2);
     return res;
@@ -318,6 +321,7 @@ SSMRESULT CQueryEngine::executeContextQuery(std::string contextQuery, int *cqid)
     pConditionedQuery->addRef();
     m_conditionedQueries[m_cqid] = pConditionedQuery;
     m_contextQueries[m_cqid] = clsContextQuery;
+    clsContextQuery = NULL; //Mark it NULL, so that it's not freed in CLEANUP.
     m_mtxQueries.unlock();
 
     if (pConditionedQuery->hasAllConditionedModels() == true)
@@ -366,6 +370,7 @@ SSMRESULT CQueryEngine::executeContextQuery(std::string contextQuery, int *cqid)
 CLEANUP:
     SAFE_RELEASE(pConditionedQuery);
     SAFE_RELEASE(pConditionedQueryResult);
+    SAFE_DELETE(clsContextQuery);
     return res;
 }
 
index 73cbe58..2c33279 100644 (file)
@@ -53,17 +53,20 @@ class ISSMResource
         ISSMResource()
         {
             location = SENSOR_LOCATION_LOCAL;
+            connectivityType = 0;
         }
         ISSMResource(const std::string &n, const std::string &t) :
             name(n), type(t)
         {
-               location = SENSOR_LOCATION_LOCAL;
+            location = SENSOR_LOCATION_LOCAL;
+            connectivityType = 0;
         }
         SENSOR_LOCATION location;
         std::string name;
         std::string type;
         std::string friendlyName;
         std::string ip;
+        int connectivityType;
         std::vector<std::string> inputList;
         std::vector<std::map<std::string, std::string> > outputProperty;
 };
index 7541ee7..a4c51d9 100644 (file)
@@ -19,6 +19,8 @@
  ******************************************************************/
 #include "ResourceFinder.h"
 
+OCConnectivityType g_connectivityType = CT_DEFAULT;
+
 SSMRESULT CResourceFinder::finalConstruct()
 {
     SSMRESULT res = SSM_E_FAIL;
@@ -76,9 +78,9 @@ void CResourceFinder::presenceHandler(OCStackResult result, const unsigned int n
     switch (result)
     {
         case OC_STACK_OK:
-            requestURI << "coap://" << hostAddress << "/oc/core?rt=SSManager.Sensor";
+            requestURI << "coap://" << hostAddress << OC_RSRVD_WELL_KNOWN_URI << "?rt=SSManager.Sensor";
 
-            ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ALL,
+            ret = OC::OCPlatform::findResource("", requestURI.str(), g_connectivityType,
                                                std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
 
             if (ret != OC_STACK_OK)
@@ -105,7 +107,7 @@ void CResourceFinder::presenceHandler(OCStackResult result, const unsigned int n
         case OC_STACK_PRESENCE_TIMEOUT:
             break;
 
-        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
+        case OC_STACK_PRESENCE_DO_NOT_HANDLE:
             break;
 
         default:
@@ -122,19 +124,19 @@ SSMRESULT CResourceFinder::startResourceFinder()
     OCStackResult ret = OC_STACK_ERROR;
 
     std::ostringstream requestURI;
-    requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=SSManager.Sensor";
+    requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=SSManager.Sensor";
 
     std::ostringstream multicastPresenceURI;
     multicastPresenceURI << "coap://" << OC_MULTICAST_PREFIX;
 
-    ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ALL,
+    ret = OC::OCPlatform::findResource("", requestURI.str(), g_connectivityType,
                                        std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
 
     if (ret != OC_STACK_OK)
         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
 
     ret = OC::OCPlatform::subscribePresence(m_multicastPresenceHandle, multicastPresenceURI.str(),
-                                            "SSManager.Sensor", OC_ALL, std::bind(&CResourceFinder::presenceHandler, this,
+                                            "SSManager.Sensor", g_connectivityType, std::bind(&CResourceFinder::presenceHandler, this,
                                                     std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
 
     if (ret != OC_STACK_OK)
@@ -192,7 +194,13 @@ void CResourceFinder::onExecute(void *pArg)
         case RESOURCE_DISCOVER_REQUESTPROFILE:
             pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
             pResourceHandler = new OICResourceHandler();
-            SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
+
+            res = pResourceHandler->initHandler(*pResource, this);
+            if (res != SSM_S_OK)
+            {
+                SAFE_DELETE(pResourceHandler);
+                SSM_CLEANUP_ASSERT(res);
+            }
 
             resourceFullPath = pResource->get()->host() + pResource->get()->uri();
 
@@ -216,8 +224,9 @@ void CResourceFinder::onExecute(void *pArg)
                 m_mapResourcePresenceHandles.end())
             {
                 ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
-                                                        "SSManager.Sensor", OC_ALL, std::bind(&CResourceFinder::presenceHandler, this,
-                                                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+                                                        "SSManager.Sensor", (OCConnectivityType)(((ISSMResource *)pMessage[1])->connectivityType),
+                                                        std::bind(&CResourceFinder::presenceHandler, this, std::placeholders::_1, std::placeholders::_2,
+                                                                std::placeholders::_3));
 
                 if (ret != OC_STACK_OK)
                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
@@ -227,9 +236,6 @@ void CResourceFinder::onExecute(void *pArg)
 
             m_pResourceFinderEvent->onResourceFound((ISSMResource *)pMessage[1]);
 
-            if (ret != OC_STACK_OK)
-                SSM_CLEANUP_ASSERT(SSM_E_FAIL);
-
             break;
 
         case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
index d9ea15f..8aa7fc0 100644 (file)
@@ -146,7 +146,7 @@ CLEANUP: return res;
                 }
 
                 void onGetResourceProfile(const OC::HeaderOptions &headerOptions,
-                                          const OC::OCRepresentation &representation, const int &eCode)
+                                          const OC::OCRepresentation &representation, const int eCode)
                 {
                     //unpack attributeMap
 
@@ -156,6 +156,7 @@ CLEANUP: return res;
                     m_SSMResource.name = m_pResource->host() + m_pResource->uri();
                     m_SSMResource.type = m_pResource->uri().substr(1);
                     m_SSMResource.ip = m_pResource->host();
+                    m_SSMResource.connectivityType = m_pResource->connectivityType();
 
                     //bind default properties
                     outputProperty["name"] = "lifetime";
index 3910a38..3c9560b 100644 (file)
@@ -1,8 +1,8 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := coap
-LOCAL_SRC_FILES := ../libs/libcoap.so
+LOCAL_MODULE := ca
+LOCAL_SRC_FILES := ../libs/libconnectivity_abstraction.so
 include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
index 7a4c12d..b092fd9 100644 (file)
@@ -45,7 +45,7 @@ public class MainActivity extends Activity {
     private ArrayList<Integer> mRunningQueries           = new ArrayList<Integer>();
 
     private IQueryEngineEvent  mQueryEngineEventListener = null;
-    private final String         LOG_TAG = this.getClass().getSimpleName();
+    private final String         LOG_TAG = "SSMSampleApp : " + this.getClass().getSimpleName();
     private static MainActivity  activityObj;
 
     void PrintLog(String log) {
@@ -54,6 +54,7 @@ public class MainActivity extends Activity {
         data.putString("Log", log);
         msg.setData(data);
         logHandler.sendMessage(msg);
+        Log.i(LOG_TAG, log);
     }
 
     private Handler      logHandler         = new Handler() {
@@ -203,18 +204,22 @@ public class MainActivity extends Activity {
                 switch (v.getId()) {
                     case R.id.btClear:
                         edtQuery.setText("");
+                        Log.i(LOG_TAG, "Query textbox is cleared");
                         break;
 
                     case R.id.btLogClear:
                         tvLog.setText("");
+                        Log.i(LOG_TAG, "Log textbox is cleared");
                         break;
 
                     case R.id.btFullDevice:
                         edtQuery.setText("subscribe Device if Device.dataId != 0");
+                        Log.i(LOG_TAG, "subscribe Device if Device.dataId != 0");
                         break;
 
                     case R.id.btDiscomfortIndex:
                         edtQuery.setText("subscribe Device.DiscomfortIndexSensor if Device.DiscomfortIndexSensor.discomfortIndex > 0");
+                        Log.i(LOG_TAG, "subscribe Device.DiscomfortIndexSensor if Device.DiscomfortIndexSensor.discomfortIndex > 0");
                         break;
                 }
             }
index 82780a5..253898e 100644 (file)
@@ -41,8 +41,6 @@ PROGMEM const char TAG[] = "TrackeeSensor";
 
 OCResourceHandle m_handle;
 
-
-
 Cble ble;
 char trackeeID[13] = "9059AF16FEF7";
 int slaver_num = 0;
@@ -50,21 +48,15 @@ int slaver_num = 0;
 char slaveList[SLAVER_EA][13] = {"9059AF1700EE", "34B1F7D004D2"};
 int g_PROXIUnderObservation = 0;
 
-
-
 const char *getResult(OCStackResult result);
 void createResource();
 
-
 #define LENGTH_VAR      50
 bool JsonGenerator( char *jsonBuf, uint16_t buf_length )
 {
-
     return true;
-
 }
 
-
 // On Arduino Atmel boards with Harvard memory architecture, the stack grows
 // downwards from the top and the heap grows upwards. This method will print
 // the distance(in terms of bytes) between those two.
@@ -91,50 +83,49 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
 {
     OCEntityHandlerResult ehRet = OC_EH_OK;
 
-    if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
+    if (entityHandlerRequest )
     {
-        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
-        if (OC_REST_GET == entityHandlerRequest->method)
+        if (flag & OC_REQUEST_FLAG)
         {
-            if ( JsonGenerator( (char *)entityHandlerRequest->resJSONPayload,
-                                entityHandlerRequest->resJSONPayloadLen ) == false )
+            OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+            if (OC_REST_GET == entityHandlerRequest->method)
             {
-                ehRet  = OC_EH_ERROR;
+                if ( JsonGenerator( (char *)entityHandlerRequest->resJSONPayload,
+                                    entityHandlerRequest->resJSONPayloadLen ) == false )
+                {
+                    ehRet  = OC_EH_ERROR;
+                }
             }
-        }
-        if (OC_REST_PUT == entityHandlerRequest->method)
-        {
-            if (JsonGenerator( (char *)entityHandlerRequest->resJSONPayload,
-                               entityHandlerRequest->resJSONPayloadLen ) == false )
+            if (OC_REST_PUT == entityHandlerRequest->method)
             {
-                ehRet  = OC_EH_ERROR;
+                if (JsonGenerator( (char *)entityHandlerRequest->resJSONPayload,
+                                   entityHandlerRequest->resJSONPayloadLen ) == false )
+                {
+                    ehRet  = OC_EH_ERROR;
+                }
             }
+    
         }
-    }
-    else if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
-    {
-        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
-        {
-            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
-            g_PROXIUnderObservation = 1;
-        }
-        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
+        else if (flag & OC_OBSERVE_FLAG)
         {
-            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+            OC_LOG (INFO, TAG, PCF("Flag includes OC_OBSERVE_FLAG"));
+            if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
+            {
+                OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
+                g_PROXIUnderObservation = 1;
+            }
+            else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
+            {
+                OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+            }
         }
-    }
 
-    Serial.println((char *)entityHandlerRequest->resJSONPayload);
+        Serial.println((char *)entityHandlerRequest->resJSONPayload);
+    }
 
     return ehRet;
 }
 
-
-
-
-
-
-
 //The setup function is called once at startup of the sketch
 void setup()
 {
@@ -168,7 +159,6 @@ void setup()
 
     ble.init( (long)115200, BLE_SLAVER, slaveList[0]);
 
-
 //  ble.StatusRead();
 
     OC_LOG_V(INFO, TAG, "Program Start-\r\n");
@@ -180,7 +170,6 @@ void loop()
 {
     // This artificial delay is kept here to avoid endless spinning
     // of Arduino microcontroller. Modify it as per specfic application needs.
-
     if (OCProcess() != OC_STACK_OK)
     {
         OC_LOG(ERROR, TAG, PCF("OCStack process error"));
@@ -202,12 +191,6 @@ void loop()
 
 }
 
-
-
-
-
-
-
 void createResource()
 {
 
index acb6e65..4df0e97 100644 (file)
@@ -68,8 +68,6 @@ class TemphumidResource
 
             printf("Running thing as %s\n", m_resourceUri.c_str());
             m_resourceRep.setUri(m_resourceUri);
-            m_resourceRep.setResourceTypes(m_resourceTypes);
-            m_resourceRep.setResourceInterfaces(m_resourceInterfaces);
         }
 
         ~TemphumidResource()
index 60316d4..9a45dc4 100644 (file)
@@ -68,8 +68,6 @@ class TemphumidResource
 
             printf("Running thing as %s\n", m_resourceUri.c_str());
             m_resourceRep.setUri(m_resourceUri);
-            m_resourceRep.setResourceTypes(m_resourceTypes);
-            m_resourceRep.setResourceInterfaces(m_resourceInterfaces);
         }
 
         ~TemphumidResource()
index c9ca9aa..4da2a05 100644 (file)
                                     <listOptionValue builtIn="false" value="SSMCore"/>
                                     <listOptionValue builtIn="false" value="oc"/>
                                     <listOptionValue builtIn="false" value="octbstack"/>
-                                    <listOptionValue builtIn="false" value="coap"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="connectivity_abstraction"/>
+                                    <listOptionValue builtIn="false" value="uuid"/>
                                 </option>
                                 <option id="gnu.cpp.link.option.debugging.prof.212252607" name="Generate prof information (-p)" superClass="gnu.cpp.link.option.debugging.prof" value="true" valueType="boolean"/>
                                 <option id="gnu.cpp.link.option.debugging.gprof.279130410" name="Generate gprof information (-pg)" superClass="gnu.cpp.link.option.debugging.gprof" value="true" valueType="boolean"/>
index ad06fe5..cb0ece5 100644 (file)
@@ -6,64 +6,60 @@
 #include "ssmtesterapp.h"
 #include "SSMInterface.h"
 
-typedef struct appdata {
-       Evas_Object *win;
-       Evas_Object *conform;
-       Evas_Object *naviframe;
-       Evas_Object *layout;
-       Evas_Object *scroller;
-       Evas_Object *box;
-
-       Evas_Object *query_text;
-       Evas_Object *log;
-       Evas_Object *unregister_query_id;
-
-       Evas_Object *register_button;
-       Evas_Object *clear_button;
-       Evas_Object *unregister_button;
-       Evas_Object *search_devices_button;
-       Evas_Object *discomfort_index_button;
-       Evas_Object *plus_button;
-       Evas_Object *minus_button;
-       Evas_Object *clear_log_button;
-
-       Evas_Object *example_queries_label;
-       Evas_Object *unregister_query_label;
+typedef struct appdata
+{
+    Evas_Object *win;
+    Evas_Object *conform;
+    Evas_Object *naviframe;
+    Evas_Object *layout;
+    Evas_Object *scroller;
+    Evas_Object *box;
+
+    Evas_Object *query_text;
+    Evas_Object *log;
+    Evas_Object *unregister_query_id;
+
+    Evas_Object *register_button;
+    Evas_Object *clear_button;
+    Evas_Object *unregister_button;
+    Evas_Object *search_devices_button;
+    Evas_Object *discomfort_index_button;
+    Evas_Object *plus_button;
+    Evas_Object *minus_button;
+    Evas_Object *clear_log_button;
+
+    Evas_Object *example_queries_label;
+    Evas_Object *unregister_query_label;
 } appdata_s;
 
-typedef struct threadContext{
-       appdata_s *ad;
-       const char *log;
+typedef struct threadContext
+{
+    appdata_s *ad;
+    const char *log;
 } threadContext_s;
 
 #define ELM_DEMO_EDJ "opt/usr/apps/org.iotivity.service.ssm.ssmtesterapp/res/ui_controls.edj"
 
-char log_buffer[10000];
 void updateLog(appdata_s *ad, const char *newlog)
 {
-       const char *log_text = NULL;
-
-       log_text = elm_entry_entry_get(ad->log);
-       strcpy(log_buffer,log_text);
-       strcat(log_buffer,newlog);
-       elm_entry_entry_set(ad->log,log_buffer);
-       elm_entry_cursor_end_set(ad->log);
+    elm_entry_entry_append(ad->log, newlog);
+    elm_entry_cursor_end_set(ad->log);
 }
 
-voidupdateCallbackLog(void *data)
+void *updateCallbackLog(void *data)
 {
-       threadContext_s  *pThreadContext = (threadContext_s*)data;
+    threadContext_s  *pThreadContext = (threadContext_s *)data;
 
-       updateLog(pThreadContext->ad, pThreadContext->log);
+    updateLog(pThreadContext->ad, pThreadContext->log);
 
-       return NULL;
+    return NULL;
 }
 
 static int s_hc2i(char hexChar)
 {
-    if ((hexChar <= '9') && (hexChar >= '0')) return (int)hexChar-(int)'0';
-    if ((hexChar <= 'F') && (hexChar >= 'A')) return 10+(int)hexChar-(int)'A';
-    if ((hexChar <= 'f') && (hexChar >= 'a')) return 10+(int)hexChar-(int)'a';
+    if ((hexChar <= '9') && (hexChar >= '0')) return (int)hexChar - (int)'0';
+    if ((hexChar <= 'F') && (hexChar >= 'A')) return 10 + (int)hexChar - (int)'A';
+    if ((hexChar <= 'f') && (hexChar >= 'a')) return 10 + (int)hexChar - (int)'a';
     return -1;
 }
 
@@ -71,61 +67,73 @@ long long s_h2uint64(const char *hex, size_t maxdigit)
 {
     long long nNumber = 0;
     int nInt;
-    size_t nLen=0;
-    while (nLen < maxdigit && (nInt = s_hc2i(*hex)) >= 0) {
-        nNumber=(nNumber*(long long)16) + (long long)nInt;
+    size_t nLen = 0;
+    while (nLen < maxdigit && (nInt = s_hc2i(*hex)) >= 0)
+    {
+        nNumber = (nNumber * (long long)16) + (long long)nInt;
         hex++;
         nLen++;
     }
     return nNumber;
 }
 
-int s_h2i(char *strHex) {
-    return (int) s_h2uint64(strHex, sizeof(int)*2);
+int s_h2i(char *strHex)
+{
+    return (int) s_h2uint64(strHex, sizeof(int) * 2);
 }
 
 void unescape(char *val)
 {
     char *tmp = (char *)val;
-    int i,nChar;
+    int i, nChar;
     int len;
 
     if (!val) return;
-    len=(int)strlen(val);
+    len = (int)strlen(val);
 
     // process special chars
-    while (*tmp) {
-        if (!strncmp((char *)tmp,"&amp;",5)) {
-            *tmp='&';
-            memmove(&tmp[1],&tmp[5],strlen((char *)&tmp[5])+1);
+    while (*tmp)
+    {
+        if (!strncmp((char *)tmp, "&amp;", 5))
+        {
+            *tmp = '&';
+            memmove(&tmp[1], &tmp[5], strlen((char *)&tmp[5]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&nbsp;",6)) {
-            *tmp=' ';
-            memmove(&tmp[1],&tmp[6],strlen((char *)&tmp[6])+1);
+        else if (!strncmp((char *)tmp, "&nbsp;", 6))
+        {
+            *tmp = ' ';
+            memmove(&tmp[1], &tmp[6], strlen((char *)&tmp[6]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&lt;",4)) {
-            *tmp='<';
-            memmove(&tmp[1],&tmp[4],strlen((char *)&tmp[4])+1);
+        else if (!strncmp((char *)tmp, "&lt;", 4))
+        {
+            *tmp = '<';
+            memmove(&tmp[1], &tmp[4], strlen((char *)&tmp[4]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&gt;",4)) {
-            *tmp='>';
-            memmove(&tmp[1],&tmp[4],strlen((char *)&tmp[4])+1);
+        else if (!strncmp((char *)tmp, "&gt;", 4))
+        {
+            *tmp = '>';
+            memmove(&tmp[1], &tmp[4], strlen((char *)&tmp[4]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&apos;",6)) {
-            *tmp='\'';
-            memmove(&tmp[1],&tmp[6],strlen((char *)&tmp[6])+1);
+        else if (!strncmp((char *)tmp, "&apos;", 6))
+        {
+            *tmp = '\'';
+            memmove(&tmp[1], &tmp[6], strlen((char *)&tmp[6]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&quot;",6)) {
-            *tmp='"';
-            memmove(&tmp[1],&tmp[6],strlen((char *)&tmp[6])+1);
+        else if (!strncmp((char *)tmp, "&quot;", 6))
+        {
+            *tmp = '"';
+            memmove(&tmp[1], &tmp[6], strlen((char *)&tmp[6]) + 1);
         }
-        else if (!strncmp((char *)tmp,"&#",2)) { // &#nnn; || &#xnn;
-            for(i=2;i<7;i++) {
-                if (tmp[i] == ';') {
-                    if (tmp[2]=='x') nChar=s_h2i((char *)&tmp[3]);
-                    else nChar=atoi((char *)&tmp[2]);
-                    *tmp=(char)nChar;
-                    memmove(&tmp[1],&tmp[i+1],strlen((char *)&tmp[i+1])+1);
+        else if (!strncmp((char *)tmp, "&#", 2)) // &#nnn; || &#xnn;
+        {
+            for (i = 2; i < 7; i++)
+            {
+                if (tmp[i] == ';')
+                {
+                    if (tmp[2] == 'x') nChar = s_h2i((char *)&tmp[3]);
+                    else nChar = atoi((char *)&tmp[2]);
+                    *tmp = (char)nChar;
+                    memmove(&tmp[1], &tmp[i + 1], strlen((char *)&tmp[i + 1]) + 1);
                     break;
                 }
             }
@@ -133,528 +141,554 @@ void unescape(char *val)
         tmp++;
     }
 
-    if (tmp < (char *)(val+len))
-        *tmp='\0';
+    if (tmp < (char *)(val + len))
+        *tmp = '\0';
 }
 
 class CQueryEngineEvent : public OIC::IQueryEngineEvent
 {
-private:
-       appdata_s *m_pAppData;
-       threadContext_s m_ThreadContext;
-
-public:
-       CQueryEngineEvent(appdata_s *pAppData)
-       {
-               m_pAppData = pAppData;
-               m_ThreadContext.ad = m_pAppData;
-               m_ThreadContext.log = NULL;
-       }
-
-       OIC::SSMRESULT onQueryEngineEvent(int cqid, OIC::IDataReader *pResult)
-       {
-               int     dataCount = 0;
-               char log[2000],buf[100];
-               OIC::IModelData      *pModelData = NULL;
-               std::vector<std::string>        affectedModels;
-
-               dlog_print(DLOG_ERROR,LOG_TAG,"Event received!");
-
-               sprintf(buf,"Event received! cqid = %d<br>", cqid);
-               strcpy(log,buf);
-
-               pResult->getAffectedModels(&affectedModels);
-
-               for (std::vector<std::string>::iterator itor = affectedModels.begin();
-                               itor != affectedModels.end(); ++itor)
-               {
-                       sprintf(buf,"Printing = %s model<br>", (*itor).c_str());
-                       strcat(log,buf);
-
-                       pResult->getModelDataCount(*itor, &dataCount);
-                       for (int i = 0; i < dataCount; i++)
-                       {
-                               pResult->getModelData(*itor, i, &pModelData);
-                               sprintf(buf,"dataId: %d<br>", pModelData->getDataId());
-                               strcat(log,buf);
-                               for (int j = 0; j < pModelData->getPropertyCount(); j++)
-                               {
-                                       sprintf(buf,"Type: %s Value: %s<br>", (pModelData->getPropertyName(j)).c_str(), (pModelData->getPropertyValue(j)).c_str());
-                                       strcat(log,buf);
-                               }
-                               m_ThreadContext.log = log;
-                               ecore_main_loop_thread_safe_call_sync((void *(*)(void *))updateCallbackLog, &m_ThreadContext);
-                       }
-               }
-
-               return OIC::SSM_S_OK;
-       }
+    private:
+        appdata_s *m_pAppData;
+        threadContext_s m_ThreadContext;
+
+    public:
+        CQueryEngineEvent(appdata_s *pAppData)
+        {
+            m_pAppData = pAppData;
+            m_ThreadContext.ad = m_pAppData;
+            m_ThreadContext.log = NULL;
+        }
+
+        OIC::SSMRESULT onQueryEngineEvent(int cqid, OIC::IDataReader *pResult)
+        {
+            int     dataCount = 0;
+            char log[2000], buf[100];
+            OIC::IModelData      *pModelData = NULL;
+            std::vector<std::string>        affectedModels;
+
+            dlog_print(DLOG_INFO, LOG_TAG, "Event received! cqid = %d", cqid);
+
+            sprintf(buf, "Event received! cqid = %d<br>", cqid);
+            strcpy(log, buf);
+
+            pResult->getAffectedModels(&affectedModels);
+
+            for (std::vector<std::string>::iterator itor = affectedModels.begin();
+                 itor != affectedModels.end(); ++itor)
+            {
+                sprintf(buf, "Printing = %s model<br>", (*itor).c_str());
+                strcat(log, buf);
+
+                pResult->getModelDataCount(*itor, &dataCount);
+                for (int i = 0; i < dataCount; i++)
+                {
+                    pResult->getModelData(*itor, i, &pModelData);
+                    dlog_print(DLOG_INFO, LOG_TAG, "dataId: %d<br>", pModelData->getDataId());
+                    sprintf(buf, "dataId: %d<br>", pModelData->getDataId());
+                    strcat(log, buf);
+                    for (int j = 0; j < pModelData->getPropertyCount(); j++)
+                    {
+                       dlog_print(DLOG_INFO, LOG_TAG, "Type: %s Value: %s<br>",
+                                (pModelData->getPropertyName(j)).c_str(),
+                                (pModelData->getPropertyValue(j)).c_str());
+                        sprintf(buf, "Type: %s Value: %s<br>",
+                                (pModelData->getPropertyName(j)).c_str(),
+                                (pModelData->getPropertyValue(j)).c_str());
+                        strcat(log, buf);
+                    }
+                    m_ThreadContext.log = log;
+                    ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
+                                                          &m_ThreadContext);
+                }
+            }
+
+            return OIC::SSM_S_OK;
+        }
 };
 
-CQueryEngineEvent              *g_pQueryEngineEvent = NULL;
+CQueryEngineEvent       *g_pQueryEngineEvent = NULL;
 
 
 static void
 win_delete_request_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       ui_app_exit();
+    ui_app_exit();
 }
 
 static void
 win_back_cb(void *data, Evas_Object *obj, void *event_info)
 {
-       //appdata_s *ad = (appdata_s *)data;
-       /* Let window go to hide state. */
-       //elm_win_lower(ad->win);
-       ui_app_exit();
+    //appdata_s *ad = (appdata_s *)data;
+    /* Let window go to hide state. */
+    //elm_win_lower(ad->win);
+    ui_app_exit();
 }
 
 
 static void
 register_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       const char *main_text = NULL;
-       char *escaped_text = NULL;
-       if (!ad->query_text)
-               return;
-       main_text = elm_entry_entry_get(ad->query_text);
-       if (!main_text || (strlen(main_text) == 0))
-               return;
-
-       //invoke registerQuery
-       int qid = 0;
-       char log[50];
-
-       escaped_text = strdup(main_text);
-       unescape(escaped_text);
-
-    dlog_print(DLOG_ERROR,LOG_TAG,"registering query");
-
-       OIC::SSMRESULT res = OIC::RegisterQuery(escaped_text, g_pQueryEngineEvent, qid);
-       if(res == OIC::SSM_S_OK)
-       {
-               updateLog(ad, "The query has been registered!<br>");
-               sprintf(log, "QID : %d<br>", qid);
-               updateLog(ad, log);
-       }
-       else
-       {
-               sprintf(log,"Error occured(%d)<br>", res);
-               updateLog(ad, log);
-       }
-
-       free(escaped_text);
-
-       dlog_print(DLOG_ERROR,LOG_TAG,"registering query done");
+    appdata_s *ad = (appdata_s *)data;
+    const char *main_text = NULL;
+    char *escaped_text = NULL;
+    if (!ad->query_text)
+        return;
+    main_text = elm_entry_entry_get(ad->query_text);
+    if (!main_text || (strlen(main_text) == 0))
+        return;
+
+    //invoke registerQuery
+    int qid = 0;
+    char log[50];
+
+    escaped_text = strdup(main_text);
+    unescape(escaped_text);
+
+    dlog_print(DLOG_ERROR, LOG_TAG, "registering query");
+
+    OIC::SSMRESULT res = OIC::RegisterQuery(escaped_text, g_pQueryEngineEvent, qid);
+    if (res == OIC::SSM_S_OK)
+    {
+        updateLog(ad, "The query has been registered!<br>");
+        dlog_print(DLOG_INFO, LOG_TAG, "QID : %d\n", qid);
+        sprintf(log, "QID : %d<br>", qid);
+        updateLog(ad, log);
+    }
+    else
+    {
+       dlog_print(DLOG_INFO, LOG_TAG, "Error occured(%d)\n", res);
+        sprintf(log, "Error occured(%d)<br>", res);
+        updateLog(ad, log);
+    }
+
+    free(escaped_text);
+
+    dlog_print(DLOG_ERROR, LOG_TAG, "registering query done");
 }
 
 static void
 search_devices_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       elm_entry_entry_set(ad->query_text, "subscribe Device if Device.dataId > 0");
+    appdata_s *ad = (appdata_s *)data;
+    elm_entry_entry_set(ad->query_text, "subscribe Device if Device.dataId > 0");
 }
 
 static void
 discomfort_index_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       elm_entry_entry_set(ad->query_text, "subscribe Device.DiscomfortIndexSensor "\
-                       "if Device.DiscomfortIndexSensor.discomfortIndex != 0");
+    appdata_s *ad = (appdata_s *)data;
+    elm_entry_entry_set(ad->query_text, "subscribe Device.DiscomfortIndexSensor "\
+                        "if Device.DiscomfortIndexSensor.discomfortIndex != 0");
 }
 
 static void
 minus_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       char output[10];
-       const char *query_id_str = elm_entry_entry_get(ad->unregister_query_id);
-       if (!query_id_str || (strlen(query_id_str) == 0))
-               return;
-       try{
-               int val = atoi(query_id_str);
-               sprintf(output,"%d",val-1);
-               elm_entry_entry_set(ad->unregister_query_id,output);
-       }
-       catch(...){
-               dlog_print(DLOG_ERROR,LOG_TAG,"#### atoi() conversion error");
-       }
+    appdata_s *ad = (appdata_s *)data;
+    char output[10];
+    const char *query_id_str = elm_entry_entry_get(ad->unregister_query_id);
+    if (!query_id_str || (strlen(query_id_str) == 0))
+        return;
+    try
+    {
+        int val = atoi(query_id_str);
+        dlog_print(DLOG_INFO, LOG_TAG, "%d", val - 1);
+        sprintf(output, "%d", val - 1);
+        elm_entry_entry_set(ad->unregister_query_id, output);
+    }
+    catch (...)
+    {
+        dlog_print(DLOG_ERROR, LOG_TAG, "#### atoi() conversion error");
+    }
 }
 
 static void
 plus_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       char output[10];
-       const char *query_id_str = elm_entry_entry_get(ad->unregister_query_id);
-       if (!query_id_str || (strlen(query_id_str) == 0))
-               return;
-       try{
-               int val = atoi(query_id_str);
-               sprintf(output,"%d",val+1);
-               elm_entry_entry_set(ad->unregister_query_id,output);
-       }
-       catch(...){
-               dlog_print(DLOG_ERROR,LOG_TAG,"#### atoi() conversion error");
-       }
+    appdata_s *ad = (appdata_s *)data;
+    char output[10];
+    const char *query_id_str = elm_entry_entry_get(ad->unregister_query_id);
+    if (!query_id_str || (strlen(query_id_str) == 0))
+        return;
+    try
+    {
+        int val = atoi(query_id_str);
+        dlog_print(DLOG_INFO, LOG_TAG, "%d", val + 1);
+        sprintf(output, "%d", val + 1);
+        elm_entry_entry_set(ad->unregister_query_id, output);
+    }
+    catch (...)
+    {
+        dlog_print(DLOG_ERROR, LOG_TAG, "#### atoi() conversion error");
+    }
 }
 
 static void
 unregister_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       const char *qidstr = NULL;
-       if (!ad->unregister_query_id)
-               return;
-       qidstr = elm_entry_entry_get(ad->unregister_query_id);
-       if (!qidstr || (strlen(qidstr) == 0))
-               return;
-       char log[50];
-       int qid;
-       try{
-               qid = atoi(qidstr);
-               //invoke unregisterQuery
-               OIC::SSMRESULT res = OIC::UnregisterQuery(qid);
-               if(res == OIC::SSM_S_OK)
-               {
-                       updateLog(ad, "The query has been unregistered!<br>");
-                       sprintf(log, "QID : %d<br>", qid);
-                       updateLog(ad, log);
-               }
-               else
-               {
-                       sprintf(log,"Error occured(%d)<br>", res);
-                       updateLog(ad, log);
-               }
-       }
-       catch(...){
-               dlog_print(DLOG_ERROR,LOG_TAG,"#### atoi() conversion error");
-       }
+    appdata_s *ad = (appdata_s *)data;
+    const char *qidstr = NULL;
+    if (!ad->unregister_query_id)
+        return;
+    qidstr = elm_entry_entry_get(ad->unregister_query_id);
+    if (!qidstr || (strlen(qidstr) == 0))
+        return;
+    char log[50];
+    int qid;
+    try
+    {
+        qid = atoi(qidstr);
+        //invoke unregisterQuery
+        OIC::SSMRESULT res = OIC::UnregisterQuery(qid);
+        if (res == OIC::SSM_S_OK)
+        {
+            updateLog(ad, "The query has been unregistered!<br>");
+            dlog_print(DLOG_INFO, LOG_TAG, "QID : %d\n", qid);
+            sprintf(log, "QID : %d<br>", qid);
+            updateLog(ad, log);
+        }
+        else
+        {
+               dlog_print(DLOG_INFO, LOG_TAG, "Error occured(%d)\n", res);
+            sprintf(log, "Error occured(%d)<br>", res);
+            updateLog(ad, log);
+        }
+    }
+    catch (...)
+    {
+        dlog_print(DLOG_ERROR, LOG_TAG, "#### atoi() conversion error");
+    }
 }
 
 static void
 clear_log_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       elm_entry_entry_set(ad->log,"");
+    appdata_s *ad = (appdata_s *)data;
+    elm_entry_entry_set(ad->log, "");
 }
 
 static void
 clear_cb(void *data , Evas_Object *obj , void *event_info)
 {
-       appdata_s *ad = (appdata_s *)data;
-       elm_entry_entry_set(ad->query_text,"");
+    appdata_s *ad = (appdata_s *)data;
+    elm_entry_entry_set(ad->query_text, "");
 }
 
 bool is_connected()
 {
-       bool isConnected = false;
-
-       static connection_h connection;
-
-       if(connection_create(&connection) == CONNECTION_ERROR_NONE)
-       {
-           char *ip_addr = NULL;
-           connection_get_ip_address(connection, CONNECTION_ADDRESS_FAMILY_IPV4, &ip_addr);
-           connection_destroy(connection);
-           if(strlen(ip_addr) > 0)
-               isConnected = true;
-           free(ip_addr);
-       }
+    bool isConnected = false;
+
+    static connection_h connection;
+
+    if (connection_create(&connection) == CONNECTION_ERROR_NONE)
+    {
+        char *ip_addr = NULL;
+        connection_get_ip_address(connection, CONNECTION_ADDRESS_FAMILY_IPV4, &ip_addr);
+        connection_destroy(connection);
+        if (strlen(ip_addr) > 0)
+            isConnected = true;
+        free(ip_addr);
+    }
 
-       return isConnected;
+    return isConnected;
 }
 
 static void
 create_base_gui(appdata_s *ad)
 {
-       /* Window */
-       ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
-       elm_win_conformant_set(ad->win, EINA_TRUE);
-       elm_win_autodel_set(ad->win, EINA_TRUE);
-
-       if (elm_win_wm_rotation_supported_get(ad->win)) {
-               int rots[4] = { 0, 90, 180, 270 };
-               elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
-       }
-
-       evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
-       eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
-
-       /* Conformant */
-       ad->conform = elm_conformant_add(ad->win);
-       evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_win_resize_object_add(ad->win, ad->conform);
-       evas_object_show(ad->conform);
-
-       /* naviframe */
-       ad->naviframe = elm_naviframe_add(ad->conform);
-       elm_object_content_set(ad->conform,ad->naviframe);
-       evas_object_show(ad->naviframe);
-
-       /* scroller */
-       ad->scroller = elm_scroller_add(ad->naviframe);
-
-       /* Box container */
-       ad->box = elm_box_add(ad->scroller);
-       evas_object_size_hint_align_set(ad->box, EVAS_HINT_FILL, 0.0);
-       evas_object_size_hint_weight_set(ad->box, EVAS_HINT_EXPAND, 0.0);
-       elm_object_content_set(ad->scroller, ad->box);
-
-       ad->layout = elm_layout_add(ad->box);
-       evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, 0.0);
-       //elm_layout_theme_set(ad->layout, "layout", "application", "default");
-       evas_object_size_hint_align_set(ad->layout, EVAS_HINT_FILL, 0.0);
-       elm_layout_file_set(ad->layout,ELM_DEMO_EDJ,"mainpage_layout");
-
-       ad->query_text = elm_entry_add(ad->layout);
-       elm_object_part_text_set(ad->query_text, "elm.guide", "Enter the query here!!!");
-       evas_object_size_hint_align_set(ad->query_text, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       evas_object_size_hint_weight_set(ad->query_text, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_object_part_content_set(ad->layout,"query_text",ad->query_text);
-       elm_entry_scrollable_set(ad->query_text,EINA_TRUE);
-       //evas_object_show(ad->query_text);
-       elm_entry_input_panel_show_on_demand_set(ad->query_text,EINA_TRUE);
-
-       ad->register_button = elm_button_add(ad->layout);
-       elm_object_text_set(ad->register_button, "Register");
-       evas_object_size_hint_weight_set(ad->register_button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       evas_object_size_hint_align_set(ad->register_button, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       evas_object_smart_callback_add(ad->register_button, "clicked", register_cb, ad);
-       elm_object_part_content_set(ad->layout,"register",ad->register_button);
-       //evas_object_show(ad->register_button);
-
-       ad->clear_button = elm_button_add(ad->layout);
-       elm_object_text_set(ad->clear_button, "Clear");
-       evas_object_size_hint_weight_set(ad->search_devices_button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       evas_object_size_hint_align_set(ad->search_devices_button, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       evas_object_smart_callback_add(ad->clear_button, "clicked", clear_cb, ad);
-       elm_object_part_content_set(ad->layout,"clear",ad->clear_button);
-       //evas_object_show(ad->clear_button);
-
-       ad->example_queries_label = elm_label_add(ad->layout);
-       elm_object_text_set(ad->example_queries_label, _("<color=#00008BFF><b><align=left>Example Queries</align></b></color>"));
-       elm_object_part_content_set(ad->layout,"example_queries",ad->example_queries_label);
-       //evas_object_show(ad->example_queries_label);
-
-       ad->search_devices_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->search_devices_button, EVAS_HINT_FILL, 0.0);
-       elm_object_text_set(ad->search_devices_button, "Search Devices");
-       evas_object_smart_callback_add(ad->search_devices_button, "clicked", search_devices_cb, ad);
-       elm_object_part_content_set(ad->layout,"search_devices",ad->search_devices_button);
-       //evas_object_show(ad->search_devices_button);
-
-       ad->discomfort_index_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->discomfort_index_button, EVAS_HINT_FILL, 0.0);
-       elm_object_part_content_set(ad->layout,"discomfort_index",ad->discomfort_index_button);
-       elm_object_text_set(ad->discomfort_index_button, "Discomfort Index");
-       evas_object_smart_callback_add(ad->discomfort_index_button, "clicked", discomfort_index_cb, ad);
-       //evas_object_show(ad->discomfort_index_button);
-
-       ad->unregister_query_label = elm_label_add(ad->layout);
-       elm_object_text_set(ad->unregister_query_label,_("<color=#00008BFF><b><align=left>Unregister Query</align></b></color>"));
-       //evas_object_size_hint_weight_set(ad->unregister_query_label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_object_part_content_set(ad->layout,"unregister_query_label",ad->unregister_query_label);
-       //evas_object_show(ad->unregister_query_label);
-
-
-       ad->minus_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->discomfort_index_button, EVAS_HINT_FILL, 0.0);
-       elm_object_part_content_set(ad->layout,"minus",ad->minus_button);
-       elm_object_text_set(ad->minus_button, "-");
-       evas_object_smart_callback_add(ad->minus_button, "clicked", minus_cb, ad);
-       //evas_object_show(ad->minus_button);
-
-       ad->unregister_query_id = elm_entry_add(ad->layout);
-       elm_object_part_text_set(ad->unregister_query_id, "elm.guide", "Query id!!!");
-       //evas_object_size_hint_align_set(ad->unregister_query_id, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       elm_object_part_content_set(ad->layout,"unregister_query_id",ad->unregister_query_id);
-       elm_entry_input_panel_show_on_demand_set(ad->unregister_query_id,EINA_TRUE);
-       elm_entry_input_panel_layout_set(ad->unregister_query_id,ELM_INPUT_PANEL_LAYOUT_NUMBER);
-       evas_object_show(ad->unregister_query_id);
-
-       ad->plus_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->discomfort_index_button, EVAS_HINT_FILL, 0.0);
-       elm_object_part_content_set(ad->layout,"plus",ad->plus_button);
-       elm_object_text_set(ad->plus_button, "+");
-       evas_object_smart_callback_add(ad->plus_button, "clicked", plus_cb, ad);
-       //evas_object_show(ad->plus_button);
-
-       ad->unregister_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->unregister_button, EVAS_HINT_FILL, 0.0);
-       elm_object_part_content_set(ad->layout,"unregister_button",ad->unregister_button);
-       elm_object_text_set(ad->unregister_button, "Unregister");
-       evas_object_smart_callback_add(ad->unregister_button, "clicked", unregister_cb, ad);
-       //evas_object_show(ad->unregister_button);
-
-       ad->clear_log_button = elm_button_add(ad->layout);
-       //evas_object_size_hint_align_set(ad->clear_log_button, EVAS_HINT_FILL, 0.0);
-       elm_object_part_content_set(ad->layout,"log_button",ad->clear_log_button);
-       elm_object_text_set(ad->clear_log_button, "Clear Log");
-       evas_object_smart_callback_add(ad->clear_log_button, "clicked", clear_log_cb, ad);
-       //evas_object_show(ad->clear_log_button);
-
-       ad->log = elm_entry_add(ad->layout);
-       elm_object_part_content_set(ad->layout,"log_text",ad->log);
-       elm_object_part_text_set(ad->log, "elm.guide", "Log messages will be update here!!!");
-       elm_entry_scrollable_set(ad->log,EINA_TRUE);
-       elm_entry_editable_set(ad->log,EINA_FALSE);
-       //evas_object_size_hint_align_set(ad->log, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       //evas_object_show(ad->log);
-
-       elm_box_pack_end(ad->box, ad->layout);
-       evas_object_show(ad->layout);
-       elm_naviframe_item_push(ad->naviframe, "Soft Sensor Manager App", NULL, NULL, ad->scroller, NULL);
-
-       //Show window after base gui is set up
-       evas_object_show(ad->win);
+    /* Window */
+    ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
+    elm_win_conformant_set(ad->win, EINA_TRUE);
+    elm_win_autodel_set(ad->win, EINA_TRUE);
+
+    if (elm_win_wm_rotation_supported_get(ad->win))
+    {
+        int rots[4] = { 0, 90, 180, 270 };
+        elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
+    }
+
+    evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
+    eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
+
+    /* Conformant */
+    ad->conform = elm_conformant_add(ad->win);
+    evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_win_resize_object_add(ad->win, ad->conform);
+    evas_object_show(ad->conform);
+
+    /* naviframe */
+    ad->naviframe = elm_naviframe_add(ad->conform);
+    elm_object_content_set(ad->conform, ad->naviframe);
+    evas_object_show(ad->naviframe);
+
+    /* scroller */
+    ad->scroller = elm_scroller_add(ad->naviframe);
+
+    /* Box container */
+    ad->box = elm_box_add(ad->scroller);
+    evas_object_size_hint_align_set(ad->box, EVAS_HINT_FILL, 0.0);
+    evas_object_size_hint_weight_set(ad->box, EVAS_HINT_EXPAND, 0.0);
+    elm_object_content_set(ad->scroller, ad->box);
+
+    ad->layout = elm_layout_add(ad->box);
+    evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, 0.0);
+    //elm_layout_theme_set(ad->layout, "layout", "application", "default");
+    evas_object_size_hint_align_set(ad->layout, EVAS_HINT_FILL, 0.0);
+    elm_layout_file_set(ad->layout, ELM_DEMO_EDJ, "mainpage_layout");
+
+    ad->query_text = elm_entry_add(ad->layout);
+    elm_object_part_text_set(ad->query_text, "elm.guide", "Enter the query here!!!");
+    evas_object_size_hint_align_set(ad->query_text, EVAS_HINT_FILL, EVAS_HINT_FILL);
+    evas_object_size_hint_weight_set(ad->query_text, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_object_part_content_set(ad->layout, "query_text", ad->query_text);
+    elm_entry_scrollable_set(ad->query_text, EINA_TRUE);
+    //evas_object_show(ad->query_text);
+    elm_entry_input_panel_show_on_demand_set(ad->query_text, EINA_TRUE);
+
+    ad->register_button = elm_button_add(ad->layout);
+    elm_object_text_set(ad->register_button, "Register");
+    evas_object_size_hint_weight_set(ad->register_button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(ad->register_button, EVAS_HINT_FILL, EVAS_HINT_FILL);
+    evas_object_smart_callback_add(ad->register_button, "clicked", register_cb, ad);
+    elm_object_part_content_set(ad->layout, "register", ad->register_button);
+    //evas_object_show(ad->register_button);
+
+    ad->clear_button = elm_button_add(ad->layout);
+    elm_object_text_set(ad->clear_button, "Clear");
+    evas_object_size_hint_weight_set(ad->search_devices_button, EVAS_HINT_EXPAND,
+                                     EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(ad->search_devices_button, EVAS_HINT_FILL, EVAS_HINT_FILL);
+    evas_object_smart_callback_add(ad->clear_button, "clicked", clear_cb, ad);
+    elm_object_part_content_set(ad->layout, "clear", ad->clear_button);
+    //evas_object_show(ad->clear_button);
+
+    ad->example_queries_label = elm_label_add(ad->layout);
+    elm_object_text_set(ad->example_queries_label,
+                        _("<color=#00008BFF><b><align=left>Example Queries</align></b></color>"));
+    elm_object_part_content_set(ad->layout, "example_queries", ad->example_queries_label);
+    //evas_object_show(ad->example_queries_label);
+
+    ad->search_devices_button = elm_button_add(ad->layout);
+    //evas_object_size_hint_align_set(ad->search_devices_button, EVAS_HINT_FILL, 0.0);
+    elm_object_text_set(ad->search_devices_button, "Search Devices");
+    evas_object_smart_callback_add(ad->search_devices_button, "clicked", search_devices_cb, ad);
+    elm_object_part_content_set(ad->layout, "search_devices", ad->search_devices_button);
+    //evas_object_show(ad->search_devices_button);
+
+    ad->discomfort_index_button = elm_button_add(ad->layout);
+    //evas_object_size_hint_align_set(ad->discomfort_index_button, EVAS_HINT_FILL, 0.0);
+    elm_object_part_content_set(ad->layout, "discomfort_index", ad->discomfort_index_button);
+    elm_object_text_set(ad->discomfort_index_button, "Discomfort Index");
+    evas_object_smart_callback_add(ad->discomfort_index_button, "clicked", discomfort_index_cb,
+                                   ad);
+
+    ad->unregister_query_label = elm_label_add(ad->layout);
+    elm_object_text_set(ad->unregister_query_label,
+                        _("<color=#00008BFF><b><align=left>Unregister Query</align></b></color>"));
+    elm_object_part_content_set(ad->layout, "unregister_query_label", ad->unregister_query_label);
+
+    ad->minus_button = elm_button_add(ad->layout);
+    elm_object_part_content_set(ad->layout, "minus", ad->minus_button);
+    elm_object_text_set(ad->minus_button, "-");
+    evas_object_smart_callback_add(ad->minus_button, "clicked", minus_cb, ad);
+
+    ad->unregister_query_id = elm_entry_add(ad->layout);
+    elm_object_part_text_set(ad->unregister_query_id, "elm.guide", "Query id!!!");
+    elm_object_part_content_set(ad->layout, "unregister_query_id", ad->unregister_query_id);
+    elm_entry_input_panel_show_on_demand_set(ad->unregister_query_id, EINA_TRUE);
+    elm_entry_input_panel_layout_set(ad->unregister_query_id, ELM_INPUT_PANEL_LAYOUT_NUMBER);
+    evas_object_show(ad->unregister_query_id);
+
+    ad->plus_button = elm_button_add(ad->layout);
+    elm_object_part_content_set(ad->layout, "plus", ad->plus_button);
+    elm_object_text_set(ad->plus_button, "+");
+    evas_object_smart_callback_add(ad->plus_button, "clicked", plus_cb, ad);
+
+    ad->unregister_button = elm_button_add(ad->layout);
+    elm_object_part_content_set(ad->layout, "unregister_button", ad->unregister_button);
+    elm_object_text_set(ad->unregister_button, "Unregister");
+    evas_object_smart_callback_add(ad->unregister_button, "clicked", unregister_cb, ad);
+
+    ad->clear_log_button = elm_button_add(ad->layout);
+    elm_object_part_content_set(ad->layout, "log_button", ad->clear_log_button);
+    elm_object_text_set(ad->clear_log_button, "Clear Log");
+    evas_object_smart_callback_add(ad->clear_log_button, "clicked", clear_log_cb, ad);
+
+    ad->log = elm_entry_add(ad->layout);
+    elm_object_part_content_set(ad->layout, "log_text", ad->log);
+    elm_object_part_text_set(ad->log, "elm.guide", "Log messages will be update here!!!");
+    elm_entry_scrollable_set(ad->log, EINA_TRUE);
+    elm_entry_editable_set(ad->log, EINA_FALSE);
+
+    elm_box_pack_end(ad->box, ad->layout);
+    evas_object_show(ad->layout);
+    elm_naviframe_item_push(ad->naviframe, "Soft Sensor Manager App", NULL, NULL, ad->scroller,
+                            NULL);
+
+    //Show window after base gui is set up
+    evas_object_show(ad->win);
 }
 
 static bool
 app_create(void *data)
 {
-       /* Hook to take necessary actions before main event loop starts
-               Initialize UI resources and application's data
-               If this function returns true, the main loop of application starts
-               If this function returns false, the application is terminated */
-       appdata_s *ad = (appdata_s *)data;
-
-       std::string xmlDescription = "<SSMCore>"
-                               "<Device>"
-                               "<UDN>abcde123-31f8-11b4-a222-08002b34c050</UDN>"
-                               "<Name>MyPC</Name>"
-                               "<Type>PC</Type>"
-                               "</Device>"
-                               "<Config>"
-                               "<SoftSensorDescription>/opt/usr/apps/org.iotivity.service.ssm.ssmtesterapp/lib/SoftSensorDescription.xml</SoftSensorDescription>"
-                               "<SoftSensorRepository>/opt/usr/apps/org.iotivity.service.ssm.ssmtesterapp/lib/</SoftSensorRepository>"
-                               "</Config>"
-                               "</SSMCore>";
-
-       g_pQueryEngineEvent = new CQueryEngineEvent(ad);
-
-       create_base_gui(ad);
-
-       if(is_connected())
-       {
-           if (OIC::InitializeSSM(xmlDescription) == OIC::SSM_S_OK){
-                   dlog_print(DLOG_DEBUG, LOG_TAG, "#### InitializeSSM() returned SSM_S_OK");
-               }
-               else{
-                   dlog_print(DLOG_DEBUG, LOG_TAG, "#### InitializeSSM() failed");
-               }
-       }
-       else
-       {
-           updateLog(ad, "WiFi not connected, connect first and re-run application");
-
-       }
-
-       return true;
+    /* Hook to take necessary actions before main event loop starts
+        Initialize UI resources and application's data
+        If this function returns true, the main loop of application starts
+        If this function returns false, the application is terminated */
+    appdata_s *ad = (appdata_s *)data;
+
+    std::string xmlDescription = "<SSMCore>"
+                                 "<Device>"
+                                 "<UDN>abcde123-31f8-11b4-a222-08002b34c050</UDN>"
+                                 "<Name>MyPC</Name>"
+                                 "<Type>PC</Type>"
+                                 "</Device>"
+                                 "<Config>"
+                                 "<SoftSensorDescription>"
+                                 "/opt/usr/apps/org.iotivity.service.ssm"
+                                 ".ssmtesterapp/lib/SoftSensorDescription.xml"
+                                 "</SoftSensorDescription>"
+                                 "<SoftSensorRepository>"
+                                 "/opt/usr/apps/org.iotivity.service.ssm"
+                                 ".ssmtesterapp/lib/"
+                                 "</SoftSensorRepository>"
+                                 "</Config>"
+                                 "</SSMCore>";
+
+    g_pQueryEngineEvent = new CQueryEngineEvent(ad);
+
+    create_base_gui(ad);
+
+    if (is_connected())
+    {
+        if (OIC::InitializeSSM(xmlDescription) == OIC::SSM_S_OK)
+        {
+            dlog_print(DLOG_DEBUG, LOG_TAG, "#### InitializeSSM() returned SSM_S_OK");
+        }
+        else
+        {
+            dlog_print(DLOG_DEBUG, LOG_TAG, "#### InitializeSSM() failed");
+        }
+    }
+    else
+    {
+        updateLog(ad, "WiFi not connected, connect first and re-run application");
+
+    }
+
+    return true;
 }
 
 static void
 app_control(app_control_h app_control, void *data)
 {
-       /* Handle the launch request. */
-       dlog_print(DLOG_INFO,LOG_TAG,"#### in app_control");
+    /* Handle the launch request. */
+    dlog_print(DLOG_INFO, LOG_TAG, "#### in app_control");
 }
 
 static void
 app_pause(void *data)
 {
-       /* Take necessary actions when application becomes invisible. */
-       dlog_print(DLOG_INFO,LOG_TAG,"#### in app_pause");
+    /* Take necessary actions when application becomes invisible. */
+    dlog_print(DLOG_INFO, LOG_TAG, "#### in app_pause");
 }
 
 static void
 app_resume(void *data)
 {
-       /* Take necessary actions when application becomes visible. */
-       dlog_print(DLOG_INFO,LOG_TAG,"#### in app_resume");
+    /* Take necessary actions when application becomes visible. */
+    dlog_print(DLOG_INFO, LOG_TAG, "#### in app_resume");
 }
 
 static void
 app_terminate(void *data)
 {
-       /* Release all resources. */
-       dlog_print(DLOG_INFO,LOG_TAG,"#### in app_terminate");
+    /* Release all resources. */
+    dlog_print(DLOG_INFO, LOG_TAG, "#### in app_terminate");
 
-       if (OIC::TerminateSSM() == OIC::SSM_S_OK){
-               dlog_print(DLOG_DEBUG, LOG_TAG, "#### TerminateSSM() returned SSM_S_OK");
-       }
-       else{
-               dlog_print(DLOG_DEBUG, LOG_TAG, "#### TerminateSSM() failed");
-       }
+    if (OIC::TerminateSSM() == OIC::SSM_S_OK)
+    {
+        dlog_print(DLOG_DEBUG, LOG_TAG, "#### TerminateSSM() returned SSM_S_OK");
+    }
+    else
+    {
+        dlog_print(DLOG_DEBUG, LOG_TAG, "#### TerminateSSM() failed");
+    }
 
-       delete g_pQueryEngineEvent;
+    delete g_pQueryEngineEvent;
 }
 
 static void
 ui_app_lang_changed(app_event_info_h event_info, void *user_data)
 {
-       /*APP_EVENT_LANGUAGE_CHANGED*/
-       char *locale = NULL;
-       system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
-       elm_language_set(locale);
-       free(locale);
-       return;
+    /*APP_EVENT_LANGUAGE_CHANGED*/
+    char *locale = NULL;
+    system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
+    elm_language_set(locale);
+    free(locale);
+    return;
 }
 
 static void
 ui_app_orient_changed(app_event_info_h event_info, void *user_data)
 {
-       /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
-       dlog_print(DLOG_INFO,LOG_TAG,"#### app orient changed");
-       return;
+    /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
+    dlog_print(DLOG_INFO, LOG_TAG, "#### app orient changed");
+    return;
 }
 
 static void
 ui_app_region_changed(app_event_info_h event_info, void *user_data)
 {
-       /*APP_EVENT_REGION_FORMAT_CHANGED*/
+    /*APP_EVENT_REGION_FORMAT_CHANGED*/
 }
 
 static void
 ui_app_low_battery(app_event_info_h event_info, void *user_data)
 {
-       /*APP_EVENT_LOW_BATTERY*/
+    /*APP_EVENT_LOW_BATTERY*/
 }
 
 static void
 ui_app_low_memory(app_event_info_h event_info, void *user_data)
 {
-       /*APP_EVENT_LOW_MEMORY*/
+    /*APP_EVENT_LOW_MEMORY*/
 }
 
 int
 main(int argc, char *argv[])
 {
-       appdata_s ad = {0,};
-       int ret = 0;
-
-       ui_app_lifecycle_callback_s event_callback = {0,};
-       app_event_handler_h handlers[5] = {NULL, };
-
-       event_callback.create = app_create;
-       event_callback.terminate = app_terminate;
-       event_callback.pause = app_pause;
-       event_callback.resume = app_resume;
-       event_callback.app_control = app_control;
-
-       ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
-       ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
-       ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
-       ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
-       ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
-       ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
-
-       ret = ui_app_main(argc, argv, &event_callback, &ad);
-
-       if (ret != APP_ERROR_NONE) {
-               dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
-       }
+    appdata_s ad = {0,};
+    int ret = 0;
+
+    ui_app_lifecycle_callback_s event_callback = {0,};
+    app_event_handler_h handlers[5] = {NULL, };
+
+    event_callback.create = app_create;
+    event_callback.terminate = app_terminate;
+    event_callback.pause = app_pause;
+    event_callback.resume = app_resume;
+    event_callback.app_control = app_control;
+
+    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY,
+                             ui_app_low_battery, &ad);
+    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY,
+                             ui_app_low_memory, &ad);
+    ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED],
+                             APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
+    ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED,
+                             ui_app_lang_changed, &ad);
+    ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
+                             APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
+    ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
+
+    ret = ui_app_main(argc, argv, &event_callback, &ad);
+
+    if (ret != APP_ERROR_NONE)
+    {
+        dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
+    }
 
-       return ret;
+    return ret;
 }
index 00fbf5b..73fd6ee 100644 (file)
@@ -42,7 +42,7 @@ if target_os not in ['windows', 'winrt']:
 
 if target_os == 'android':
     things_manager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
-    things_manager_env.PrependUnique(LIBS = ['oc', 'octbstack', 'gnustl_shared', 'android_cpp11_compat', 'log'])
+    things_manager_env.PrependUnique(LIBS = ['oc', 'octbstack', 'gnustl_shared'])
 
 ######################################################################
 # Source files and Targets
@@ -52,6 +52,11 @@ tgmsdk_static = things_manager_env.StaticLibrary('TGMSDKLibrary', tgm_src)
 tgmsdk_shared = things_manager_env.SharedLibrary('TGMSDKLibrary', tgm_src)
 
 things_manager_env.InstallTarget([tgmsdk_static,tgmsdk_shared], 'libTGMSDK')
+things_manager_env.UserInstallTargetLib([tgmsdk_static,tgmsdk_shared], 'libTGMSDK')
+
+# Build JNI layer
+#if target_os == 'android':
+#    SConscript(os.path.join('sdk', 'java', 'jni', 'SConscript'))
 
 #Go to build sample apps
 SConscript('sampleapp/SConscript')
index a509fe7..e8de3c4 100644 (file)
@@ -38,8 +38,8 @@ import android.util.Log;
  */
 public class ActionListener implements IActionListener {
 
-    private final String     LOG_TAG             = this.getClass()
-                                                         .getSimpleName();
+    private final String     LOG_TAG             = "[TMSample] " + this.getClass()
+                                                                   .getSimpleName();
     private static Message   msg;
     private String           logMessage;
     private GroupApiActivity groupApiActivityObj = null;
index 4795338..ca6b781 100644 (file)
@@ -227,6 +227,7 @@ public class ConfigurationApiActivity extends Activity {
                     case 0:
                         logs.setText("");
                         logs.setText(logMessage);
+                        Log.i(LOG_TAG, logMessage);
                 }
             }
         };
@@ -239,11 +240,9 @@ public class ConfigurationApiActivity extends Activity {
                 .get(CONFIGURATION_COLLECTION_RESOURCE_URI);
         if (null == configurationCollection
                 || null == configurationCollection.resource) {
-            Log.e(LOG_TAG, "configuration collection resource doest not exist!");
             displayToastMessage("Configuration collection resource does not exist!");
         }
         if (false == configurationResourceFlag) {
-            Log.e(LOG_TAG, "configuration resource doest not exist!");
             displayToastMessage("Configuration resource does not exist!");
         } else {
             final Dialog dialog = new Dialog(mcontext);
@@ -465,13 +464,11 @@ public class ConfigurationApiActivity extends Activity {
                 .get(CONFIGURATION_COLLECTION_RESOURCE_URI);
         if (null == configurationCollection
                 || null == configurationCollection.resource) {
-            Log.e(LOG_TAG, "configuration collection resource doest not exist!");
             displayToastMessage("Configuration collection resource does not exist!");
             return;
         }
         if (false == configurationResourceFlag) {
 
-            Log.e(LOG_TAG, "configuration resource doest not exist!");
             displayToastMessage("Configuration resource does not exist!");
             return;
         }
@@ -547,13 +544,11 @@ public class ConfigurationApiActivity extends Activity {
                 .get(DIAGNOSTIC_COLLECTION_RESOURCE_URI);
         if (null == diagnosticsCollection
                 || null == diagnosticsCollection.resource) {
-            Log.e(LOG_TAG, "Diagnostic collection doest not exist!");
             displayToastMessage("Diagnostic collection does not exist!");
             return;
         }
 
         if (false == diagnosticsResourceFlag) {
-            Log.e(LOG_TAG, "Diagnostic resource doest not exist!");
             displayToastMessage("Diagnostic resource does not exist!");
             return;
         }
@@ -587,12 +582,10 @@ public class ConfigurationApiActivity extends Activity {
                 .get(DIAGNOSTIC_COLLECTION_RESOURCE_URI);
         if (null == diagnosticsCollection
                 || null == diagnosticsCollection.resource) {
-            Log.e(LOG_TAG, "Diagnostic collection doest not exist!");
             displayToastMessage("Diagnostic collection does not exist!");
             return;
         }
         if (false == diagnosticsResourceFlag) {
-            Log.e(LOG_TAG, "Diagnostic resource doest not exist!");
             displayToastMessage("Diagnostic resource does not exist!");
             return;
         }
@@ -626,6 +619,7 @@ public class ConfigurationApiActivity extends Activity {
     private void displayToastMessage(String message) {
         Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
         toast.show();
+        Log.i(LOG_TAG, message);
     }
 
     private void collectionFound(OcResource resource) {
index 935eb4f..d5e502e 100644 (file)
@@ -32,7 +32,7 @@ import android.util.Log;
  */
 public class ConfigurationListener implements IConfigurationListener {
 
-    private final String LOG_TAG = this.getClass().getSimpleName();
+    private final String LOG_TAG = "[TMSample] " + this.getClass().getSimpleName();
 
     @Override
     public void onBootStrapCallback(Vector<OcHeaderOption> headerOptions,
index 31132d8..9905015 100644 (file)
@@ -32,7 +32,7 @@ import android.util.Log;
  */
 public class DiagnosticListener implements IDiagnosticsListener {
 
-    private final String LOG_TAG = this.getClass().getSimpleName();
+    private final String LOG_TAG = "[TMSample] " + this.getClass().getSimpleName();
 
     @Override
     public void onRebootCallback(Vector<OcHeaderOption> headerOptions,
index 02a3c5f..3ab7793 100644 (file)
@@ -28,6 +28,7 @@ import android.content.Context;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
@@ -62,6 +63,9 @@ public class GroupApiActivity extends Activity {
     // For Scheduled ActionSet
     public static Context           mcontext;
     public static Calendar          scheduleTime;
+    
+    private final String            LOG_TAG = "[TMSample] " + this.getClass()
+                                                               .getSimpleName();;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -112,6 +116,7 @@ public class GroupApiActivity extends Activity {
                     case 1:
                         logs.setText("");
                         logs.setText(logMessage);
+                        Log.i(LOG_TAG, logMessage);
                 }
             }
         };
@@ -249,5 +254,6 @@ public class GroupApiActivity extends Activity {
     public void displayToastMessage(String message) {
         Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
         toast.show();
+        Log.i(LOG_TAG, message);
     }
 }
index 093dfac..0bc6d72 100644 (file)
@@ -50,7 +50,7 @@ import android.util.Log;
  */
 public class GroupClient {
 
-    private static final String     LOG_TAG             = "GroupClient";
+    private static final String     LOG_TAG             = "[TMSample] GroupClient";
     private static Message          msg;
     public String                   logMessage;
 
@@ -99,8 +99,8 @@ public class GroupClient {
                 String uri = resource.getUri();
                 if (uri.equals("/b/collection") == true) {
                     String hostAddress = resource.getHost();
-                    Log.d("URI: onGroupFindCallback", uri);
-                    Log.d("HOST: onGroupFindCallback", hostAddress);
+                    Log.d(LOG_TAG, "onGroupFindCallback URI : " + uri);
+                    Log.d(LOG_TAG, "onGroupFindCallback HOST : " + hostAddress);
 
                     groupResource = resource;
                     Message msg = Message.obtain();
@@ -115,7 +115,7 @@ public class GroupClient {
                     msg.what = 1;
                     groupApiActivityObj.getHandler().sendMessage(msg);
                 } else {
-                    Log.d("onGroupFindCallback URI : ", uri);
+                    Log.d(LOG_TAG, "onGroupFindCallback URI : " + uri);
                 }
             } else {
                 Log.i(LOG_TAG, "Resource is NULL");
index 2482055..3ea6935 100644 (file)
@@ -54,8 +54,8 @@ public class MainActivity extends Activity {
     private ArrayAdapter<String> apis;
     private ArrayList<String>    apisList;
     private ListView             list;
-    private final String         LOG_TAG          = this.getClass()
-                                                          .getSimpleName();
+    private final String         LOG_TAG          = "[TMSample] " + this.getClass()
+                                                                           .getSimpleName();
     public ThingsManager         thingsManagerObj = new ThingsManager();
 
     @Override
@@ -130,6 +130,7 @@ public class MainActivity extends Activity {
 
             dialog = dialogBuilder.create();
             dialog.show();
+            Log.i(LOG_TAG, "WiFi is not enabled/connected! Please connect the WiFi and start application again...");
             return;
         }
         // If wifi is connected calling the configure method for configuring the
index 63d9286..1acdc3b 100644 (file)
@@ -46,7 +46,7 @@ import android.widget.EditText;
  */
 public class MainActivity extends Activity {
 
-    private final String         LOG_TAG = this.getClass().getSimpleName();
+    private final String         LOG_TAG = "[CON-SERVER]" + this.getClass().getSimpleName();
     private Handler              mHandler;
     private static MainActivity  mainActivityObj;
     private ConfigurationServer  conServerObj;
@@ -72,6 +72,7 @@ public class MainActivity extends Activity {
                 switch (msg.what) {
                     case 0:
                         editText.setText(message);
+                        Log.i(LOG_TAG, message);
                 }
             }
         };
@@ -124,6 +125,7 @@ public class MainActivity extends Activity {
 
             AlertDialog dialog = dialogBuilder.create();
             dialog.show();
+            Log.i(LOG_TAG, "WiFi is not enabled/connected! Please connect the WiFi and start application again...");
             return;
         }
 
@@ -162,6 +164,7 @@ public class MainActivity extends Activity {
         dialog.setProgress(0);
         dialog.setMax(100);
         dialog.show();
+        Log.i(LOG_TAG, "Rebooting.. Please wait ...");
         Thread thread = new Thread() {
             @Override
             public void run() {
index c3332ce..962b7f2 100644 (file)
@@ -57,7 +57,7 @@ conserver = linux_sample_env.Program('con-server', ['ConfigurationCollection.cpp
 conclient = linux_sample_env.Program('con-client', 'con-client.cpp')
 bootstrapserver = linux_sample_env.Program('bootstrapserver', 'bootstrapserver.cpp')
 Alias("ConServerApp", conserver)
-Alias("ConCleintApp", conclient)
+Alias("ConClientApp", conclient)
 Alias("BootstrapServerApp", bootstrapserver)
 env.AppendTarget('ConServerApp')
 env.AppendTarget('ConClientApp')
index 413b324..8959a01 100644 (file)
@@ -479,13 +479,13 @@ int main()
 
                 if (n == 9)
                 {
-                    std::string query = OC_MULTICAST_DISCOVERY_URI;
+                    std::string query = OC_RSRVD_WELL_KNOWN_URI;
                     query.append("?rt=");
                     query.append(resourceTypeName);
 
                     OCPlatform::findResource("",
                             query,
-                            OC_ALL,
+                            CT_DEFAULT,
                             &foundResource);
 
                     // OCPlatform::findResource("",
@@ -495,13 +495,13 @@ int main()
                 }
                 else if (n == 0)
                 {
-                    std::string query = OC_MULTICAST_DISCOVERY_URI;
+                    std::string query = OC_RSRVD_WELL_KNOWN_URI;
                     query.append("?rt=");
                     query.append("core.bookmark");
 
                     OCPlatform::findResource("",
                             query,
-                            OC_ALL,
+                            CT_DEFAULT,
                             &foundResource);
                     // OCPlatform::findResource("",
                     //         query,
index e4efebb..159a99c 100644 (file)
@@ -38,7 +38,7 @@ musicplayer = linux_sample_env.Program('musicplayer', 'musicplayer.cpp')
 phone = linux_sample_env.Program('phone', 'phone.cpp')
 speaker = linux_sample_env.Program('speaker', 'speaker.cpp')
 Alias("GroupApp", group)
-Alias("ConCleintApp", musicplayer)
+Alias("MusicplayerApp", musicplayer)
 Alias("PhoneApp", phone)
 Alias("SpeakerApp", speaker)
 env.AppendTarget('GroupApp')
old mode 100644 (file)
new mode 100755 (executable)
index 91e9950..fd90e82
@@ -38,38 +38,44 @@ void onFindResource(std::shared_ptr< OCResource > resource)
 {
     cout << "onFindResource" << endl;
 
-    if (resource)
+    try
     {
-        OCResourceHandle resourceHandle;
-        OCStackResult result = OCPlatform::registerResource(resourceHandle, resource);
-        if (OC_STACK_OK == result)
-        {
-            cout << "onFindResource : Resource creation was successful\n";
-        }
-        else
+        if (resource)
         {
-            cout << "onFindResource : Resource creation was unsuccessful\n";
-            return;
-        }
+            OCResourceHandle resourceHandle;
+            OCStackResult result = OCPlatform::registerResource(resourceHandle, resource);
+            if (OC_STACK_OK == result)
+            {
+                cout << "onFindResource : Resource creation was successful\n";
+            }
+            else
+            {
+                cout << "onFindResource : Resource creation was unsuccessful\n";
+                return;
+            }
 
-        result = gThingManager->joinGroup(collectionResourceType, resourceHandle);
-        if (OC_STACK_OK == result)
-        {
-            cout << "onFindResource : Joining group was successful\n";
+            result = gThingManager->joinGroup(collectionResourceType, resourceHandle);
+            if (OC_STACK_OK == result)
+            {
+                cout << "onFindResource : Joining group was successful\n";
+            }
+            else
+            {
+                cout << "onFindResource : Joining group was unsuccessful\n";
+
+                OCPlatform::unregisterResource(resourceHandle);
+                return;
+            }
+
+            gResourceHandleList.push_back(resourceHandle);
         }
         else
         {
-            cout << "onFindResource : Joining group was unsuccessful\n";
-
-            OCPlatform::unregisterResource(resourceHandle);
-            return;
+            cout << "onFindResource : There is no found resource." << endl;
         }
-
-        gResourceHandleList.push_back(resourceHandle);
-    }
-    else
+    }catch (std::exception& e)
     {
-        cout << "onFindResource : There is no found resource." << endl;
+        std::cout << "Exception: " << e.what() << std::endl;
     }
 }
 
@@ -113,17 +119,12 @@ int main(int argc, char* argv[])
             else if (selectedMenu == 11)
             {
                 ostringstream query;
-                query << OC_MULTICAST_DISCOVERY_URI << "?rt=core.musicplayer";
+                query << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.musicplayer";
 
                 cout << query.str() << endl;
                 result = OCPlatform::findResource("",
                             query.str(),
-                            OC_ALL,
-                            onFindResource);
-
-                result = OCPlatform::findResource("",
-                            "coap://224.0.1.187/oc/core?rt=core.musicplayer",
-                            OC_ALL,
+                            CT_DEFAULT,
                             onFindResource);
 
                 if (OC_STACK_OK == result)
@@ -138,10 +139,10 @@ int main(int argc, char* argv[])
             else if (selectedMenu == 12)
             {
                 ostringstream query;
-                query << OC_MULTICAST_DISCOVERY_URI << "?rt=core.speaker";
+                query << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.speaker";
                 result = OCPlatform::findResource("",
                             query.str(),
-                            OC_ALL,
+                            CT_DEFAULT,
                             onFindResource);
 
                 if (OC_STACK_OK == result)
old mode 100644 (file)
new mode 100755 (executable)
index fa148b2..64fa656
@@ -86,6 +86,8 @@ int main(int argc, char* argv[])
 
     OCPlatform::Configure(cfg);
 
+    OCPlatform::startPresence(30);
+
     int selectedMenu;
     OCStackResult result;
     OCResourceHandle mpResourceHandle = NULL;
old mode 100644 (file)
new mode 100755 (executable)
index 1e9ad79..4693637
@@ -40,6 +40,11 @@ static ActionSet* gPlayStart;
 
 static ActionSet* gPlayStop;
 
+void presenceCallback(std::string msg, OCStackResult res)
+{
+    std::cout << "Presence Callback: " << msg << "(" << res << ")" << std::endl;
+}
+
 void onFindGroup(std::shared_ptr< OCResource > resource)
 {
     if (resource)
@@ -60,6 +65,12 @@ void onFindGroup(std::shared_ptr< OCResource > resource)
         {
             cout << "onFindGroup : Found group is saved now." << endl;
             gFindGroup = resource;
+            {
+                OCStackResult res;
+                res = gThingManager->subscribeCollectionPresence( resource, &presenceCallback);
+
+                std::cout << "Return Value: " << res << std::endl;
+            }
         }
 
         gThingManager->joinGroup(gFindGroup, gPhoneResourceHandle);
old mode 100644 (file)
new mode 100755 (executable)
index 4e90f3f..9f6d5a2
@@ -87,6 +87,8 @@ int main(int argc, char* argv[])
 
     OCPlatform::Configure(cfg);
 
+    OCPlatform::startPresence(30);
+
     int selectedMenu;
     OCStackResult result;
     OCResourceHandle speakerResourceHandle = NULL;
index 544c81e..b7c81d1 100644 (file)
                                     <listOptionValue builtIn="false" value="TGMSDKLibrary"/>
                                     <listOptionValue builtIn="false" value="oc"/>
                                     <listOptionValue builtIn="false" value="octbstack"/>
-                                    <listOptionValue builtIn="false" value="coap"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="connectivity_abstraction"/>
+                                    <listOptionValue builtIn="false" value="uuid"/>
                                 </option>
                                 <option id="sbi.gnu.cpp.linker.option.shared_flag.core.1600357455" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" value="false" valueType="boolean"/>
                                 <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1548223100" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
index de6c1b3..c58825f 100644 (file)
@@ -214,6 +214,7 @@ OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceReques
         if (OC_STACK_OK == sendResponseForResource(request))
         {
             ehResult = OC_EH_OK;
+            dlog_print(DLOG_INFO, LOG_TAG, "#### sendResponse success.");
         }
         else
         {
@@ -235,6 +236,7 @@ void *updateLog(void *data)
     elm_entry_entry_append(log_entry, log->c_str());
     elm_entry_cursor_end_set(log_entry);
 
+    dlog_print(DLOG_INFO, LOG_TAG, "%s", log->c_str());
     dlog_print(DLOG_INFO, LOG_TAG, "#### updateLog exit!!!!");
 
     return NULL;
@@ -296,6 +298,8 @@ void onBootStrapCallback(const HeaderOptions &headerOptions, const OCRepresentat
     logMessage += "currency : " + defaultCurrency + "<br>";
     logMessage += "Region : " + defaultRegion + "<br>";
 
+    dlog_print(DLOG_INFO, LOG_TAG, "  %s", logMessage.c_str());
+
     //Call updateLog in the thread safe mode
     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
 
@@ -343,6 +347,8 @@ createConfResource_cb(void *data , Evas_Object *obj , void *event_info)
     {
         logMessage += "Resources were created already!!! <br>";
     }
+
+    dlog_print(DLOG_INFO, LOG_TAG, "  %s", logMessage.c_str());
     // Show the log in the UI
     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
 }
index 7510b8c..fca08f6 100644 (file)
@@ -141,6 +141,7 @@ void DiagnosticsResource::diagnosticsMonitor(int second)
             logMessage = "----------------------------<br>";
             logMessage += "*** System Reboot Success ***<br>";
 
+            dlog_print(DLOG_INFO, LOG_TAG, "  %s", logMessage.c_str());
             //Show the log
             ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
 
index 2d67c99..94660c2 100644 (file)
                                     <listOptionValue builtIn="false" value="TGMSDKLibrary"/>
                                     <listOptionValue builtIn="false" value="oc"/>
                                     <listOptionValue builtIn="false" value="octbstack"/>
-                                    <listOptionValue builtIn="false" value="coap"/>
                                     <listOptionValue builtIn="false" value="oc_logger"/>
                                     <listOptionValue builtIn="false" value="connectivity_abstraction"/>
+                                    <listOptionValue builtIn="false" value="uuid"/>
                                 </option>
                                 <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.618645708" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
                                     <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
index 509a086..ee434ed 100644 (file)
@@ -99,6 +99,7 @@ void onFoundCollectionResource(std::vector< std::shared_ptr< OCResource > > reso
                 logMessage += "----------------------<br>";
                 dlog_print(DLOG_INFO, LOG_TAG, "FoundHost: %s", resourceURI.c_str());
                 dlog_print(DLOG_INFO, LOG_TAG, "FoundUri : %s", hostAddress.c_str());
+                dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
                 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog,
                                                       &logMessage);
 
@@ -117,7 +118,9 @@ void onFoundCollectionResource(std::vector< std::shared_ptr< OCResource > > reso
             else
             {
                 // Resource is invalid
+
                 logMessage = "Found Resource invalid!";
+                dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
                 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog,
                                                       &logMessage);
             }
@@ -168,6 +171,7 @@ void onFoundCandidateResource(std::vector< std::shared_ptr< OCResource > > resou
                         logMessage += "----------------------<br>";
                         dlog_print(DLOG_INFO, LOG_TAG, "Host: %s", resourceURI.c_str());
                         dlog_print(DLOG_INFO, LOG_TAG, "Uri : %s", hostAddress.c_str());
+                        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
                         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog,
                                                               &logMessage);
 
@@ -294,6 +298,7 @@ static void onUpdateConfigurationsCallback(const HeaderOptions &headerOptions,
         logMessage = logMessage + "Region : " + rep.getValue< std::string >("r") + "<br>";
     }
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog,
                                           &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### onUpdateConfigurationsCallback: EXIT!!!!");
@@ -343,6 +348,7 @@ static void onGetConfigurationsCallback(const HeaderOptions &headerOptions,
     }
 
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### onGetConfigurationsCallback: exit!!!!");
 }
@@ -366,6 +372,7 @@ static void onFactoryReset(const HeaderOptions &headerOptions, const OCRepresent
     logMessage = logMessage + "FactoryReset : " +
                  rep.getValue< std::string >("value") + "<br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### onFactoryReset: exit!!!!");
 }
@@ -389,6 +396,7 @@ static void onReboot(const HeaderOptions &headerOptions, const OCRepresentation
     logMessage = logMessage + "Reboot : " +
                  rep.getValue< std::string >("value") + "<br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### onReboot: exit!!!!");
 }
@@ -412,6 +420,7 @@ static void createResourceCollection(string uri, string typeName, OCResourceHand
     string logMessage;
     logMessage = "Resource created : <br>" + typeName + "<br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### createResourceCollection: exit!!!!");
 }
@@ -514,6 +523,7 @@ static void getConfiguration(void *data, Evas_Object *obj, void *event_info)
     {
         dlog_print(DLOG_ERROR, LOG_TAG, "Note that you first create a group to use this command");
         string logMessage = "FIRST CREATE GROUP <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
         return;
     }
@@ -547,6 +557,7 @@ static void updateConfiguration(std::string newRegionValue)
         dlog_print(DLOG_ERROR, LOG_TAG, "Note that you first create a group to use this command");
         string logMessage = "FIRST CREATE GROUP <br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
         return;
     }
@@ -572,6 +583,7 @@ static void updateConfiguration(std::string newRegionValue)
     {
         string logMessage = "UpdateConfigurations called successfully<br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     }
 
@@ -587,6 +599,7 @@ static void factoryReset(void *data, Evas_Object *obj, void *event_info)
         dlog_print(DLOG_ERROR, LOG_TAG, "Note that you first create a group to use this command");
         string logMessage = "FIRST CREATE GROUP <br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
         return;
     }
@@ -606,6 +619,7 @@ static void factoryReset(void *data, Evas_Object *obj, void *event_info)
     {
         string logMessage = "FactoryReset called successfully<br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     }
 
@@ -621,6 +635,7 @@ static void reboot(void *data, Evas_Object *obj, void *event_info)
         dlog_print(DLOG_INFO, LOG_TAG, "Note that you first create a group to use this command");
         string logMessage = "FIRST CREATE GROUP <br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
         return;
     }
@@ -640,6 +655,7 @@ static void reboot(void *data, Evas_Object *obj, void *event_info)
     {
         string logMessage = "Reboot called successfully<br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     }
     dlog_print(DLOG_INFO, LOG_TAG, "#### reboot EXIT!!!!");
@@ -657,6 +673,7 @@ static void getListOfSupportedConfigurationUnits(void *data, Evas_Object *obj, v
     string logMessage;
     logMessage = "Supported Configuration List :<br>" + listOfSupportedConfigurationUnits + "<br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### getListOfSupportedConfigurationUnits EXIT!!!!");
 }
@@ -708,6 +725,7 @@ popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
         dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL RegionValue");
         string logMessage = "Region Value should not be NULL<br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
     }
     else
@@ -726,6 +744,7 @@ list_update_region_cb(void *data, Evas_Object *obj, void *event_info)
     {
         dlog_print(DLOG_ERROR, LOG_TAG, "Note that you first create a group to use this command");
         string logMessage = "FIRST CREATE GROUP <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
         return;
     }
@@ -761,8 +780,6 @@ list_update_region_cb(void *data, Evas_Object *obj, void *event_info)
     if (NULL == popup_fields)
     {
         dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
-        popup_fields->popup = NULL;
-        popup_fields->entry = NULL;
     }
     else
     {
@@ -812,6 +829,7 @@ static Eina_Bool
 naviframe_pop_cb(void *data, Elm_Object_Item *it)
 {
     onDestroyConfigure();
+    resourceTable.clear();
     if (NULL != log_entry)
     {
         evas_object_del(log_entry);
index 3175137..5bce243 100644 (file)
@@ -76,6 +76,7 @@ void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, cons
         dlog_print(DLOG_INFO, LOG_TAG, "#### Invalid Parameter");
     }
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                           &logMessage);
 }
@@ -127,6 +128,7 @@ void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, con
         }
     }
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                           &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### onPost callback received EXIT!!!!");
@@ -146,6 +148,7 @@ static void createActionSet_AllBulbOff()
         string logMessage = "NO LIGHTSERVER FOUND <br>";
         logMessage += "----------------------<br>";
         dlog_print(DLOG_INFO, LOG_TAG, "#### NO LIGHT SERVER FOUND");
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                               &logMessage);
         delete actionSet;
@@ -182,6 +185,7 @@ static void createActionSet_AllBulbOff()
 
     string logMessage = "Create actionset AllBulbOFF success <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### createActionSet_AllBulbOff EXIT");
 }
@@ -239,6 +243,7 @@ static void createActionSet_AllBulbOn()
 
     string logMessage = "Create actionset AllBulbON success <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### createActionSet_AllBulbOff OFF EXIT");
 }
@@ -392,6 +397,7 @@ static void executeActionSetOff(void *data, Evas_Object *obj, void *event_info)
 
     string logMessage = "Actionset OFF called successfully <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### executeActionSetOff EXIT");
 }
@@ -426,6 +432,7 @@ static void executeActionSetOn(void *data, Evas_Object *obj, void *event_info)
 
     string logMessage = "Actionset ON called successfully <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### executeActionSetOn EXIT");
 }
@@ -522,6 +529,7 @@ static void deleteActionSetOff(void *data, Evas_Object *obj, void *event_info)
 
     string logMessage = "Actionset OFF DELETED <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### deleteActionSetOff EXIT");
 }
@@ -556,6 +564,7 @@ static void deleteActionSetOn(void *data, Evas_Object *obj, void *event_info)
 
     string logMessage = "Actionset ON DELETED <br>";
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     dlog_print(DLOG_INFO, LOG_TAG, "#### deleteActionSetOn EXIT");
 }
@@ -593,12 +602,14 @@ void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep, c
         }
         sprintf(buf, "%d", level);
         logMessage += "level:" + string(buf) + "<br>";
+        free(buf);
     }
     else
     {
         logMessage = "onObserve error!!!";
     }
     logMessage += "----------------------<br>";
+    dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                           &logMessage);
 }
@@ -660,6 +671,7 @@ void foundResources(std::vector< std::shared_ptr< OC::OCResource > > listOfResou
                 (*rsrc)->observe(ObserveType::Observe, QueryParamsMap(), &onObserve);
                 dlog_print(DLOG_INFO, LOG_TAG, "#### after calling observe() for bookmark!!!!");
             }
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                                   &logMessage);
         }
@@ -868,6 +880,7 @@ popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
         dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL DateTime Value");
         string logMessage = "DateTime should not be NULL<br>";
         logMessage += "----------------------<br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
     }
     else
@@ -897,6 +910,7 @@ popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
             dlog_print(DLOG_INFO, LOG_TAG, "#### Incorrect date/time values");
             string logMessage = "Incorrect date/time value<br>";
             logMessage += "----------------------<br>";
+            dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                                   &logMessage);
         }
@@ -940,8 +954,6 @@ list_scheduled_actionset_cb(void *data, Evas_Object *obj, void *event_info)
     if (NULL == popup_fields)
     {
         dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
-        popup_fields->popup = NULL;
-        popup_fields->entry = NULL;
     }
     else
     {
@@ -1036,6 +1048,7 @@ void foundResource(shared_ptr< OCResource > resource)
             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showGroupAPIs, NULL);
 
         }
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
                                               &logMessage);
     }
index 1aa9465..5ec0a20 100644 (file)
@@ -35,7 +35,6 @@
 #include <ActionSet.h>
 #include "OCPlatform.h"
 #include "OCApi.h"
-#include "GroupManager.h"
 
 using namespace OC;
 
index 395d11f..2d17144 100644 (file)
@@ -1,56 +1,69 @@
 LOCAL_PATH := $(call my-dir)
 
-ifeq ($(strip $(ANDROID_NDK)),)
-$(error ANDROID_NDK is not set!)
-endif
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/release
+LOCAL_MODULE := android-oc_logger
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc_logger.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/release
+LOCAL_MODULE := android-octbstack
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboctbstack.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-OIC_LIB_PATH := ../../../../../dep/android/$(TARGET_ARCH_ABI)/usr/lib
-LOCAL_MODULE := libandroid-boost_system
-LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libboost_system.a
-include $(PREBUILT_STATIC_LIBRARY)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/release
+LOCAL_MODULE := android-oc
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/release
+LOCAL_MODULE := android-connectivity_abstraction
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../android/android_api/base/libs/$(TARGET_ARCH_ABI)
+LOCAL_MODULE := android-ocstack-jni
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocstack-jni.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../android/android_api/base/libs/$(TARGET_ARCH_ABI)
+LOCAL_MODULE := android-ca-interface
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libca-interface.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
 OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/release
-LOCAL_MODULE := libandroid-thingsmanager
+LOCAL_MODULE := android-thingsmanager
 LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libTGMSDKLibrary.so
 include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release
-BASE_LIB_PATH := ../../../../android/android_api/base/libs/$(TARGET_ARCH_ABI)
-OIC_RESOURCE_PATH := ../../../../resource
-OIC_SERVICE_PATH := ../../../../service
-OIC_OUT_PATH := ../../../../out
+OIC_SRC_DIR := ../../../..
 LOCAL_MODULE    := things-manager-jni
 
-LOCAL_C_INCLUDES := $(OIC_RESOURCE_PATH)/include \
-                    $(OIC_RESOURCE_PATH)/csdk/stack/include \
-                    $(OIC_RESOURCE_PATH)/csdk/ocsocket/include \
-                    $(OIC_RESOURCE_PATH)/oc_logger/include \
-                    $(OIC_RESOURCE_PATH)/android/include \
-                    $(OIC_RESOURCE_PATH)/dependencies/cereal/include \
-                    $(OIC_RESOURCE_PATH)/../extlibs/boost/boost_1_58_0 \
-                    $(OIC_RESOURCE_PATH)/../extlibs/timer \
-                    $(OIC_SERVICE_PATH)/things-manager/sdk/inc \
-                    $(OIC_SERVICE_PATH)/things-manager/sdk/src \
-                    $(OIC_SERVICE_PATH)/../android/android_api/base/jni \
-                    $(OIC_SERVICE_PATH)/../build_common/android/compatibility \
-                    $(LOCAL_PATH)/jniutil/inc \
-                    $(LOCAL_PATH)/tm/inc \
-                    $(LOCAL_PATH)/tm/src \
-                    $(LOCAL_PATH)/tm/src/base \
-                    $(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/include \
-                    $(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI)/include \
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/jniutil/inc \
+                    $(OIC_SRC_DIR)/android/android_api/base/jni \
+                    $(OIC_SRC_DIR)/resource/include \
+                    $(OIC_SRC_DIR)/resource/csdk/stack/include \
+                    $(OIC_SRC_DIR)/resource/oc_logger/include \
+                    $(OIC_SRC_DIR)/extlibs/boost/boost_1_58_0 \
+                    $(OIC_SRC_DIR)/extlibs/timer \
+                    $(OIC_SRC_DIR)/service/things-manager/sdk/inc \
+                    $(LOCAL_PATH)/tm/inc
 
 LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/jniutil/src/*.cpp))
 LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/tm/src/*.cpp))
 
 LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions
 
-LOCAL_LDLIBS := -llog -L$(BASE_LIB_PATH) -locstack-jni -L$(OIC_LIB_PATH) -loc -loctbstack -lcoap -loc_logger
-LOCAL_LDLIBS += -L$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI) -lgnustl_shared
-LOCAL_SHARED_LIBRARIES := android-thingsmanager
-LOCAL_STATIC_LIBRARIES := android-boost_system
+LOCAL_LDLIBS := -llog
+LOCAL_SHARED_LIBRARIES := android-ocstack-jni
+LOCAL_SHARED_LIBRARIES += android-thingsmanager
+LOCAL_SHARED_LIBRARIES += android-oc
 
 include $(BUILD_SHARED_LIBRARY)
index d02cd64..c177a13 100644 (file)
@@ -1,2 +1,2 @@
 NDK_TOOLCHAIN_VERSION := 4.9
-#APP_STL               := gnustl_shared
+APP_STL               := gnustl_shared
index bad2e0b..2c1219b 100644 (file)
@@ -2,6 +2,7 @@
 # Things manager service JNI build script
 ##
 
+import os
 Import('env')
 
 # Add third party libraries
@@ -9,31 +10,46 @@ lib_env = env.Clone()
 SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
 
 tm_jni_env = lib_env.Clone()
-target_os = env.get('TARGET_OS')
-tm_sdk = env.get('SRC_DIR') + '/service/things-manager/sdk'
-base_jni = env.get('SRC_DIR') + '/android/android_api/base/jni'
+target_os = tm_jni_env.get('TARGET_OS')
+tm_sdk = tm_jni_env.get('SRC_DIR') + '/service/things-manager/sdk'
+base_jni = tm_jni_env.get('SRC_DIR') + '/android/android_api/base/jni'
+extlibs = tm_jni_env.get('SRC_DIR') + '/extlibs'
 
 ######################################################################
 # Build flags
 ######################################################################
 tm_jni_env.AppendUnique(CXXFLAGS = ['-Wall', '-DLINUX', '-DNDEBUG'])
-tm_jni_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
-tm_jni_env.AppendUnique(LIBPATH = [base_jni+'/../libs/'+env.get('TARGET_ARCH')])
-tm_jni_env.PrependUnique(LIBS = ['ocstack-jni', 'TGMSDKLibrary', 'oc', 'octbstack', 'boost_system', 'gnustl_shared', 'compatibility', 'log'])
+tm_jni_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions', '-std=c++0x'])
+tm_jni_env.AppendUnique(LIBPATH = [base_jni+'/../libs/'+tm_jni_env.get('TARGET_ARCH')])
+tm_jni_env.PrependUnique(LIBS = ['ocstack-jni', 'TGMSDKLibrary', 'oc', 'gnustl_shared', 'log'])
 
-tm_jni_env.AppendUnique(CPPPATH = [tm_sdk+'/inc', tm_sdk+'/src'])
+tm_jni_env.AppendUnique(CPPPATH = [tm_sdk+'/inc'])
 tm_jni_env.AppendUnique(CPPPATH = [base_jni])
-tm_jni_env.AppendUnique(CPPPATH = ['tm/inc', 'tm/src', 'jniutil/inc', 'jniutil/src', '../../../../../extlibs/timer/'])
+tm_jni_env.AppendUnique(CPPPATH = ['tm/inc', 'jniutil/inc', extlibs+'/timer/'])
 
 ######################################################################
 # Source files and Targets
 ######################################################################
-tm_jni_src = [env.Glob('tm/src/*.cpp'), env.Glob('jniutil/src/*.cpp')]
+tm_jni_src = [tm_jni_env.Glob('tm/src/*.cpp'), tm_jni_env.Glob('jniutil/src/*.cpp')]
 tm_jni = tm_jni_env.SharedLibrary('things-manager-jni', tm_jni_src)
 
 tm_jni_env.InstallTarget(tm_jni, 'libthings-manager-jni')
+tm_jni_env.UserInstallTargetLib(tm_jni, 'libthings-manager-jni')
 
 # Install the libraries to /libs/<TARGET_ARCH> directory
-tm_jni_env.Install(tm_sdk+'/java/libs/'+env.get('TARGET_ARCH'),env.get('BUILD_DIR')+'/libTGMSDKLibrary.so')
-tm_jni_env.Install(tm_sdk+'/java/libs/'+env.get('TARGET_ARCH'),tm_jni)
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni_env.get('BUILD_DIR')+'/liboc_logger.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni_env.get('BUILD_DIR')+'/liboctbstack.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni_env.get('BUILD_DIR')+'/liboc.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni_env.get('BUILD_DIR')+'/libconnectivity_abstraction.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),base_jni+'/../libs/'+tm_jni_env.get('TARGET_ARCH')+'/libocstack-jni.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),base_jni+'/../libs/'+tm_jni_env.get('TARGET_ARCH')+'/libca-interface.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni_env.get('BUILD_DIR')+'/libTGMSDKLibrary.so')
+tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'),tm_jni)
+
+gnu_lib_paths = env.get('LIBPATH')
+for gnu_lib_path in gnu_lib_paths:
+    gnu_lib_path = gnu_lib_path + '/libgnustl_shared.so'
+    if os.path.exists(gnu_lib_path):
+        tm_jni_env.Install(tm_sdk+'/java/libs/'+tm_jni_env.get('TARGET_ARCH'), gnu_lib_path)
+        break
 
index cbcc4d0..cac79df 100644 (file)
  *
  */
 
-#include "GroupManager.h"
 #include <algorithm>
 #include <thread>
 #include <unistd.h>
-
 #include <string.h>
 
+#include "GroupManager.h"
+
 #define PLAIN_DELIMITER "\""
 #define ACTION_DELIMITER "*"
 #define DESC_DELIMITER "|"
@@ -223,13 +223,13 @@ OCStackResult GroupManager::findCandidateResources(
     {
         // std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
 
-        std::string query = OC_MULTICAST_DISCOVERY_URI;
+        std::string query = OC_RSRVD_WELL_KNOWN_URI;
         query.append("?rt=");
         query.append(resourceTypes.at(i));
 
         OCPlatform::findResource("",
                 query,
-                OC_ALL,
+                CT_DEFAULT,
                 std::function < void(std::shared_ptr < OCResource > resource)
                         > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
                                 waitsec)));
@@ -362,7 +362,7 @@ void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep,
             result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
                     // resourceType,
                     resourceTypes.front(),
-                    OC_ALL,
+                    CT_DEFAULT,
                     std::function<
                             void(OCStackResult result, const unsigned int nonce,
                                     const std::string& hostAddress) >(
@@ -486,6 +486,7 @@ ActionSet* GroupManager::getActionSetfromString(std::string description)
     char *plainPtr = NULL;
     char *attr = NULL, *desc = NULL;
 
+    Action *action = NULL;
     Capability *capa = NULL;
     ActionSet *actionset = new ActionSet();
 
@@ -540,7 +541,6 @@ ActionSet* GroupManager::getActionSetfromString(std::string description)
 
         if (desc != NULL)
         {
-            Action *action = NULL;
             strcpy(desc, token);
             token = strtok_r(desc, DESC_DELIMITER, &descPtr);
 
@@ -554,7 +554,7 @@ ActionSet* GroupManager::getActionSetfromString(std::string description)
                 token = strtok_r(attr, ATTR_DELIMITER, &attrPtr);
                 while (token != NULL)
                 {
-                    if (strcmp(token, "uri") == 0)
+                    if ( (action == NULL) && strcmp(token, "uri") == 0)    //consider only first "uri" as uri, other as attribute.
                     {
                         token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
                         if(token == NULL)
@@ -596,7 +596,10 @@ ActionSet* GroupManager::getActionSetfromString(std::string description)
             }
 
             if( action != NULL )
+            {
                 actionset->listOfAction.push_back(action);
+                action = NULL;
+            }
             else
                 goto exit;
             //delete action;
@@ -612,10 +615,11 @@ ActionSet* GroupManager::getActionSetfromString(std::string description)
         token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
     }
 
-    DELETE(plainText);
+    DELETEARRAY(plainText);
     return actionset;
 
 exit:
+    DELETE(action);
     DELETE(capa)
     DELETE(actionset)
     DELETEARRAY(attr);
index b60c045..d8c3e9b 100644 (file)
@@ -73,12 +73,12 @@ namespace OIC
         for (unsigned int i = 0; i < collectionResourceTypes.size(); ++i)
         {
 
-            std::string query = OC_MULTICAST_DISCOVERY_URI;
+            std::string query = OC_RSRVD_WELL_KNOWN_URI;
             query.append("?rt=");
             query.append(collectionResourceTypes.at(i));
 
             OCPlatform::findResource("", query,
-                    OC_ALL,
+                    CT_DEFAULT,
                     std::bind(&GroupSynchronization::onFindGroup, this,
                         std::placeholders::_1));
         }
@@ -288,7 +288,7 @@ namespace OIC
         OCResource::Ptr groupSyncResource =
                         OCPlatform::constructResourceObject(host, uri,
 
-                            OC_ALL, false,
+                            CT_DEFAULT, false,
                             resourceTypes, resourceInterface);
 
         // OCResource::Ptr groupSyncResource = OCPlatform::constructResourceObject(host, uri,
@@ -466,7 +466,7 @@ OCStackResult GroupSynchronization::leaveGroup(
 
         OCResource::Ptr groupSyncResource;
         groupSyncResource = OCPlatform::constructResourceObject(host, uri,
-                OC_ALL, false,
+                CT_DEFAULT, false,
                 resourceTypes, resourceInterface);
         // groupSyncResource = OCPlatform::constructResourceObject(host, uri,
         //         OC_WIFI, false, resourceTypes, resourceInterface);
@@ -697,7 +697,7 @@ OCStackResult GroupSynchronization::leaveGroup(
 
                     if (methodType == "joinGroup")
                     {
-                        std::string resourceName = OC_MULTICAST_DISCOVERY_URI;
+                        std::string resourceName = OC_RSRVD_WELL_KNOWN_URI;
                         resourceName.append("?rt=");
                         resourceName.append(resourceType);
                         OC_LOG_V(DEBUG, TAG, "\t\t\tresourceName : %s", resourceName.c_str());
@@ -705,7 +705,7 @@ OCStackResult GroupSynchronization::leaveGroup(
                         resourceRequest = request;
 
                         OCPlatform::findResource("", resourceName,
-                            OC_ALL,
+                            CT_DEFAULT,
                             std::bind(&GroupSynchronization::onFindResource, this,
                                 std::placeholders::_1));
 
index 4ea8804..9c68645 100644 (file)
@@ -285,7 +285,7 @@ namespace OIC
                                     std::placeholders::_1, std::placeholders::_2,
                                     std::placeholders::_3, conf)));
 
-            free(newActionSet);
+            delete(newActionSet);
         }
     }
 
@@ -326,7 +326,7 @@ namespace OIC
 
             std::string host = getHostFromURI(oit->getUri());
 
-            tempResource = OCPlatform::constructResourceObject(host, uri, OC_IPV4, true,
+            tempResource = OCPlatform::constructResourceObject(host, uri, CT_ADAPTER_IP, true,
                     oit->getResourceTypes(), m_if);
 
             p_resources.push_back(tempResource);
index 03ca932..5c65f21 100644 (file)
@@ -257,7 +257,7 @@ namespace OIC
                                     std::placeholders::_1, std::placeholders::_2,
                                     std::placeholders::_3, diag)));
 
-            free(newActionSet);
+            delete(newActionSet);
 
         }
     }
diff --git a/tools/__init__.py b/tools/__init__.py
new file mode 100644 (file)
index 0000000..05bfb69
--- /dev/null
@@ -0,0 +1,17 @@
+# ------------------------------------------------------------------------
+# Copyright 2015 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ------------------------------------------------------------------------
+
+__all__ = [ "scons" ]
index edde6fe..2b6abb8 100755 (executable)
@@ -1,10 +1,9 @@
 #!/bin/bash
 
 # change this to what version of Xcode you have installed
-SDKVER=8.2
 
-scons TARGET_OS=ios TARGET_ARCH=armv7 SYS_VERSION=$SDKVER RELEASE=false
-scons TARGET_OS=ios TARGET_ARCH=armv7s SYS_VERSION=$SDKVER RELEASE=false
-scons TARGET_OS=ios TARGET_ARCH=arm64 SYS_VERSION=$SDKVER RELEASE=false
-scons TARGET_OS=ios TARGET_ARCH=i386 SYS_VERSION=$SDKVER RELEASE=false
-scons TARGET_OS=ios TARGET_ARCH=x86_64 SYS_VERSION=$SDKVER RELEASE=false
+scons TARGET_OS=ios TARGET_ARCH=armv7 RELEASE=false
+scons TARGET_OS=ios TARGET_ARCH=armv7s RELEASE=false
+scons TARGET_OS=ios TARGET_ARCH=arm64 RELEASE=false
+scons TARGET_OS=ios TARGET_ARCH=i386  RELEASE=false
+scons TARGET_OS=ios TARGET_ARCH=x86_64 RELEASE=false
index 0eb86b7..59fa0f8 100755 (executable)
@@ -1,5 +1,9 @@
 #!/bin/sh
-
+#===============================================================================
+# Author:    Pete Goodliffe
+# Copyright: (c) Copyright 2009 Pete Goodliffe
+# Licence:   Please feel free to use this, with attribution
+#===============================================================================
 
 #VERSION_IOS="${MAJOR_VERSION}.${MINOR_VERSION}.${RELEASE_NUMBER}.${BUILD_NUMBER}"
 VERSION_IOS="0.9.0.1"
index f0ede46..fc5554f 100755 (executable)
@@ -1,5 +1,9 @@
 #!/bin/sh
-
+#===============================================================================
+# Author:    Pete Goodliffe
+# Copyright: (c) Copyright 2009 Pete Goodliffe
+# Licence:   Please feel free to use this, with attribution
+#===============================================================================
 
 #VERSION_IOS="${MAJOR_VERSION}.${MINOR_VERSION}.${RELEASE_NUMBER}.${BUILD_NUMBER}"
 VERSION_IOS="0.9.0.1"
@@ -81,7 +85,6 @@ find $OUTDIR/objs -name "*.o" | xargs rm
 
 echo "Framework: Copying includes..."
 cp -r  resource/csdk/stack/include/*.h  $FRAMEWORK_BUNDLE/Headers
-cp -r  resource/csdk/ocsocket/include/*.h  $FRAMEWORK_BUNDLE/Headers
 cp -r  resource/csdk/ocrandom/include/*.h  $FRAMEWORK_BUNDLE/Headers
 cp -r  resource/csdk/ocmalloc/include/*.h  $FRAMEWORK_BUNDLE/Headers
 
diff --git a/tools/scons/RunTest.py b/tools/scons/RunTest.py
new file mode 100644 (file)
index 0000000..0d9f023
--- /dev/null
@@ -0,0 +1,58 @@
+# ------------------------------------------------------------------------
+# Copyright 2015 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ------------------------------------------------------------------------
+
+import os
+
+def run_test(env, xml_file, test):
+    """
+    Run test with the given SCons Environment, dumping Valgrind
+    results to the given XML file.  If no Valgrind run is desired
+    simply pass in an empty string or None for the xml_file
+    parameter.
+
+    Note that the test path should not include the build directory
+    where binaries are placed.  The build directory will be prepended
+    to the test path automatically.
+    """
+
+    build_dir = env.get('BUILD_DIR')
+    result_dir = os.path.join(build_dir, 'test_out/')
+    if not os.path.isdir(result_dir):
+        os.makedirs(result_dir)
+
+    # Dump test report in XML format to the results directory.
+    env.AppendENVPath('GTEST_OUTPUT', ['xml:' + result_dir])
+
+    # Make sure the Google Test libraries are in the dynamic
+    # linker/loader path.
+    env.AppendENVPath('LD_LIBRARY_PATH', [build_dir])
+    env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
+
+    test_cmd = os.path.join(build_dir, test)
+
+    if xml_file:
+        # Environment variables to be made available during the
+        # Valgrind run.
+        valgrind_environment = ''
+
+        # Valgrind suppressions file.
+        suppression_file = env.File('#tools/valgrind/iotivity.supp').srcnode().path
+
+        # Set up to run the test under Valgrind.
+        test_cmd = '%s valgrind --leak-check=full --suppressions=%s --xml=yes --xml-file=%s %s' % (valgrind_environment, suppression_file, xml_file, test_cmd)
+
+    ut = env.Command('ut', None, test_cmd)
+    env.AlwaysBuild('ut')
diff --git a/tools/scons/__init__.py b/tools/scons/__init__.py
new file mode 100644 (file)
index 0000000..9c7eea5
--- /dev/null
@@ -0,0 +1,17 @@
+# ------------------------------------------------------------------------
+# Copyright 2015 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ------------------------------------------------------------------------
+
+__all__ = [ "RunTest" ]
index 1de6847..78d675f 100644 (file)
@@ -28,18 +28,14 @@ then
        scp -p -P 29418 ${GIT_USER}@gerrit.iotivity.org:hooks/commit-msg iotivity/.git/hooks/
 fi
 
-export CEREAL_DIR=iotivity/extlibs/cereal
+export TINYCBOR_DIR=iotivity/extlibs/tinycbor
 if [ ! -d ${CEREAL_DIR} ]
 then
-       git clone https://github.com/USCiLab/cereal.git ${CEREAL_DIR}
-       pushd ${CEREAL_DIR}
-       git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
-       git apply ../../resource/patches/cereal_gcc46.patch
-       popd
+       git clone https://github.com/01org/tinycbor ${CEREAL_DIR}
 fi
 
 #######################################
-# Android 
+# Android
 #######################################
 
 echo "Set up Android NDK"
diff --git a/tools/valgrind/iotivity.supp b/tools/valgrind/iotivity.supp
new file mode 100644 (file)
index 0000000..bc2289e
--- /dev/null
@@ -0,0 +1,20 @@
+# ------------------------------------------------------------------------
+# Copyright 2015 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ------------------------------------------------------------------------
+
+# This file contains Valgrind suppressions.  It is meant to make
+# Valgrind ignore memory violations that are out of the control of
+# IoTivity developers.  Do NOT abuse this file by adding suppressions
+# for memory violations that can be addressed in IoTivity itself.