Merge from master to connectivity-abstraction branch
authorSudarshan Prasad <sudarshan.prasad@intel.com>
Tue, 23 Dec 2014 22:49:30 +0000 (14:49 -0800)
committerSudarshan Prasad <sudarshan.prasad@intel.com>
Tue, 23 Dec 2014 22:49:30 +0000 (14:49 -0800)
Change-Id: Ib27785b3f8681b37885a94e608650eed871f9051
Signed-off-by: Sudarshan Prasad <sudarshan.prasad@intel.com>
234 files changed:
.gitignore
SConstruct
build_common/SConscript
build_common/arduino/SConscript [changed mode: 0755->0644]
resource/csdk/SConscript
resource/csdk/connectivity/common/src/logger.c
resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c
resource/csdk/libcoap-4.1.1/examples/tiny.c
resource/csdk/libcoap-4.1.1/net.c
resource/csdk/libcoap-4.1.1/sec/netdtls.c
resource/csdk/logger/src/logger.c
resource/csdk/logger/test/loggertests.cpp
resource/csdk/makefile
resource/csdk/occoap/include/occoaphelper.h
resource/csdk/occoap/src/occoap.c
resource/csdk/occoap/src/occoaphelper.c
resource/csdk/ocsocket/src/ocsocket.c
resource/csdk/ocsocket/src/ocsocket_arduino.cpp
resource/csdk/ocsocket/src/ocsocket_arduino_wifi.cpp
resource/csdk/stack/include/internal/ocresource.h
resource/csdk/stack/include/internal/ocresourcehandler.h
resource/csdk/stack/include/internal/oicgroup.h [new file with mode: 0644]
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/csdk/stack/samples/linux/secure/ocserverbasicops.cpp
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocobserve.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c [new file with mode: 0644]
resource/examples/SConscript
resource/examples/devicediscoveryclient.cpp [new file with mode: 0644]
resource/examples/devicediscoveryserver.cpp [new file with mode: 0644]
resource/examples/groupclient.cpp [new file with mode: 0755]
resource/examples/groupserver.cpp [new file with mode: 0755]
resource/examples/lightserver.cpp [new file with mode: 0755]
resource/examples/makefile [changed mode: 0644->0755]
resource/examples/presenceclient.cpp
resource/examples/presenceserver.cpp
resource/include/IClientWrapper.h
resource/include/IServerWrapper.h
resource/include/InProcClientWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCResourceRequest.h
resource/include/OutOfProcClientWrapper.h
resource/include/OutOfProcServerWrapper.h
resource/include/StringConstants.h
resource/releaseNotes/Dec20th2014.txt [new file with mode: 0644]
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/OCUtilities.cpp
resource/third_party_libs.scons
resource/unittests/README
resource/unittests/makefile
service/SConscript
service/docs/Control Manager-Programmer's guide.pdf [new file with mode: 0644]
service/docs/Getting Started_IoTivity Services_20141218.pdf [new file with mode: 0755]
service/docs/Getting Started_SSM_PPM_Things Manager_NM_20141218.pdf [new file with mode: 0755]
service/docs/IoTivity Services_20141216.pdf [new file with mode: 0644]
service/docs/Notification Manager - Programmer's guide.pdf [new file with mode: 0644]
service/docs/PPM - Programmer's Guide_20141218.pdf [new file with mode: 0755]
service/docs/SSM - Programmer's guide_20141216.pdf [new file with mode: 0755]
service/docs/Things Manager - Programmer's guide_M2_SDK_APIs.pdf [new file with mode: 0644]
service/notification-manager/NotificationManager/build/linux/Makefile
service/notification-manager/NotificationManager/include/HostingConfig.h [new file with mode: 0644]
service/notification-manager/NotificationManager/include/HostingHandler.h [new file with mode: 0644]
service/notification-manager/NotificationManager/include/HostingInterface.h [new file with mode: 0644]
service/notification-manager/NotificationManager/include/NotificationManager.h
service/notification-manager/NotificationManager/include/OICPlatformConfig.h [new file with mode: 0644]
service/notification-manager/NotificationManager/include/RegistrationManager.h
service/notification-manager/NotificationManager/include/ResourceManager.h
service/notification-manager/NotificationManager/include/VirtualRepresentation.h
service/notification-manager/NotificationManager/src/HostingHandler.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/HostingInterface.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/LinuxMain.cpp [deleted file]
service/notification-manager/NotificationManager/src/NotificationManager.cpp
service/notification-manager/NotificationManager/src/OICPlatformConfig.cpp [new file with mode: 0644]
service/notification-manager/NotificationManager/src/RegistrationManager.cpp
service/notification-manager/NotificationManager/src/ResourceManager.cpp
service/notification-manager/NotificationManager/src/VirtualRepresentation.cpp
service/notification-manager/NotificationManager/src/linux/main.cpp [new file with mode: 0644]
service/notification-manager/SampleApp/linux/sampleConsumer/SampleConsumer.cpp
service/notification-manager/SampleApp/linux/sampleProvider/SampleProvider.cpp
service/protocol-plugin/build/linux/Makefile
service/protocol-plugin/lib/cpluff/SConscript
service/protocol-plugin/lib/cpluff/libcpluff/psymbol.c
service/protocol-plugin/plugin-manager/SConscript
service/protocol-plugin/plugin-manager/src/Config.cpp
service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp
service/protocol-plugin/plugin-manager/src/CpluffAdapter.h
service/protocol-plugin/plugin-manager/src/FelixAdapter.h
service/protocol-plugin/plugin-manager/src/Plugin.h
service/protocol-plugin/plugin-manager/src/PluginManager.cpp
service/protocol-plugin/plugin-manager/src/PluginManager.h
service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp
service/protocol-plugin/plugins/SConscript
service/protocol-plugin/plugins/mqtt-fan/build/linux/Makefile
service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.cpp
service/protocol-plugin/plugins/mqtt-light/build/linux/Makefile
service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.cpp
service/protocol-plugin/readme
service/protocol-plugin/sample-app/linux/SConscript
service/protocol-plugin/sample-app/linux/mqtt/Makefile
service/protocol-plugin/sample-app/linux/mqtt/mqttclient.cpp
service/soft-sensor-manager/Readme.txt
service/soft-sensor-manager/SConscript
service/soft-sensor-manager/SDK/cpp/build/linux/Makefile [moved from service/soft-sensor-manager/SDK/build/linux/Makefile with 76% similarity]
service/soft-sensor-manager/SDK/cpp/include/SSMInterface.h [new file with mode: 0644]
service/soft-sensor-manager/SDK/cpp/src/InprocSSMCore.cpp [moved from service/soft-sensor-manager/SDK/src/InprocSSMCore.cpp with 100% similarity]
service/soft-sensor-manager/SDK/include/ISSMClientListener.h [deleted file]
service/soft-sensor-manager/SDK/include/SSMClient.h [deleted file]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/CoreController.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/DataReader.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IQueryEngineEvent.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IReportReceiver.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/ModelData.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/QueryEngine.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/SSMInterface.java [new file with mode: 0644]
service/soft-sensor-manager/SDK/src/SSMClient.cpp [deleted file]
service/soft-sensor-manager/SSMCore/build/linux/Makefile
service/soft-sensor-manager/SSMCore/include/SSMInterface.h
service/soft-sensor-manager/SSMCore/src/Common/ObjectManager.h
service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h
service/soft-sensor-manager/SSMCore/src/Common/sqlite3.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp
service/soft-sensor-manager/SSMCore/src/SSMInterface/SSMCore.h
service/soft-sensor-manager/SSMCore/src/SSMInterface/SSMResourceServer.cpp
service/soft-sensor-manager/SSMCore/src/SSMInterface/SSMResourceServer.h
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h
service/soft-sensor-manager/SampleApp/SConscript
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/build/makefile [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/bleLib.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/oic_lanLib.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/bleLib.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/oic_lanLib.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/readme.txt [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/reference.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/Makefile [deleted file]
service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/makefile [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/THSensorApp/src/thserver.cpp
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/build/makefile [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/bleLib.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/oic_lanLib.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/proximity.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/trackee.h [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/bleLib.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/oic_lanLib.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/proximity.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/readme.txt [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/trackee.cpp [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/linux/ClientApp/SConscript [deleted file]
service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/SConscript [new file with mode: 0644]
service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/build/Makefile
service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/include/SSMTestApp.h
service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/src/SSMTestApp.cpp
service/soft-sensor-manager/SampleApp/linux/THSensorApp/SConscript
service/soft-sensor-manager/SampleApp/linux/THSensorApp/include/ThingResourceServer.h
service/soft-sensor-manager/SampleApp/linux/THSensorApp/src/ThingResourceServer.cpp
service/soft-sensor-manager/SampleApp/linux/THSensorApp1/SConscript
service/soft-sensor-manager/SampleApp/linux/THSensorApp1/include/ThingResourceServer1.h
service/soft-sensor-manager/SampleApp/linux/THSensorApp1/src/ThingResourceServer1.cpp
service/soft-sensor-manager/SampleApp/tizen/SSMTesterApp/oic-sample/CMakeLists.txt
service/soft-sensor-manager/SampleApp/tizen/SSMTesterApp/oic-sample/src/oicapp-test.cpp
service/soft-sensor-manager/SoftSensorPlugin/DiscomfortIndexSensor/SoftSensorDescription.xml [deleted file]
service/soft-sensor-manager/SoftSensorPlugin/DiscomfortIndexSensor/build/linux/Makefile
service/soft-sensor-manager/SoftSensorPlugin/SoftSensorDescription.xml [new file with mode: 0644]
service/soft-sensor-manager/build/arduino/Makefile
service/soft-sensor-manager/build/arduino/environment.mk
service/soft-sensor-manager/build/arduino/local.properties
service/soft-sensor-manager/build/linux/environment.mk
service/soft-sensor-manager/doc/SSM Developer s guide_v0.1.pdf [deleted file]
service/soft-sensor-manager/doc/SSM Getting Started_v0.1.pdf [deleted file]
service/things-manager/SConscript
service/things-manager/build/linux/Makefile [deleted file]
service/things-manager/build/linux/makefile [new file with mode: 0644]
service/things-manager/sampleapp/SConscript
service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/SConscript [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/con-client.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/con-server.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/configuration/makefile [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupaction/SConscript [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupaction/bookmark.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupaction/groupserver.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupaction/lightserver.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupaction/makefile [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/SConscript [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/group.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/makefile [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp [new file with mode: 0644]
service/things-manager/sampleapp/linux/makefile [new file with mode: 0644]
service/things-manager/sampleapp/linux/tgmclient/SConscript [deleted file]
service/things-manager/sampleapp/linux/tgmclient/makefile [deleted file]
service/things-manager/sampleapp/linux/tgmclient/tgmsdkclient.cpp [deleted file]
service/things-manager/sdk/build/linux/Makefile
service/things-manager/sdk/inc/TGMClient.h [deleted file]
service/things-manager/sdk/inc/ThingsManager.h [new file with mode: 0644]
service/things-manager/sdk/src/GroupManager.cpp [new file with mode: 0644]
service/things-manager/sdk/src/GroupManager.h [new file with mode: 0644]
service/things-manager/sdk/src/GroupSynchronization.cpp [new file with mode: 0644]
service/things-manager/sdk/src/GroupSynchronization.h [new file with mode: 0644]
service/things-manager/sdk/src/TGMClient.cpp [deleted file]
service/things-manager/sdk/src/ThingsConfiguration.cpp [new file with mode: 0644]
service/things-manager/sdk/src/ThingsConfiguration.h [new file with mode: 0644]
service/things-manager/sdk/src/ThingsDiagnostics.cpp [new file with mode: 0644]
service/things-manager/sdk/src/ThingsDiagnostics.h [new file with mode: 0644]
service/things-manager/sdk/src/ThingsManager.cpp [new file with mode: 0644]
service/third_party_libs.scons

index a5463f0..aec3a0b 100644 (file)
@@ -44,3 +44,14 @@ dependencies/
 
 #ignore various swap files
 *.swp
+
+# Ignore SCons generated files and directories
+.scon*
+config.log
+os
+out/
+platform
+
+# Ignore downloaded dependencies
+extlibs/gtest*
+extlibs/cereal
index fd1b034..92eac38 100644 (file)
@@ -28,7 +28,7 @@ build_dir = env.get('BUILD_DIR')
 SConscript(build_dir + 'resource/SConscript')
 
 # Build 'service' sub-project
-#SConscript(build_dir + 'service/SConscript')
+SConscript(build_dir + 'service/SConscript')
 
 # Append targets information to the help information, to see help info, execute command line:
 #     $ scon [options] -h
index c6708e4..db23ac3 100644 (file)
@@ -7,7 +7,7 @@ import platform
 
 # Map of host os and allowed target os (host: allowed target os)
 host_target_map = {
-               'linux': ['linux', 'android', 'arduino'],
+               'linux': ['linux', 'android', 'arduino', 'yocto', 'tizen'],
                'windows': ['windows', 'winrt', 'android', 'arduino'],
                'darwin': ['darwin', 'ios', 'android', 'arduino'],
                }
@@ -15,12 +15,14 @@ host_target_map = {
 # Map of os and allowed archs (os: allowed archs)
 os_arch_map = {
                'linux': ['x86', 'x86_64', 'arm', 'arm64'],
+               'tizen': ['x86', 'x86_64', 'arm', 'arm64'],
                'android': ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'arm64-v8a'],
                'windows': ['x86', 'amd64', 'arm'],
                'winrt': ['arm'],
                'darwin': ['i386', 'x86_64'],
                'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'],
                'arduino': ['avr', 'arm'],
+               'yocto': ['x86', 'x86_64'],
                }
 
 host = platform.system().lower()
@@ -167,8 +169,63 @@ env.SetDir(env.GetLaunchDir())
 
 Export('env')
 
-# Load config of target os
-env.SConscript(target_os + '/SConscript')
+######################################################################
+# Link scons to Yocto cross-toolchain ONLY when target_os is yocto
+######################################################################
+if target_os == "yocto":
+    '''
+    This code injects Yocto cross-compilation tools+flags into scons' 
+    build environment in order to invoke the relevant tools while 
+    performing a build.
+    '''
+    import os.path
+    try:
+        CC = os.environ['CC']
+        target_prefix = CC.split()[0]
+        target_prefix = target_prefix[:len(target_prefix)-3]
+        tools = {"CC" : target_prefix+"gcc",
+                "CXX" : target_prefix+"g++",
+                "AS" : target_prefix+"as",
+                "LD" : target_prefix+"ld",
+                "GDB" : target_prefix+"gdb",
+                "STRIP" : target_prefix+"strip",
+                "RANLIB" : target_prefix+"ranlib",
+                "OBJCOPY" : target_prefix+"objcopy",
+                "OBJDUMP" : target_prefix+"objdump",
+                "AR" : target_prefix+"ar",
+                "NM" : target_prefix+"nm",
+                "M4" : "m4",
+                "STRINGS": target_prefix+"strings"}
+        PATH = os.environ['PATH'].split(os.pathsep)
+        for tool in tools:
+            if tool in os.environ:
+                for path in PATH:
+                    if os.path.isfile(os.path.join(path, tools[tool])):
+                        env[tool] = os.path.join(path, os.environ[tool])
+                        break
+    except:
+        print "ERROR in Yocto cross-toolchain environment"
+        Exit(1)
+    '''
+    Now reset TARGET_OS to linux so that all linux specific build configurations
+    hereupon apply for the entirety of the build process.
+    '''
+    env['TARGET_OS'] = 'linux'
+    '''
+    We want to preserve debug symbols to allow BitBake to generate both DEBUG and
+    RELEASE packages for OIC. 
+    '''
+    env['CCFLAGS'].append('-g')
+    Export('env')
+else:
+    '''
+    If target_os is not Yocto, continue with the regular build process
+    '''
+    # Load config of target os
+    if target_os in ['linux', 'tizen']:
+               env.SConscript('linux/SConscript')
+    else:
+               env.SConscript(target_os + '/SConscript')
 
 # Delete the temp files of configuration
 if env.GetOption('clean'):
old mode 100755 (executable)
new mode 100644 (file)
index 5df1507..6de4c2d 100644 (file)
@@ -68,9 +68,10 @@ liboctbstack_src = [
        OCTBSTACK_SRC + 'occlientcb.c',
        OCTBSTACK_SRC + 'ocresource.c',
        OCTBSTACK_SRC + 'ocobserve.c',
-        OCTBSTACK_SRC + 'ocserverrequest.c',
+    OCTBSTACK_SRC + 'ocserverrequest.c',
        OCTBSTACK_SRC + 'occollection.c',
-       OCTBSTACK_SRC + 'ocsecurity.c'
+       OCTBSTACK_SRC + 'ocsecurity.c',
+    OCTBSTACK_SRC + 'oicgroup.c'
        ]
 if target_os == 'arduino':
        liboctbstack = liboctbstack_env.StaticLibrary('octbstack', liboctbstack_src)
index 5f7848f..799e289 100644 (file)
@@ -178,7 +178,8 @@ void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16
     for (i = 0; i < bufferSize; i++)
     {
         // Format the buffer data into a line
-        sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
+        snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+        lineIndex++;
         // Output 16 values per line
         if (((i + 1) % 16) == 0)
         {
@@ -259,7 +260,8 @@ void OICLogBuffer(LogLevel level, PROGMEM const char *tag, const uint8_t *buffer
     for (uint8_t i = 0; i < bufferSize; i++)
     {
         // Format the buffer data into a line
-        sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
+        snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+        lineIndex++;
         // Output 16 values per line
         if (((i + 1) % 16) == 0)
         {
index 6bb89c8..7b7d437 100644 (file)
@@ -40,7 +40,7 @@ make_pdu(unsigned int value)
     enc = COAP_PSEUDOFP_ENCODE_8_4_DOWN(value,ls);
     coap_add_data(pdu, 1, &enc);
 
-    len = sprintf((char *) buf, "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
+    len = snprintf((char *) buf, sizeof(buf), "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
     if (len > 0)
     {
         coap_add_data(pdu, len, buf);
index 86cef84..0583c28 100644 (file)
@@ -39,7 +39,7 @@ make_pdu( unsigned int value ) {
   enc = COAP_PSEUDOFP_ENCODE_8_4_DOWN(value,ls);
   coap_add_data( pdu, 1, &enc);
 
-  len = sprintf((char *)buf, "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
+  len = snprintf((char *)buf, sizeof(buf), "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
   if ( len > 0 ) {
     coap_add_data( pdu, len, buf );
   }
index 4fce8f9..d36b0e2 100644 (file)
@@ -997,9 +997,9 @@ int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id,
 
     if (!queue || !*queue)
         return 0;
+    debug("*** looking for transaction %u == %u\n", id, (*queue)->id);
 
     /* replace queue head if PDU's time is less than head's time */
-
     if (id == (*queue)->id) { /* found transaction */
         *node = *queue;
         *queue = (*queue)->next;
index 1535670..e90e64b 100644 (file)
@@ -406,7 +406,7 @@ int coap_dtls_init(coap_context_t *ctx, uint8_t ipAddr[]) {
     ret = 0;
 
 exit:
-    if (ret == -1 && coap_dtls_ctx) {
+    if (ret == -1) {
         coap_dtls_deinit(ctx);
     }
     return ret;
@@ -420,18 +420,21 @@ exit:
  *
  */
 void coap_dtls_deinit(coap_context_t *ctx) {
-    if (!ctx)
+
+    if (!ctx || !ctx->coap_dtls_ctx)
         return;
 
     coap_dtls_context_t *coap_dtls_ctx = ctx->coap_dtls_ctx;
 
-    if (coap_dtls_ctx) {
-        coap_delete_all(coap_dtls_ctx->cachedqueue);
-        if (ctx->sockfd_dtls != -1)
-            OCClose(ctx->sockfd_dtls);
-        dtls_free_context(coap_dtls_ctx->dtls_ctx);
-        coap_free(coap_dtls_ctx);
-    }
+    coap_delete_all(coap_dtls_ctx->cachedqueue);
+
+    dtls_free_context(coap_dtls_ctx->dtls_ctx);
+    coap_dtls_ctx->dtls_ctx = NULL;
+
+    if (ctx->sockfd_dtls != -1)
+        OCClose(ctx->sockfd_dtls);
+
+    coap_free(coap_dtls_ctx);
     ctx->coap_dtls_ctx = NULL;
 }
 
index 684c0ba..ad9afd2 100644 (file)
@@ -146,7 +146,8 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
     int i;
     for (i = 0; i < bufferSize; i++) {
         // Format the buffer data into a line
-        sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
+        snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+        lineIndex++;
         // Output 16 values per line
         if (((i+1)%16) == 0) {
             OCLog(level, tag, lineBuffer);
@@ -216,7 +217,8 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
         uint8_t lineIndex = 0;
         for (uint8_t i = 0; i < bufferSize; i++) {
             // Format the buffer data into a line
-            sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
+            snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+            lineIndex++;
             // Output 16 values per line
             if (((i+1)%16) == 0) {
                 OCLogString(level, tag, lineBuffer);
index 4c7c395..27971ba 100644 (file)
@@ -107,7 +107,7 @@ bool directStdOutToConsole() {
 bool CalcFileMD5(const char *file_name, char *md5_sum) {
     #define MD5SUM_CMD_FMT "md5sum %." STR(PATH_LEN) "s 2>/dev/null"
     char cmd[PATH_LEN + sizeof (MD5SUM_CMD_FMT)];
-    sprintf(cmd, MD5SUM_CMD_FMT, file_name);
+    snprintf(cmd, sizeof(cmd), MD5SUM_CMD_FMT, file_name);
     #undef MD5SUM_CMD_FMT
 
     FILE *p = popen(cmd, "r");
index f367384..540ea2e 100644 (file)
@@ -143,6 +143,7 @@ OCTBSTACK_SOURCES   += $(OCTBSTACK_SRC)/ocresource.c
 OCTBSTACK_SOURCES      += $(OCTBSTACK_SRC)/ocobserve.c
 OCTBSTACK_SOURCES      += $(OCTBSTACK_SRC)/ocserverrequest.c
 OCTBSTACK_SOURCES      += $(OCTBSTACK_SRC)/occollection.c
+OCTBSTACK_SOURCES      += $(OCTBSTACK_SRC)/oicgroup.c
 OCTBSTACK_SOURCES      += $(OCTBSTACK_SRC)/ocsecurity.c
 
 SOURCES                        := $(CJSON_SOURCES)
index 7e5b60e..20ef714 100644 (file)
 #include "occoaptoken.h"
 #include "ocstackinternal.h"
 
-#define BUF_SIZE (64)
+/**
+ * The Max Size of the buffer that is used to parse uri and query
+ * individually.
+ */
+#define MAX_URI_QUERY_BUF_SIZE ((MAX_URI_LENGTH) >= (MAX_QUERY_LENGTH) ?\
+                            (MAX_URI_LENGTH) : (MAX_QUERY_LENGTH))
+
+#define COAP_WK_IPAddr_0 (224)
+#define COAP_WK_IPAddr_1 (0)
+#define COAP_WK_IPAddr_2 (1)
+#define COAP_WK_IPAddr_3 (187)
 
 // checks if optionID is within vendor specific range
 OCStackResult isVendorSpecific(uint16_t optionID);
@@ -44,7 +54,7 @@ OCStackResult isVendorSpecific(uint16_t optionID);
 uint8_t OCToCoAPResponseCode(OCStackResult result);
 
 //Convert OCQualityOfService to coap NON vs CON
-uint8_t OCToCoAPQoS(OCQualityOfService qos);
+uint8_t OCToCoAPQoS(OCQualityOfService qos, uint8_t * ipAddr);
 
 // Convert CoAP code to OCStack code
 OCStackResult CoAPToOCResponseCode(uint8_t coapCode);
index 755ac6c..491d125 100644 (file)
@@ -22,6 +22,8 @@
 //=============================================================================
 // Includes
 //=============================================================================
+#define _POSIX_C_SOURCE 200112L
+#include <string.h>
 #include "occoap.h"
 #include "ocstackconfig.h"
 #include "occlientcb.h"
@@ -53,7 +55,6 @@
 // Private Variables
 //=============================================================================
 
-static uint8_t coapWKIpAddr[] = { 224, 0, 1, 187 };
 static coap_context_t *gCoAPCtx = NULL;
 
 //=============================================================================
@@ -226,7 +227,8 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
     if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
             requestResult == OC_STACK_OK ||
             requestResult == OC_STACK_RESOURCE_CREATED ||
-            requestResult == OC_STACK_RESOURCE_DELETED)
+            requestResult == OC_STACK_RESOURCE_DELETED ||
+            requestResult == OC_STACK_INVALID_DEVICE_INFO)
     {
         goto exit;
     }
@@ -424,8 +426,8 @@ OCStackResult OCInitCoAP(const char *address, uint16_t port, OCMode mode) {
 
     // To allow presence notification work we need to init socket gCoAPCtx->sockfd_wellknown
     // for servers as well as clients
-    OCBuildIPv4Address(coapWKIpAddr[0], coapWKIpAddr[1], coapWKIpAddr[2],
-            coapWKIpAddr[3], COAP_DEFAULT_PORT, &mcastAddr);
+    OCBuildIPv4Address(COAP_WK_IPAddr_0, COAP_WK_IPAddr_1, COAP_WK_IPAddr_2,
+            COAP_WK_IPAddr_3, COAP_DEFAULT_PORT, &mcastAddr);
     VERIFY_SUCCESS(
             coap_join_wellknown_group(gCoAPCtx,
                     (coap_address_t* )&mcastAddr), 0);
@@ -502,7 +504,7 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
         OC_LOG_V(DEBUG, TAG, "secure uri %d", uri.secure);
     }
 
-    coapMsgType = OCToCoAPQoS(qos);
+    coapMsgType = OCToCoAPQoS(qos, ipAddr);
 
     // Decide method type
     switch (method) {
index 4ce5cb9..1f544f7 100644 (file)
@@ -90,8 +90,13 @@ uint8_t OCToCoAPResponseCode(OCStackResult result)
     return ret;
 }
 
-uint8_t OCToCoAPQoS(OCQualityOfService qos)
+uint8_t OCToCoAPQoS(OCQualityOfService qos, uint8_t * ipAddr)
 {
+    if(ipAddr[0] == COAP_WK_IPAddr_0 && ipAddr[1] == COAP_WK_IPAddr_1 &&
+            ipAddr[2] == COAP_WK_IPAddr_2 && ipAddr[3] == COAP_WK_IPAddr_3)
+    {
+        return COAP_MESSAGE_NON;
+    }
     switch (qos)
     {
         case OC_HIGH_QOS:
@@ -392,7 +397,7 @@ OCStackResult FormOptionList(coap_list_t * * optListLoc, uint8_t * addMediaType,
     coap_list_t * optNode = NULL;
     int res;
     size_t buflen;
-    unsigned char _buf[BUF_SIZE];
+    unsigned char _buf[MAX_URI_QUERY_BUF_SIZE];
     unsigned char *buf = _buf;
 
     if(addMediaType)
@@ -430,7 +435,7 @@ OCStackResult FormOptionList(coap_list_t * * optListLoc, uint8_t * addMediaType,
     if(uri && uriLength)
     {
         buf = _buf;
-        buflen = BUF_SIZE;
+        buflen = MAX_URI_QUERY_BUF_SIZE;
         res = coap_split_path(uri, uriLength, buf, &buflen);
         while (res--) {
             optNode = CreateNewOptionNode(COAP_OPTION_URI_PATH,
@@ -444,7 +449,7 @@ OCStackResult FormOptionList(coap_list_t * * optListLoc, uint8_t * addMediaType,
     if(query && queryLength)
     {
         buf = _buf;
-        buflen = BUF_SIZE;
+        buflen = MAX_URI_QUERY_BUF_SIZE;
         res = coap_split_query(query, queryLength, buf, &buflen);
         while (res--) {
             optNode = CreateNewOptionNode(COAP_OPTION_URI_QUERY,
index a857546..fb4b700 100644 (file)
@@ -259,7 +259,7 @@ int32_t OCInitUDPMulticast(OCDevAddr* ipmcastaddr, int32_t* sockfd)
     }
 
     // add membership to receiving socket
-    struct ip_mreq mreq = {0};
+    struct ip_mreq mreq = {{0}};
     mreq.imr_interface.s_addr = htonl(INADDR_ANY);
     mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
     if ((ret = setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq))) < 0) {
@@ -367,7 +367,7 @@ int32_t OCDevAddrToString(OCDevAddr* addr, char* stringAddress)
             return ERR_INVALID_INPUT;
         }
 
-        sprintf(stringAddress, "%u.%u.%u.%u",
+        snprintf(stringAddress, DEV_ADDR_SIZE_MAX, "%u.%u.%u.%u",
                 a, b, c, d);
         return ERR_SUCCESS;
     }
index a579bef..ed51f79 100644 (file)
@@ -87,7 +87,7 @@ int32_t OCGetInterfaceAddress(uint8_t* ifName, uint32_t ifNameLen, uint16_t addr
         return ERR_INVALID_INPUT;
     }
     W5100.getIPAddress(rawIPAddr);
-    sprintf((char *)addr,"%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
+    snprintf((char *)addr, addrLen, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
 
     OC_LOG_BUFFER(INFO, MOD_NAME, addr, addrLen);
 
index 6f42420..37f5fe9 100644 (file)
@@ -96,7 +96,7 @@ int32_t OCGetInterfaceAddress(uint8_t* ifName, uint32_t ifNameLen, uint16_t addr
     }
 
     IPAddress ip = WiFi.localIP();
-    sprintf((char *)addr,"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    snprintf((char *)addr, addrLen, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
 
     OC_LOG_BUFFER(INFO, MOD_NAME, addr, addrLen);
 
index 542cfb6..bbd652b 100644 (file)
@@ -49,9 +49,42 @@ typedef enum {
     STACK_IF_DEFAULT = 0,
     STACK_IF_LL,
     STACK_IF_BATCH,
+    STACK_IF_GROUP,
     STACK_IF_INVALID
 } OCStackIfTypes;
 
+// following structure will be created in occollection.
+typedef struct occapability {
+    struct occapability* next;
+
+    char *capability;           // It is a name about resource capability.
+    char *status;               // It is mean status of capability.
+} OCCapability;
+
+
+// following structure will be created in occollection.
+typedef struct ocaction {
+    struct ocaction *next;
+
+    // Target Uri.
+    // It will be used to execute the action.
+    char *resourceUri;
+
+    OCCapability* head;
+} OCAction;
+
+// following structure will be created in occollection.
+typedef struct ocactionset {
+
+    struct ocactionset *next;
+
+    char *actionsetName;
+
+    OCAction* head;
+} OCActionSet;
+
+
+
 typedef struct resourcetype_t {
     struct resourcetype_t *next; // linked list; for multiple types on resource
 
@@ -116,6 +149,8 @@ typedef struct rsrc_t {
     /* method_t methods; */
     // Sequence number for observable resources. Per the CoAP standard it is a 24 bit value.
     uint32_t sequenceNum;
+    // Pointer of ActionSet which to support group action.
+    OCActionSet *actionsetHead;
 } OCResource;
 
 
index 8522e14..f54e3fe 100644 (file)
 #define OC_RSRVD_RESOURCE_TYPE          "rt"
 #define OC_RSRVD_RESOURCE_TYPE_PRESENCE "core.presence"
 #define OC_RSRVD_INTERFACE              "if"
+#define OC_RSRVD_DEVICE_ID              "di"
+#define OC_RSRVD_DEVICE_NAME            "dn"
 #define OC_RSRVD_INTERFACE_DEFAULT      "oc.mi.def"
 #define OC_RSRVD_INTERFACE_LL           "oc.mi.ll"
 #define OC_RSRVD_INTERFACE_BATCH        "oc.mi.b"
+#define OC_RSRVD_INTERFACE_GROUP        "oc.mi.c"
+
+
 #define OC_RSRVD_OBSERVABLE             "obs"
 #define OC_RSRVD_SECURE                 "sec"
 #define OC_RSRVD_HOSTING_PORT           "port"
@@ -51,7 +56,9 @@
 typedef enum {
     STACK_RES_DISCOVERY_NOFILTER = 0,
     STACK_RES_DISCOVERY_IF_FILTER,
-    STACK_RES_DISCOVERY_RT_FILTER
+    STACK_RES_DISCOVERY_RT_FILTER,
+    STACK_DEVICE_DISCOVERY_DI_FILTER,
+    STACK_DEVICE_DISCOVERY_DN_FILTER
 } StackQueryTypes;
 
 typedef enum {
@@ -78,6 +85,10 @@ OCStackResult DetermineResourceHandling (OCServerRequest *request,
 OCStackResult
 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request);
 
+OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo);
+
+void DeleteDeviceInfo();
+
 #ifdef CA_INT
 OCStackResult
 BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
diff --git a/resource/csdk/stack/include/internal/oicgroup.h b/resource/csdk/stack/include/internal/oicgroup.h
new file mode 100644 (file)
index 0000000..2493fba
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// 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_GROUP_H
+#define OIC_GROUP_H
+
+#include "ocstack.h"
+#include "ocstackinternal.h"
+
+void AddCapability(OCCapability** head, OCCapability* node);
+
+void AddAction(OCAction** head, OCAction* node);
+
+void AddActionSet(OCActionSet **head, OCActionSet* node);
+
+void DeleteCapability(OCCapability *del);
+
+void DeleteAction(OCAction** action);
+
+void DeleteActionSet(OCActionSet** actionset);
+
+OCStackResult DeleteActionSets(OCResource** resource);
+
+OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName);
+
+OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
+        char **actionsetName);
+
+OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc);
+
+OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
+        OCClientResponse* clientResponse);
+
+void ActionSetCD(void *context);
+
+OCStackResult
+BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
+        OCResource *resource, OCEntityHandlerRequest *ehRequest);
+
+#endif // OIC_GROUP_H
index 085f497..8be0d12 100644 (file)
@@ -170,6 +170,7 @@ typedef enum {
     OC_STACK_MALFORMED_RESPONSE,        /* the remote reply contained malformed data */
     OC_STACK_PERSISTENT_BUFFER_REQUIRED,
     OC_STACK_INVALID_REQUEST_HANDLE,
+    OC_STACK_INVALID_DEVICE_INFO,
     OC_STACK_ERROR
     /* Error status code - END HERE */
 } OCStackResult;
@@ -276,6 +277,26 @@ typedef struct {
     OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
 }OCClientResponse;
 
+/**
+ * Following structure describes the device properties. All non-Null properties will be included
+ * in a device discovery request.
+ */
+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.
@@ -404,7 +425,10 @@ OCStackResult OCProcess();
  * @param requiredUri        - URI of the resource to interact with
  * @param referenceUri       - URI of the reference resource
  * @param request            - JSON encoded request
- * @param qos                - quality of service
+ * @param qos                - quality of service. Note that if this API is called on a uri with
+ *                             the well-known multicast IP address, the qos will be forced to
+ *                             OC_LOW_QOS
+ *                             since it is impractical to send other QOS levels on such addresses.
  * @param clientApplicationCB- asynchronous callback function that is invoked
  *                             by the stack when discovery or resource interaction is complete
  * @param options            - The address of an array containing the vendor specific
@@ -490,6 +514,20 @@ OCStackResult OCStopPresence();
 OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler);
 
 /**
+ * Set device information.
+ *
+ * @param deviceInfo - Structure passed by the server application containing
+ *                     the device information.
+ *
+ *
+ * @return
+ *     OC_STACK_OK              - no errors
+ *     OC_STACK_INVALID_PARAM   - invalid paramerter
+ *     OC_STACK_ERROR           - stack process error
+ */
+OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo);
+
+/**
  * Create a resource.
  *
  * @param handle - pointer to handle to newly created resource.  Set by ocstack.  Used to refer to resource
index 650949c..9e14bd3 100644 (file)
 #define MAX_QUERY_LENGTH (64)
 
 /**
+ * Maximum length of the Manufacturer name supported by the server
+ * for manufacturer name
+ */
+#define MAX_MANUFACTURER_NAME_LENGTH (16)
+
+/**
+ * Maximum length of the URL to the Manufacturer details supported by
+ * the server.
+ */
+#define MAX_MANUFACTURER_URL_LENGTH (32)
+
+/**
  * Maximum number of resources which can be contained inside collection
  * resource.
  */
index b3b640e..d9dec6c 100644 (file)
@@ -32,6 +32,8 @@
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
 static const char * TEST_APP_UNICAST_DISCOVERY_QUERY = "coap://0.0.0.0:5683/oc/core";
+static const char * TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY = "coap://0.0.0.0:5683/oc/core/d";
+static const char * TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY = "coap://224.0.1.187:5683/oc/core/d";
 static std::string putPayload = "{\"state\":\"on\",\"power\":5}";
 static std::string coapServerIP = "255.255.255.255";
 static std::string coapServerPort = "5683";
@@ -77,11 +79,17 @@ static void PrintUsage()
 
     #ifdef WITH_PRESENCE
     OC_LOG(INFO, TAG, "-t 12 :  Discover Resources and Initiate Nonconfirmable presence");
-    OC_LOG(INFO, TAG, "-t 13 :  Discover Resources and Initiate Nonconfirmable presence with filter");
+    OC_LOG(INFO, TAG, "-t 13 :  Discover Resources and Initiate Nonconfirmable presence with "\
+            "filter");
+    OC_LOG(INFO, TAG, "-t 14 :  Discover Resources and Initiate Nonconfirmable presence with "\
+            "2 filters");
     #endif
 
-    OC_LOG(INFO, TAG, "-t 14 :  Discover Resources and Initiate Nonconfirmable Observe Requests then cancel immediately");
-    OC_LOG(INFO, TAG, "-t 15 :  Discover Resources and Initiate Nonconfirmable Get Request and add  vendor specific header options");
+    OC_LOG(INFO, TAG, "-t 15 :  Discover Resources and Initiate Nonconfirmable Observe Requests "\
+            "then cancel immediately");
+    OC_LOG(INFO, TAG, "-t 16 :  Discover Resources and Initiate Nonconfirmable Get Request and "\
+            "add  vendor specific header options");
+    OC_LOG(INFO, TAG, "-t 17 :  Discover Devices");
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -324,12 +332,16 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             #ifdef WITH_PRESENCE
             case TEST_OBS_PRESENCE:
             case TEST_OBS_PRESENCE_WITH_FILTER:
+            case TEST_OBS_PRESENCE_WITH_FILTERS:
                 InitPresence();
                 break;
             #endif
             case TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS:
                 InitGetRequest(OC_LOW_QOS, 1);
                 break;
+            case TEST_DISCOVER_DEV_REQ:
+                InitDeviceDiscovery();
+                break;
             default:
                 PrintUsage();
                 break;
@@ -339,17 +351,56 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     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 truncates the response as it is too long.
+        fprintf(stderr, "Discovery response: \n %s\n", clientResponse->resJSONPayload);
+        fflush(stderr);
+    }
+
+    return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
+}
+
 #ifdef WITH_PRESENCE
 int InitPresence()
 {
+    OCStackResult result = OC_STACK_OK;
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
     std::ostringstream query;
+    std::ostringstream querySuffix;
     query << "coap://" << coapServerIP << ":" << coapServerPort << OC_PRESENCE_URI;
-    if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTER)
+    if(TEST_CASE == TEST_OBS_PRESENCE)
+    {
+        result = InvokeOCDoResource(query, OC_REST_PRESENCE, OC_LOW_QOS,
+                presenceCB, NULL, 0);
+    }
+    if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTER || TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
     {
-        query << "?rt=core.light";
+        querySuffix.str("");
+        querySuffix << query.str() << "?rt=core.light";
+        result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
+                presenceCB, NULL, 0);
     }
-    return (InvokeOCDoResource(query, OC_REST_PRESENCE, OC_LOW_QOS, presenceCB, NULL, 0));
+    if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
+    {
+        if(result == OC_STACK_OK)
+        {
+            querySuffix.str("");
+            querySuffix << query.str() << "?rt=core.fan";
+            result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
+                    presenceCB, NULL, 0);
+        }
+    }
+    return result;
 }
 #endif
 int InitGetRequestToUnavailableResource()
@@ -495,6 +546,38 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
     }
 }
 
+int InitDeviceDiscovery()
+{
+    OCStackResult ret;
+    OCCallbackData cbData;
+    OCDoHandle handle;
+    char szQueryUri[64] = { 0 };
+
+    cbData.cb = DeviceDiscoveryReqCB;
+    cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    if(UNICAST_DISCOVERY)
+    {
+        strncpy(szQueryUri, TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY,
+                        (strlen(TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY) + 1));
+    }
+    else
+    {
+        strncpy(szQueryUri, TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY,
+                (strlen(TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY) + 1));
+    }
+
+    ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_LOW_QOS, &cbData, NULL, 0);
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack device error");
+    }
+
+    return ret;
+}
+
 int InitDiscovery()
 {
     OCStackResult ret;
index cb59cb0..96444ca 100644 (file)
@@ -55,9 +55,11 @@ typedef enum {
 #ifdef WITH_PRESENCE
     TEST_OBS_PRESENCE,
     TEST_OBS_PRESENCE_WITH_FILTER,
+    TEST_OBS_PRESENCE_WITH_FILTERS,
 #endif
     TEST_OBS_REQ_NON_CANCEL_IMM,
     TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
+    TEST_DISCOVER_DEV_REQ,
     MAX_TESTS
 } CLIENT_TEST;
 
@@ -91,6 +93,7 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
 int InitPostRequest(OCQualityOfService qos);
 int InitDeleteRequest(OCQualityOfService qos);
 int InitGetRequest(OCQualityOfService qos);
+int InitDeviceDiscovery();
 int InitDiscovery();
 
 /* Function to retrieve ip address, port no. of the server
index 1bed2bf..6131cd0 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
+#include <string>
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
 #include <pthread.h>
+#include <array>
 #include "ocstack.h"
 #include "logger.h"
 #include "cJSON.h"
@@ -50,6 +52,7 @@ Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
 
 #ifdef WITH_PRESENCE
 static int stopPresenceCount = 10;
+#define numPresenceResources (2)
 #endif
 
 //TODO: Follow the pattern used in constructJsonResponse() when the payload is decided.
@@ -61,6 +64,20 @@ const char responsePayloadDeleteResourceNotSupported[] =
 
 
 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 = "myManufacturerNa";
+const char *manufacturerUrl = "myManufacturerUrl";
+const char *modelNumber = "myModelNumber";
+const char *platformVersion = "myPlatformVersion";
+const char *supportUrl = "mySupportUrl";
+const char *version = "myVersion";
+
+OCDeviceInfo deviceInfo;
 
 static uint16_t OC_WELL_KNOWN_PORT = 5683;
 
@@ -466,6 +483,14 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
     return ehResult;
 }
 
+OCEntityHandlerResult
+OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest)
+{
+    // This is callback is associated with the 2 presence notification
+    // resources. They are non-operational.
+    return OC_EH_OK;
+}
 
 OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
@@ -671,6 +696,57 @@ void *ChangeLightRepresentation (void *param)
     return NULL;
 }
 
+void *presenceNotificationGenerator(void *param)
+{
+    sleep(5);
+    (void)param;
+    OCDoHandle presenceNotificationHandles[numPresenceResources];
+    OCStackResult res = OC_STACK_OK;
+
+    std::array<std::string, numPresenceResources> presenceNotificationResources { {
+        std::string("core.fan"),
+        std::string("core.led") } };
+    std::array<std::string, numPresenceResources> presenceNotificationUris { {
+        std::string("/a/fan"),
+        std::string("/a/led") } };
+
+    for(int i=0; i<numPresenceResources; i++)
+    {
+        if(res == OC_STACK_OK)
+        {
+            sleep(1);
+            res = OCCreateResource(&presenceNotificationHandles[i],
+                    presenceNotificationResources.at(i).c_str(),
+                    "oc.mi.def",
+                    presenceNotificationUris.at(i).c_str(),
+                    OCNOPEntityHandlerCb,
+                    OC_DISCOVERABLE|OC_OBSERVABLE);
+        }
+        if(res != OC_STACK_OK)
+        {
+            OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
+                    "%s with result %s.", presenceNotificationResources.at(i).c_str(),
+                    getResult(res));
+            break;
+        }
+    }
+    sleep(5);
+    for(int i=0; i<numPresenceResources; i++)
+    {
+        if(res == OC_STACK_OK)
+        {
+            res = OCDeleteResource(presenceNotificationHandles[i]);
+        }
+        if(res != OC_STACK_OK)
+        {
+            OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
+                    "resource %s.", presenceNotificationResources.at(i).c_str());
+            break;
+        }
+    }
+    return NULL;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
@@ -685,6 +761,7 @@ int main(int argc, char* argv[])
     uint16_t port = OC_WELL_KNOWN_PORT;
     uint8_t ifname[] = "eth0";
     pthread_t threadId;
+    pthread_t threadId_presence;
     int opt;
 
     while ((opt = getopt(argc, argv, "o:")) != -1)
@@ -729,6 +806,24 @@ int main(int argc, char* argv[])
 
     OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
 
+    OCStackResult deviceResult = SetDeviceInfo(contentType, dateOfManufacture, deviceName,
+            deviceUUID, firmwareVersion, hostName, manufacturerName,
+            manufacturerUrl, modelNumber, platformVersion, supportUrl, version);
+
+    if (deviceResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
+    deviceResult = OCSetDeviceInfo(deviceInfo);
+
+    if (deviceResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
     /*
      * Declare and create the example resource: Light
      */
@@ -745,8 +840,15 @@ int main(int argc, char* argv[])
      */
     pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
 
+    /*
+     * Create a thread for generating changes that cause presence notifications
+     * to be sent to clients
+     */
+    pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
+
     // Break from loop with Ctrl-C
     OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    DeleteDeviceInfo();
     signal(SIGINT, handleSigInt);
     while (!gQuitFlag) {
         if (OCProcess() != OC_STACK_OK) {
@@ -762,6 +864,8 @@ int main(int argc, char* argv[])
      */
     pthread_cancel(threadId);
     pthread_join(threadId, NULL);
+    pthread_cancel(threadId_presence);
+    pthread_join(threadId_presence, NULL);
 
     OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
 
@@ -792,3 +896,126 @@ int createLightResource (char *uri, LightResource *lightResource)
 
     return 0;
 }
+
+void DeleteDeviceInfo()
+{
+    free(deviceInfo.contentType);
+    free(deviceInfo.dateOfManufacture);
+    free(deviceInfo.deviceName);
+    free(deviceInfo.deviceUUID);
+    free(deviceInfo.firmwareVersion);
+    free(deviceInfo.hostName);
+    free(deviceInfo.manufacturerName);
+    free(deviceInfo.manufacturerUrl);
+    free(deviceInfo.modelNumber);
+    free(deviceInfo.platformVersion);
+    free(deviceInfo.supportUrl);
+    free(deviceInfo.version);
+}
+
+bool DuplicateString(char** targetString, const char* sourceString)
+{
+    if(!sourceString)
+    {
+        return false;
+    }
+    else
+    {
+        *targetString = (char *) malloc(strlen(sourceString) + 1);
+
+        if(targetString)
+        {
+            strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
+            return true;
+        }
+    }
+    return false;
+}
+
+OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
+        const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
+        const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
+        const char *modelNumber, const char *platformVersion, const char *supportUrl,
+        const char *version)
+{
+
+    bool success = true;
+
+    if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(!DuplicateString(&deviceInfo.contentType, contentType))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.deviceUUID, deviceUUID))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.hostName, hostName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.manufacturerName, manufacturerName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.modelNumber, modelNumber))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.platformVersion, platformVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.supportUrl, supportUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.version, version))
+    {
+        success = false;
+    }
+
+    if(success)
+    {
+        return OC_STACK_OK;
+    }
+
+    DeleteDeviceInfo();
+    return OC_STACK_ERROR;
+}
index f5e45e5..81a9507 100644 (file)
@@ -91,6 +91,15 @@ OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest);
 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest);
 
+void DeleteDeviceInfo();
+
+OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
+                const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
+                const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
+                const char *modelNumber, const char *platformVersion, const char *supportUrl,
+                const char *version);
+
+
 //-----------------------------------------------------------------------------
 // Callback functions
 //-----------------------------------------------------------------------------
index 216268b..b6d579c 100644 (file)
@@ -158,7 +158,8 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
         {
             // Create new LED instance
             char newLedUri[15] = "/a/led/";
-            sprintf (newLedUri + strlen(newLedUri), "%d", gCurrLedInstance);
+            int newLedUriLength = strlen(newLedUri);
+            snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
 
             json = cJSON_CreateObject();
 
index 92c73c8..a529b0f 100644 (file)
 #include "debug.h"
 #include "cJSON.h"
 /// Module Name
+#include <stdio.h>
+
+#define WITH_GROUPACTION 1
+
+#include "oicgroup.h"
+
 #define TAG PCF("occollection")
 
 #define NUM_PARAM_IN_QUERY  2
@@ -141,6 +147,10 @@ ValidateQuery (const unsigned char *query, OCResourceHandle resource,
         {
             *ifParam = STACK_IF_BATCH;
         }
+        else if(strcmp (ifPtr, OC_RSRVD_INTERFACE_GROUP) == 0)
+        {
+            *ifParam = STACK_IF_GROUP;
+        }
         else
         {
             return OC_STACK_ERROR;
@@ -387,8 +397,10 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
     if (result != OC_STACK_OK)
         return result;
 
-    if ((ehRequest->method != OC_REST_GET) &&
-        (ehRequest->method != OC_REST_PUT))
+  
+    if(!((ehRequest->method == OC_REST_GET) || 
+        (ehRequest->method == OC_REST_PUT) ||
+        (ehRequest->method == OC_REST_POST)))
         return OC_STACK_ERROR;
 
     if (ehRequest->method == OC_REST_GET)
@@ -412,7 +424,9 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
                 ((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);
             default:
                 return OC_STACK_ERROR;
         }
@@ -433,6 +447,29 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
                         GetNumOfResourcesInCollection((OCResource *)ehRequest->resource) + 1;
                 return HandleBatchInterface(ehRequest);
 
+            case STACK_IF_GROUP:
+            {
+                OC_LOG_V(INFO, TAG, "IF_COLLECTION PUT with request ::\n%s\n ",
+                        ehRequest->reqJSONPayload);
+                return BuildCollectionGroupActionJSONResponse(OC_REST_PUT/*flag*/,
+                        (OCResource *) ehRequest->resource, ehRequest);
+            }
+            default:
+                return OC_STACK_ERROR;
+        }
+    }
+    else if (ehRequest->method == OC_REST_POST)
+    {
+
+        switch (ifQueryParam)
+        {
+            case STACK_IF_GROUP:
+            {
+                OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ",
+                        ehRequest->reqJSONPayload);
+                return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/,
+                        (OCResource *) ehRequest->resource, ehRequest);
+            }
             default:
                 return OC_STACK_ERROR;
         }
index 0a8c270..6b9173c 100644 (file)
@@ -157,12 +157,13 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
                     // we create the payload here
                     if(resourceType && resourceType->resourcetypename)
                     {
-                        sprintf((char *)presenceResBuf, "%u:%u:%s",
+                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u:%s",
                                 resPtr->sequenceNum, maxAge, resourceType->resourcetypename);
                     }
                     else
                     {
-                        sprintf((char *)presenceResBuf, "%u:%u", resPtr->sequenceNum, maxAge);
+                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u",
+                                resPtr->sequenceNum, maxAge);
                     }
                     ehResponse.ehResult = OC_EH_OK;
                     ehResponse.payload = presenceResBuf;
index 8725b8d..38d6856 100644 (file)
@@ -18,6 +18,7 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#define _POSIX_C_SOURCE 200112L
 #include <string.h>
 #include "ocstack.h"
 #include "ocstackconfig.h"
@@ -45,6 +46,7 @@
              TAG, PCF(#arg " is NULL")); return (retVal); } }
 
 extern OCResource *headResource;
+static cJSON *savedDeviceInfo = NULL;
 
 static const char * VIRTUAL_RSRCS[] = {
        "/oc/core",
@@ -107,11 +109,13 @@ static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
     if (!url)
         return OC_STACK_INVALID_URI;
 
-    if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0) {
+    if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
+                strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0) {
         *filterOn = STACK_RES_DISCOVERY_NOFILTER;
         if (query && *query) {
-            filterParam = strtok ((char *)query, "=");
-            *filterValue = strtok (NULL, " ");
+            char* strTokPtr;
+            filterParam = strtok_r((char *)query, "=", &strTokPtr);
+            *filterValue = strtok_r(NULL, " ", &strTokPtr);
             if (!(*filterValue)) {
                 return OC_STACK_INVALID_QUERY;
             } else if (strcmp (filterParam, OC_RSRVD_INTERFACE) == 0) {
@@ -120,6 +124,12 @@ static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
             } 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;
@@ -261,6 +271,85 @@ BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
     return ret;
 }
 
+OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
+                                                    char *out, uint16_t *remaining)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    if (savedDeviceInfo != NULL)
+    {
+        char *jsonStr = NULL;
+        uint16_t jsonLen = 0;
+        cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, "rep");
+
+        OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
+
+        if (filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER)
+        {
+            if((cJSON_GetObjectItem(repObj,"di") != NULL) &&
+                    strcmp(cJSON_GetObjectItem(repObj,"di")->valuestring, filterValue) == 0)
+            {
+                ret = OC_STACK_OK;
+            }
+        }
+        else if (filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER)
+        {
+            if((cJSON_GetObjectItem(repObj,"dn") != NULL) &&
+                    strcmp(cJSON_GetObjectItem(repObj,"dn")->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;
+                }
+
+                free(jsonStr);
+            }
+            else
+            {
+                ret = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            ret = OC_STACK_INVALID_DEVICE_INFO;
+        }
+    }
+    else
+    {
+        //error so that stack won't respond with empty payload
+        ret = OC_STACK_INVALID_DEVICE_INFO;
+    }
+
+    OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
+    return ret;
+}
+
 TODO ("Does it make sense to make this method as inline")
 const char * GetVirtualResourceUri( OCVirtualResources resource)
 {
@@ -490,6 +579,33 @@ HandleVirtualResource (OCServerRequest *request, OCResource* resource)
                 result = OCDoResponse(&response);
             }
         }
+        else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+        {
+            remaining = MAX_RESPONSE_LENGTH;
+            ptr = discoveryResBuf;
+
+            result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
+                    (char*)ptr, &remaining);
+
+            if(result == OC_STACK_OK)
+            {
+                ptr += strlen((char*)ptr);
+            }
+
+            if(remaining < MAX_RESPONSE_LENGTH)
+            {
+                OCEntityHandlerResponse response = {0};
+
+                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;
+
+                result = OCDoResponse(&response);
+            }
+        }
         #ifdef WITH_PRESENCE
         else
         {
@@ -721,4 +837,109 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
     return ret;
 }
 
+void DeleteDeviceInfo()
+{
+    if(savedDeviceInfo)
+    {
+        cJSON_Delete(savedDeviceInfo);
+    }
+}
+
+OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo)
+{
+    DeleteDeviceInfo();
+
+    savedDeviceInfo = cJSON_CreateObject();
+    cJSON *repObj = NULL;
+
+    cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_HREF,
+            cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
+
+    cJSON_AddItemToObject (savedDeviceInfo, "rep", repObj = cJSON_CreateObject());
+
+    if (deviceInfo.contentType)
+    {
+        cJSON_AddItemToObject (repObj, "ct",
+                cJSON_CreateString(deviceInfo.contentType));
+    }
+
+    if (deviceInfo.dateOfManufacture)
+    {
+        cJSON_AddItemToObject (repObj, "mndt",
+                cJSON_CreateString(deviceInfo.dateOfManufacture));
+    }
+
+    if (deviceInfo.deviceName)
+    {
+        cJSON_AddItemToObject (repObj, "dn",
+                cJSON_CreateString(deviceInfo.deviceName));
+    }
+
+    if (deviceInfo.deviceUUID)
+    {
+        cJSON_AddItemToObject (repObj, "di",
+                cJSON_CreateString(deviceInfo.deviceUUID));
+    }
+
+    if (deviceInfo.firmwareVersion)
+    {
+        cJSON_AddItemToObject (repObj, "mnfv",
+                cJSON_CreateString(deviceInfo.firmwareVersion));
+    }
+
+    if (deviceInfo.hostName)
+    {
+        cJSON_AddItemToObject (repObj, "hn", cJSON_CreateString(deviceInfo.hostName));
+    }
+
+    if (deviceInfo.manufacturerName)
+    {
+        if(strlen(deviceInfo.manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        cJSON_AddItemToObject (repObj, "mnmn",
+                cJSON_CreateString(deviceInfo.manufacturerName));
+    }
+
+    if (deviceInfo.manufacturerUrl)
+    {
+        if(strlen(deviceInfo.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        cJSON_AddItemToObject (repObj, "mnml",
+                cJSON_CreateString(deviceInfo.manufacturerUrl));
+    }
+
+    if (deviceInfo.modelNumber)
+    {
+        cJSON_AddItemToObject (repObj, "mnmo",
+                cJSON_CreateString(deviceInfo.modelNumber));
+    }
+
+    if (deviceInfo.platformVersion)
+    {
+        cJSON_AddItemToObject (repObj, "mnpv",
+                cJSON_CreateString(deviceInfo.platformVersion));
+    }
+
+    if (deviceInfo.supportUrl)
+    {
+        cJSON_AddItemToObject (repObj, "mnsl",
+                cJSON_CreateString(deviceInfo.supportUrl));
+    }
+
+    if (deviceInfo.version)
+    {
+        cJSON_AddItemToObject (repObj, "icv",
+                cJSON_CreateString(deviceInfo.version));
+    }
+
+    return OC_STACK_OK;
+}
 
index 083424a..6ed8f7c 100644 (file)
@@ -574,7 +574,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
         {
             OC_LOG(INFO, TAG, PCF("There is room in response buffer"));
             // append
-            sprintf((char *)serverResponse->payload, "%s%s", (char *)serverResponse->payload, (char *)ehResponse->payload);
+            snprintf((char *)serverResponse->payload, serverResponse->remainingPayloadSize, "%s%s", (char *)serverResponse->payload, (char *)ehResponse->payload);
             OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
             serverResponse->remainingPayloadSize -= ehResponse->payloadSize;
             (serverRequest->numResponses)--;
@@ -592,7 +592,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
             {
                 OC_LOG(INFO, TAG, PCF("More response fragment to come"));
                 // TODO: we should consider using strcat rather than setting a char by char here!
-                sprintf((char *)serverResponse->payload, "%s%c", (char *)serverResponse->payload,OC_JSON_SEPARATOR);
+                snprintf((char *)serverResponse->payload, serverResponse->remainingPayloadSize, "%s%c", (char *)serverResponse->payload,OC_JSON_SEPARATOR);
                 OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
                 (serverResponse->remainingPayloadSize)--;
                 stackRet = OC_STACK_OK;
index 0edcad6..46dd9d4 100644 (file)
@@ -22,6 +22,9 @@
 //-----------------------------------------------------------------------------
 // Includes
 //-----------------------------------------------------------------------------
+#define _POSIX_C_SOURCE 200112L
+#include <string.h>
+
 #include "ocstack.h"
 #include "ocstackinternal.h"
 #include "ocresourcehandler.h"
@@ -42,7 +45,7 @@
 // Typedefs
 //-----------------------------------------------------------------------------
 typedef enum {
-    OC_STACK_UNINITIALIZED = 0, OC_STACK_INITIALIZED
+    OC_STACK_UNINITIALIZED = 0, OC_STACK_INITIALIZED, OC_STACK_UNINIT_IN_PROGRESS
 } OCStackState;
 
 #ifdef WITH_PRESENCE
@@ -1004,12 +1007,19 @@ OCStackResult OCStop()
 
     OC_LOG(INFO, TAG, PCF("Entering OCStop"));
 
-    if (stackState != OC_STACK_INITIALIZED)
+    if (stackState == OC_STACK_UNINIT_IN_PROGRESS)
+    {
+        OC_LOG(DEBUG, TAG, PCF("Stack already stopping, exiting"));
+        return OC_STACK_OK;
+    }
+    else if (stackState != OC_STACK_INITIALIZED)
     {
         OC_LOG(ERROR, TAG, PCF("Stack not initialized"));
         return OC_STACK_ERROR;
     }
 
+    stackState = OC_STACK_UNINIT_IN_PROGRESS;
+
     #ifdef WITH_PRESENCE
     // Ensure that the TTL associated with ANY and ALL presence notifications originating from
     // here send with the code "OC_STACK_PRESENCE_STOPPED" result.
@@ -1018,6 +1028,7 @@ OCStackResult OCStop()
 
     // Free memory dynamically allocated for resources
     deleteAllResources();
+    DeleteDeviceInfo();
 
     // Make call to OCCoAP layer
     if (OCStopCoAP() == OC_STACK_OK)
@@ -1029,6 +1040,7 @@ OCStackResult OCStop()
         stackState = OC_STACK_UNINITIALIZED;
         result = OC_STACK_OK;
     } else {
+        stackState = OC_STACK_INITIALIZED;
         result = OC_STACK_ERROR;
     }
 
@@ -1655,6 +1667,18 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
     return OC_STACK_OK;
 }
 
+OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Entering OCSetDeviceInfo"));
+
+    if(myStackMode == OC_CLIENT)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    return SaveDeviceInfo(deviceInfo);
+}
+
 /**
  * Create a resource
  *
@@ -1688,8 +1712,13 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         return result;
     }
     // Validate parameters
+    if(!uri || (strlen(uri) == 0))
+    {
+        OC_LOG(ERROR, TAG, PCF("URI is invalid"));
+        return OC_STACK_INVALID_URI;
+    }
     // Is it presented during resource discovery?
-    if (!handle || !resourceTypeName || !uri) {
+    if (!handle || !resourceTypeName) {
         OC_LOG(ERROR, TAG, PCF("Input parameter is NULL"));
         return OC_STACK_INVALID_PARAM;
     }
@@ -3105,7 +3134,8 @@ OCStackResult getResourceType(const char * uri, unsigned char** resourceType, ch
         goto exit;
     }
     strcpy(tempURI, uri);
-    leftToken = strtok((char *)tempURI, "?");
+    char* strTokPtr;
+    leftToken = strtok_r((char *)tempURI, "?", &strTokPtr);
 
     while(leftToken != NULL)
     {
@@ -3119,7 +3149,7 @@ OCStackResult getResourceType(const char * uri, unsigned char** resourceType, ch
             strcpy((char *)*resourceType, ((const char *)&leftToken[3]));
             break;
         }
-        leftToken = strtok(NULL, "?");
+        leftToken = strtok_r(NULL, "?", &strTokPtr);
     }
 
     *newURI = tempURI;
diff --git a/resource/csdk/stack/src/oicgroup.c b/resource/csdk/stack/src/oicgroup.c
new file mode 100644 (file)
index 0000000..b9f70ac
--- /dev/null
@@ -0,0 +1,864 @@
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#define _POSIX_C_SOURCE 200112L
+#include <string.h>
+
+#include "cJSON.h"
+#include "ocmalloc.h"
+#include "oicgroup.h"
+#include "ocresource.h"
+#include "occollection.h"
+
+#define TAG PCF("OICGROUP")
+
+#define DESC_DELIMITER "\""
+#define ACTION_DELIMITER "*"
+#define ATTR_DELIMITER "|"
+
+typedef struct aggregatehandleinfo
+{
+    OCServerRequest *ehRequest;
+    OCDoHandle required;
+    OCResource *collResource;
+
+    struct aggregatehandleinfo *next;
+} ClientRequstInfo;
+
+// unsigned int nHandleIdx = 0;
+// ClientRequstInfo g_AggregateResponseHandle[10];
+
+ClientRequstInfo *clientRequstList = NULL;
+
+void AddClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* add)
+{
+    ClientRequstInfo *tmp = NULL;
+
+    if (*head != NULL)
+    {
+        tmp = *head;
+
+        while (tmp->next)
+        {
+            tmp = tmp->next;
+        }
+        tmp->next = add;
+    }
+    else
+    {
+        *head = add;
+    }
+}
+
+ClientRequstInfo* GetClientRequestInfo(ClientRequstInfo *head, OCDoHandle handle)
+{
+    ClientRequstInfo *tmp = NULL;
+
+    tmp = head;
+
+    if (tmp)
+    {
+        while (tmp)
+        {
+//            printf("%p :: %p\n", tmp->required, handle);
+            if (tmp->required == handle)
+            {
+                break;
+            }
+
+            tmp = tmp->next;
+        }
+
+        return tmp;
+    }
+    return NULL;
+}
+
+void RemoveClientRequestInfo(ClientRequstInfo **head, ClientRequstInfo* del)
+{
+    ClientRequstInfo *tmp = NULL;
+
+    if (*head == del)
+    {
+        *head = (*head)->next;
+    }
+    else
+    {
+        tmp = *head;
+        while (tmp->next && (tmp->next != del))
+        {
+            tmp = tmp->next;
+        }
+        if (tmp->next)
+        {
+            tmp->next = del->next;
+        }
+    }
+}
+
+
+
+void AddCapability(OCCapability** head, OCCapability* node)
+{
+    OCCapability *pointer = *head;
+    if (NULL == pointer)
+    {
+        *head = node;
+    }
+    else
+    {
+        while (pointer->next != NULL)
+        {
+            pointer = pointer->next;
+        }
+
+        pointer->next = node;
+    }
+}
+
+void AddAction(OCAction** head, OCAction* node)
+{
+    OCAction *pointer = *head;
+    if (NULL == pointer)
+    {
+        *head = node;
+    }
+    else
+    {
+
+        while (pointer->next != NULL)
+        {
+            pointer = pointer->next;
+        }
+
+        pointer->next = node;
+    }
+}
+
+void AddActionSet(OCActionSet **head, OCActionSet* node)
+{
+    OCActionSet *pointer = *head;
+    if (NULL == pointer)
+    {
+        *head = node;
+    }
+    else
+    {
+
+        while (pointer->next != NULL)
+        {
+            pointer = pointer->next;
+        }
+
+        pointer->next = node;
+    }
+}
+
+void DeleteCapability(OCCapability *del)
+{
+    free(del->capability);
+    del->capability = NULL;
+    free(del->status);
+    del->status = NULL;
+}
+
+void DeleteAction(OCAction** action)
+{
+    OCCapability* pointer = (*action)->head;
+    OCCapability* pDel = NULL;
+
+    while (pointer)
+    {
+        pDel = pointer;
+        pointer = pointer->next;
+
+        DeleteCapability(pDel);
+        pDel->next = NULL;
+    }
+    OCFree((*action)->resourceUri);
+    (*action)->resourceUri = NULL;
+    (*action)->next = NULL;
+}
+
+void DeleteActionSet(OCActionSet** actionset)
+{
+    OCAction* pointer = (*actionset)->head;
+    OCAction* pDel = NULL;
+
+    while (pointer)
+    {
+        pDel = pointer;
+        pointer = pointer->next;
+
+        DeleteAction(&pDel);
+        pDel->next = NULL;
+    }
+
+    OCFree((*actionset)->actionsetName);
+    (*actionset)->head = NULL;
+}
+
+OCStackResult FindAndDeleteActionSet(OCResource **resource, const char * actionsetName)
+{
+
+    if (*resource != NULL)
+    {
+
+        OCActionSet *pointer = NULL;
+        OCActionSet *pDel = NULL;
+
+        pointer = (*resource)->actionsetHead;
+
+        if (pointer == NULL)
+        {
+            return OC_STACK_ERROR;
+        }
+        else
+        {
+            if (strcmp(pointer->actionsetName, actionsetName) == 0)
+            {
+                if (pointer->next != NULL)
+                    (*resource)->actionsetHead = pointer->next;
+                else
+                    (*resource)->actionsetHead = NULL;
+
+                DeleteActionSet(&pointer);
+
+            }
+            else if (pointer->next != NULL)
+            {
+                while (pointer)
+                {
+                    if (pointer->next != NULL)
+                    {
+                        if (strcmp(pointer->next->actionsetName, actionsetName) == 0)
+                        {
+                            pDel = pointer->next;
+                            pointer->next = pointer->next->next;
+
+                            DeleteActionSet(&pDel);
+                        }
+                    }
+                }
+            }
+
+            return OC_STACK_OK;
+        }
+
+    }
+
+    return OC_STACK_ERROR;
+}
+
+OCStackResult DeleteActionSets(OCResource** resource)
+{
+    OCActionSet *pointer = (*resource)->actionsetHead;
+    OCActionSet *pDel = pointer;
+
+    while (pointer)
+    {
+        pDel = pointer;
+        pointer = pointer->next;
+
+        DeleteActionSet(&pDel);
+        pDel->next = NULL;
+    }
+
+    (*resource)->actionsetHead = NULL;
+    return OC_STACK_OK;
+}
+
+OCStackResult GetActionSet(const char *actionName, OCActionSet *head, OCActionSet** actionset)
+{
+    OCActionSet *pointer = head;
+
+    while (pointer)
+    {
+        if (strcmp(pointer->actionsetName, actionName) == 0)
+        {
+            *actionset = pointer;
+            return OC_STACK_OK;
+        }
+
+        pointer = pointer->next;
+    }
+
+    return OC_STACK_ERROR;
+
+}
+
+OCStackResult GetActionSetFromString(OCResource **resource, unsigned char *request, char** method,
+        char **actionsetName)
+{
+    char *acitonRequest;
+    char *iterTokenPtr = NULL;
+    char *iterToken = NULL;
+    char *description = NULL;
+    char *iterDescPtr = NULL;
+
+    char *attributes = NULL;
+    char *iterAttrbutesPtr = NULL;
+
+    char *attr = NULL;
+    char *iterAttrPtr = NULL;
+
+    OCActionSet* actionset = NULL;
+    OCAction* action = NULL;
+
+    acitonRequest = (char *) OCMalloc(strlen((char *) request) + 1);
+    strncpy(acitonRequest, (char *) request, strlen((char *) request) + 1);
+
+    //printf("\t%s\n", acitonRequest);
+    if (acitonRequest != NULL)
+    {
+        iterToken = (char *) strtok_r(acitonRequest, DESC_DELIMITER, &iterTokenPtr);
+
+        while (iterToken != NULL)
+        {
+            if (strcmp(iterToken, "ActionSet") == 0)
+            { // if iterToken is ActionSet, will be created and added a new action set.
+
+                *method = (char *) OCMalloc(strlen(iterToken) + 1);
+                strncpy(*method, iterToken, strlen(iterToken) + 1);
+
+                //GetActionName(iterToken, &actionsetName);
+                // printf("%s\n", iterToken, &iterTokenPtr);
+                iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
+                // printf("%s\n", iterToken);
+                iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
+                // printf("%s\n", iterToken);
+
+                // printf("DESC :: %s\n", iterToken);
+                description = (char *) OCMalloc(strlen(iterToken) + 1);
+                strncpy(description, iterToken, strlen(iterToken) + 1);
+                // printf("DESC Copied :: %s\n", description);
+
+                // Find the action name from description.
+                iterDescPtr = NULL;
+                iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
+                //while(iterToken != NULL)
+                if (iterToken != NULL)
+                {
+                    if (*actionsetName != NULL)
+                    {
+                        // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
+                        return OC_STACK_ERROR; // ERROR OCCURED.
+                    }
+                    else
+                    {
+                        //  Actionset name.
+                        // printf("ACTION SET NAME :: %s\n", iterToken);
+                        *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
+
+                        strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
+                        // printf("ACTION SET NAME :: %s\n", *actionsetName);
+                        // break;
+                    }
+
+                    iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
+                }
+                else
+                {
+                    return OC_STACK_ERROR;
+
+                } // end Action Set Name.
+
+                // New ActionSet Add to OCResource's ActionSet list.
+                // 1. Allocate a new pointer for actionset.
+                actionset = (OCActionSet*) OCMalloc(sizeof(OCActionSet));
+                // 2. Initiate actionset.
+                memset(actionset, 0, sizeof(OCActionSet));
+                actionset->actionsetName = (char *) OCMalloc(strlen(*actionsetName) + 1);
+                strncpy(actionset->actionsetName, *actionsetName, strlen(*actionsetName) + 1);
+                // printf("ACTION SET NAME :: %s\n", actionset->actionsetName);
+
+                while (iterToken != NULL)
+                {
+                    action = (OCAction *) OCMalloc(sizeof(OCAction));
+                    memset(action, 0, sizeof(OCAction));
+
+                    // printf("ATTR Copied :: %s\n", iterToken);
+                    attributes = (char *) OCMalloc(strlen(iterToken) + 1);
+                    strncpy(attributes, iterToken, strlen(iterToken) + 1);
+                    // printf("ATTR Copied :: %s\n", attributes);
+
+                    iterToken = (char *) strtok_r(attributes, ATTR_DELIMITER, &iterAttrbutesPtr);
+                    while (iterToken != NULL)
+                    {
+                        attr = (char *) OCMalloc(strlen(iterToken) + 1);
+                        strncpy(attr, iterToken, strlen(iterToken) + 1);
+
+                        iterToken = (char *) strtok_r(attr, "=", &iterAttrPtr);
+                        while (iterToken != NULL)
+                        {
+                            // Find the URI from description.
+                            if (strcmp(iterToken, "uri") == 0)
+                            {
+                                iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
+                                //printf("uri :: %s\n", iterToken);
+                                action->resourceUri = (char *) OCMalloc(strlen(iterToken) + 1);
+                                strncpy(action->resourceUri, iterToken, strlen(iterToken) + 1);
+                            }
+                            else
+                            {
+                                OCCapability* capa = (OCCapability*) OCMalloc(sizeof(OCCapability));
+                                memset(capa, 0, sizeof(OCCapability));
+                                //printf("%s :: ", iterToken);
+                                capa->capability = (char *) OCMalloc(strlen(iterToken) + 1);
+                                strncpy(capa->capability, iterToken, strlen(iterToken) + 1);
+                                iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
+                                //printf("%s\n", iterToken);
+                                capa->status = (char *) OCMalloc(strlen(iterToken) + 1);
+                                strncpy(capa->status, iterToken, strlen(iterToken) + 1);
+
+                                AddCapability(&action->head, capa);
+                            }
+
+                            iterToken = (char *) strtok_r(NULL, "=", &iterAttrPtr);
+                        }
+
+                        iterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &iterAttrbutesPtr);
+                    } // End of Action
+
+                    AddAction(&actionset->head, action);
+
+                    iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
+                }
+
+                // 3. Add the pointer OCResource's ActionSet list.
+                AddActionSet(&(*resource)->actionsetHead, actionset);
+                return OC_STACK_OK;
+            }
+            else if (strcmp(iterToken, "DoAction") == 0 || strcmp(iterToken, "DelActionSet") == 0
+                    || strcmp(iterToken, "GetActionSet") == 0)
+            {
+                *method = (char *) OCMalloc(strlen(iterToken) + 1);
+                strncpy(*method, iterToken, strlen(iterToken) + 1);
+
+                iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is mean ':'.
+                // printf("%s\n", iterToken);
+                iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr); // it is body of action description.
+                // printf("%s\n", iterToken);
+
+                description = (char *) OCMalloc(strlen(iterToken) + 1);
+                strncpy(description, iterToken, strlen(iterToken) + 1);
+
+                // Find the action name from description.
+                iterDescPtr = NULL;
+                iterToken = (char *) strtok_r(description, ACTION_DELIMITER, &iterDescPtr);
+                if (iterToken != NULL)
+                {
+                    if (*actionsetName != NULL)
+                    {
+                        // printf("ERROR :: ACTIONSET NAME as ActionSet(%s)\n", iterToken);
+                        return OC_STACK_ERROR; // ERROR OCCURED.
+                    }
+                    else
+                    {
+                        //  Actionset name.
+                        // printf("ACTION SET NAME :: %s\n", iterToken);
+                        *actionsetName = (char *) OCMalloc(strlen(iterToken) + 1);
+
+                        strncpy(*actionsetName, iterToken, strlen(iterToken) + 1);
+                        // printf("ACTION SET NAME :: %s\n", *actionsetName);
+                    }
+
+                    iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterDescPtr);
+                    return OC_STACK_OK;
+                }
+                else
+                {
+                    return OC_STACK_ERROR;
+
+                } // end Action Set Name.
+                break;
+            }
+
+            iterToken = (char *) strtok_r(NULL, DESC_DELIMITER, &iterTokenPtr);
+        }
+    }
+
+    return OC_STACK_ERROR;
+}
+
+OCStackResult GetStringFromActionSet(OCActionSet* actionset, char** desc)
+{
+    char temp[1024] =
+    { 0 };
+    int remaining = 1023;
+
+    // OCActionSet *as = resource->actionsetHead;
+    // while(as != NULL)
+    // {
+    printf("\n\n\nAction Set Name :: %s\n", actionset->actionsetName);
+    OCAction *action = actionset->head;
+
+    if (remaining >= strlen(actionset->actionsetName) + 1)
+    {
+        strcat(temp, actionset->actionsetName);
+        remaining -= strlen(actionset->actionsetName);
+        strcat(temp, "*");
+        remaining--;
+    }
+    else
+    {
+        return OC_STACK_ERROR;
+    }
+
+    while (action != NULL)
+    {
+        printf("\tURI :: %s\n", action->resourceUri);
+        strcat(temp, "uri=");
+        remaining -= strlen("uri=");
+        strcat(temp, action->resourceUri);
+        remaining -= strlen(action->resourceUri);
+        strcat(temp, "|");
+        remaining--;
+
+        OCCapability *capas = action->head;
+        while (capas != NULL)
+        {
+            printf("\t\t%s = %s\n", capas->capability, capas->status);
+            strcat(temp, capas->capability);
+            remaining -= strlen(capas->capability);
+            strcat(temp, "=");
+            remaining--;
+            strcat(temp, capas->status);
+            remaining -= strlen(capas->capability);
+
+            capas = capas->next;
+            if (capas != NULL)
+            {
+                strcat(temp, "|");
+            }
+        }
+
+        action = action->next;
+        if (action != NULL)
+        {
+            strcat(temp, "*");
+            remaining--;
+        }
+    }
+    //     as = as->next;
+    // }
+
+    *desc = (char *) OCMalloc(1024 - remaining);
+    strcpy(*desc, temp);
+    // printf("\t\tPlain Text = %s(%i)\n", *desc, 1024 - remaining);
+
+    return OC_STACK_OK;
+}
+
+OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle,
+        OCClientResponse* clientResponse)
+{
+    printf("\n\n\tcallback is called\n\n");
+
+    ClientRequstInfo *info = GetClientRequestInfo(clientRequstList, handle);
+
+    if (info)
+    {
+        int idx;
+
+        unsigned char *responseJson;
+        responseJson = (unsigned char *) OCMalloc(
+                (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + 1));
+
+        // 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;
+        // And insert NULL at the end of body.
+        (responseJson[idx]) = 0;
+
+        OCEntityHandlerResponse response = { 0 };
+        response.ehResult = OC_EH_OK;
+        response.payload = responseJson;
+        response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1;
+        response.persistentBufferFlag = 0;
+        response.requestHandle = (OCRequestHandle) info->ehRequest;
+        response.resourceHandle = (OCResourceHandle) info->collResource;
+
+        OCDoResponse(&response);
+
+        RemoveClientRequestInfo(&clientRequstList, info);
+        OCFree(responseJson);
+    }
+
+    // g_AggregateResponseHandle
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+void ActionSetCD(void *context)
+{
+    // printf("\n\t\tCD is called\n");
+
+    // free( context );
+}
+
+OCStackResult BuildActionJSON(OCAction* action, unsigned char* bufferPtr, uint16_t *remaining)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    cJSON *json;
+    cJSON *body;
+
+    char *jsonStr;
+    uint16_t jsonLen;
+
+    OC_LOG(INFO, TAG, PCF("Entering BuildActionJSON"));
+    json = cJSON_CreateObject();
+
+    cJSON_AddItemToObject(json, "rep", body = cJSON_CreateObject());
+
+    OCCapability* pointerCapa = action->head;
+    while (pointerCapa)
+    {
+        cJSON_AddStringToObject(body, pointerCapa->capability, pointerCapa->status);
+        pointerCapa = pointerCapa->next;
+    }
+
+    jsonStr = cJSON_PrintUnformatted(json);
+
+    jsonLen = strlen(jsonStr);
+    if (jsonLen < *remaining)
+    {
+        strcat((char*) bufferPtr, jsonStr);
+        *remaining -= jsonLen;
+        bufferPtr += jsonLen;
+        ret = OC_STACK_OK;
+    }
+
+    cJSON_Delete(json);
+    free(jsonStr);
+
+    return ret;
+}
+
+unsigned int GetNumOfTargetResource(OCAction *actionset)
+{
+    int numOfREsource = 0;
+
+    OCAction *pointerAction = actionset;
+
+    while (pointerAction != NULL)
+    {
+        numOfREsource++;
+        pointerAction = pointerAction->next;
+    }
+
+    return numOfREsource;
+}
+
+OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const unsigned char *action)
+{
+    OCCallbackData cbdata =
+    { 0 };
+    cbdata.cb = &ActionSetCB;
+    cbdata.cd = &ActionSetCD;
+    cbdata.context = (void *) 0x99;
+
+    return OCDoResource(handle, OC_REST_PUT, targetUri,
+    //temp->rsrcType->resourcetypename,
+            NULL, (char *) action, OC_NA_QOS, &cbdata, NULL, 0);
+}
+
+OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/,
+        OCResource *resource, OCEntityHandlerRequest *ehRequest)
+{
+    OCStackResult stackRet = OC_STACK_ERROR;
+
+    OC_LOG(INFO, TAG, PCF("Group Action is requested."));
+    // if (stackRet == OC_STACK_OK)
+    {
+
+        char *doWhat = NULL;
+        char *actionName = NULL;
+
+        size_t bufferLength = 0;
+        unsigned char buffer[MAX_RESPONSE_LENGTH] =
+        { 0 };
+        unsigned char *bufferPtr = NULL;
+
+        bufferPtr = buffer;
+
+        OCResource * collResource = (OCResource *) ehRequest->resource;
+
+        char *jsonResponse;
+
+        cJSON *json;
+        cJSON *format;
+
+        if (method == OC_REST_PUT)
+        {
+            json = cJSON_CreateObject();
+            cJSON_AddStringToObject(json, "href", resource->uri);
+            cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+
+            OC_LOG(INFO, TAG, PCF("Group Action[PUT]."));
+
+            unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
+            GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
+
+            if (strcmp(doWhat, "DelActionSet") == 0)
+            {
+                if (FindAndDeleteActionSet(&resource, actionName) == OC_STACK_OK)
+                {
+                    stackRet = OC_STACK_OK;
+                }
+                else
+                {
+                    stackRet = OC_STACK_ERROR;
+                }
+            }
+
+            jsonResponse = cJSON_Print(json);
+            cJSON_Delete(json);
+
+            strcat((char *) bufferPtr, jsonResponse);
+
+            bufferLength = strlen((const char *) buffer);
+            if (bufferLength > 0)
+            {
+                OCEntityHandlerResponse response =
+                { 0 };
+                response.ehResult = OC_EH_OK;
+                response.payload = buffer;
+                response.payloadSize = bufferLength + 1;
+                response.persistentBufferFlag = 0;
+                response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
+                response.resourceHandle = (OCResourceHandle) collResource;
+                stackRet = OCDoResponse(&response);
+            }
+
+            stackRet = OC_STACK_OK;
+        }
+
+        if (method == OC_REST_POST)
+        {
+            OC_LOG(INFO, TAG, PCF("Group Action[POST]."));
+
+            OCActionSet *actionset = NULL;
+            unsigned char *actionPtr = (unsigned char *) ehRequest->reqJSONPayload;
+
+            GetActionSetFromString(&resource, actionPtr, &doWhat, &actionName);
+
+            json = cJSON_CreateObject();
+            cJSON_AddStringToObject(json, "href", resource->uri);
+
+            if (strcmp(doWhat, "DoAction") == 0)
+            {
+                if (GetActionSet(actionName, resource->actionsetHead, &actionset) != OC_STACK_OK)
+                {
+                    OC_LOG(INFO, TAG, PCF("ERROR"));
+                    stackRet = OC_STACK_ERROR;
+                }
+
+                if (actionset == NULL)
+                {
+                    OC_LOG(INFO, TAG, PCF("ERROR"));
+                    stackRet = OC_STACK_ERROR;
+                }
+                else
+                {
+
+                    OCAction *pointerAction = actionset->head;
+
+                    unsigned int num = GetNumOfTargetResource(pointerAction);
+
+                    ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler =
+                            HandleAggregateResponse;
+                    ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1;
+
+//                    printf("ActionSet Name :: %s\n", actionset->actionsetName);
+                    while (pointerAction != NULL)
+                    {
+                        unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 };
+                        unsigned char* actionDescPtr = actionDesc;
+                        uint16_t remaining = MAX_RESPONSE_LENGTH;
+
+                        strcpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX);
+                        BuildActionJSON(pointerAction, actionDescPtr, &remaining);
+                        strcat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX);
+
+                        ClientRequstInfo *info = (ClientRequstInfo *) OCMalloc(
+                                sizeof(ClientRequstInfo));
+                        memset(info, 0, sizeof(ClientRequstInfo));
+
+                        info->collResource = resource;
+                        info->ehRequest = (OCServerRequest *) ehRequest->requestHandle;
+
+                        SendAction(&info->required, pointerAction->resourceUri, actionDescPtr);
+
+                        AddClientRequestInfo(&clientRequstList, info);
+
+
+                        pointerAction = pointerAction->next;
+                    }
+
+
+                    stackRet = OC_STACK_OK;
+                }
+            }
+            else if (strcmp(doWhat, "GetActionSet") == 0)
+            {
+                char *plainText = NULL;
+                OCActionSet *actionset = NULL;
+
+                cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+                GetActionSet(actionName, resource->actionsetHead, &actionset);
+                if (actionset != NULL)
+                {
+                    GetStringFromActionSet(actionset, &plainText);
+
+                    if (plainText != NULL)
+                    {
+                        cJSON_AddStringToObject(format, "ActionSet", plainText);
+                    }
+
+                    stackRet = OC_STACK_OK;
+                }
+            }
+
+            jsonResponse = cJSON_Print(json);
+            cJSON_Delete(json);
+
+            strcat((char *) bufferPtr, jsonResponse);
+
+            bufferLength = strlen((const char *) buffer);
+            if (bufferLength > 0)
+            {
+                OCEntityHandlerResponse response =
+                { 0 };
+                response.ehResult = OC_EH_OK;
+                response.payload = buffer;
+                response.payloadSize = bufferLength + 1;
+                response.persistentBufferFlag = 0;
+                response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
+                response.resourceHandle = (OCResourceHandle) collResource;
+                stackRet = OCDoResponse(&response);
+            }
+        }
+    }
+
+    return stackRet;
+}
index 12a7dcc..4a12d01 100644 (file)
@@ -60,11 +60,13 @@ roomserver = examples_env.Program('roomserver', 'roomserver.cpp')
 roomclient = examples_env.Program('roomclient', 'roomclient.cpp')
 garageserver = examples_env.Program('garageserver', 'garageserver.cpp')
 garageclient = examples_env.Program('garageclient', 'garageclient.cpp')
+devicediscoveryserver = examples_env.Program('devicediscoveryserver', 'devicediscoveryserver.cpp')
+devicediscoveryclient = examples_env.Program('devicediscoveryclient', 'devicediscoveryclient.cpp')
 
 Alias("examples", [simpleserver, simpleserverHQ, simpleclient, simpleclientHQ,
                fridgeserver, fridgeclient, presenceserver, presenceclient,
                simpleclientserver, roomserver, roomclient, garageserver,
-               garageclient])
+               garageclient, devicediscoveryserver, devicediscoveryclient])
 env.AppendTarget('examples')
 
 #ios doesn't allow run application from terminal, so won't build these examples
diff --git a/resource/examples/devicediscoveryclient.cpp b/resource/examples/devicediscoveryclient.cpp
new file mode 100644 (file)
index 0000000..f08a8c7
--- /dev/null
@@ -0,0 +1,147 @@
+//******************************************************************
+//
+// 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 sample demonstrates the device discovery feature
+///The client queries for the device related information
+///stored by the server.
+///
+
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+//Callback after device information is received
+void receivedDeviceInfo(const OCRepresentation& rep)
+{
+    std::cout << "\nDevice Information received ---->\n";
+
+    std::string contentType;
+    std::string dateOfManufacture;
+    std::string deviceName;
+    std::string deviceUUID;
+    std::string firmwareVersion;
+    std::string hostName;
+    std::string manufacturerName;
+    std::string manufacturerUrl;
+    std::string modelNumber;
+    std::string platformVersion;
+    std::string supportUrl;
+    std::string version;
+
+    if(rep.getValue("ct", contentType))
+    {
+        std::cout << "Content Type: " << contentType << std::endl;
+    }
+
+    if(rep.getValue("mndt", dateOfManufacture))
+    {
+        std::cout << "Date of manufacture: " << dateOfManufacture << std::endl;
+    }
+
+    if(rep.getValue("dn", deviceName))
+    {
+        std::cout << "Device Name: " << deviceName << std::endl;
+    }
+
+    if(rep.getValue("di", deviceUUID))
+    {
+        std::cout << "Device UUID: " << deviceUUID << std::endl;
+    }
+
+    if(rep.getValue("mnfv", firmwareVersion))
+    {
+        std::cout << "Firmware Version: " << firmwareVersion << std::endl;
+    }
+
+    if(rep.getValue("hn", hostName))
+    {
+        std::cout << "Host Name: " << hostName << std::endl;
+    }
+
+    if(rep.getValue("mnmn", manufacturerName))
+    {
+        std::cout << "Manufacturer Name: " << manufacturerName << std::endl;
+    }
+
+    if(rep.getValue("mnml", manufacturerUrl))
+    {
+        std::cout << "Manufacturer Url: " << manufacturerUrl << std::endl;
+    }
+
+    if(rep.getValue("mnmo", modelNumber))
+    {
+        std::cout << "Model No. : " << modelNumber << std::endl;
+    }
+
+    if(rep.getValue("mnpv", platformVersion))
+    {
+        std::cout << "Platform Version: " << platformVersion << std::endl;
+    }
+
+    if(rep.getValue("mnsl", supportUrl))
+    {
+        std::cout << "Support URL: " << supportUrl << std::endl;
+    }
+
+    if(rep.getValue("icv", version))
+    {
+        std::cout << "Version: " << version << std::endl;
+    }
+}
+
+int main() {
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Client,
+        "0.0.0.0",
+        0,
+        OC::QualityOfService::LowQos
+    };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+        OCPlatform::getDeviceInfo("", "coap://224.0.1.187/oc/core/d", &receivedDeviceInfo);
+        std::cout<< "Querying for device information... " <<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)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/resource/examples/devicediscoveryserver.cpp b/resource/examples/devicediscoveryserver.cpp
new file mode 100644 (file)
index 0000000..9db7736
--- /dev/null
@@ -0,0 +1,170 @@
+//******************************************************************
+//
+// 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 sample demonstrates the device discovery feature
+///The server sets the device related info. which can
+///be later retrieved by a client.
+///
+
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+//Set of strings for each of deviceInfo fields
+std::string contentType = "myContentType";
+std::string dateOfManufacture = "myDateOfManufacture";
+std::string deviceName = "myDeviceName";
+std::string deviceUUID = "myDeviceUUID";
+std::string firmwareVersion = "myFirmwareVersion";
+std::string hostName = "myHostName";
+std::string manufacturerName = "myManufacturerNa";
+std::string manufacturerUrl = "myManufacturerUrl";
+std::string modelNumber = "myModelNumber";
+std::string platformVersion = "myPlatformVersion";
+std::string supportUrl = "mySupportUrl";
+std::string version = "myVersion";
+
+//OCDeviceInfo Contains all the device info to be stored
+OCDeviceInfo deviceInfo;
+
+void DeleteDeviceInfo()
+{
+    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)
+{
+    *targetString = new char[sourceString.length() + 1];
+    strncpy(*targetString, sourceString.c_str(), (sourceString.length() + 1));
+}
+
+OCStackResult SetDeviceInfo(std::string contentType, std::string dateOfManufacture,
+                std::string deviceName, std::string deviceUUID, std::string firmwareVersion,
+                std::string hostName, std::string manufacturerName, std::string manufacturerUrl,
+                std::string modelNumber, std::string platformVersion, std::string supportUrl,
+                std::string version)
+{
+    if(manufacturerName.length() > MAX_MANUFACTURER_NAME_LENGTH)
+    {
+        return OC_STACK_INVALID_PARAM;
+
+    }
+
+    if(manufacturerUrl.length() > MAX_MANUFACTURER_URL_LENGTH)
+    {
+        return OC_STACK_INVALID_PARAM;
+
+    }
+
+    try
+    {
+        DuplicateString(&deviceInfo.contentType, contentType);
+        DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture);
+        DuplicateString(&deviceInfo.deviceName, deviceName);
+        DuplicateString(&deviceInfo.deviceUUID, deviceUUID);
+        DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion);
+        DuplicateString(&deviceInfo.hostName, hostName);
+        DuplicateString(&deviceInfo.manufacturerName, manufacturerName);
+        DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl);
+        DuplicateString(&deviceInfo.modelNumber, modelNumber);
+        DuplicateString(&deviceInfo.platformVersion, platformVersion);
+        DuplicateString(&deviceInfo.supportUrl, supportUrl);
+        DuplicateString(&deviceInfo.version, version);
+    }catch(exception &e)
+    {
+        std::cout<<"String Copy failed!!\n";
+        return OC_STACK_ERROR;
+    }
+
+    return OC_STACK_OK;
+}
+
+
+
+int main()
+{
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Server,
+        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
+        0,         // Uses randomly available port
+        OC::QualityOfService::LowQos
+    };
+
+    OCPlatform::Configure(cfg);
+
+    std::cout<<"Starting server & setting device info\n";
+
+    OCStackResult result = SetDeviceInfo(contentType, dateOfManufacture, deviceName,
+            deviceUUID, firmwareVersion, hostName, manufacturerName, manufacturerUrl,
+            modelNumber, platformVersion, supportUrl, version);
+
+    if(result != OC_STACK_OK)
+    {
+        std::cout << "Device Registration failed\n";
+        return -1;
+    }
+
+    result = OCPlatform::registerDeviceInfo(deviceInfo);
+
+    if(result != OC_STACK_OK)
+    {
+        std::cout << "Device Registration failed\n";
+        return -1;
+    }
+
+    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
+    // 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);
+
+    // No explicit call to stop the platform.
+    // When OCPlatform::destructor is invoked, internally we do platform cleanup
+
+    return 0;
+
+}
+
+
+
diff --git a/resource/examples/groupclient.cpp b/resource/examples/groupclient.cpp
new file mode 100755 (executable)
index 0000000..11afb80
--- /dev/null
@@ -0,0 +1,234 @@
+//******************************************************************
+//
+// 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 "OCPlatform.h"
+#include "OCApi.h"
+
+#include <functional>
+#include <pthread.h>
+#include <iostream>
+
+using namespace std;
+using namespace OC;
+namespace PH = std::placeholders;
+
+OCResourceHandle resourceHandle;
+
+shared_ptr< OCResource > g_resource;
+vector< string > lights;
+
+bool isReady = false;
+
+void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode);
+
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+
+void foundResource(std::shared_ptr< OCResource > resource)
+{
+    std::string resourceURI;
+    std::string hostAddress;
+
+    try
+    {
+        cout << "FOUND Resource" << endl;
+
+        if (resource)
+        {
+            string resourceURI = resource->uri();
+            cout << resourceURI << endl;
+            if (resourceURI == "/core/a/collection")
+            {
+                g_resource = resource;
+            }
+
+            g_resource->get("", DEFAULT_INTERFACE, QueryParamsMap(), onGet);
+            printf("HOST :: %s\n", resource->host().c_str());
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << "" << std::endl;
+    }
+}
+
+void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode)
+{
+    // printf("onGet\n");
+
+    std::vector< OCRepresentation > children = rep.getChildren();
+
+    cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl;
+    for (auto iter = children.begin(); iter != children.end(); ++iter)
+    {
+        lights.push_back((*iter).getUri());
+        cout << "\tURI :: " << (*iter).getUri() << endl;
+    }
+
+    isReady = true;
+}
+
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    printf("\nonPut\n");
+}
+
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    printf("\nonPost\n");
+
+    std::vector< OCRepresentation > children = rep.getChildren();
+
+    cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl;
+    for (auto iter = children.begin(); iter != children.end(); ++iter)
+    {
+        std::string power;
+        (*iter).getValue("power", power);
+
+        cout << "\tURI :: " << (*iter).getUri() << endl;
+        cout << "\t\tpower :: " << power << endl;
+    }
+
+    if (rep.hasAttribute("ActionSet"))
+    {
+        std::string plainText;
+
+        rep.getValue("ActionSet", plainText);
+
+        printf("\tPlain Text :: %s\n", plainText.c_str());
+    }
+    else
+    {
+        printf("Not found ActionSet\n");
+    }
+}
+
+int main()
+{
+    PlatformConfig config
+    { OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    bool isRun = true;
+
+    try
+    {
+        OCPlatform::Configure(config);
+
+        string resourceTypeName = "a.collection";
+        OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=a.collection", &foundResource);
+
+        isReady = false;
+
+        while (isRun)
+        {
+            usleep(100);
+            while (isReady)
+            {
+                int n;
+
+                cout << endl
+                        << "1 :: CREATE ACTIONSET 2 :: EXECUTE ACTION SET 3 :: GET ACTIONSET\n";
+                cout << "4 :: DELETE ACTIONSET 5 :: Quit\n";
+
+                cin >> n;
+                if (n == 1)
+                {
+                    string actionsetDesc;
+                    //"movieTime*uri=coap://10.251.44.228:49858/a/light|power=10*uri=coap://10.251.44.228:49858/a/light|power=10|";
+
+                    actionsetDesc = "allbulboff";
+                    actionsetDesc.append("*");
+                    for (auto iter = lights.begin(); iter != lights.end(); ++iter)
+                    {
+                        actionsetDesc.append("uri=").append((*iter));
+                        actionsetDesc.append("|");
+                        actionsetDesc.append("power=");
+                        actionsetDesc.append("off");
+                        if ((iter + 1) != lights.end())
+                        {
+                            actionsetDesc.append("*");
+                        }
+                    }
+
+                    cout << "ActionSet :: " << actionsetDesc << endl;
+
+                    OCRepresentation rep;
+                    rep.setValue("ActionSet", actionsetDesc);
+
+                    if (g_resource)
+                    {
+                        g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
+                                &onPut);
+                    }
+                }
+                else if (n == 2)
+                {
+                    OCRepresentation rep;
+
+                    rep.setValue("DoAction", std::string("allbulboff"));
+
+                    if (g_resource)
+                    {
+                        g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
+                                &onPost);
+                    }
+                }
+                else if (n == 3)
+                {
+                    OCRepresentation rep;
+
+                    rep.setValue("GetActionSet", std::string("allbulboff"));
+
+                    if (g_resource)
+                    {
+                        g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
+                                &onPost);
+                    }
+                }
+                else if (n == 4)
+                {
+                    OCRepresentation rep;
+
+                    rep.setValue("DelActionSet", std::string("allbulboff"));
+
+                    if (g_resource)
+                    {
+                        g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
+                                &onPut);
+                    }
+                }
+                else if (n == 5)
+                {
+                    isRun = false;
+                    break;
+                }
+
+                fflush(stdin);
+            }
+        }
+    }
+    catch (OCException& e)
+    {
+        cout << e.what() << endl;
+    }
+
+    return 0;
+}
diff --git a/resource/examples/groupserver.cpp b/resource/examples/groupserver.cpp
new file mode 100755 (executable)
index 0000000..4cebd44
--- /dev/null
@@ -0,0 +1,129 @@
+//******************************************************************
+//
+// 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 "OCPlatform.h"
+#include "OCApi.h"
+
+#include <functional>
+#include <pthread.h>
+#include <iostream>
+
+using namespace std;
+using namespace OC;
+
+namespace PH = std::placeholders;
+
+OCResourceHandle resourceHandle;
+std::vector< OCResourceHandle > resourceHandleVector;
+
+void foundResource(std::shared_ptr< OCResource > resource)
+{
+
+    std::string resourceURI;
+    std::string hostAddress;
+
+    try
+    {
+        cout << "FOUND RESOURCE" << endl;
+
+        if (resource)
+        {
+            resourceURI = resource->uri();
+            hostAddress = resource->host();
+
+            cout << "\tResource URI : " << resourceURI << endl;
+            cout << "\tResource Host : " << hostAddress << endl;
+            cout << "\tResource Interfaces : " << resource->getResourceInterfaces().front() << endl;
+            cout << "\tResource Type : " << resource->getResourceTypes().front() << endl;
+            if (resourceURI == "/a/light" || resourceURI == "/a/fan")
+            {
+                OCResourceHandle foundResourceHandle;
+                OCStackResult result = OCPlatform::registerResource(foundResourceHandle, resource);
+                cout << "\tresource registed!" << endl;
+                if (result == OC_STACK_OK)
+                {
+                    OCPlatform::bindResource(resourceHandle, foundResourceHandle);
+                    resourceHandleVector.push_back(foundResourceHandle);
+                }
+                else
+                {
+                    cout << "\tresource Error!" << endl;
+                }
+            }
+
+            // p_platform.bindResource(resourceHandle, foundResourceHandle);
+
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << "" << std::endl;
+    }
+
+}
+
+int main()
+{
+    PlatformConfig config
+    { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    try
+    {
+        string resourceURI = "/core/a/collection";
+        string resourceTypeName = "a.collection";
+        string resourceInterface = BATCH_INTERFACE;
+        OCPlatform::Configure(config);
+
+        // EntityHandler cb = std::bind(, PH::_1, PH::_2);
+
+        OCPlatform::registerResource(resourceHandle, resourceURI, resourceTypeName,
+                resourceInterface,
+                NULL,
+                //&entityHandler, // entityHandler
+                OC_DISCOVERABLE);
+
+        cout << "registerResource is called." << endl;
+
+        OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.light", &foundResource);
+        OCPlatform::bindInterfaceToResource(resourceHandle, GROUP_INTERFACE);
+        OCPlatform::bindInterfaceToResource(resourceHandle, DEFAULT_INTERFACE);
+
+        int selectedMenu;
+        while (true)
+        {
+            std::cin >> selectedMenu;
+
+            if (selectedMenu == 1)
+            {
+                for (unsigned int i = 0; i < resourceHandleVector.size(); ++i)
+                {
+                    OCPlatform::unregisterResource(resourceHandleVector.at(i));
+                }
+            }
+
+        }
+    }
+    catch (OCException& e)
+    {
+
+    }
+
+    return 0;
+}
diff --git a/resource/examples/lightserver.cpp b/resource/examples/lightserver.cpp
new file mode 100755 (executable)
index 0000000..f95722d
--- /dev/null
@@ -0,0 +1,334 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample provides steps to define an interface for a resource
+/// (properties and methods) and host this resource on the server.
+///
+
+#include <functional>
+
+#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace std;
+namespace PH = std::placeholders;
+
+int gObservation = 0;
+void * ChangeLightRepresentation (void *param);
+void * handleSlowResponse (void *param, std::shared_ptr<OCResourceRequest> pRequest);
+
+// Specifies secure or non-secure
+// false: non-secure resource
+// true: secure resource
+bool isSecure = false;
+
+/// Specifies whether Entity handler is going to do slow response or not
+bool isSlowResponse = false;
+
+// Forward declaring the entityHandler
+
+/// This class represents a single resource named 'lightResource'. This resource has
+/// two simple properties named 'state' and 'power'
+
+class LightResource
+{
+
+public:
+    /// Access this property from a TB client
+    std::string m_power;
+    std::string m_lightUri;
+    OCResourceHandle m_resourceHandle;
+    OCRepresentation m_lightRep;
+
+public:
+    /// Constructor
+    LightResource()
+        :m_power(""), m_lightUri("/a/light") {
+        // Initialize representation
+        m_lightRep.setUri(m_lightUri);
+
+        m_lightRep.setValue("power", m_power);
+    }
+
+    /* Note that this does not need to be a member function: for classes you do not have
+    access to, you can accomplish this with a free function: */
+
+    /// This function internally calls registerResource API.
+    void createResource()
+    {
+        std::string resourceURI = m_lightUri; //URI of the resource
+        std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
+        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+
+        EntityHandler cb = std::bind(&LightResource::entityHandler, this,PH::_1);
+
+        // This will internally create and register the resource.
+        OCStackResult result = OCPlatform::registerResource(
+                                    m_resourceHandle, resourceURI, resourceTypeName,
+                                    resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation was unsuccessful\n";
+        }
+    }
+
+    OCResourceHandle getHandle()
+    {
+        return m_resourceHandle;
+    }
+
+    // Puts representation.
+    // Gets values from the representation and
+    // updates the internal state
+    void put(OCRepresentation& rep)
+    {
+        try {
+            if (rep.getValue("power", m_power))
+            {
+                cout << "\t\t\t\t" << "power: " << m_power << endl;
+            }
+            else
+            {
+                cout << "\t\t\t\t" << "power not found in the representation" << endl;
+            }
+        }
+        catch (exception& e)
+        {
+            cout << e.what() << endl;
+        }
+
+    }
+
+    // Post representation.
+    // Post can create new resource or simply act like put.
+    // Gets values from the representation and
+    // updates the internal state
+    OCRepresentation post(OCRepresentation& rep)
+    {
+        put(rep);
+        return get();
+    }
+
+
+    // gets the updated representation.
+    // Updates the representation with latest internal state before
+    // sending out.
+    OCRepresentation get()
+    {
+        m_lightRep.setValue("power", m_power);
+
+        return m_lightRep;
+    }
+
+    void addType(const std::string& type) const
+    {
+        OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+    }
+
+    void addInterface(const std::string& interface) const
+    {
+        OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+    }
+
+private:
+// This is just a sample implementation of entity handler.
+// Entity handler can be implemented in several ways by the manufacturer
+OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
+{
+    cout << "\tIn Server CPP entity handler:\n";
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+    if(request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if(requestFlag & RequestHandlerFlag::InitFlag)
+        {
+            cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        if(requestFlag & RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\t\trequestFlag : Request\n";
+            auto pResponse = std::make_shared<OC::OCResourceResponse>();
+            pResponse->setRequestHandle(request->getRequestHandle());
+            pResponse->setResourceHandle(request->getResourceHandle());
+
+            // If the request type is GET
+            if(requestType == "GET")
+            {
+                cout << "\t\t\trequestType : GET\n";
+                if(isSlowResponse) // Slow response case
+                {
+                    static int startedThread = 0;
+                    if(!startedThread)
+                    {
+                        std::thread t(handleSlowResponse, (void *)this, request);
+                        startedThread = 1;
+                        t.detach();
+                    }
+                    ehResult = OC_EH_SLOW;
+                }
+                else // normal response case.
+                {
+                    pResponse->setErrorCode(200);
+                    pResponse->setResponseResult(OC_EH_OK);
+                    pResponse->setResourceRepresentation(get());
+                    if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        ehResult = OC_EH_OK;
+                    }
+                }
+            }
+            else if(requestType == "PUT")
+            {
+                cout << "\t\t\trequestType : PUT\n";
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                // Do related operations related to PUT request
+                // Update the lightResource
+                put(rep);
+                pResponse->setErrorCode(200);
+                pResponse->setResponseResult(OC_EH_OK);
+                pResponse->setResourceRepresentation(get());
+                if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                {
+                    ehResult = OC_EH_OK;
+                }
+            }
+            else if(requestType == "POST")
+            {
+                cout << "\t\t\trequestType : POST\n";
+
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                // Do related operations related to POST request
+                OCRepresentation rep_post = post(rep);
+                pResponse->setResourceRepresentation(rep_post);
+                pResponse->setErrorCode(200);
+                if(rep_post.hasAttribute("createduri"))
+                {
+                    pResponse->setResponseResult(OC_EH_RESOURCE_CREATED);
+                    pResponse->setNewResourceUri(rep_post.getValue<std::string>("createduri"));
+                }
+
+                if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                {
+                    ehResult = OC_EH_OK;
+                }
+            }
+            else if(requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+
+    return ehResult;
+}
+};
+
+void * handleSlowResponse (void *param, std::shared_ptr<OCResourceRequest> pRequest)
+{
+    // This function handles slow response case
+    LightResource* lightPtr = (LightResource*) param;
+    // Induce a case for slow response by using sleep
+    std::cout << "SLOW response" << std::endl;
+    sleep (10);
+
+    auto pResponse = std::make_shared<OC::OCResourceResponse>();
+    pResponse->setRequestHandle(pRequest->getRequestHandle());
+    pResponse->setResourceHandle(pRequest->getResourceHandle());
+    pResponse->setResourceRepresentation(lightPtr->get());
+    pResponse->setErrorCode(200);
+    pResponse->setResponseResult(OC_EH_OK);
+
+    // Set the slow response flag back to false
+    isSlowResponse = false;
+    OCPlatform::sendResponse(pResponse);
+    return NULL;
+}
+
+
+int main(int argc, char* argv[])
+{
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Server,
+        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
+        0,         // Uses randomly available port
+        OC::QualityOfService::LowQos
+    };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+        // Create the instance of the resource class
+        // (in this case instance of class 'LightResource').
+        LightResource myLight;
+
+        // Invoke createResource function of class light.
+        myLight.createResource();
+
+        myLight.addType(std::string("core.brightlight"));
+        myLight.addInterface(std::string("oc.mi.ll"));
+
+        // 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)
+    {
+        //log(e.what());
+    }
+
+    // No explicit call to stop the platform.
+    // When OCPlatform::destructor is invoked, internally we do platform cleanup
+
+    return 0;
+}
old mode 100644 (file)
new mode 100755 (executable)
index 1360c01..3387126
@@ -19,7 +19,7 @@
 # //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 #
 # override with `make BUILD=release`
-# default to release build
+# default to release build+
 BUILD    := release
 PLATFORM  := linux
 CXX          := g++
@@ -43,11 +43,11 @@ LIB_OC_LOGGER := ../oc_logger/lib/oc_logger.a
 CXX_LIBS  := ../$(BUILD)/obj/liboc.a ../csdk/$(PLATFORM)/$(BUILD)/liboctbstack.a $(LIB_OC_LOGGER) -L../csdk/connectivity/build/out -lconnectivity_abstraction
 
 # Force metatargets to build:
-all.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient ocicuc_target threadingsample
+all.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient ocicuc_target threadingsample devicediscoveryserver devicediscoveryclient groupserver groupclient lightserver
 
-apps.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample
+apps.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample devicediscoveryserver devicediscoveryclient groupserver groupclient lightserver
 
-buildScript_all.PHONY: prep_dirs simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample
+buildScript_all.PHONY: prep_dirs simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample devicediscoveryserver devicediscoveryclient groupserver groupclient lightserver
 
 all: all.PHONY
 
@@ -103,6 +103,23 @@ garageclient: garageclient.cpp
 threadingsample: threadingsample.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ threadingsample.cpp $(CXX_INC) $(CXX_LIBS)
 
+groupserver: groupserver.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ groupserver.cpp $(CXX_INC) $(CXX_LIBS)
+
+groupclient: groupclient.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ groupclient.cpp $(CXX_INC) $(CXX_LIBS)
+
+lightserver: lightserver.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ lightserver.cpp $(CXX_INC) $(CXX_LIBS)
+
+devicediscoveryserver: devicediscoveryserver.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ devicediscoveryserver.cpp $(CXX_INC) $(CXX_LIBS)
+
+devicediscoveryclient: devicediscoveryclient.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ devicediscoveryclient.cpp $(CXX_INC) $(CXX_LIBS)
+       
+       
+
 ocicuc_target:
        cd ocicuc && $(MAKE) apps
 
index 6bd79fe..857d0f4 100644 (file)
@@ -41,8 +41,10 @@ static int TEST_CASE = 0;
 typedef enum {
     TEST_UNICAST_PRESENCE_NORMAL = 1,
     TEST_UNICAST_PRESENCE_WITH_FILTER,
+    TEST_UNICAST_PRESENCE_WITH_FILTERS,
     TEST_MULTICAST_PRESENCE_NORMAL,
     TEST_MULTICAST_PRESENCE_WITH_FILTER,
+    TEST_MULTICAST_PRESENCE_WITH_FILTERS,
     MAX_TESTS
 } CLIENT_TEST;
 
@@ -52,9 +54,13 @@ void printUsage()
     std::cout << "-t 1 : Discover Resources and Initiate Unicast Presence" << std::endl;
     std::cout << "-t 2 : Discover Resources and Initiate Unicast Presence with Filter"
               << std::endl;
-    std::cout << "-t 3 : Discover Resources and Initiate Multicast Presence" << std::endl;
-    std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence with Filter"
+    std::cout << "-t 3 : Discover Resources and Initiate Unicast Presence with Two Filters"
+            << std::endl;
+    std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence" << std::endl;
+    std::cout << "-t 5 : Discover Resources and Initiate Multicast Presence with Filter"
               << std::endl;
+    std::cout << "-t 6 : Discover Resources and Initiate Multicast Presence with two Filters"
+                  << std::endl;
 }
 
 // Callback to presence
@@ -123,21 +129,52 @@ void foundResource(std::shared_ptr<OCResource> resource)
 
             if(resourceURI == "/a/light")
             {
+                OCStackResult result = OC_STACK_OK;
                 curResource = resource;
                 OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
                 if(TEST_CASE == TEST_UNICAST_PRESENCE_NORMAL)
                 {
-                    OCPlatform::subscribePresence(presenceHandle, hostAddress,
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
                             &presenceHandler);
-                    std::cout<< "Subscribed to unicast address:" << hostAddress <<std::endl;
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress << std::endl;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address:" << hostAddress
+                                << std::endl;
+                    }
                 }
-                else if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER)
+                if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER ||
+                        TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
                 {
-                    OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.light",
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
+                            "core.light", &presenceHandler);
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
+                    }
+                    std::cout << " with resource type \"core.light\"." << std::endl;
+                }
+                if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
+                {
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.fan",
                             &presenceHandler);
-                    std::cout<< "Subscribed (with resource type) to unicast address:"
-                                << hostAddress << std::endl;
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
+                    }
+                    std::cout << " with resource type \"core.fan\"." << std::endl;
                 }
             }
         }
@@ -191,23 +228,73 @@ int main(int argc, char* argv[]) {
         std::cout << "Created Platform..."<<std::endl;
 
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        OCStackResult result = OC_STACK_OK;
 
         if(TEST_CASE == TEST_MULTICAST_PRESENCE_NORMAL)
         {
-            OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, presenceHandler);
-            std::cout<< "Subscribed to multicast" <<std::endl;
+            result = OCPlatform::subscribePresence(presenceHandle,
+                    OC_MULTICAST_IP, presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence." << std::endl;
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence." << std::endl;
+            }
         }
         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTER)
         {
-            OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
+            result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
                     &presenceHandler);
-            std::cout<< "Subscribed to multicast with resource type" <<std::endl;
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type";
+            }
+            std::cout << "\"core.light\"." << std::endl;
+        }
+        else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTERS)
+        {
+            result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
+                    &presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type";
+            }
+            std::cout << "\"core.light\"." << std::endl;
+
+            result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.fan",
+                    &presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout<< "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type.";
+            }
+            std::cout << "\"core.fan\"." << std::endl;
         }
         else
         {
             // Find all resources
-            OCPlatform::findResource("", "coap://224.0.1.187/oc/core", &foundResource);
-            std::cout<< "Finding Resource... " <<std::endl;
+            result = OCPlatform::findResource("", "coap://224.0.1.187/oc/core", &foundResource);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Finding Resource... " << std::endl;
+            }
+            else
+            {
+                std::cout << "Failed to request to find resource(s)." << std::endl;
+            }
         }
         //
         // A condition variable will free the mutex it is given, then do a non-
index 63d63da..18e0d7e 100644 (file)
@@ -26,6 +26,7 @@
 #include <functional>
 
 #include <pthread.h>
+#include <array>
 #include <mutex>
 #include <condition_variable>
 
@@ -35,6 +36,8 @@
 using namespace OC;
 using namespace std;
 
+#define numPresenceResources (2)
+
 // Forward declaring the entityHandler
 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request);
 
@@ -149,6 +152,35 @@ public:
 
 };
 
+void createPresenceResources()
+{
+    std::array<std::string, numPresenceResources> resourceURI { {
+        "/a/fan",
+        "/a/led" } };
+    std::array<std::string, numPresenceResources> resourceTypeName { {
+        "core.fan",
+        "core.led" } };
+
+    std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+    OCResourceHandle handle;
+    // OCResourceProperty is defined ocstack.h
+    uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+
+    // This will internally create and register the resource.
+    OCStackResult result = OC_STACK_OK;
+    for(int i=0; i<numPresenceResources; i++)
+    {
+        result = OCPlatform::registerResource(handle,
+                resourceURI.at(i), resourceTypeName.at(i), resourceInterface,
+                &entityHandler, resourceProperty);
+        if (result != OC_STACK_OK)
+        {
+            cout << "Resource creation was unsuccessful with resource URI "
+                    << resourceURI.at(i);
+        }
+    }
+}
+
 // Create the instance of the resource class (in this case instance of class 'LightResource').
 LightResource myLightResource;
 
@@ -178,8 +210,9 @@ int main()
 
         // Invoke createResource function of class light.
         myLightResource.createResource();
+        printf("Created first resource of type \"core.light\"");
 
-        printf("\nEnter a key to create the second resource\n");
+        printf("\nEnter a key to create the second resource of type \"core.light\"\n");
         getchar();
 
         myLightResource.createResource2();
@@ -193,11 +226,16 @@ int main()
 
         startPresence(30);
 
-        printf("\nEnter a key to create the third resource\n");
+        printf("\nEnter a key to create the third resource of type \"core.light\"\n");
         getchar();
 
         myLightResource.createResource3();
 
+        printf("\nEnter a key to create two non-operational resources.\"\n");
+        getchar();
+
+        createPresenceResources();
+
         // 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 8ec23a5..1e40e23 100644 (file)
@@ -44,6 +44,10 @@ namespace OC
                         const std::string& resourceType, FindCallback& callback,
                         QualityOfService QoS) = 0;
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+                        const std::string& deviceURI, FindDeviceCallback& callback,
+                        QualityOfService QoS) = 0;
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
                         const std::string& uri, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
index 10e0515..c6c0b2d 100644 (file)
@@ -51,6 +51,9 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty) = 0;
 
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo) = 0;
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index 39e1df4..ced111d 100644 (file)
@@ -49,6 +49,12 @@ namespace OC
         struct ListenContext
         {
             FindCallback callback;
+            std::weak_ptr<IClientWrapper> clientWrapper;
+        };
+
+        struct DeviceListenContext
+        {
+            FindDeviceCallback callback;
             IClientWrapper::Ptr clientWrapper;
         };
 
@@ -81,6 +87,10 @@ namespace OC
             const std::string& resourceType, FindCallback& callback,
             QualityOfService QoS);
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+            const std::string& deviceURI, FindDeviceCallback& callback,
+            QualityOfService QoS);
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
             const std::string& uri, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions,
index aab856b..b68f599 100644 (file)
@@ -45,6 +45,9 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty);
 
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo);
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index 97076c5..b523da5 100644 (file)
@@ -194,8 +194,14 @@ namespace OC
     // Used in GET, PUT, POST, DELETE methods on links to other resources of a collection.
     const std::string BATCH_INTERFACE = "oc.mi.b";
 
+    // Used in GET, PUT, POST methods on links to other remote resources of a group.
+    const std::string GROUP_INTERFACE = "oc.mi.c";
+
+
     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
 
+    typedef std::function<void(const OCRepresentation&)> FindDeviceCallback;
+
     typedef std::function<OCEntityHandlerResult(
                             const std::shared_ptr<OCResourceRequest>)> EntityHandler;
 
index 61a0f48..1cad339 100644 (file)
@@ -120,6 +120,21 @@ namespace OC
                     FindCallback resourceHandler, QualityOfService QoS);
 
         /**
+         * API for Device Discovery
+         *
+         *
+         * @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")
+         * @param QualityOfService the quality of communication
+         *
+         */
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler);
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler, QualityOfService QoS);
+
+        /**
         * This API registers a resource with the server
         * NOTE: This API applies to server side only.
         *
@@ -167,6 +182,18 @@ namespace OC
                         const std::shared_ptr< OCResource > resource);
 
         /**
+         * Register Device Info
+         *
+         * @param deviceInfo - structure containing all the device specific information
+         *
+         * @return
+         *      OC_STACK_OK   - no errors
+         *      OC_STACK_ERROR - stack process error
+         */
+
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo);
+
+        /**
         * Set default device entity handler
         *
         * @param entityHandler - entity handler to handle requests for
index 896ce3a..f25ce2e 100644 (file)
@@ -146,6 +146,21 @@ namespace OC
                     FindCallback resourceHandler, QualityOfService QoS);
 
         /**
+         * API for Device Discovery
+         *
+         * @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")
+         *
+         * @param QualityOfService the quality of communication
+         *
+         */
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler);
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler, QualityOfService QoS);
+
+        /**
         * This API registers a resource with the server
         * NOTE: This API applies to server side only.
         *
@@ -193,6 +208,17 @@ namespace OC
                         const std::shared_ptr<OCResource> resource);
 
         /**
+         * This API registers all the device specific information
+         *
+         * @param OCDeviceInfo - Structure containing all the device related information
+         *
+         * @return OCStackResult return value of the API. Returns OC_STACK_OK if success
+         *
+         * Note: OCDeviceInfo is defined in OCStack.h
+         */
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo);
+
+        /**
         * Set default device entity handler
         *
         * @param entityHandler - entity handler to handle requests for
index a435b47..101f6fb 100644 (file)
@@ -159,6 +159,11 @@ namespace OC
 
         void setPayload(const std::string& requestPayload)
         {
+            if(requestPayload.empty())
+            {
+                return;
+            }
+
             MessageContainer info;
             info.setJSONRepresentation(requestPayload);
 
index dfae653..049c445 100644 (file)
@@ -36,6 +36,11 @@ namespace OC
             const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+            const std::string& deviceURI, FindDeviceCallback& callback,
+            QualityOfService QoS)
+            {return OC_STACK_NOTIMPL;}
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
             const std::string& uri, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, GetCallback& callback,
index be51f3d..91c6f15 100644 (file)
@@ -43,6 +43,14 @@ namespace OC
             // Not implemented
             return OC_STACK_NOTIMPL;
         }
+
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo)
+        {
+            // Not implemented
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index 6e7a42a..d30539c 100644 (file)
@@ -88,10 +88,8 @@ namespace OC
         static const std::string STACK_RESOURCE_DELETED     =
                 "The specified resource has been deleted";
         static const std::string PRESENCE_STOPPED           = "Stack presence stopped";
-        static const std::string PRESENCE_NOT_HANDLED       =
-                "Stack presence should not be handled";
-        static const std::string REQUEST_NOT_HANDLED        =
-                "Incoming Request should not be handled";
+        static const std::string PRESENCE_TIMEOUT           = "Stack presence timed out";
+        static const std::string PRESENCE_NOT_HANDLED       = "Stack presence should not be handled";
         static const std::string INVALID_OPTION             = "Invalid option";
         static const std::string GENERAL_FAULT              = "General Fault";
         static const std::string MALFORMED_STACK_RESPONSE   =
diff --git a/resource/releaseNotes/Dec20th2014.txt b/resource/releaseNotes/Dec20th2014.txt
new file mode 100644 (file)
index 0000000..d14cd6a
--- /dev/null
@@ -0,0 +1,130 @@
+Release notes
+****************************************************************************
+Release date: Dec 20th, 2014.
+OS: Ubuntu 12.0.4 and above
+Requires boost version 1.55 to build.
+Code buildable in gcc 4.6.3 and above.
+NOTE: Boost is not distributed but should be installed in the Ubuntu machine.
+*****************************************************************************
+
+What is new?
+
+Features:
+---------
+
+Device discovery:
+-----------------
+The device description resource is a virtual resource that provides a representation
+that contains information about the device. It provides a standard mechanism to query
+well-known device meta-data including but not limited to device id, name etc. Device
+discovery feature provides a mechanism to find devices based on specific device-level
+attributes.
+
+Samples demonstrating device discovery:
+devicediscoveryserver and devicediscoveryclient in C++
+ocserver and occlient in C
+
+
+------------
+API changes:
+------------
+
+--------------------------------------------
+Class OCPlatform (Header file: OCPlatform.h)
+--------------------------------------------
+
+***********************
+registerDeviceInfo API
+***********************
+
+This new API allows server app to provide the device information.
+
+***********************
+getDeviceInfo API
+***********************
+
+This new API allows client app to find the device and get the device information.
+
+--------------------------------------------
+Header file: ocstack.h
+--------------------------------------------
+
+***********************
+OCSetDeviceInfo API
+***********************
+
+This new API allows to set the device information.
+
+
+------------
+Notes:
+------------
+1. Multiple improvements in active discovery/presence
+- Callback includes host information
+- Added support to allow more than one presence resource type filter
+
+2. Klocwork issues fixed in C++ samples, SDK and C samples.
+
+3. Multiple bug fixes updated in Jira.
+
+General notes:
+--------------
+Maximum length of URI supported is 64 bytes (sent from the client)
+Maximum length of query supported is 64 bytes (sent from the client)
+Maximum length of request from client and response from server for Arduino is is 256 bytes
+Maximum length of request from client and response from server for non-Ardunio is is 1024 bytes
+
+OIC base supports Arduino WiFi shield.
+This support has been tested with Arduino Mega 2560 and with Arduino 1.0.5 WiFi library.
+Please refer to oic-resource/csdk/README file for building OIC base with WiFi support.
+
+--------
+Samples:
+--------
+
+C++ Samples
+-----------
+
+A basic sample for hosting a resource on a server and a sample for client for discovering resources
+are provided here:
+Simple server sample location: oic-resource/examples/simpleserver.cpp
+Simple client sample location: oic-resource/examples/simpleclient.cpp
+Server and client mode (mode type both) location: oic-resource/examples/simpleclientserver.cpp
+Simpleserver and simpleclient samples also provide examples for doing POST operation.
+Simpleserver also demonstrates slow response case for a GET request.
+
+Garage samples provide usage of OCRepresentation, get/set attribute values
+oic-resource/examples/garageclient.cpp
+oic-resource/examples/garageserver.cpp
+
+Fridge samples provide usage of constructResourceObject API, std bind
+(for mapping request and responses), default
+device entity handler, header options support and Delete operation.
+oic-resource/examples/fridgeclient.cpp
+oic-resource/examples/fridgeserver.cpp
+
+Presence samples provides examples to use presence APIs
+Sample with basic presence feature for server side: oic-resource/examples/presenceserver.cpp
+Sample with basic presence feature for client side: oic-resource/examples/presenceclient.cpp
+
+Room samples provides examples to use resource collection.
+oic-resource/examples/roomclient.cpp
+oic-resource/examples/roomserver.cpp
+
+After building the code in oic-resource, executables for samples are in directory named
+'oic-resource/samples/release'.
+After building the code in oic-resource, executables are in directory named 'oic-resource/release'.
+
+C Samples
+---------
+Collection samples are demonstrated in:
+ocservercoll and occlientcoll
+
+Slow response feature is demonstrated in:
+ocserverslow and occlientslow
+
+Client and server basic operations -- discovery, GET, PUT, POST (NON messages) demonstrated in:
+ocserverbasicops and occlientbasicops
+
+Client and server - discovery, GET,PUT,POST,DELETE,OBS for both NON and CON demonstrated in:
+ocserver and occlient
index e7804c1..83e4ef8 100644 (file)
@@ -58,7 +58,12 @@ namespace OC
             m_listeningThread.join();
         }
 
-        OCStop();
+        // only stop if we are the ones who actually called 'init'.  We are counting
+        // on the server to do the stop.
+        if(m_cfg.mode == ModeType::Client)
+        {
+            OCStop();
+        }
     }
 
     void InProcClientWrapper::listeningFunc()
@@ -87,6 +92,33 @@ namespace OC
         }
     }
 
+    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    {
+        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
+        {
+            throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_ERROR);
+        }
+
+        MessageContainer oc;
+        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+
+        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
+        if(it == oc.representations().end())
+        {
+            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_ERROR);
+        }
+
+        // first one is considered the root, everything else is considered a child of this one.
+        OCRepresentation root = *it;
+        ++it;
+
+        std::for_each(it, oc.representations().end(),
+                [&root](const OCRepresentation& repItr)
+                {root.addChild(repItr);});
+        return root;
+
+    }
+
     OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
         OCClientResponse* clientResponse)
     {
@@ -102,12 +134,21 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
+        auto clientWrapper = context->clientWrapper.lock();
+
+        if(!clientWrapper)
+        {
+            oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
+                    << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         std::stringstream requestStream;
         requestStream << clientResponse->resJSONPayload;
 
         try
         {
-            ListenOCContainer container(context->clientWrapper, *clientResponse->addr,
+            ListenOCContainer container(clientWrapper, *clientResponse->addr,
                     requestStream);
 
             // loop to ensure valid construction of all resources
@@ -129,7 +170,6 @@ namespace OC
         }
 
         return OC_STACK_KEEP_TRANSACTION;
-
     }
 
     OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
@@ -167,31 +207,52 @@ namespace OC
         return result;
     }
 
-    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
+            OCClientResponse* clientResponse)
     {
-        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
-        {
-            return OCRepresentation();
-        }
+        ClientCallbackContext::DeviceListenContext* context =
+            static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
 
-        MessageContainer oc;
-        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+        OCRepresentation rep = parseGetSetCallback(clientResponse);
+        std::thread exec(context->callback, rep);
+        exec.detach();
 
-        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
-        if(it == oc.representations().end())
-        {
-            return OCRepresentation();
-        }
+        return OC_STACK_KEEP_TRANSACTION;
+    }
 
-        // first one is considered the root, everything else is considered a child of this one.
-        OCRepresentation root = *it;
-        ++it;
+    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
+        const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
+    {
+        OCStackResult result;
 
-        std::for_each(it, oc.representations().end(),
-                [&root](const OCRepresentation& repItr)
-                {root.addChild(repItr);});
-        return root;
+        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);};
+
+        auto cLock = m_csdkLock.lock();
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCDoHandle handle;
+            result = OCDoResource(&handle, OC_REST_GET,
+                                  deviceURI.c_str(),
+                                  nullptr, nullptr,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  NULL, 0);
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     void parseServerHeaderOptions(OCClientResponse* clientResponse,
index c92a036..0159bb8 100644 (file)
@@ -271,6 +271,18 @@ namespace OC
         }
     }
 
+    OCStackResult InProcServerWrapper::registerDeviceInfo(const OCDeviceInfo deviceInfo)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSetDeviceInfo(deviceInfo);
+        }
+        return result;
+    }
+
     OCStackResult InProcServerWrapper::registerResource(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceURI,
@@ -351,7 +363,7 @@ namespace OC
                         resourceTypeName.c_str(), // const char * resourceTypeName
                         resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
                         resourceHOST.c_str(), // const char * host
-                        resourceURI.c_str(), // const char * uri
+                        (resourceHOST + resourceURI).c_str(), // const char * uri
                         EntityHandlerWrapper, // OCEntityHandler entityHandler
                         resourceProperties // uint8_t resourceProperties
                         );
@@ -362,7 +374,7 @@ namespace OC
                         resourceTypeName.c_str(), // const char * resourceTypeName
                         resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
                         resourceHOST.c_str(), // const char * host
-                        resourceURI.c_str(), // const char * uri
+                        (resourceHOST + resourceURI).c_str(), // const char * uri
                         nullptr, // OCEntityHandler entityHandler
                         resourceProperties // uint8_t resourceProperties
                         );
index 97381e5..9bea2e2 100644 (file)
@@ -66,6 +66,10 @@ std::string OC::OCException::reason(const OCStackResult sr)
 #ifdef WITH_PRESENCE
         case OC_STACK_PRESENCE_STOPPED:
             return OC::Exception::PRESENCE_STOPPED;
+        case OC_STACK_PRESENCE_TIMEOUT:
+            return OC::Exception::PRESENCE_TIMEOUT;
+        case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+            return OC::Exception::PRESENCE_NOT_HANDLED;
 #endif
         case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
             return OC::Exception::VIRTUAL_DO_NOT_HANDLE;
index f26ffc7..9a17833 100644 (file)
@@ -95,6 +95,22 @@ namespace OC
                                                 resourceHandler, QoS);
         }
 
+        OCStackResult getDeviceInfo(const std::string& host,
+                                                const std::string& deviceURI,
+                                                FindDeviceCallback deviceInfoHandler)
+        {
+            return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI, deviceInfoHandler);
+        }
+
+        OCStackResult getDeviceInfo(const std::string& host,
+                                                const std::string& deviceURI,
+                                                FindDeviceCallback deviceInfoHandler,
+                                                QualityOfService QoS)
+        {
+            return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI,
+                    deviceInfoHandler, QoS);
+        }
+
 
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
                                                 std::string& resourceURI,
@@ -114,6 +130,11 @@ namespace OC
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resource);
         }
 
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo)
+        {
+            return OCPlatform_impl::Instance().registerDeviceInfo(deviceInfo);
+        }
+
         OCStackResult unregisterResource(const OCResourceHandle& resourceHandle)
         {
             return OCPlatform_impl::Instance().unregisterResource(resourceHandle);
index e99cea7..9d9ae52 100644 (file)
@@ -172,6 +172,21 @@ namespace OC
                              host, resourceName, resourceHandler, QoS);
     }
 
+    OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
+                                            const std::string& deviceURI,
+                                            FindDeviceCallback deviceInfoHandler)
+    {
+        return result_guard(getDeviceInfo(host, deviceURI, deviceInfoHandler, m_cfg.QoS));
+    }
+
+    OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
+                                            const std::string& deviceURI,
+                                            FindDeviceCallback deviceInfoHandler,
+                                            QualityOfService QoS)
+    {
+        return checked_guard(m_client, &IClientWrapper::ListenForDevice,
+                             host, deviceURI, deviceInfoHandler, QoS);
+    }
 
     OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
                                             std::string& resourceURI,
@@ -185,17 +200,22 @@ namespace OC
                              resourceInterface, entityHandler, resourceProperty);
     }
 
+    OCStackResult OCPlatform_impl::registerDeviceInfo(const OCDeviceInfo deviceInfo)
+    {
+        return checked_guard(m_server, &IServerWrapper::registerDeviceInfo, deviceInfo);
+    }
 
-       OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
+    OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
                                             const std::shared_ptr< OCResource > resource)
     {
         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+        std::vector<std::string> resourceTypes = resource->getResourceTypes();
 
         return checked_guard(m_server, &IServerWrapper::registerResourceWithHost,
-                ref(resourceHandle), resource->host(), resource->uri(), "core.remote", "oc.mi.def",
+                ref(resourceHandle), resource->host(), resource->uri(), resourceTypes[0]/*"core.remote"*/, "oc.mi.def",
                 (EntityHandler) nullptr, resourceProperty);
-
     }
+
     OCStackResult OCPlatform_impl::unregisterResource(const OCResourceHandle& resourceHandle) const
     {
         return checked_guard(m_server, &IServerWrapper::unregisterResource,
index 460e9ac..71487cd 100644 (file)
@@ -33,7 +33,7 @@
 #include <OicJsonSerializer.hpp>
 #include <algorithm>
 
-// code needed to serialize a string::Attribute value map
+// code needed to serialize a string=>Attribute value map
 namespace OC
 {
     namespace detail
@@ -165,6 +165,11 @@ namespace OC
     { }
     std::string OCRepresentation::getJSONRepresentation() const
     {
+        if(empty())
+        {
+            return "{}";
+        }
+
         std::stringstream os;
 
         // note: the block is required because cereal closes the JSON string
@@ -255,6 +260,11 @@ namespace OC
             return false;
         }
 
+        if(m_children.size() > 0)
+        {
+            return false;
+        }
+
         return true;
     }
 
index 0ed64c2..75ab524 100644 (file)
@@ -204,6 +204,8 @@ OCStackResult result_guard(const OCStackResult r)
     case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
 #ifdef WITH_PRESENCE
     case OC_STACK_PRESENCE_STOPPED:
+    case OC_STACK_PRESENCE_TIMEOUT:
+    case OC_STACK_PRESENCE_DO_NOT_HANDLE:
 #endif
     break;
  }
index de307f3..4b1c902 100644 (file)
@@ -16,7 +16,7 @@ src_dir = env.get('SRC_DIR')
 ######################################################################
 # Check dependent packages (Linux only)
 ######################################################################
-if target_os == 'linux':
+if target_os in ['linux', 'tizen']:
        if not env.GetOption('help'):
                if not target_arch == platform.machine():
                        print '''
@@ -57,4 +57,4 @@ elif target_os == 'ios':
        lib_env.AppendUnique(FRAMEWORKS = ['boost'])
 elif target_os == 'darwin':
        lib_env.AppendUnique(CPPPATH = ['/usr/local/include'])
-       lib_env.AppendUnique(LIBPATH = ['/usr/local/lib'])
\ No newline at end of file
+       lib_env.AppendUnique(LIBPATH = ['/usr/local/lib'])
index de6594e..70d5515 100644 (file)
@@ -4,24 +4,11 @@ It is not a system or end-to-end test.
 
 Unit Test Requirements:
 
-1. Install Google Test 1.7.0 on a Linux build machine to <gtest-1.7.0> from the
-   following address:
-
-       http://code.google.com/p/googletest/downloads/list
-
-2. Create/Append a file named "local.properties" at <oic-resource>/csdk.
-   "local.properties" is used by the build process to specify the path to the
-   Google Test directory.
-
-   local.properties should contain GTEST_DIR, as follows:
-
-   GTEST_DIR := <gtest-1.7.0>
-
-3. To run the unit test, first build the unit tests with the following command
+1. To run the unit test, first build the unit tests with the following command
    from <oic-resource>:
 
    make -f buildScript.mk linux_ub_unittests
 
-4. Run the unit test by issuing the following command from <oic-resource>:
+2. Run the unit test by issuing the following command from <oic-resource>:
 
    ./unittests/tests
index 5461731..6a05e80 100644 (file)
@@ -29,13 +29,8 @@ ROOT_DIR     = ./
 # You must create the file "local.properties" on your local machine which contains any local paths, etc
 # local.properties should NOT be committed to repo
 include $(ROOT_DIR)/../csdk/local.properties
-# GTEST_DIR contains the path to Google Test libs and must be defined in local.properties
-#  Example:
-#  GTEST_DIR := /home/johndoe/utils/gtest-1.7.0
-
-# NOTE:  to run app, make sure that LD_LIBRARY_PATH env variable
-#        contains $(GTEST_DIR)/lib/.libs
 
+GTEST_DIR= ../../extlibs/gtest-1.7.0
 OUT_DIR          := $(BUILD)
 
 ifeq ($(ROOT_DIR),)
@@ -53,8 +48,9 @@ INC_DIRS  += -I$(GTEST_DIR)/include
 
 LIB_OC_LOGGER := ../oc_logger/lib/oc_logger.a
 
+GTEST_LIBS := $(GTEST_DIR)/lib/.libs/libgtest.a $(GTEST_DIR)/lib/.libs/libgtest_main.a 
 CXX_LIBS  := ../$(BUILD)/obj/liboc.a ../csdk/$(PLATFORM)/$(BUILD)/liboctbstack.a $(LIB_OC_LOGGER)
-CXX_LIBS  += $(GTEST_DIR)/lib/.libs/libgtest.a $(GTEST_DIR)/lib/.libs/libgtest_main.a
+CXX_LIBS  += $(GTEST_LIBS)
 
 CC_FLAGS.debug      := -g -O0 -g3 -Wall -ffunction-sections -fdata-sections \
                         -std=c++0x -pedantic $(INC_DIRS) -L$(ROOT_DIR)/$(BUILD) -DTB_LOG
@@ -68,9 +64,17 @@ all: prep_dirs tests
 prep_dirs:
        -mkdir -p $(OUT_DIR)
 
-tests: tests.cpp
+tests: tests.cpp $(GTEST_LIBS)
        $(CXX) $^ $(CPPFLAGS) -o $(OUT_DIR)/$@
 
+$(GTEST_LIBS): $(GTEST_DIR)
+       cd $(GTEST_DIR) && ./configure && make
+
+$(GTEST_DIR):
+       cd ../../extlibs && \
+       wget -q https://googletest.googlecode.com/files/gtest-1.7.0.zip && \
+       unzip gtest-1.7.0.zip
+
 .PHONY: clean
 
 clean:
index 4f49777..4b69d4a 100644 (file)
@@ -11,15 +11,15 @@ if target_os != 'arduino':
        SConscript('things-manager/SConscript')
 
        # Build soft sensor manager project
-       SConscript('soft-sensor-manager/SConscript')
+#      SConscript('soft-sensor-manager/SConscript')
 
        # Build protocol plugin project
-       # protocol-plugin use 'sys/inotify.h', this header file doesn't
-       # exist on MAC OSX
+       # protocol-plugin uses 'inotify' feature, which isn't supported by
+       # MAC OSX and IOS
        if target_os not in ['darwin', 'ios']:
                SConscript('protocol-plugin/SConscript')
 
        # Build notification manager project
-       SConscript('notification-manager/SConscript')
-else:
-       SConscript('notification-manager/SampleApp/arduino/SConscript')
+#      SConscript('notification-manager/SConscript')
+#else:
+#      SConscript('notification-manager/SampleApp/arduino/SConscript')
diff --git a/service/docs/Control Manager-Programmer's guide.pdf b/service/docs/Control Manager-Programmer's guide.pdf
new file mode 100644 (file)
index 0000000..f5fe8a5
Binary files /dev/null and b/service/docs/Control Manager-Programmer's guide.pdf differ
diff --git a/service/docs/Getting Started_IoTivity Services_20141218.pdf b/service/docs/Getting Started_IoTivity Services_20141218.pdf
new file mode 100755 (executable)
index 0000000..360143d
Binary files /dev/null and b/service/docs/Getting Started_IoTivity Services_20141218.pdf differ
diff --git a/service/docs/Getting Started_SSM_PPM_Things Manager_NM_20141218.pdf b/service/docs/Getting Started_SSM_PPM_Things Manager_NM_20141218.pdf
new file mode 100755 (executable)
index 0000000..3172d78
Binary files /dev/null and b/service/docs/Getting Started_SSM_PPM_Things Manager_NM_20141218.pdf differ
diff --git a/service/docs/IoTivity Services_20141216.pdf b/service/docs/IoTivity Services_20141216.pdf
new file mode 100644 (file)
index 0000000..ff8f4ba
Binary files /dev/null and b/service/docs/IoTivity Services_20141216.pdf differ
diff --git a/service/docs/Notification Manager - Programmer's guide.pdf b/service/docs/Notification Manager - Programmer's guide.pdf
new file mode 100644 (file)
index 0000000..2d91b78
Binary files /dev/null and b/service/docs/Notification Manager - Programmer's guide.pdf differ
diff --git a/service/docs/PPM - Programmer's Guide_20141218.pdf b/service/docs/PPM - Programmer's Guide_20141218.pdf
new file mode 100755 (executable)
index 0000000..bfc3915
Binary files /dev/null and b/service/docs/PPM - Programmer's Guide_20141218.pdf differ
diff --git a/service/docs/SSM - Programmer's guide_20141216.pdf b/service/docs/SSM - Programmer's guide_20141216.pdf
new file mode 100755 (executable)
index 0000000..5ecc3a4
Binary files /dev/null and b/service/docs/SSM - Programmer's guide_20141216.pdf differ
diff --git a/service/docs/Things Manager - Programmer's guide_M2_SDK_APIs.pdf b/service/docs/Things Manager - Programmer's guide_M2_SDK_APIs.pdf
new file mode 100644 (file)
index 0000000..ab356e1
Binary files /dev/null and b/service/docs/Things Manager - Programmer's guide_M2_SDK_APIs.pdf differ
index 647c6f4..d1e9288 100644 (file)
@@ -1,4 +1,4 @@
-VPATH = ../../src:../../../SampleApp/linux/sampleConsumer:../../../SampleApp/linux/sampleProvider
+VPATH = ../../src:../../src/linux:../../../SampleApp/linux/sampleConsumer:../../../SampleApp/linux/sampleProvider
 
 OCPATH = ../../../../../resource
 OCINCLUDE = $(OCPATH)/include
@@ -11,7 +11,8 @@ BOOSTPATH = ../../../../../boost_1_51_0
 CXX=g++
 CXXFLAGS = -O2 -g -Wall -fmessage-length=0 -std=c++0x -I$(NOTIFICATIONINCLUDE) -I$(OCINCLUDE) -I$(STACKINCLUDE) -I$(SOCKETINCLUDE) -I$(OCLOGGERINCLUDE) -I$(BOOSTPATH)
 
-OBJS =  ResourceManager.o RegistrationManager.o VirtualRepresentation.o NotificationManager.o LinuxMain.o
+#OBJS =         ResourceManager.o RegistrationManager.o VirtualRepresentation.o NotificationManager.o LinuxMain.o
+OBJS =  OICPlatformConfig.o HostingHandler.o HostingInterface.o ResourceManager.o RegistrationManager.o VirtualRepresentation.o NotificationManager.o main.o
 
 LIBS = $(OCPATH)/release/obj/liboc.a $(OCPATH)/csdk/linux/release/liboctbstack.a $(OCPATH)/oc_logger/lib/oc_logger.a
 
diff --git a/service/notification-manager/NotificationManager/include/HostingConfig.h b/service/notification-manager/NotificationManager/include/HostingConfig.h
new file mode 100644 (file)
index 0000000..98a09e4
--- /dev/null
@@ -0,0 +1,47 @@
+
+#ifndef HOSTINGCONFIG_H_
+#define HOSTINGCONFIG_H_
+
+#include "NotificationManager.h"
+
+
+enum class HostingMode
+{
+       None,
+       ManualMode,
+       AutomaticMode,
+};
+
+enum class AutomaticMethod
+{
+       None,
+       NetworkStatusChange,
+       Timer,
+       DeviceStatus
+};
+
+enum class NotifyMethod
+{
+       Frequence,
+       Equalization,
+       Granularity,
+       None
+};
+
+enum class NotifyFrequency
+{
+       OnTime,
+       Periodically,
+       None
+};
+
+
+struct HostingConfig
+{
+       HostingMode             hostingMode;
+       AutomaticMethod automaticMethod;
+       NotifyMethod            notifyMethod;
+       NotifyFrequency frequency;
+};
+
+#endif /* HOSTINGCONFIG_H_ */
diff --git a/service/notification-manager/NotificationManager/include/HostingHandler.h b/service/notification-manager/NotificationManager/include/HostingHandler.h
new file mode 100644 (file)
index 0000000..3f8a6fb
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * HostingHandler.h
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#ifndef HOSTINGHANDLER_H_
+#define HOSTINGHANDLER_H_
+
+#include "NotificationManager.h"
+
+class HostingHandler
+{
+public:
+
+       static void initialize();
+       static void initialize(HostingConfig cfg);
+       static HostingHandler *getInstance();
+
+       void setHostingConfig(HostingConfig cfg);
+
+       void changeHostingMode(HostingMode hostingMode, AutomaticMethod autoMethod = AutomaticMethod::None);
+       void changeAutomaticHostingMethod(AutomaticMethod autoMethod);
+       void changeNotifiyMethod(NotifyMethod notifyMethod);
+       void changeNotifyFrequencyType(NotifyFrequency notifyFrequency);
+
+private:
+
+       HostingHandler();
+       ~HostingHandler();
+
+       static HostingHandler *s_instance;
+       static mutex s_mutexForCreation;
+
+       HostingConfig hostingCfg;
+
+       static std::function< void(bool isHosting) > s_findHostingCandidate;
+       static std::function< void(std::string) > s_addExtraStr;
+       static std::function< void(std::shared_ptr< OCResource > resource) > s_startHosting;
+       static std::function< void(OCResourceHandle resourceHandle) > s_notify;
+
+       void startFindHost();
+       void onObserve(AttributeMap &AttMap, OCResourceHandle resourceHandle);
+       void onFoundCandidate(std::shared_ptr< OCResource > resource);
+
+       void runAutomaticHosting(AutomaticMethod autoMethod);
+       void stopAutomaticHosting();
+
+       void notifyFrequence(OCResourceHandle resourceHandle);
+
+};
+
+#endif /* HOSTINGHANDLER_H_ */
diff --git a/service/notification-manager/NotificationManager/include/HostingInterface.h b/service/notification-manager/NotificationManager/include/HostingInterface.h
new file mode 100644 (file)
index 0000000..4fb2164
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * HostingInterface.h
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#ifndef HOSTINGINTERFACE_H_
+#define HOSTINGINTERFACE_H_
+
+#include "NotificationManager.h"
+
+using namespace OC;
+using namespace OCPlatform;
+
+class HostingInterface
+{
+
+public:
+       HostingInterface();
+       ~HostingInterface();
+
+       int setOnFoundHostingCandidate(
+                       std::function< void(std::shared_ptr< OCResource > resource) > func);
+       int setOnObserve(std::function< void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) > func);
+
+       int setFindHosting(std::function< void(bool isHosting) > &func);
+       int setStartHosting(std::function< void(std::shared_ptr< OCResource > resource) > &func);
+       int setNotifyObservers(std::function< void(OCResourceHandle resourceHandle) > &func);
+       int setAddExtraStr(std::function< void(std::string) > &func);
+
+};
+
+#endif /* HOSTINGINTERFACE_H_ */
index 3ac4db3..294b12e 100644 (file)
 #include <string>
 #include <vector>
 #include <list>
+#include <condition_variable>
 
-#include "OCApi.h"
-#include "OCPlatform.h"
-#include "OCResource.h"
-#include "OCResourceRequest.h"
-#include "OCResourceResponse.h"
-#include "ocstack.h"
-
+#include "OICPlatformConfig.h"
+#include "HostingConfig.h"
 #include "ResourceManager.h"
 #include "RegistrationManager.h"
 #include "VirtualRepresentation.h"
+#include "HostingHandler.h"
+#include "HostingInterface.h"
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
 
-#define ISFORDEMO 1
+#define IN
+#define OUT
 
 using namespace OC;
 using namespace OCPlatform;
@@ -53,47 +60,24 @@ class NotificationManager
 
 private:
 
-    static NotificationManager *s_instance;
-//    static OCPlatform *s_nmOCPlatform;
-
-    static PlatformConfig s_cfg;
+    NotificationManager();
+    NotificationManager(HostingConfig cfg);
+    ~NotificationManager();
 
-    std::function< void(AttributeMap &inputAttMap) > m_print;
-    std::function< void(std::shared_ptr< OCResource > resource) > m_onfound;
-    std::function< void(AttributeMap &inputAttMap) > m_onObserve;
+    static NotificationManager *s_instance;
+    static mutex s_mutexForCreation;
 
-    std::function< void(std::shared_ptr< OCResource > resource) > m_startHosting;
-    std::function< void() > m_findHosting;
-    std::function< void(std::string) > m_addExtraStr;
+    int getNetInfo(IN int& sck, IN struct ifreq* item, OUT std::string& ip_addres);
+    bool scanAndGetNetworkInterface(OUT std::string& ip_addres);
 
 public:
 
-    NotificationManager();
-    ~NotificationManager();
-
+    static void initialize();
+    static void initialize(HostingConfig cfg);
     static NotificationManager *getInstance();
 
-    void initialize();
-    void findHostingCandidate();
     void registerHostingEventListener();
 
-    int setPrint(std::function< void(AttributeMap &inputAttMap) > func);
-    int setOnFoundHostingCandidate(
-            std::function< void(std::shared_ptr< OCResource > resource) > func);
-    int setOnObserve(std::function< void(AttributeMap &inputAttMap) > func);
-
-    std::function< void(AttributeMap &inputAttMap) > getPrint();
-    std::function< void(std::shared_ptr< OCResource > resource) > getOnFoundHostingCandidate();
-    std::function< void(AttributeMap &inputAttMap) > getOnObserve();
-
-    int setStartHosting(std::function< void(std::shared_ptr< OCResource > resource) > &func);
-    int setFindHosting(std::function< void() > &func);
-    int setAddExtraStr(std::function< void(std::string) > &func);
-
-    std::function< void(std::shared_ptr< OCResource > resource) > getStartHosting();
-    std::function< void() > getFindHosting();
-    std::function< void(std::string) > getAddExtraStr();
-
 };
 
 #endif /* NOTIFICATIONMANAGER_H_ */
diff --git a/service/notification-manager/NotificationManager/include/OICPlatformConfig.h b/service/notification-manager/NotificationManager/include/OICPlatformConfig.h
new file mode 100644 (file)
index 0000000..4c4ffc8
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * OICPlatformConfig.h
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#ifndef OICPLATFORMCONFIG_H_
+#define OICPLATFORMCONFIG_H_
+
+#include "OCApi.h"
+#include "OCPlatform.h"
+#include "OCResource.h"
+#include "OCResourceRequest.h"
+#include "OCResourceResponse.h"
+#include "ocstack.h"
+
+using namespace OC;
+using namespace OCPlatform;
+
+class OICPlatformConfig
+{
+private:
+
+       OICPlatformConfig();
+       ~OICPlatformConfig();
+
+       static OICPlatformConfig *s_instance;
+       static mutex s_mutexForCreation;
+       static PlatformConfig s_cfg;
+
+public:
+
+       void initialize();
+       static OICPlatformConfig *getInstance();
+       void setIP(std::string ipaddress);
+};
+
+#endif /* OICPLATFORMCONFIG_H_ */
index bca32cf..6cf39bf 100644 (file)
 using namespace OC;
 using namespace OCPlatform;
 
+class OICPlatformConfig;
 class VirtualRepresentation;
 
 class RegistrationManager
 {
 
 private:
+    RegistrationManager();
+    ~RegistrationManager();
+
     static RegistrationManager *s_instance;
+    static mutex s_mutexForCreation;
 
 public:
-    RegistrationManager();
-    ~RegistrationManager();
 
     static RegistrationManager *getInstance();
 
index 343881b..216d815 100644 (file)
 #ifndef RESOURCEMANAGER_H_
 #define RESOURCEMANAGER_H_
 
-#include <map>
-#include <memory>
-#include <string>
-#include "OCPlatform.h"
-#include "OCResource.h"
-#include "OCResourceResponse.h"
-#include "ocstack.h"
-
 #include "NotificationManager.h"
 
 using namespace OC;
 using namespace OCPlatform;
 
+
+class OICPlatformConfig;
 class VirtualRepresentation;
 
 class ResourceManager
 {
 
 private:
-    static ResourceManager *s_instance;
+    ResourceManager();
+    ~ResourceManager();
 
+    static ResourceManager *s_instance;
+    static mutex s_mutexForCreation;
     static std::list< VirtualRepresentation > s_resourceList;
-
     static std::string s_extraStr;
 
     void foundResourceforhosting(std::shared_ptr< OCResource > resource);
@@ -52,21 +48,26 @@ private:
     void saveResourceDB();
 
 public:
-    ResourceManager();
-    virtual ~ResourceManager();
+
+       std::function< void(std::shared_ptr< OCResource > resource) > m_onFoundforHosting;
+       std::function< void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) > m_onObserve;
+       std::function< void(OCResourceHandle resourceHandle) > m_notify;
 
     static ResourceManager *getInstance();
-    VirtualRepresentation findVirtualRepresentation(std::string uri);
 
-    OCStackResult findNMResource(const std::string& host , const std::string& resourceName ,
-            bool ishosting);
+    void findNMResource(bool isHosting);
+
+    void onFoundforHostingDefault(std::shared_ptr< OCResource > resource);
+    void onObserveDefault(AttributeMap &inputAttMap, OCResourceHandle resourceHandle);
+    void notifyObserversDefault(OCResourceHandle resourceHandle);
+
     void startHosting(std::shared_ptr< OCResource > resource);
+    void notifyObservers(OCResourceHandle resourceHandle);
 
+    VirtualRepresentation findVirtualRepresentation(std::string uri);
     AttributeMap copyAttributeMap(AttributeMap &inputAttMap);
     bool isEmptyAttributeMap(AttributeMap &inputAttMap);
-
     void printAttributeMap(AttributeMap &inputAttMap);
-    void onFoundReport(std::shared_ptr< OCResource > resource);
 
     void addExtraStr(std::string str);
     std::string getExtraStr();
index 7b67875..7702f7f 100644 (file)
 #ifndef VIRTUALREPRESENTATION_H_
 #define VIRTUALREPRESENTATION_H_
 
-#include <functional>
-#include <condition_variable>
-
-#include "OCPlatform.h"
-#include "OCApi.h"
 #include "NotificationManager.h"
 
 #define SUCCESS_RESPONSE 0
@@ -78,9 +73,9 @@ public:
     std::string addVirtualTag(std::string uri);
 
     OCEntityHandlerResult entityHandler(const std::shared_ptr<OCResourceRequest> request ,
-               const std::shared_ptr<OCResourceResponse> response);
+                       const std::shared_ptr<OCResourceResponse> response);
     void onObserve(const HeaderOptions &headerOption, const OCRepresentation &rep ,
-            const int eCode , const int sequenceNumber);
+                const int eCode , const int sequenceNumber);
 
 };
 
diff --git a/service/notification-manager/NotificationManager/src/HostingHandler.cpp b/service/notification-manager/NotificationManager/src/HostingHandler.cpp
new file mode 100644 (file)
index 0000000..7e45a85
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * HostingHandler.cpp
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#include "HostingHandler.h"
+
+HostingHandler *HostingHandler::s_instance = NULL;
+mutex HostingHandler::s_mutexForCreation;
+
+std::function< void(bool isHosting) > HostingHandler::s_findHostingCandidate;
+std::function< void(std::shared_ptr< OCResource > resource) > HostingHandler::s_startHosting;
+std::function< void(OCResourceHandle resourceHandle) > HostingHandler::s_notify;
+std::function< void(std::string) > HostingHandler::s_addExtraStr;
+
+HostingHandler::HostingHandler()
+{
+
+}
+
+HostingHandler::~HostingHandler()
+{
+
+}
+
+HostingHandler *HostingHandler::getInstance()
+{
+       if(!s_instance)
+       {
+               s_mutexForCreation.lock();
+               if(!s_instance)
+               {
+                       s_instance = new HostingHandler();
+               }
+               s_mutexForCreation.unlock();
+       }
+
+       return s_instance;
+}
+
+void HostingHandler::initialize()
+{
+       // Create Hosting Handler instance
+       HostingHandler *ptr = HostingHandler::getInstance();
+
+       // Registration interface about hosting
+       HostingInterface hostingInterface;
+
+       hostingInterface.setFindHosting(ptr->s_findHostingCandidate);
+       hostingInterface.setStartHosting(ptr->s_startHosting);
+       hostingInterface.setNotifyObservers(ptr->s_notify);
+       hostingInterface.setAddExtraStr(ptr->s_addExtraStr);
+
+       hostingInterface.setOnFoundHostingCandidate(
+                       std::function< void(std::shared_ptr< OCResource > resource) >(
+                                       std::bind(&HostingHandler::onFoundCandidate , HostingHandler::getInstance() , std::placeholders::_1)));
+       hostingInterface.setOnObserve(
+                       std::function< void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) >(
+                                       std::bind(&HostingHandler::onObserve , HostingHandler::getInstance() , std::placeholders::_1, std::placeholders::_2)));
+
+       ptr->s_addExtraStr("virtual");
+       ptr->startFindHost();
+}
+
+void HostingHandler::initialize(HostingConfig cfg)
+{
+       // Create Hosting Handler instance
+       HostingHandler *ptr = HostingHandler::getInstance();
+
+       // Registration interface about hosting
+       HostingInterface hostingInterface;
+
+       hostingInterface.setFindHosting(ptr->s_findHostingCandidate);
+       hostingInterface.setStartHosting(ptr->s_startHosting);
+       hostingInterface.setNotifyObservers(ptr->s_notify);
+       hostingInterface.setAddExtraStr(ptr->s_addExtraStr);
+
+       hostingInterface.setOnFoundHostingCandidate(
+                       std::function< void(std::shared_ptr< OCResource > resource) >(
+                                       std::bind(&HostingHandler::onFoundCandidate , HostingHandler::getInstance() , std::placeholders::_1)));
+       hostingInterface.setOnObserve(
+                       std::function< void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) >(
+                                       std::bind(&HostingHandler::onObserve , HostingHandler::getInstance() , std::placeholders::_1, std::placeholders::_2)));
+
+       // Set Hosting Config
+       ptr->setHostingConfig(cfg);
+       ptr->changeHostingMode(ptr->hostingCfg.hostingMode);
+
+       ptr->s_addExtraStr("virtual");
+       ptr->startFindHost();
+}
+
+void HostingHandler::setHostingConfig(HostingConfig cfg)
+{
+       hostingCfg.automaticMethod      = cfg.automaticMethod;
+       hostingCfg.frequency            = cfg.frequency;
+       hostingCfg.hostingMode          = cfg.hostingMode;
+       hostingCfg.notifyMethod         = cfg.notifyMethod;
+}
+
+void HostingHandler::changeHostingMode(HostingMode hostingMode, AutomaticMethod autoMethod)
+{
+       if(hostingCfg.hostingMode != hostingMode)
+       {
+               hostingCfg.hostingMode = hostingMode;
+               if(hostingCfg.hostingMode == HostingMode::AutomaticMode)
+               {
+                       runAutomaticHosting(autoMethod);
+               }
+               else
+               {
+                       stopAutomaticHosting();
+               }
+       }
+}
+
+void HostingHandler::runAutomaticHosting(AutomaticMethod autoMethod)
+{
+       // TODO Triggering from Event Listener.
+       if(hostingCfg.automaticMethod != autoMethod)
+       {
+               hostingCfg.automaticMethod = autoMethod;
+               switch(hostingCfg.automaticMethod)
+               {
+               case AutomaticMethod::None:
+                       break;
+               case AutomaticMethod::Timer:
+               case AutomaticMethod::DeviceStatus:
+               case AutomaticMethod::NetworkStatusChange:
+               default:
+                       break;
+               }
+       }
+}
+
+void HostingHandler::stopAutomaticHosting()
+{
+       if(hostingCfg.automaticMethod != AutomaticMethod::None)
+       {
+// TODO
+       }
+}
+
+void HostingHandler::changeAutomaticHostingMethod(AutomaticMethod autoMethod)
+{
+//     TODO
+}
+void HostingHandler::changeNotifiyMethod(NotifyMethod notifyMethod)
+{
+//     TODO
+}
+void HostingHandler::changeNotifyFrequencyType(NotifyFrequency notifyFrequency)
+{
+//     TODO
+}
+
+void HostingHandler::startFindHost()
+{
+       if(hostingCfg.hostingMode != HostingMode::None)
+       {
+               s_findHostingCandidate(true);
+       }
+}
+
+void HostingHandler::onFoundCandidate(std::shared_ptr< OCResource > resource)
+{
+       // TODO
+       // Condition of Hosting
+       s_startHosting(resource);
+}
+
+void HostingHandler::onObserve(AttributeMap &AttMap, OCResourceHandle resourceHandle)
+{
+
+       switch(hostingCfg.notifyMethod)
+       {
+       case NotifyMethod::None:
+               break;
+       case NotifyMethod::Equalization:
+       case NotifyMethod::Granularity:
+       case NotifyMethod::Frequence:
+       default:
+               notifyFrequence(resourceHandle);
+               break;
+       }
+}
+
+void HostingHandler::notifyFrequence(OCResourceHandle resourceHandle)
+{
+
+       switch(hostingCfg.frequency)
+       {
+       case NotifyFrequency::None:
+               break;
+       case NotifyFrequency::Periodically:
+       case NotifyFrequency::OnTime:
+       default:
+               s_notify(resourceHandle);
+               break;
+       }
+}
diff --git a/service/notification-manager/NotificationManager/src/HostingInterface.cpp b/service/notification-manager/NotificationManager/src/HostingInterface.cpp
new file mode 100644 (file)
index 0000000..61c9d60
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * HostingInterface.cpp
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#include "HostingInterface.h"
+
+HostingInterface::HostingInterface()
+{
+
+}
+
+HostingInterface::~HostingInterface()
+{
+       // TODO Auto-generated destructor stub
+}
+
+int HostingInterface::setOnFoundHostingCandidate(
+        std::function< void(std::shared_ptr< OCResource > resource) > func)
+{
+    if(func != NULL)
+    {
+        try
+        {
+               ResourceManager::getInstance()->m_onFoundforHosting = func;
+        }
+        catch(exception &e)
+        {
+            return false;
+        }
+    }
+    else
+    {
+        ResourceManager::getInstance()->m_onFoundforHosting = std::function<
+                void(std::shared_ptr< OCResource > resource) >(
+                std::bind(&ResourceManager::onFoundforHostingDefault , ResourceManager::getInstance() ,
+                        std::placeholders::_1));
+    }
+
+    return true;
+}
+
+int HostingInterface::setOnObserve(std::function< void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) > func)
+{
+    if(func != NULL)
+    {
+        try
+        {
+               ResourceManager::getInstance()->m_onObserve = func;
+        }
+        catch(exception &e)
+        {
+            return false;
+        }
+    }
+    else
+    {
+       ResourceManager::getInstance()->m_onObserve = std::function<
+                       void(AttributeMap &inputAttMap, OCResourceHandle resourceHandle) >(
+                       std::bind(&ResourceManager::onObserveDefault , ResourceManager::getInstance() ,
+                               std::placeholders::_1, std::placeholders::_2));
+    }
+
+    return true;
+}
+
+int HostingInterface::setNotifyObservers(std::function< void(OCResourceHandle resourceHandle) > &func)
+{
+       try
+       {
+               func = std::function< void(OCResourceHandle resourceHandle) >(
+                               std::bind(&ResourceManager::notifyObservers , ResourceManager::getInstance() ,
+                                               std::placeholders::_1));
+       }
+       catch(exception &e)
+       {
+               return false;
+       }
+
+       return true;
+}
+
+int HostingInterface::setStartHosting(
+        std::function< void(std::shared_ptr< OCResource > resource) > &func)
+{
+    try
+    {
+        func = std::function< void(std::shared_ptr< OCResource > resource) >(
+                std::bind(&ResourceManager::startHosting , ResourceManager::getInstance() ,
+                        std::placeholders::_1));
+    }
+    catch(exception &e)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+int HostingInterface::setFindHosting(std::function< void(bool isHosting) > &func)
+{
+    try
+    {
+        func = std::function< void(bool isHosting) >(
+                       std::bind(&ResourceManager::findNMResource ,
+                                       ResourceManager::getInstance() ,
+                                               std::placeholders::_1));
+    }
+    catch(exception &e)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+int HostingInterface::setAddExtraStr(std::function< void(std::string) > &func)
+{
+    try
+    {
+        func = std::function< void(std::string str) >(
+                std::bind(&ResourceManager::addExtraStr , ResourceManager::getInstance() ,
+                        std::placeholders::_1));
+    }
+    catch(exception &e)
+    {
+        return false;
+    }
+
+    return true;
+}
diff --git a/service/notification-manager/NotificationManager/src/LinuxMain.cpp b/service/notification-manager/NotificationManager/src/LinuxMain.cpp
deleted file mode 100644 (file)
index 5827932..0000000
+++ /dev/null
@@ -1,117 +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 <memory>
-#include "OCApi.h"
-#include "OCPlatform.h"
-#include "NotificationManager.h"
-
-using namespace OC;
-
-class NotificationService
-{
-
-public:
-
-    static std::function< void(std::shared_ptr< OCResource > resource) > s_startHosting;
-    static std::function< void() > s_findHostingCandidate;
-    static std::function< void(std::string) > s_addExtraStr;
-
-    void onObserve(AttributeMap &inputAttMap)
-    {
-       std::cout << endl;
-       std::cout << "========================================================" << endl;
-       std::cout << "On Observe:\n";
-       for(auto it = inputAttMap.begin() ; it != inputAttMap.end() ; ++it)
-        {
-            std::cout << "\tAttribute name: " << it->first << " value: ";
-
-            for(auto valueItr = it->second.begin() ; valueItr != it->second.end() ; ++valueItr)
-            {
-                std::cout << "\t" << *valueItr << " ";
-            }
-
-            std::cout << std::endl;
-        }
-    }
-
-    void onFoundCandidate(std::shared_ptr< OCResource > resource)
-    {
-        s_startHosting(resource);
-    }
-
-};
-
-std::function< void(std::shared_ptr< OCResource > resource) > NotificationService::s_startHosting;
-std::function< void() > NotificationService::s_findHostingCandidate;
-std::function< void(std::string) > NotificationService::s_addExtraStr;
-
-int main(void)
-{
-
-    std::cout << endl;
-    std::cout << "========================================================" << endl;
-    std::cout << "Start Notification Manager : Hosting v0.5\n";
-
-    NotificationService a;
-
-    NotificationManager *Ptr = NotificationManager::getInstance();
-    Ptr->initialize();
-
-    Ptr->setOnFoundHostingCandidate(
-            std::function< void(std::shared_ptr< OCResource > resource) >(
-                    std::bind(&NotificationService::onFoundCandidate , a , std::placeholders::_1)));
-    Ptr->setOnObserve(
-            std::function< void(AttributeMap &inputAttMap) >(
-                    std::bind(&NotificationService::onObserve , a , std::placeholders::_1)));
-
-    Ptr->setFindHosting(a.s_findHostingCandidate);
-    Ptr->setStartHosting(a.s_startHosting);
-    Ptr->setAddExtraStr(a.s_addExtraStr);
-
-    a.s_addExtraStr("visual");
-    a.s_findHostingCandidate();
-
-    while(true)
-    {
-       char signal;
-       cin >> signal;
-
-       switch(signal)
-       {
-       case 'q':
-       case 'Q':
-               std::cout << endl;
-                       std::cout << "========================================================" << endl;
-                       std::cout << "End Notification Manager : Hosting v0.5\n";
-               return true;
-       default:
-               break;
-       }
-    }
-
-    std::cout << endl;
-    std::cout << "========================================================" << endl;
-    std::cout << "End Notification Manager : Hosting v0.5\n";
-
-    return true;
-}
index 71a04d8..d03b1b9 100644 (file)
 #include "NotificationManager.h"
 
 NotificationManager *NotificationManager::s_instance = NULL;
-//OCPlatform *NotificationManager::s_nmOCPlatform = NULL;
-PlatformConfig NotificationManager::s_cfg;
-//(ServiceType::InProc, ModeType::Both, "134.134.161.33", 5683, QualityOfService::NonConfirmable);
+mutex NotificationManager::s_mutexForCreation;
 
 NotificationManager::NotificationManager()
 {
 
-    m_print = NULL;
-    m_onfound = NULL;
-    m_onObserve = NULL;
-    m_startHosting = NULL;
-    m_findHosting = NULL;
-    m_addExtraStr = NULL;
 }
 
-NotificationManager::~NotificationManager()
-{
-}
-
-void NotificationManager::initialize()
+NotificationManager::NotificationManager(HostingConfig cfg)
 {
 
-    Configure(s_cfg);
-
-    setPrint(NULL);
-    setOnFoundHostingCandidate(NULL);
-    setStartHosting(NotificationManager::getInstance()->m_startHosting);
-    setFindHosting(NotificationManager::getInstance()->m_findHosting);
-    setAddExtraStr(NotificationManager::getInstance()->m_addExtraStr);
-
-#ifndef ISFORDEMO
-    findHostingCandidate();
-#endif
-
 }
 
-void NotificationManager::registerHostingEventListener()
-{
-    // TODO : Initial HostingEventListener (v1.0)
-}
-
-void NotificationManager::findHostingCandidate()
-{
-    try
-    {
-        ResourceManager::getInstance()->findNMResource("" , "coap://224.0.1.187/oc/core" , true);
-    }
-    catch(OCException e)
-    {
-    }
-}
-
-NotificationManager *NotificationManager::getInstance()
-{
-    if(!s_instance)
-    {
-        s_instance = new NotificationManager();
-    }
-
-    return s_instance;
-}
-
-int NotificationManager::setPrint(std::function< void(AttributeMap &inputAttMap) > func)
+NotificationManager::~NotificationManager()
 {
-    if(func != NULL)
-    {
-        try
-        {
-            NotificationManager::getInstance()->m_print = func;
-        }
-        catch(exception e)
-        {
-            return false;
-        }
-    }
-    else
-    {
-        NotificationManager::getInstance()->m_print =
-                std::function< void(AttributeMap &inputAttMap) >(
-                        std::bind(&ResourceManager::printAttributeMap ,
-                                ResourceManager::getInstance() , std::placeholders::_1));
-    }
-    return true;
-}
 
-int NotificationManager::setOnFoundHostingCandidate(
-        std::function< void(std::shared_ptr< OCResource > resource) > func)
-{
-    if(func != NULL)
-    {
-        try
-        {
-            NotificationManager::getInstance()->m_onfound = func;
-        }
-        catch(exception e)
-        {
-            return false;
-        }
-    }
-    else
-    {
-        NotificationManager::getInstance()->m_onfound = std::function<
-                void(std::shared_ptr< OCResource > resource) >(
-                std::bind(&ResourceManager::onFoundReport , ResourceManager::getInstance() ,
-                        std::placeholders::_1));
-    }
-
-    return true;
 }
 
-int NotificationManager::setOnObserve(std::function< void(AttributeMap &inputAttMap) > func)
+void NotificationManager::initialize()
 {
-    if(func != NULL)
-    {
-        try
-        {
-            NotificationManager::getInstance()->m_onObserve = func;
-        }
-        catch(exception e)
-        {
-            return false;
-        }
-    }
-    return true;
-}
+       // find local ip address
+    std::string ipAddress;
+    NotificationManager::getInstance()->scanAndGetNetworkInterface(ipAddress);
 
-std::function< void(AttributeMap &inputAttMap) > NotificationManager::getPrint()
-{
-    return m_print;
-}
+    // set ip address
+    OICPlatformConfig::getInstance()->setIP(ipAddress);
 
-std::function< void(std::shared_ptr< OCResource > resource) > NotificationManager::getOnFoundHostingCandidate()
-{
-    return m_onfound;
+    // initialize hosting handler
+    HostingHandler::initialize();
 }
 
-std::function< void(AttributeMap &inputAttMap) > NotificationManager::getOnObserve()
+void NotificationManager::initialize(HostingConfig cfg)
 {
-    return m_onObserve;
-}
+       // find local ip address
+    std::string ipAddress;
+    NotificationManager::getInstance()->scanAndGetNetworkInterface(ipAddress);
 
-int NotificationManager::setStartHosting(
-        std::function< void(std::shared_ptr< OCResource > resource) > &func)
-{
-    try
-    {
-        func = std::function< void(std::shared_ptr< OCResource > resource) >(
-                std::bind(&ResourceManager::startHosting , ResourceManager::getInstance() ,
-                        std::placeholders::_1));
-    }
-    catch(exception e)
-    {
-        return false;
-    }
-
-    return true;
-}
+    // set ip address
+    OICPlatformConfig::getInstance()->setIP(ipAddress);
 
-int NotificationManager::setFindHosting(std::function< void() > &func)
-{
-    try
-    {
-        func = std::function< void() >(
-                std::bind(&NotificationManager::findHostingCandidate ,
-                        NotificationManager::getInstance()));
-    }
-    catch(exception e)
-    {
-        return false;
-    }
-
-    return true;
+    // initialize hosting handler
+    HostingHandler::initialize(cfg);
 }
 
-int NotificationManager::setAddExtraStr(std::function< void(std::string) > &func)
+void NotificationManager::registerHostingEventListener()
 {
-    try
-    {
-        func = std::function< void(std::string str) >(
-                std::bind(&ResourceManager::addExtraStr , ResourceManager::getInstance() ,
-                        std::placeholders::_1));
-    }
-    catch(exception e)
-    {
-        return false;
-    }
-
-    return true;
+    // TODO : Initial HostingEventListener (v1.0)
 }
 
-std::function< void(std::shared_ptr< OCResource > resource) > NotificationManager::getStartHosting()
+NotificationManager *NotificationManager::getInstance()
 {
-    if(m_startHosting)
-    {
-        return m_startHosting;
-    }
-    else
-    {
-        return NULL;
-    }
-}
+       if(!s_instance)
+       {
+               s_mutexForCreation.lock();
+               if(!s_instance)
+               {
+                       s_instance = new NotificationManager();
+               }
+               s_mutexForCreation.unlock();
+       }
 
-std::function< void() > NotificationManager::getFindHosting()
-{
-    if(m_findHosting)
-    {
-        return m_findHosting;
-    }
-    else
-    {
-        return NULL;
-    }
+    return s_instance;
 }
 
-std::function< void(std::string) > NotificationManager::getAddExtraStr()
-{
-    if(m_addExtraStr)
-    {
-        return m_addExtraStr;
-    }
-    else
-    {
-        return NULL;
-    }
+int NotificationManager::getNetInfo(IN int& sck, IN struct ifreq* item, OUT std::string& ip_addres)
+{
+       struct ifreq temp_ifr;
+       memset(&temp_ifr, 0, sizeof(temp_ifr));
+       strcpy(temp_ifr.ifr_name, item->ifr_name);
+
+       if (ioctl(sck, SIOCGIFFLAGS, &temp_ifr))
+       {
+               return -1;
+       }
+
+       if (!((temp_ifr.ifr_flags & IFF_UP) && (temp_ifr.ifr_flags & IFF_RUNNING)))
+       {
+               return -1;
+       }
+
+       std::string ip(inet_ntoa(((struct sockaddr_in *) &item->ifr_addr)->sin_addr));
+       if (ip.empty())
+       {
+               return -1;
+       }
+
+       if (ip.find("127.0.0") == 0)
+       {
+               return -1;
+       }
+
+       ip_addres = ip;
+       return 0;
+}
+
+bool NotificationManager::scanAndGetNetworkInterface(OUT std::string& ip_addres)
+{
+       while(1)
+       {
+               char buf[1024] =        { 0, };
+               struct ifconf ifc;
+               struct ifreq *ifr;
+               int sck;
+               int interfaces;
+               int i;
+
+               sck = socket(AF_INET, SOCK_DGRAM, 0);
+               if (sck < 0)
+               {
+                       usleep(10);
+                       continue;
+               }
+
+               ifc.ifc_len = sizeof(buf);
+               ifc.ifc_buf = buf;
+               if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
+               {
+                       printf( "SIOCGIFCONF Failed ");
+                       close(sck);
+                       usleep(10);
+                       continue;
+               }
+
+               ifr = ifc.ifc_req;
+               interfaces = ifc.ifc_len / sizeof(struct ifreq);
+
+               for (i = 0; i < interfaces; i++)
+               {
+                       if(  getNetInfo(sck, &ifr[i], ip_addres) == 0 )
+                       {
+                               return 0;
+                       }
+                       continue;
+               }
+               close(sck);
+               usleep(10);
+       }
+
+       return 0;
 }
diff --git a/service/notification-manager/NotificationManager/src/OICPlatformConfig.cpp b/service/notification-manager/NotificationManager/src/OICPlatformConfig.cpp
new file mode 100644 (file)
index 0000000..e9e1756
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * OICPlatformConfig.cpp
+ *
+ *  Created on: 2014. 10. 15.
+ *      Author: jyong2
+ */
+
+#include "OICPlatformConfig.h"
+
+
+OICPlatformConfig *OICPlatformConfig::s_instance = NULL;
+mutex OICPlatformConfig::s_mutexForCreation;
+//OCPlatform *OICPlatformConfig::s_nmOCPlatform = NULL;
+PlatformConfig OICPlatformConfig::s_cfg;
+//(ServiceType::InProc, ModeType::Both,"", 5683, QualityOfService::NonConfirmable);
+
+OICPlatformConfig::OICPlatformConfig()
+{
+       // TODO Auto-generated constructor stub
+
+}
+
+OICPlatformConfig::~OICPlatformConfig()
+{
+       // TODO Auto-generated destructor stub
+}
+
+
+OICPlatformConfig *OICPlatformConfig::getInstance()
+{
+       if(!s_instance)
+       {
+               s_mutexForCreation.lock();
+               if(!s_instance)
+               {
+                       s_instance = new OICPlatformConfig();
+                       Configure(s_cfg);
+               }
+               s_mutexForCreation.unlock();
+       }
+
+       return s_instance;
+}
+
+//void OICPlatformConfig::getOCPlatform()
+//{
+////   if(!s_nmOCPlatform)
+////   {
+////           if(s_cfg.ipAddress.empty())
+////           {
+////                   return NULL;
+////           }
+////           s_nmOCPlatform = new OCPlatform(s_cfg);
+////           Configure(s_cfg);
+////   }
+////   return s_nmOCPlatform;
+//}
+
+void OICPlatformConfig::initialize()
+{
+
+}
+
+void OICPlatformConfig::setIP(std::string ipaddress)
+{
+       s_cfg.ipAddress = ipaddress;
+}
index ff9f47b..0649da6 100644 (file)
@@ -21,6 +21,7 @@
 #include "RegistrationManager.h"
 
 RegistrationManager *RegistrationManager::s_instance = NULL;
+mutex RegistrationManager::s_mutexForCreation;
 
 RegistrationManager::RegistrationManager()
 {
@@ -32,11 +33,17 @@ RegistrationManager::~RegistrationManager()
 
 RegistrationManager *RegistrationManager::getInstance()
 {
-    if(!s_instance)
-    {
-        s_instance = new RegistrationManager();
-    }
-    return s_instance;
+       if(!s_instance)
+       {
+               s_mutexForCreation.lock();
+               if(s_instance)
+               {
+                       s_instance = new RegistrationManager();
+               }
+               s_mutexForCreation.unlock();
+       }
+
+       return s_instance;
 }
 
 int RegistrationManager::addResource()
@@ -64,15 +71,15 @@ bool RegistrationManager::registerNMResource(VirtualRepresentation &resourceObje
     OCResourceHandle resourceHandle;
 
     OCStackResult result;
-
     result = registerResource(resourceHandle , uri , type ,
-            interface ,
-            std::function<
-                    OCEntityHandlerResult(const std::shared_ptr< OCResourceRequest > request ,
-                            const std::shared_ptr< OCResourceResponse > response) >(
-                    std::bind(&VirtualRepresentation::entityHandler , resourceObject ,
-                            std::placeholders::_1 , std::placeholders::_2)) ,
-            resourceObject.getResourceProperty());
+                interface ,
+                std::function<
+                        OCEntityHandlerResult(const std::shared_ptr< OCResourceRequest > request ,
+                                const std::shared_ptr< OCResourceResponse > response) >(
+                        std::bind(&VirtualRepresentation::entityHandler , resourceObject ,
+                                       std::placeholders::_1 , std::placeholders::_2)) ,
+                resourceObject.getResourceProperty());
+
     resourceObject.setResourceHandle(resourceHandle);
 
     if(OC_STACK_OK != result)
@@ -85,8 +92,8 @@ bool RegistrationManager::registerNMResource(VirtualRepresentation &resourceObje
         resource->observe(ObserveType::Observe , queryParmaMap ,
                 std::function<
                         void(const HeaderOptions headerOption,
-                                       const OCRepresentation& rep , const int eCode ,
-                                const int sequenceNumber) >(
+                                       const OCRepresentation& rep , const int& eCode ,
+                                const int& sequenceNumber) >(
                         std::bind(&VirtualRepresentation::onObserve , resourceObject ,
                                 std::placeholders::_1 , std::placeholders::_2 ,
                                 std::placeholders::_3 , std::placeholders::_4)));
index e6f0128..19fb8bd 100644 (file)
 #include "ResourceManager.h"
 
 ResourceManager *ResourceManager::s_instance = NULL;
+mutex ResourceManager::s_mutexForCreation;
 std::list< VirtualRepresentation > ResourceManager::s_resourceList;
 
 std::string ResourceManager::s_extraStr;
 
 ResourceManager::ResourceManager()
 {
+       m_onFoundforHosting     = NULL;
+       m_onObserve                     = NULL;
+       m_notify                                = NULL;
 }
 
 ResourceManager::~ResourceManager()
@@ -37,7 +41,12 @@ ResourceManager *ResourceManager::getInstance()
 {
     if(!s_instance)
     {
-        s_instance = new ResourceManager();
+        s_mutexForCreation.lock();
+        if(!s_instance)
+        {
+               s_instance = new ResourceManager();
+        }
+        s_mutexForCreation.unlock();
     }
     return s_instance;
 }
@@ -59,13 +68,15 @@ VirtualRepresentation ResourceManager::findVirtualRepresentation(std::string uri
     return retObject;
 }
 
-OCStackResult ResourceManager::findNMResource(const std::string& host ,
-        const std::string& resourceName , bool ishosting)
+void ResourceManager::findNMResource(bool isHosting)
 {
-       return findResource(host , resourceName ,
-            std::function< void(std::shared_ptr< OCResource > resource) >(
-                    std::bind(&ResourceManager::foundResourceforhosting , this ,
-                            std::placeholders::_1)));
+       if(isHosting)
+       {
+               findResource("" , "coap://224.0.1.187/oc/core",
+                               std::function< void(std::shared_ptr< OCResource > resource) >(
+                                                                       std::bind(&ResourceManager::foundResourceforhosting , ResourceManager::getInstance() ,
+                                                                                       std::placeholders::_1)));
+       }
 }
 
 void ResourceManager::foundResourceforhosting(std::shared_ptr< OCResource > resource)
@@ -76,21 +87,24 @@ void ResourceManager::foundResourceforhosting(std::shared_ptr< OCResource > reso
         {
             if(resource->uri().find("/a/NM") != std::string::npos)
             {
-                NotificationManager::getInstance()->getOnFoundHostingCandidate()(resource);
+                ResourceManager::getInstance()->m_onFoundforHosting(resource);
             }
         }
         else
         {
+               // TODO
         }
 
     }
-    catch(std::exceptione)
+    catch(std::exception &e)
     {
     }
 }
 
 void ResourceManager::startHosting(std::shared_ptr< OCResource > resource)
 {
+
+       cout << "start hosting" << endl;
     VirtualRepresentation tmp = findVirtualRepresentation( resource->uri() );
 
     if( !tmp.getUri().empty() )
@@ -124,13 +138,40 @@ void ResourceManager::startHosting(std::shared_ptr< OCResource > resource)
 
 }
 
+void ResourceManager::notifyObservers(OCResourceHandle resourceHandle)
+{
+       OCStackResult result = OC_STACK_OK;
+
+       result = notifyAllObservers(resourceHandle);
+
+       if(OC_STACK_NO_OBSERVERS == result)
+       {
+               // No observers.
+               // TODO
+       }
+}
+
 AttributeMap ResourceManager::copyAttributeMap(AttributeMap &inputAttMap)
 {
 
     AttributeMap retAttMap;
 
     retAttMap = inputAttMap;
-
+//    for(auto it = inputAttMap.begin() ; it != inputAttMap.end() ; ++it)
+//    {
+//        AttributeValues tmpVal;
+//
+//        for(auto valueItr = it->second.begin() ; valueItr != it->second.end() ; ++valueItr)
+//        {
+//            std::string tmpStr;
+//
+//            tmpStr.append(*valueItr);
+//
+//            tmpVal.push_back(tmpStr);
+//        }
+//        retAttMap[it->first] = tmpVal;
+//
+//    }
     return retAttMap;
 }
 
@@ -146,9 +187,13 @@ bool ResourceManager::isEmptyAttributeMap(AttributeMap &inputAttMap)
     return false;
 }
 
-void ResourceManager::onFoundReport(std::shared_ptr< OCResource > resource)
+void ResourceManager::onFoundforHostingDefault(std::shared_ptr< OCResource > resource)
+{
+    ResourceManager::getInstance()->startHosting(resource);
+}
+void ResourceManager::onObserveDefault(AttributeMap &inputAttMap , OCResourceHandle resourceHandle)
 {
-    NotificationManager::getInstance()->getStartHosting()(resource);
+       ResourceManager::getInstance()->notifyObservers(resourceHandle);
 }
 
 void ResourceManager::printAttributeMap(AttributeMap &inputAttMap)
index 7eae069..4e2ce1c 100644 (file)
@@ -126,118 +126,122 @@ OCEntityHandlerResult VirtualRepresentation::entityHandler(const std::shared_ptr
         int requestFlag = request->getRequestHandlerFlag();
 
         if(requestFlag == RequestHandlerFlag::InitFlag)
-        {
-        }
+               {
+               }
+
         else if(requestFlag == RequestHandlerFlag::RequestFlag)
         {
-            if(requestType == "GET")
+            if( (requestType == "GET") && response )
             {
 
-                if(response)
-                {
-                    std::unique_lock< std::mutex > lck(s_mutexAttributeMap);
-                    while(!m_isReadyAttributeMap)
-                    {
-                        s_conditionAttributeMap.wait(lck);
-                    }
-                    m_isReadyAttributeMap = false;
+                               std::unique_lock< std::mutex > lck(s_mutexAttributeMap);
+                               while(!m_isReadyAttributeMap)
+                               {
+                                       s_conditionAttributeMap.wait(lck);
+                               }
+                               m_isReadyAttributeMap = false;
 
-                    NotificationManager::getInstance()->getPrint()(s_attributeMap);
+                               OCRepresentation rep;
+                               getRepresentation(rep);
 
-                    OCRepresentation rep;
-                    getRepresentation(rep);
-
-                    response->setErrorCode(200);
-                    response->setResourceRepresentation(rep , "");
-
-                    m_isReadyAttributeMap = true;
-                    s_conditionAttributeMap.notify_all();
-                }
-                else
-                {
-                }
+                               response->setErrorCode(200);
+                               response->setResourceRepresentation(rep , DEFAULT_INTERFACE);
 
-            }
+                               m_isReadyAttributeMap = true;
+                               s_conditionAttributeMap.notify_all();
+                       }
             else if(requestType == "PUT")
             {
+               // TODO
             }
             else if(requestType == "POST")
             {
+               // TODO
             }
             else if(requestType == "DELETE")
             {
+               // TODO
             }
             else
             {
+               // TODO
             }
         }
+        else if(requestFlag == RequestHandlerFlag::InitFlag)
+               {
+                       // TODO
+               }
         else if(requestFlag == RequestHandlerFlag::ObserverFlag)
         {
+               // TODO
+               cout << "requestFlag == RequestHandlerFlag::ObserverFlag\n";
         }
         else
         {
+               // requestFlag is not [Request, Init, Observer]
+               // TODO
         }
     }
     else
     {
+       // Param(request) is empty.
+       // TODO
     }
-
     return OC_EH_OK;
 }
 
 void VirtualRepresentation::onObserve(const HeaderOptions &headerOption, const OCRepresentation &rep , const int eCode , const int sequenceNumber)
 {
+       cout << "VirtualRepresentation::onObserve Enter\n";
     if(eCode == SUCCESS_RESPONSE)
     {
-        AttributeMap tmp = rep.getAttributeMap();
+       cout << "1\n";
+        AttributeMap inputAttributeMap = rep.getAttributeMap();
 
-        if(ResourceManager::getInstance()->isEmptyAttributeMap(tmp))
+        if(ResourceManager::getInstance()->isEmptyAttributeMap(inputAttributeMap))
         {
+               cout << "2\n";
             return;
         }
-
-        if(NotificationManager::getInstance()->getOnObserve())
-        {
-            NotificationManager::getInstance()->getOnObserve()(tmp);
-        }
-
-        NotificationManager::getInstance()->getPrint()(tmp);
-
-        OCStackResult result = OC_STACK_OK;
-
+        cout << "3\n";
         VirtualRepresentation tmpObj = *this;
         if(!tmpObj.getUri().empty())
         {
-
-            AttributeMap tmpAttMap = ResourceManager::getInstance()->copyAttributeMap(tmp);
-
+               cout << "4\n";
+            AttributeMap tmpAttMap = ResourceManager::getInstance()->copyAttributeMap(inputAttributeMap);
+            cout << "5\n";
             {
+               cout << "6\n";
                 std::unique_lock< std::mutex > lck(s_mutexAttributeMap);
+                cout << "7\n";
                 while(!m_isReadyAttributeMap)
                 {
+                       cout << "8\n";
                     s_conditionAttributeMap.wait(lck);
                 }
+                cout << "9\n";
                 m_isReadyAttributeMap = false;
-
+                cout << "10\n";
                 s_attributeMap = tmpAttMap;
-
+                cout << "11\n";
                 m_isReadyAttributeMap = true;
+                cout << "12\n";
                 s_conditionAttributeMap.notify_all();
+                cout << "13\n";
             }
 
-            result = notifyAllObservers(tmpObj.getResourceHandle());
+            if(ResourceManager::getInstance()->m_onObserve)
+                       {
+               cout << "14\n";
+                               ResourceManager::getInstance()->m_onObserve(inputAttributeMap, tmpObj.getResourceHandle());
+                               cout << "15\n";
+                       }
         }
-        else
-        {
-        }
-
-        if(OC_STACK_NO_OBSERVERS == result)
-        {
-        }
-
     }
     else
     {
-        std::exit(-1);
+       // Check the error.
+       // TODO
     }
+    cout << "VirtualRepresentation::onObserve Out\n";
 }
diff --git a/service/notification-manager/NotificationManager/src/linux/main.cpp b/service/notification-manager/NotificationManager/src/linux/main.cpp
new file mode 100644 (file)
index 0000000..26724da
--- /dev/null
@@ -0,0 +1,66 @@
+//******************************************************************
+//
+// 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 <iostream>
+#include "NotificationManager.h"
+
+using namespace OC;
+
+int main(void)
+{
+
+    std::cout << endl;
+    std::cout << "========================================================" << endl;
+    std::cout << "Start Notification Manager : Hosting v0.5\n";
+
+
+       HostingConfig cfg;
+       cfg.hostingMode         = HostingMode::ManualMode;
+       cfg.automaticMethod     = AutomaticMethod::None;
+       cfg.notifyMethod                = NotifyMethod::Frequence;
+       cfg.frequency                   = NotifyFrequency::OnTime;
+
+       NotificationManager::initialize(cfg);
+
+    while(true)
+    {
+       char signal;
+       cin >> signal;
+
+       switch(signal)
+       {
+       case 'q':
+       case 'Q':
+               std::cout << endl;
+                       std::cout << "========================================================" << endl;
+                       std::cout << "End Notification Manager : Hosting v0.5\n";
+               return true;
+       default:
+               break;
+       }
+
+    }
+
+    std::cout << endl;
+    std::cout << "========================================================" << endl;
+    std::cout << "End Notification Manager : Hosting v0.5\n";
+
+    return true;
+}
index 6f4cd86..fd1e6f6 100644 (file)
@@ -29,7 +29,7 @@
 
 using namespace OC;
 
-const int SUCCESS_RESPONSE = 0;
+const int SUCCESS_RESPONSE = OC_STACK_OK;
 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
 
 std::shared_ptr< OCResource > g_curResource;
@@ -81,7 +81,8 @@ int observe_count()
 void onObserve(const HeaderOptions &headerOption , const OCRepresentation& rep , const int& eCode, const int& sequenceNumber)
 {
        std::cout << "onObserve" << std::endl;
-    if(eCode == SUCCESS_RESPONSE)
+//    if(eCode == SUCCESS_RESPONSE)
+       if(eCode <= OC_STACK_RESOURCE_DELETED)
     {
 
         AttributeMap attributeMap = rep.getAttributeMap();
@@ -96,6 +97,7 @@ void onObserve(const HeaderOptions &headerOption , const OCRepresentation& rep ,
 
         if(rep.getUri().empty())
         {
+               cout << "uri is null\n";
             return;
         }
 
@@ -140,7 +142,8 @@ void foundResource(std::shared_ptr< OCResource > resource)
     {
         if(resource)
         {
-            if(resource->uri().find("/a/NM/TempHumSensor/virtual") != std::string::npos)
+//            if(resource->uri().find("/a/NM/TempHumSensor/virtual") != std::string::npos)
+                       if(resource->uri().find("/a/NM/TempHumSensor") != std::string::npos)
             {
                 std::cout << std::endl;
                 std::cout << "========================================================" << std::endl;
index 0375ce5..7cbec29 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "OCPlatform.h"
 #include "OCApi.h"
+#include "OCResourceResponse.h"
 
 #include <memory>
 
@@ -32,8 +33,11 @@ using namespace std;
 
 int g_Observation = 0;
 
+pthread_cond_t m_cond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request ,
-        std::shared_ptr< OCResourceResponse > response);
+                                    std::shared_ptr< OCResourceResponse > response);
 
 class TempHumidResource
 {
@@ -142,7 +146,7 @@ public:
                        }
                        else
                        {
-                               cout << "\t\t\t\t" << "m_power not found in the representation" << endl;
+                               cout << "\t\t\t\t" << "humidity not found in the representation" << endl;
                        }
                }
                catch (exception& e)
@@ -154,9 +158,12 @@ public:
 
     OCRepresentation get()
        {
+       cout << "resource get\n";
                m_Rep.setValue("temperature", m_temp);
                m_Rep.setValue("humidity", m_humid);
 
+               cout << "resource get : done\n";
+
                return m_Rep;
        }
 
@@ -166,54 +173,78 @@ TempHumidResource myResource;
 
 void *ChangeLightRepresentation(void *param)
 {
+       cout << "ChangeLigthRepresentation Enter\n";
+       while(1){
+               cout << "pthread_cond_wait\n";
+               pthread_cond_wait(&m_cond, &m_mutex);
+               cout << "pthread_cond_start\n";
+               if(g_Observation)
+               {
 
-    if(g_Observation)
-    {
-
-        cout << endl;
-        cout << "========================================================" << endl;
-        cout << "HUMTepm updated to : " << myResource.m_temp << endl;
-        cout << "Notifying observers with resource handle: " << myResource.getHandle() << endl;
+                       cout << endl;
+                       cout << "========================================================" << endl;
+                       cout << "HUMTepm updated to : " << myResource.m_temp << endl;
+                       cout << "Notifying observers with resource handle: " << myResource.getHandle() << endl;
 
-        cout << endl;
-        cout << "========================================================" << endl;
-        cout << "Send data : \n";
-        cout << "Attribute Name: Temp\tvalue: " << myResource.m_temp << endl;
-        cout << "Attribute Name: Humid\tvalue: " << myResource.m_humid << endl;
+                       cout << endl;
+                       cout << "========================================================" << endl;
+                       cout << "Send data : \n";
+                       cout << "Attribute Name: Temp\tvalue: " << myResource.m_temp << endl;
+                       cout << "Attribute Name: Humid\tvalue: " << myResource.m_humid << endl;
 
-        OCStackResult result = OCPlatform::notifyAllObservers(myResource.getHandle());
+                       OCStackResult result = OCPlatform::notifyAllObservers(myResource.getHandle());
+                       cout << "Notify Success\n";
 
-        if(OC_STACK_NO_OBSERVERS == result)
-        {
-            cout << "No More observers, stopping notifications" << endl;
-            g_Observation = 0;
-        }
-    }
+                       if(OC_STACK_NO_OBSERVERS == result)
+                       {
+                               cout << "No More observers, stopping notifications" << endl;
+                               g_Observation = 0;
+                       }
+               }
+               cout << "ChangeLigthRepresentation Out\n";
 
+       }
     return NULL;
 }
 
 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request ,
         std::shared_ptr< OCResourceResponse > response)
 {
-
+       cout << "Sample Provider entityHandler\n";
     if(request)
     {
+       cout << "flag : request\n";
         std::string requestType = request->getRequestType();
         int requestFlag = request->getRequestHandlerFlag();
 
         if(requestFlag == RequestHandlerFlag::InitFlag)
         {
+               cout << "\t\trequestFlag : Init\n";
         }
+
         if(requestFlag == RequestHandlerFlag::RequestFlag)
         {
+               cout << "\t\trequestFlag : Request\n";
             if(requestType == "GET")
             {
-                if(response)
-                {
-                    response->setErrorCode(200);
-                    response->setResourceRepresentation(myResource.get());
-                }
+               cout << "\t\trequestType : GET\n";
+               try
+               {
+                                       if(response)
+                                       {
+                                               OCRepresentation rep = myResource.get();
+                                               cout << rep.getJSONRepresentation() << endl;
+                                               response->setErrorCode(200);
+                                               response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                                       }
+                                       else
+                                       {
+                                               cout << "response is null\n";
+                                       }
+               } catch(exception& e)
+               {
+                       cout << e.what() << endl;
+               }
             }
             else if(requestType == "PUT")
             {
@@ -237,16 +268,21 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
         }
         else if(requestFlag & RequestHandlerFlag::ObserverFlag)
         {
-            pthread_t threadId;
+               pthread_t threadId;
+
+            cout << request->getResourceUri() << endl;
+            cout << request->getResourceRepresentation().getUri() << endl;
 
             cout << "========================================================" << endl;
             cout << "Receive ObserverFlag : Start Observe\n";
             cout << "========================================================" << endl;
             g_Observation = 1;
 
+            cout << "\t\trequestFlag : Observer\n";
             static int startedThread = 0;
             if(!startedThread)
             {
+               cout << "\t\tpthrerad_create\n";
                 pthread_create(&threadId , NULL , ChangeLightRepresentation , (void *) NULL);
                 startedThread = 1;
             }
@@ -297,16 +333,16 @@ int main()
                 {
                     cout << "Temp is up!" << endl;
                     myResource.m_temp += 10;
-                    ChangeLightRepresentation((void *) NULL);
-
+                    pthread_cond_signal(&m_cond);
+                    cout << "ChangeLightRepresentation Done!" << endl;
                     break;
                 }
                 case 2:
                 {
                     cout << "Temp is down!" << endl;
                     myResource.m_temp -= 10;
-                    ChangeLightRepresentation((void *) NULL);
-
+                    pthread_cond_signal(&m_cond);
+                    cout << "ChangeLightRepresentation Done!" << endl;
                     break;
                 }
                 case 3:
@@ -327,7 +363,8 @@ int main()
             }
         }
     }
-    catch(OCException e)
+    catch(exception& e)
     {
+       cout << "main exception  : " << e.what() << endl;
     }
 }
index 53f0396..a3f6aa1 100644 (file)
@@ -1,6 +1,6 @@
 PROTOCOL_ROOT = ../../
 
-.PHONY:pre resource plugin-manager plugins sample-app
+.PHONY:pre plugin-manager plugins sample-app
 
 all: .PHONY
 
@@ -23,7 +23,7 @@ sample-app:
        cd $(PROTOCOL_ROOT)sample-app/linux/mqtt && $(MAKE)
        cp -Rdp $(PROTOCOL_ROOT)plugin-manager/build/linux/libpmimpl.so $(PROTOCOL_ROOT)sample-app/linux/mqtt/
        cp -Rdp $(PROTOCOL_ROOT)sample-app/linux/mqtt/mqttclient release/
-       
+       cp -Rdp $(PROTOCOL_ROOT)sample-app/linux/mqtt/pluginmanager.xml release/
 
 clean:
        cd $(PROTOCOL_ROOT)plugin-manager/build/linux && $(MAKE) clean
index 58e79f7..0dc1b9f 100644 (file)
@@ -12,15 +12,21 @@ target_os = env.get('TARGET_OS')
 ######################################################################
 # Build flags
 ######################################################################
-cpluff_env.AppendUnique(CPPPATH = ['libcpluff/'])
+cpluff_env.AppendUnique(CPPPATH= ['libcpluff/'])
 if target_os not in ['windows', 'winrt']:
-       cpluff_env.AppendUnique(CFLAGS = ['-g','-fPIC', '-DPIC',
-                               '-DDLOPEN_POSIX',
-                               '-DCP_HOST=\\"' + platform.platform() + '\\"',
-                               '-DCP_SHREXT=\\".so\\"',
-                               '-DCP_FNAMESEP_CHAR=\\"\'/\'\\"',
-                               '-DCP_THREADS=\\"Posix\\"'])
+       cpluff_env.AppendUnique(CPPDEFINES = ['CP_C_API=CP_EXPORT',
+                                       'CP_HOST=\"\\"'+env.get('TARGET_OS')+'\\"\"',
+                                       'CP_DATADIR=\"\\\"/usr/local/share\\\"\"',
+                                       'DLOPEN_POSIX',
+                                       'DPIC',
+                                       'CP_THREADS=\"\\\"Posix\\"\"',
+                                       'CP_SHREXT=\"\\".so\\"\"',
+                                       'CP_FNAMESEP_CHAR=\"\'/\'\"',
+                                       'CP_FNAMESEP_STR=\"\\\"/\\"\"',
+                                       'PACKAGE=\"\\\"cpluff\\\"\"'])
        cpluff_env.AppendUnique(LIBS = ['dl'])
+       cpluff_env.PrependUnique(CCFLAGS = ['-fPIC'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
@@ -28,4 +34,4 @@ cpluff_src = [f for f in env.Glob('libcpluff/*.c') if os.path.basename(f.path) n
 cpluff_src.extend(env.Glob('kazlib/*.c'))
 
 cpluff = cpluff_env.StaticLibrary('cpluff', cpluff_src)
-cpluff_env.InstallTarget(cpluff, 'libcpluff')
\ No newline at end of file
+cpluff_env.InstallTarget(cpluff, 'libcpluff')
index ccf9ea6..a2bca4a 100644 (file)
@@ -74,7 +74,7 @@ CP_C_API cp_status_t cp_define_symbol(cp_context_t *context, const char *name, v
        
        CHECK_NOT_NULL(context);
        CHECK_NOT_NULL(name);
-       CHECK_NOT_NULL(ptr);
+//     CHECK_NOT_NULL(ptr);
        if (context->plugin == NULL) {
                cpi_fatalf(_("Only plug-ins can define context specific symbols."));
        }
index 1e7d42b..e15658f 100644 (file)
@@ -15,7 +15,8 @@ target_os = env.get('TARGET_OS')
 ######################################################################
 plugin_manager_env.AppendUnique(CPPPATH = [
                '../lib/cpluff/libcpluff',
-               'src'
+               'src',
+               '../lib/rapidxml'
                ])
 
 if target_os not in ['windows', 'winrt']:
@@ -26,6 +27,18 @@ if target_os == 'android':
        plugin_manager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
        plugin_manager_env.AppendUnique(LIBS = ['boost_thread-gcc-mt-1_49', 'gnustl_static'])
 
+plugin_manager_env.AppendUnique(CPPDEFINES = ['CP_C_API=CP_EXPORT',
+                                       'CP_HOST=\"\\"'+env.get('TARGET_OS')+'\\"\"',
+                                       'CP_DATADIR=\"\\\"/usr/local/share\\\"\"',
+                                       'DLOPEN_POSIX',
+                                       'DPIC',
+                                       'CP_THREADS=\"\\\"Posix\\"\"',
+                                       'CP_SHREXT=\"\\".so\\"\"',
+                                       'CP_FNAMESEP_CHAR=\"\'/\'\"',
+                                       'CP_FNAMESEP_STR=\"\\\"/\\"\"',
+                                       'PACKAGE=\"\\\"cpluff\\\"\"'])
+
+
 plugin_manager_env.AppendUnique(LIBS = ['oc', 'octbstack', 'expat', 'dl'])
 ######################################################################
 # Source files and Targets
@@ -37,7 +50,8 @@ pmimpl_src = [
                'src/CpluffAdapter.cpp',
                'src/FelixAdapter.cpp',
                'src/Plugin.cpp',
-               'src/PluginManagerImpl.cpp']
+               'src/PluginManagerImpl.cpp',
+               'src/Config.cpp']
 
 pmimpl_env = plugin_manager_env.Clone()
 pmimpl_env.PrependUnique(CCFLAGS = ['-fPIC'])
index 528c7dd..d473421 100644 (file)
@@ -51,6 +51,10 @@ PMRESULT Config::loadConfigFile(const std::string configfilepath)
 {
     // Read the xml file
     std::ifstream xmlFile(configfilepath.c_str());
+    if(!xmlFile.good())
+    {
+        return PM_S_FALSE;
+    }
     xml_document<> doc;
     //into a vector
     std::vector<char> buffer((istreambuf_iterator<char>(xmlFile)), istreambuf_iterator<char>());
index addc2a7..3acd2f5 100644 (file)
@@ -457,7 +457,7 @@ int CpluffAdapter::start(Plugin *const plugin, void *const arg)
         {
             ctx = cpi_new_context((cp_plugin_t *)hnode_get(hash_lookup(m_context->env->plugins, id.c_str())),
                                   m_context->env, &status);
-            cp_define_symbol(ctx, "START_ARGUMENT", arg);
+            //cp_define_symbol(ctx, "START_ARGUMENT", arg);
             //printf("start ocplatform address : %x\n", arg);
 
             if ((status = cp_start_plugin(m_context, (char *)id.c_str()) ) != CP_OK)
index e0b934f..6c108d0 100644 (file)
@@ -31,7 +31,6 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/inotify.h>
 #include <unistd.h>
 #include <boost/thread.hpp>
 #include <boost/bind.hpp>
@@ -40,7 +39,6 @@
 #include "Plugin.h"
 #include "Config.h"
 
-#define EVENT_SIZE  ( sizeof (struct inotify_event) )
 #define BUF_LEN     (int)( 1024 * ( EVENT_SIZE + 16 ) )
 
 namespace OIC
index 7c6398c..7f03f7f 100644 (file)
@@ -31,7 +31,6 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/inotify.h>
 #include <unistd.h>
 #include <boost/thread.hpp>
 #include <boost/bind.hpp>
@@ -40,7 +39,6 @@
 #include "Plugin.h"
 #include "Config.h"
 
-#define EVENT_SIZE  ( sizeof (struct inotify_event) )
 #define BUF_LEN     (int)( 1024 * ( EVENT_SIZE + 16 ) )
 
 namespace OIC
index 5b1e3a6..d360cf0 100644 (file)
@@ -60,11 +60,7 @@ namespace OIC
     */
     class Plugin
     {
-
-
         public:
-
-
             /**
             * Constructor for Plugin.
             *
@@ -120,18 +116,6 @@ namespace OIC
             */
             std::string getValueByAttribute(const std::string attribute);
 
-
-            /**
-            * Set key, value. key is attribute name.
-            *
-            * @param key is atrribute name.
-            * @param value for the attribute.
-            * @return void
-            *
-            */
-            void setValue(const std::string key, const std::string value);
-
-
             /**
             * Check whether the plugin same or not.
             *
@@ -142,6 +126,18 @@ namespace OIC
             bool operator==(Plugin &plugin);
 
         private:
+            friend class CpluffAdapter;
+            friend class FelixAdapter;
+              /**
+            * Set key, value. key is attribute name.
+            *
+            * @param key is atrribute name.
+            * @param value for the attribute.
+            * @return void
+            *
+            */
+            void setValue(const std::string key, const std::string value);
+
             std::map<std::string, AttributeValue> m_attributeMap;
             std::vector<std::string> m_supportedType;
     };
index c3abdb8..7e0f0ed 100644 (file)
@@ -29,7 +29,7 @@ using namespace OIC;
 
 PluginManager::PluginManager()
 {
-    void *handle = dlopen("./libpmimpl.so", RTLD_LAZY);
+    handle = dlopen("./libpmimpl.so", RTLD_LAZY);
     if (!handle)
     {
         fprintf(stderr, "%s\n", dlerror());
@@ -44,6 +44,7 @@ PluginManager::PluginManager()
 PluginManager::~PluginManager(void)
 {
     destroy(pluginManagerImpl);
+    free(handle);
 }
 
 int PluginManager::startPlugins(const std::string key, const std::string value)
index 2ae8b73..12c11ab 100644 (file)
@@ -96,6 +96,7 @@ namespace OIC
         private:
             PluginManagerImpl *pluginManagerImpl;
             void (*destroy)(PluginManagerImpl *);
+            void *handle;
     };
 }
 #endif //__PLUGINMANAGER_H
index 2795e83..1f527fb 100644 (file)
@@ -74,9 +74,6 @@ int PluginManagerImpl::unregisterPlugin(std::string id)
 {
     int flag = 0;
 
-    Plugin *plugin = new Plugin;
-    plugin->setValue("Id", id);
-
     for (unsigned int i = 0 ; i < m_plugins.size(); i++)
     {
         if (!m_plugins[i].getID().compare(id))
index 0d9e0cf..e00a35e 100644 (file)
@@ -18,6 +18,7 @@ plugins_env.AppendUnique(CPPPATH = ['../lib/cpluff/libcpluff'])
 
 if target_os not in ['windows', 'winrt']:
        plugins_env.AppendUnique(CXXFLAGS = ['-g3', '-Wall', '-pthread', '-std=c++0x'])
+       plugins_env.PrependUnique(CCFLAGS = ['-fPIC']) 
        plugins_env.AppendUnique(LINKFLAGS = ['-fPIC'])
 
        if target_os not in ['arduino', 'android']:
@@ -28,13 +29,19 @@ if target_os == 'android':
        plugins_env.AppendUnique(LIBS = ['gnustl_static'])
        plugins_env.AppendUnique(CPPDEFINES = ['_GLIBCXX_USE_C99=1', '_GLIBCXX_HAVE_WCSTOF=1'])
 
+plugins_env.AppendUnique(LIBS = [File(env.get('BUILD_DIR') + '/libmosquitto.a'),
+               'mosquitto', 'ssl', 'rt'])
+
+
 ######################################################################
 # Source files and Targets
 ######################################################################
+plugins_env['LIBPREFIX'] = ''
+
 mqtt_fan_src = Glob('mqtt-fan/src/' + '*.cpp')
-fanserver = plugins_env.SharedLibrary('fanserver_mqtt_plugin', mqtt_fan_src)
+fanserver = plugins_env.SharedLibrary('mqtt-fan/fanserver_mqtt_plugin', mqtt_fan_src)
 
 mqtt_light_src = Glob('mqtt-light/src/' + '*.cpp')
-lightserver = plugins_env.SharedLibrary('lightserver_mqtt_plugin', mqtt_light_src)
+lightserver = plugins_env.SharedLibrary('mqtt-light/lightserver_mqtt_plugin', mqtt_light_src)
 
 SConscript('mqtt-fan/lib/SConscript')
index 9f258f1..248e35c 100644 (file)
@@ -2,6 +2,7 @@ CXX = g++
 
 CXX_FLAGS = -std=c++0x -Wall -pthread
 
+TOP_DIR = ../../../../../..
 LIB_DIR = ../../../../../../resource
 
 SRC_DIR = ../../src
@@ -22,7 +23,7 @@ CXX_INC         += -I../csdk/libcoap
 CXX_INC   += -I$(CEREAL_DIR)/include
 
 LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a
-CXX_LIBS  := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a
+CXX_LIBS  := ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a
 
 .PHONY: lib release_build ./release/fanserver_mqtt_plugin.so 
 
@@ -37,7 +38,7 @@ release_build:
        cp plugin.xml release
 
 ./release/fanserver_mqtt_plugin.so: ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o
-       $(CXX) -shared -o ./release/fanserver_mqtt_plugin.so ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o $(CXX_LIBS)  -L../../lib -lmosquitto -lssl -lrt
+       $(CXX) -shared -o ./release/fanserver_mqtt_plugin.so ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o $(CXX_LIBS)  -L../../lib -L$(TOP_DIR)/out/linux/x86/release -lmosquitto -lssl -lrt -loc -loctbstack -loc_logger -lcoap
 
 ./release/obj/fanserver_mqtt_plugin.o: $(SRC_DIR)/fanserver_mqtt_plugin.cpp
        $(CXX) $(CXX_INC) -fPIC -o ./release/obj/fanserver_mqtt_plugin.o -c $(SRC_DIR)/fanserver_mqtt_plugin.cpp 
index f93be96..82cedfc 100644 (file)
@@ -43,7 +43,7 @@ static int start(void *d)
 {
     plugin_data_t *data = (plugin_data_t *)d;
 
-    data->str = (void *)cp_resolve_symbol(data->ctx, "fanserver_mqtt_plugin", "START_ARGUMENT", NULL);
+    //data->str = (void *)cp_resolve_symbol(data->ctx, "fanserver_mqtt_plugin", "START_ARGUMENT", NULL);
 
     //cp_run_function(data->ctx, (cp_run_func_t)start_fanserver);           // 1
     pthread_create(&(data->m_thread), NULL, start_fanserver, data);         // 2
@@ -56,7 +56,7 @@ static void stop(void *d)
     plugin_data_t *data = (plugin_data_t *)d;
 
     data->flag = false;
-    cp_release_symbol(data->ctx, data->str);
+    //cp_release_symbol(data->ctx, data->str);
     pthread_join(data->m_thread, (void **)NULL);
 }
 
index 026b3a9..788b7cf 100644 (file)
@@ -2,6 +2,7 @@ CXX = g++
 
 CXX_FLAGS = -std=c++0x -Wall -pthread
 
+TOP_DIR = ../../../../../..
 LIB_DIR = ../../../../../../resource
 
 SRC_DIR = ../../src
@@ -22,7 +23,7 @@ CXX_INC         += -I../csdk/libcoap
 CXX_INC   += -I$(CEREAL_DIR)/include
 
 LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a
-CXX_LIBS  := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a
+CXX_LIBS  := ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a
 
 .PHONY: lib release_build ./release/lightserver_mqtt_plugin.so 
 
@@ -37,7 +38,7 @@ release_build:
        cp plugin.xml release
 
 ./release/lightserver_mqtt_plugin.so: ./release/obj/lightserver_mqtt_plugin.o ./release/obj/lightserver.o
-       $(CXX) -shared -o ./release/lightserver_mqtt_plugin.so ./release/obj/lightserver_mqtt_plugin.o ./release/obj/lightserver.o $(CXX_LIBS)  -L../../lib -lmosquitto -lssl -lrt
+       $(CXX) -shared -o ./release/lightserver_mqtt_plugin.so ./release/obj/lightserver_mqtt_plugin.o ./release/obj/lightserver.o $(CXX_LIBS)  -L../../lib  -L$(TOP_DIR)/out/linux/x86/release -lmosquitto -lssl -lrt -loc -loctbstack -loc_logger -lcoap
 
 ./release/obj/lightserver_mqtt_plugin.o: $(SRC_DIR)/lightserver_mqtt_plugin.cpp
        $(CXX) $(CXX_INC) -fPIC -o ./release/obj/lightserver_mqtt_plugin.o -c $(SRC_DIR)/lightserver_mqtt_plugin.cpp 
index 28b1c5d..dccac9f 100644 (file)
@@ -43,7 +43,7 @@ static int start(void *d)
 {
     plugin_data_t *data = (plugin_data_t *)d;
 
-    data->str = (void *)cp_resolve_symbol(data->ctx, "lightserver_mqtt_plugin", "START_ARGUMENT", NULL);
+    //data->str = (void *)cp_resolve_symbol(data->ctx, "lightserver_mqtt_plugin", "START_ARGUMENT", NULL);
 
     //cp_run_function(data->ctx, (cp_run_func_t)start_fanserver);           // 1
     pthread_create(&(data->m_thread), NULL, start_lightserver, data);         // 2
@@ -56,7 +56,7 @@ static void stop(void *d)
     plugin_data_t *data = (plugin_data_t *)d;
 
     data->flag = false;
-    cp_release_symbol(data->ctx, data->str);
+    //cp_release_symbol(data->ctx, data->str);
     pthread_join(data->m_thread, (void **)NULL);
 }
 
index 351756b..94f5841 100644 (file)
@@ -38,15 +38,17 @@ The Protocol Plug-in directory includes following sub directories;
 /build         Directory for Building and Binary Release
 
 
+If you build by scons skip 2,3.
+
 2. Compiling C-Pluff library 
 Before building Protocol-Plugin Manager, C-Pluff library should be compiled as follows.
 
-~/oic/oic-service/protocol-plugin/lib/cpluff$ aclocal
-~/oic/oic-service/protocol-plugin/lib/cpluff$ autoconf
-~/oic/oic-service/protocol-plugin/lib/cpluff$ autoheader
-~/oic/oic-service/protocol-plugin/lib/cpluff$ automake
-~/oic/oic-service/protocol-plugin/lib/cpluff$ ./configure
-~/oic/oic-service/protocol-plugin/lib/cpluff$ make
+~/service/protocol-plugin/lib/cpluff$ aclocal
+~/service/protocol-plugin/lib/cpluff$ autoconf
+~/service/protocol-plugin/lib/cpluff$ autoheader
+~/service/protocol-plugin/lib/cpluff$ automake
+~/service/protocol-plugin/lib/cpluff$ ./configure
+~/service/protocol-plugin/lib/cpluff$ make
 
  
 3. Run make
@@ -54,22 +56,25 @@ By running make in the protocol-plugin path, protocol-plugin manager, all plugin
  
 NOTE: To build plugins in 64-bit Ubuntu Linux, OCLib.a and libcoap.a library should be re-compiled with ?fPIC option.
  
-~/oic/oic-service/protocol-plugin/build/linux$make
+~/service/protocol-plugin/build/linux$make
 
 
 4. Using Plugins 
 This version of protocol plug-in source code has following functionality.
 
-1) provides plug-in manager which can start and stop plug-in library.
-2) provides plug-in library which can communicate with MQTT protocol Fan and Light.
-3) provides OIC Sample Client which can get info about Fan and Light with configuration file(pluginmanager.xml).
+1) Provides plug-in manager which can start and stop plug-in library.
+2) Provides plug-in library which can communicate with MQTT protocol Fan and Light.
+3) Locate shared plug-in library and XML file in a specific folder.
 
 So, to test a plug-in, follow below steps.
 
-1) Locate shared plug-in library and XML file in a specific folder.
-2) Register the plug-in with directory path input from plug-in manager sample.
-3) Start the plug-in from plug-in manager sample.
-4) Run OIC sample client.
-   ex)service/protocol-plugin/sample-app/linux/mqtt$./mqttclient
-  (mqtt broker is already installed in the local system.)
+1) Copy libpmimple.so from {Top_Dir}/out/linux/x86/release to sample-app folder.
+2) Provides OIC Sample Client which can get info about Fan and Light with configuration file(pluginmanager.xml).
+3) Copy the pluginmanager.xml from ~/service/protocol-plugin/sample-app/linux/mqtt/ to sample-app folder.
+4) Modifty the pluginmanager.xml 
+5) Before starting sample app need as below command. 
+   $export LD_LIBRARY_PATH={Top_Dir}/out/linux/x86/release/:$LD_LIBRARY_PATH
+6) Start the plug-in from plug-in manager sample.
+   ex)~service/protocol-plugin/sample-app/linux/mqtt$./mqttclient
+   (Need mqtt broker working in the local system(127.0.0.1) for test.)
 
index 339d4bb..2e6b311 100644 (file)
@@ -13,16 +13,19 @@ target_os = env.get('TARGET_OS')
 ######################################################################
 # Build flags
 ######################################################################
-sample_env.AppendUnique(CPPPATH = ['../../plugin-manager/src/',
-                               '../../lib/cpluff/libcpluff/'])
+sample_env.AppendUnique(CPPPATH = [
+                               '../../plugin-manager/src/',
+                               '../../lib/cpluff/libcpluff/',
+                               '../../lib/rapidxml'])
 if target_os not in ['windows', 'winrt']:
        sample_env.AppendUnique(CXXFLAGS = ['-Wall', '-pthread', '-std=c++0x'])
 
+sample_env.AppendUnique(LIBS = ['pthread'])
 sample_env.AppendUnique(LIBS = ['oc', 'oc_logger', 'octbstack', 'coap', 'ppm', 'pmimpl', 'dl'])
 ######################################################################
 # Source files and Targets
 ######################################################################
-fanclient = sample_env.Program('fanclient', 'fan-control/fanclient.cpp')
+mqttclient = sample_env.Program('mqtt/mqttclient', 'mqtt/mqttclient.cpp')
 
-Alias('fanclient', fanclient)
-env.AppendTarget('fanclient')
\ No newline at end of file
+Alias('mqttclient', mqttclient)
+env.AppendTarget('mqttclient')
\ No newline at end of file
index e3b3841..131e83a 100644 (file)
@@ -2,6 +2,7 @@ CXX = g++
 
 CXX_FLAGS = -std=c++0x -Wall -pthread
 
+TOP_DIR = ../../../../..
 LIB_DIR = ../../../../../resource
 
 DEPEND_DIR:= $(LIB_DIR)/dependencies
@@ -21,8 +22,8 @@ CXX_INC   += -I$(CEREAL_DIR)/include
 CXX_INC += -I../../../lib/rapidxml 
 
 LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a
-CXX_LIBS  := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../build/linux/release/libppm.a ../../../lib/cpluff/libcpluff/.libs/libcpluff.a
-LINK_LIB = -lboost_system -ldl -lexpat -lboost_thread 
+CXX_LIBS  := ../../../build/linux/release/libppm.a ../../../lib/cpluff/libcpluff/.libs/libcpluff.a
+LINK_LIB = -lboost_system -ldl -lexpat -lboost_thread -L$(TOP_DIR)/out/linux/x86/release -loc -loctbstack -loc_logger -lcoap
 
 .PHONY: mqttclient
 
@@ -37,4 +38,5 @@ mqttclient.o: mqttclient.cpp
        
 clean:
        rm -f *.o
+       rm -f *.so
        rm -f mqttclient
index eda93d4..59ec85d 100644 (file)
@@ -54,6 +54,21 @@ class Fan
 
 Fan myfan;
 
+class Light
+{
+    public:
+
+        bool m_state;
+        int m_power;
+        std::string m_name;
+
+        Light() : m_state(false), m_power(0), m_name("")
+        {
+        }
+};
+
+Light mylight;
+
 int observe_count()
 {
     static int oc = 0;
@@ -237,11 +252,11 @@ void putFanRepresentation(std::shared_ptr<OCResource> resource)
 }
 
 // Callback handler on GET request
-void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+void onFanGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
 {
     if (eCode == OC_STACK_OK)
     {
-        std::cout << "GET request was successful" << std::endl;
+        std::cout << "GET Fan request was successful" << std::endl;
         std::cout << "Resource URI: " << rep.getUri() << std::endl;
 
         rep.getValue("state", myfan.m_state);
@@ -261,6 +276,29 @@ void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, cons
     }
 }
 
+void onLightGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        std::cout << "GET Light request was successful" << std::endl;
+        std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+        rep.getValue("state", mylight.m_state);
+        rep.getValue("power", mylight.m_power);
+        rep.getValue("name", mylight.m_name);
+
+        std::cout << "\tstate: " << mylight.m_state << std::endl;
+        std::cout << "\tpower: " << mylight.m_power << std::endl;
+        std::cout << "\tname: " << mylight.m_name << std::endl; 
+    }
+    else
+    {
+        std::cout << "onGET Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+
+
 // Local function to get representation of fan resource
 void getFanRepresentation(std::shared_ptr<OCResource> resource)
 {
@@ -270,7 +308,7 @@ void getFanRepresentation(std::shared_ptr<OCResource> resource)
         // Invoke resource's get API with the callback parameter
 
         QueryParamsMap test;
-        resource->get(test, &onGet);
+        resource->get(test, &onFanGet);
     }
 }
 
@@ -282,7 +320,7 @@ void getLightRepresentation(std::shared_ptr<OCResource> resource)
         // Invoke resource's get API with the callback parameter
 
         QueryParamsMap test;
-        resource->get(test, &onGet);
+        resource->get(test, &onLightGet);
     }
 }
 
@@ -531,7 +569,7 @@ int main(int argc, char *argv[])
         std::cout << "======================" << std::endl;
         std::cout << "Start Fan Plugin by Name\n" << std::endl;
 
-        name = user_plugin[0].getName().c_str();
+        name = user_plugin[0].getName();
         m_pm->startPlugins(key, name);
 
         sleep(5);
index fb078ff..1e295bf 100644 (file)
-Before run make,                                                                   
-                                                                                   
-you have to modify Soft Sensor repository path                                     
-                                                                                   
-that Soft Sensor Manager can find assets while it starts.                          
-                                                                                   
-                                                                                   
-If you want to build THSensorApp for Arduino, let's install follow.
-$ sudo apt-get install arduino
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
 
-Download Time library(Time.zip) from http://playground.arduino.cc/Code/Time 
-Unzip Time.zip to /usr/share/arduino/libraries/Time.
 
-$ sudo cp -Rdp THSensorApp/Time /usr/share/arduino/libraries/
+===============================================================================
+==                How to       Build SoftSensorManager                          ==
+===============================================================================
 
-Open the file located at "THSensorApp/build/Makefile"
+Once the source code is downloaded in your local specific folder, you may follow 
+the steps to build and execute Soft Sensor Manager and its applications. 
+In this context, we assume that the code was downloaded into 'oic' folder.
 
-Line 9, ARDUINO_PORT is the serial port path,
 
-which has to be aligned on your system.
+=======================================
+1. Download source code
+=======================================
 
+Once you download the codes, please make sure that the downloaded code structure is as follows; 
 
-If you type "make" at SoftSensorManager folder.
+oic/resource 
+oic/service
+oic/utilities
+The path for Soft Sensor Manager is as following;
 
-All packages will be pushed to "Outputs" folder.
+oic/service/soft-sensor-manager
+The SoftSensorManager directory includes following sub directories;
 
-You can also found other packages from their.
+Directories    Description
+oic/service/soft-sensor-manager/build            : There are makefiles for different platform; Linux, Tizen, and Arduino.  
+oic/service/soft-sensor-manager/doc              : SSM developer's guide and Getting started documents
+oic/service/soft-sensor-manager/SampleApp        : There are two types of sample applications; application for UI, and application for physical sensors.
+                                                   For UI application, there are SSMTesterApp in /linux, and /Tizen.
+                                                   For physical sensors, 
+                                                        1) Temperature and Humidity sensors, THSensorApp, in \linux and \arduino.
+                                                           In the two directories, in \linux and \arduino , there are two TemperaterHumiditySensor applications, 
+                                                           THSensorApp and THSensorApp1, and they are for DiscomfortSoftSensor which aggregates 
+                                                           two TemperaterHumiditySensors to calculate current discomfort index in the given room.
+                                                        2) Trackee_Thing for IndoorTrajectorySensor in \linux and \arduino
+oic/service/soft-sensor-manager/SDK              : The SDK APIs for applications is located.
+oic/service/soft-sensor-manager/SSMCore          : The SSM service codes 
+oic/service/soft-sensor-manager/SoftSensorPlugin : The source codes for soft sensors can be located in this folder. 
+                                                       Examples of soft sensors are DiscomfortIndexSensor and IndoorTrajectorySensor.
+
+
+=======================================
+2. Refer readme files in each build 
+   directory for each module.
+=======================================
+There are readme files in the build directories for each module (e.g. \SDK, \ SSMCore,  \SampleApp). 
+Please refer the files for specific setup.
+
+
+=======================================
+3. Run make
+=======================================
+
+3.1 Run make for SoftSensorManager & App in Ubuntu. 
+
+3.1.1 Before running make for SoftSensorManager & App in Ubuntu, resource should be built in advance. 
+   Please refer to ¡®Build the IoTivity project for Linux¡¯ in previous section
+
+3.1.2 If you type "make" at ¡°soft-sensor-manager/build/linux¡±, all packages will be pushed to "/soft-sensor-manager/build/linux/release".  
+   You can also found other packages in the folder
+
++--------------------------------------------------------------+
+| ~/oic/service/soft-sensor-manager/build/linux$ make          |
++--------------------------------------------------------------+
+
+3.2 Run make for App in Arduino
+
+3.2.1 If you want to build for Arduino, download Arduino IDE (Arduino 1.0.6) from following url. 
+   Extract ¡®arduino-1.0.6-linux32.tgz¡¯ and change folder name from ¡®arduino-1.0.6¡¯ to ¡®arduino¡¯ and then move to "/usr/share/".
+   url: http://arduino.cc/en/Main/Software
+
++--------------------------------------------------------------------+
+| $ mv arduino-1.0.6 arduino                                         |
+| $ sudo cp -Rdp ./arduino /usr/share/                               |
++--------------------------------------------------------------------+
+  
+3.2.2 Download Time library (Time.zip, Click ¡°The download¡±) from following url. 
+   Unzip Time.zip and move them to /usr/share/arduino/libraries.  
+   url: http://playground.arduino.cc/Code/Time
+
++--------------------------------------------------------------------+
+| $ sudo cp -Rdp ./Time /usr/share/arduino/libraries/                |
++--------------------------------------------------------------------+
+
+3.2.3 Create file named ¡®local.properties¡¯ in  ¡°/oic/resource/csdk/¡± with the following definitions.
+
++------------------------------------------------------------------------------------+
+| < local.properties >                                                               |
+| ARDUINO_DIR = /usr/share/arduino                                                   |
+| ARDUINO_TOOLS_DIR = $(ARDUINO_DIR)/hardware/tools/avr/bin                          |
++------------------------------------------------------------------------------------+
+   If you have a problem with compiling ¡®resource¡¯ when you compile arduino application, 
+   you may need to check 'local.properties' which is written in the readme file, '/oic/resource/csdk/README'.
+
+3.2.4 Before running make for application, you need to build resource with arduino platform first. 
+   Please refer to below example.
+
++------------------------------------------------------------------------------------------+
+| ~/oic/resource/csdk$ make PLATFORM=arduinomega ARDUINOWIFI=1                             |
++------------------------------------------------------------------------------------------+
+   PLATFORM :  arduinomega or arduinodue.
+   ARDUINOWIFI : 0 (Ethernet), 1(Wifi)
+
+3.2.5 Now, you are ready to build sample arduino application. 
+   To build all sample  applications for arduino, just do as below.
+
++------------------------------------------------------------------------------------------------+
+|~/oic/service/soft-sensor-manager/ build/Arduino$ make PLATFORM=arduinomega ARDUINOWIFI=1       |                           
++------------------------------------------------------------------------------------------------+ 
+
+   If you want to build each sample application separately, go to build directory for sample application. 
+   Belowing is example for THSensor App. 
+   
++-------------------------------------------------------------------------------------------------------------------+
+|~/oic/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build$ make PLATFORM=arduinomega ARDUINOWIFI=1     |                           
++-------------------------------------------------------------------------------------------------------------------+ 
+
+3.2.6. To build and deploy the binary into the target hardware board, Aruino in this case, you need 'install' option. 
+   Please refer to below example for THSensorApp;
+
++--------------------------------------------------------------------------------------------------------------------------+
+|~/oic/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build$ make install PLATFORM=arduinomega ARDUINOWIFI=1    |                           
++--------------------------------------------------------------------------------------------------------------------------+ 
+   Before ¡®make install¡¯, you need to check the file located at "/oic/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/Makefile". 
+   Line 26, ARDUINO_PORT is the serial port path, which has to be aligned on your system.  
+
+
+=======================================
+4. Execute THSensorApp and SSMTesterApp
+=======================================
+
+If you want to check how soft-sensor-manager is working, you can run simple applications - THSensorApp and SSMTesterApp
+
+4.1 To initiate THSensorApp, please enter as following; 
+
++------------------------------------------------------------------------+
+|~/oic/service/soft-sensor-manager/build/linux/release$ ./THSensorApp    |           
+|~/oic/service/soft-sensor-manager/build/linux/release$ ./THSensorApp1   |                 
++------------------------------------------------------------------------+
+4.2 To initiate SSMTesterApp, please enter as following;
+
++--------------------------------------------------------------------------+
+|~/oic/service/soft-sensor-manager/build/linux/release$ ./SSMTesterApp     |
++--------------------------------------------------------------------------+
+
+Note that the sequence of process initiations should be followed due to the process dependencies.
+
+
+=======================================
+5. Build with SCons
+=======================================
+
+If you want to use Scons to build soft-sensor-manager, build the source code and execute sample applications as following steps.
+
+5.1 After downloading the source codes, type "scons" at project root directory "oic/"
+
++---------------------------------------+
+|~/oic$ scons                           |
++---------------------------------------+
+
+5.2 To execute Soft Sensor Manager and its applications, some shared libraries must be exported.
+
+5.2.1 Go to "oic/out/<target_os>/<target_arch>/release", and check if there are following .so files
+ liboc.so
+ liboctbstack.so
+ liboc_logger.so
+5.2.2 To export the shared libraries, please enter as following;
+
++---------------------------------------------------------------------------------------------------------------------------+
+|~/oic/out/<target_os>/<target_arch>/release$ export LD_LIBRARY_PATH=~/oic/out/<target_os>/<target_arch>/release            |
++---------------------------------------------------------------------------------------------------------------------------+
+
+5.3 Generated outputs from building soft-sensor-manager will be in "oic/out/<target_os>/<target_arch>/release/service/soft-sensor-manager".
+
+5.4 To initiate THSensorApp, please enter as following;
+
++------------------------------------------------------------------------------------------+
+|~/oic/out/<target_os>/<target_arch>/release/service/soft-sensor-manager$ ./THSensorApp    |           
+|~/oic/out/<target_os>/<target_arch>/release/service/soft-sensor-manager$ ./THSensorApp1   |                 
++------------------------------------------------------------------------------------------+
+
+5.5 To initiate SSMTesterApp, please enter as following;
+
++--------------------------------------------------------------------------------------------+
+|~/oic/out/<target_os>/<target_arch>/release/service/soft-sensor-manager$ ./SSMTesterApp     |
++--------------------------------------------------------------------------------------------+
\ No newline at end of file
index aec6fcb..687b690 100644 (file)
@@ -20,7 +20,7 @@ if target_os == 'arduino':
 # Build flags
 ######################################################################
 if target_os not in ['windows', 'winrt']:
-       soft_sensor_manager_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+       soft_sensor_manager_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-DLINUX'])
        if target_os != 'android':
                soft_sensor_manager_env.AppendUnique(CXXFLAGS = ['-pthread'])
 
@@ -28,12 +28,20 @@ if target_os not in ['windows', 'winrt']:
 ## build SSM SDK
 #######################################################################
 sdk_env = soft_sensor_manager_env.Clone()
-sdk_env.AppendUnique(CPPPATH = ['SDK/include'])
+sdk_env.AppendUnique(CPPPATH = ['SSMCore/include'])
+sdk_env.AppendUnique(CPPPATH = ['SSMCore/src'])
+sdk_env.AppendUnique(CPPPATH = ['SDK/cpp/include'])
 
-ssm_sdk = sdk_env.Object('SDK/src/SSMClient.cpp')
-i_ssmsdk = sdk_env.Install(env.get('BUILD_DIR'), )
-Alias('libSSMSDKLibrary', i_ssmsdk)
-env.AppendTarget('libSSMSDKLibrary')
+ssm_sdk_cpp_src = [
+               Glob('SDK/cpp/src/*.cpp')
+               ]
+
+env.AppendTarget('libSSMSDK')
+libssmsdk = sdk_env.StaticLibrary(
+               target = 'libSSMSDK',
+               source = [ssm_sdk_cpp_src]
+               )               
+sdk_env.InstallTarget(libssmsdk, 'libSSMCORE')
 
 ######################################################################
 # build DiscomfortIndexSensor plugin
@@ -56,10 +64,7 @@ DiscomfortIndexSensor_env.InstallTarget(DiscomfortIndexSensor, 'libDiscomfortInd
 # build SSM CORE
 ######################################################################
 ssmcore_env = soft_sensor_manager_env.Clone()
-MODEL_DIR = "\"\\\"" + env.get('BUILD_DIR') + "\\\"\""
-LOCATION = "\"\\\"" + env.get('BUILD_DIR') + "HighContextDictionary.xml" + "\\\"\""
 
-ssmcore_env.AppendUnique(CPPDEFINES = ['MODEL_DIRECTORY='+MODEL_DIR, 'HIGH_LOCATION='+LOCATION])
 ssmcore_env.AppendUnique(CPPPATH = [
                'SSMCore/include/',
                'SSMCore/src/',
@@ -79,7 +84,6 @@ else :
        ssminterface_src = Glob(SSMINTERFACE_PATH + '*.cpp')
 
 ssm_core_cpp_src = [
-               'SSMCore/src/SSMResourceServerLauncher.cpp',
                Glob('SSMCore/src/Common/*.cpp'),
                Glob('SSMCore/src/QueryProcessor/*.cpp'),
                Glob('SSMCore/src/SensorProcessor/*.cpp'),
@@ -91,7 +95,7 @@ ssm_core_c_src = [
 ]
 
 libssmcore = ssmcore_env.StaticLibrary(
-               target = 'SSMCoreUbuntu',
+               target = 'SSMCore',
                source = [ssm_core_cpp_src, ssm_core_c_src]
                )
 
@@ -100,4 +104,13 @@ ssmcore_env.InstallTarget(libssmcore, 'libSSMCORE')
 #######################################################################
 ## build SampleApp
 #######################################################################
-#SConscript('SampleApp/SConscript')
+SConscript('SampleApp/SConscript')
+
+
+######################################################################
+# Copy description xml and deliverables
+######################################################################
+Command("SSMTesterApp","SampleApp/linux/SSMTesterApp/SSMTesterApp", Copy("$TARGET", "$SOURCE"))
+Command("SoftSensorDescription.xml", "SoftSensorPlugin/SoftSensorDescription.xml", Copy("$TARGET", "$SOURCE"))
+Command("THSensorApp","SampleApp/linux/THSensorApp/THSensorApp", Copy("$TARGET", "$SOURCE"))
+Command("THSensorApp1","SampleApp/linux/THSensorApp1/THSensorApp1", Copy("$TARGET", "$SOURCE"))
\ No newline at end of file
@@ -1,5 +1,5 @@
--include ../../../build/linux/root_path.inc
--include ../../../build/linux/environment.mk
+-include ../../../../build/linux/root_path.inc
+-include ../../../../build/linux/environment.mk
 
 BOOST=${BOOST_BASE}
 SRC_PATH=../../src
@@ -13,7 +13,7 @@ TARGET=${SSM_LIB}
 
 CXX=g++
 CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX
-CXX_INC=-I../../ -I${INC_PATH}/ -I${FD_SSMCORE}/include -I${FD_SSMCORE}/src -I${IOT_BASE}/include/ -I${IOT_LOG_DIR}/include -I${IOT_BASE}/csdk/stack/include -I${IOT_BASE}/csdk/ocsocket/include -I${IOT_BASE}/csdk/ocrandom/include -I${IOT_BASE}/csdk/logger/include -I${BOOST}
+CXX_INC=-I../../ -I${INC_PATH}/ -I${FD_SSMCORE}/include -I${FD_SSMCORE}/src -I${BOOST}
 CXX_LIB= 
 
 SRCLIST=${wildcard ${SRC_PATH}/*.cpp}
diff --git a/service/soft-sensor-manager/SDK/cpp/include/SSMInterface.h b/service/soft-sensor-manager/SDK/cpp/include/SSMInterface.h
new file mode 100644 (file)
index 0000000..0085b3b
--- /dev/null
@@ -0,0 +1,229 @@
+#ifndef _SSMInterface_H_
+#define _SSMInterface_H_
+
+#include <string>
+#include <vector>
+
+namespace OIC
+{
+    enum SSMRESULT
+    {
+        SSM_S_OK
+        , SSM_S_FALSE
+        , SSM_E_POINTER
+        , SSM_E_OUTOFMEMORY
+        , SSM_E_FAIL
+        , SSM_E_NOINTERFACE
+        , SSM_E_NOTIMPL
+    };
+
+    /**
+    * @class    IModelData
+    * @brief    This class represents context model data package
+    *
+    * @see
+    */
+    class IModelData
+    {
+        public:
+            /**
+            * @fn     getDataId
+            * @brief Get affected DataId. ContextModel has plenty of data so \n
+            *         returned data is matched from given condition
+            *
+            * @param None
+            *
+            * @return int
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual int getDataId() = 0;
+
+            /**
+            * @fn     GetPropertyCount
+            * @brief ContextModel has at least one property that contains data \n
+            *         property is described from its specification.
+            *
+            * @param None
+            *
+            * @return int
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual int getPropertyCount() = 0;
+
+            /**
+            * @fn     getPropertyName
+            * @brief Retrieve propertyName
+            *
+            * @param [in] int propertyIndex - index of property to read
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyName(int propertyIndex) = 0;
+
+            /**
+            * @fn     getPropertyValue
+            * @brief Retrieve propertyValue
+            *
+            * @param [in] int propertyIndex - index of property to read
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyValue(int propertyIndex) = 0;
+
+            /**
+            * @fn     getPropertyValueByName
+            * @brief Retrieve propertyValue using given name
+            *
+            * @param [in] std::string propertyName - property name looking for
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyValueByName(std::string propertyName) = 0;
+        protected:
+            virtual ~IModelData() {};
+    };
+
+    /**
+    * @class    IDataReader
+    * @brief    This class represents context model data package's reader
+    *
+    * @see
+    */
+    class IDataReader
+    {
+        public:
+            /**
+            * @fn     getAffectedModels
+            * @brief Get affected ContextModels. The CQL can specify multiple ContextModels for retrieving data.
+            *
+            * @param [in, out] std::vector<std::string> *pAffectedModels - affected ContextModel list
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getAffectedModels(std::vector<std::string> *pAffectedModels) = 0;
+
+            /**
+            * @fn     getModelDataCount
+            * @brief Get affected data count. There are multiple data can exist from given condition.
+            *
+            * @param [in] std::string modelName - affected ContextModel name
+            *
+            * @param [in, out] int *pDataCount - affected dataId count
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getModelDataCount(std::string modelName, int *pDataCount) = 0;
+
+            /**
+            * @fn     getModelData
+            * @brief Get actual Context Model data
+            *
+            * @param [in] std::string modelName - affected ContextModel name
+            *
+            *
+            * @param [in] int dataIndex - affected dataId index
+            *
+            *
+            * @param [out] IModelData **ppModelData - affected ContextModel data reader
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getModelData(std::string modelName, int dataIndex, IModelData **ppModelData) = 0;
+        protected:
+            virtual ~IDataReader() {};
+    };
+
+    /**
+    * @class    IQueryEngineEvent
+    * @brief    This class represents Query Engine's event that contains results
+    *
+    * @see
+    */
+    class IQueryEngineEvent
+    {
+        public:
+            /**
+            * @fn     onQueryEngineEvent
+            * @brief Transmit result of SSMCore to Application layer
+            *
+            * @param [in] int cqid - entered ContextQuery ID
+            *
+            * @param [in] IDataReader *pResult - result of SSMCore
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT onQueryEngineEvent(int cqid, IDataReader *pResult) = 0;
+        protected:
+            virtual ~IQueryEngineEvent() {};
+    };
+
+    /**
+    * @class    SSMInterface
+    * @brief    This class represents main class for querying Soft Sensors
+    *
+    * @see
+    */
+    class SSMInterface
+    {
+        public:
+            SSMInterface();
+            ~SSMInterface();
+
+            /**
+            * @fn     registerQuery
+            * @brief Execute ContextQuery and return ContextQuery ID
+            *
+            * @param [in] std::string queryString - query for requesting data
+            *
+            * @param [in] IQueryEngineEvent listener - listener for receiving data related to query
+            *
+            * @param [in, out] int &cqid - ID of ContextQuery
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            SSMRESULT registerQuery(std::string queryString, IQueryEngineEvent *listener, int &cqid);
+
+            /**
+            * @fn    unregisterQuery
+            * @brief unregister registered ContextQuery according to cqid
+            *
+            * @param [in] int cqid - Context query corresponding to the cqid will be terminated
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            SSMRESULT unregisterQuery(int cqid);
+    };
+
+}
+#endif
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/include/ISSMClientListener.h b/service/soft-sensor-manager/SDK/include/ISSMClientListener.h
deleted file mode 100644 (file)
index f425b3d..0000000
+++ /dev/null
@@ -1,61 +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    ISSMClientListener.h
- * @brief   This file contains client listener interfaces.
- */
-
-#ifndef ISSMCLIENTLISTENER_H_
-#define ISSMCLIENTLISTENER_H_
-#include <string>
-#include "OCPlatform.h"
-
-/**
- * @brief This enum defines Soft Sensor return types
- */
-typedef enum
-{
-    SSM_SUCCESS, SSM_ERROR, SSM_ERROR_QUERY_PARSING, SSM_ERROR_NO_QUERY, SSM_ERROR_NETWORK
-} SSMReturn;
-
-using namespace OC;
-/**
- *  @brief  ISSMClientListener is a listener interface from which application is derived to get callback from SoftSensorManager service
- */
-class ISSMClientListener
-{
-    public:
-        /**
-         * @brief   onRegisterQuery is a pure virtual operation which should be implemented in applications to get callback messages.
-         * @param [in] attributeMap - A data map in which SoftSensorManager service sends sensor data with cqid.
-         * @param [in] eCode - The address of listener class.  When an application which inherits the ISSMClientListener calls this operation, it sends its address for the listener so that
-         *                          SSMClient can callback message to the appication.
-         * @param [out] cqid - A query id generated from SoftSensorManager service for the queryString request.
-         * @return  SSMReturn
-
-         */
-        virtual void onRegisterQuery(const AttributeMap &attributeMap, SSMReturn &eCode) = 0;
-        virtual ~ISSMClientListener()
-        {
-        }
-};
-
-#endif /* ISSMCLIENTLISTENER_H_ */
diff --git a/service/soft-sensor-manager/SDK/include/SSMClient.h b/service/soft-sensor-manager/SDK/include/SSMClient.h
deleted file mode 100644 (file)
index 36d6d57..0000000
+++ /dev/null
@@ -1,247 +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    SSMClient.h
- * @brief   This file contains the declaration of classes and its members related to SSMClient.
- */
-
-#ifndef RESOURCECLIENT_H_
-#define RESOURCECLIENT_H_
-
-#include <string>
-
-#include "OCResource.h"
-#include "OCPlatform.h"
-#include "ISSMClientListener.h"
-
-using namespace OC;
-
-#if defined(WIN32)
-class CSemaphore
-{
-    private:
-        HANDLE hSemaphore;
-        int m_MaxTimeOut;
-
-    public:
-        /**
-         * This is CSemaphore constructor.
-         */
-        CSemaphore()
-        {
-            m_MaxTimeOut = 0;
-        }
-        /**
-         *This is CSemaphore destructor.
-         */
-        ~CSemaphore()
-        {
-        }
-
-        /**
-         * This is a function to creat a semaphore
-         * This is syncronus call.
-         * @param maximumRequestTimeOut
-         *          [IN] Request Time out.
-         *
-         * @return  None
-         *
-         */
-        void create(int maximumRequestTimeOut)
-        {
-            hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
-            m_MaxTimeOut = maximumRequestTimeOut;
-        }
-
-        /**
-         * This is a function to wait for semaphore
-         *
-         * @return  None
-         *
-         */
-        void wait()
-        {
-            WaitForSingleObject(hSemaphore, m_MaxTimeOut);
-        }
-
-        /**
-         * This is a function to release  semaphore
-         *
-         * @return  None
-         *
-         */
-        void release()
-        {
-            ReleaseSemaphore(hSemaphore, 1, NULL);
-        }
-
-};
-
-#elif defined(LINUX)
-#include <semaphore.h>
-
-#define SEM_SUCCESS     0
-
-class CSemaphore
-{
-    private:
-        sem_t hSemaphore;
-        timespec m_MaxTimeOut;
-
-    public:
-        /**
-         * This is CSemaphore constructor.
-         */
-        CSemaphore()
-        {
-            m_MaxTimeOut.tv_sec = 0;
-            m_MaxTimeOut.tv_nsec = 0;
-        }
-        /**
-         *This is CSemaphore destructor.
-         */
-        ~CSemaphore()
-        {
-        }
-        /**
-         * This is a function to creat a semaphore
-         * This is syncronus call.
-         * @param maximumRequestTimeOut
-         *          [IN] Request Time out.
-         *
-         * @return  None
-         *
-         */
-        void create(int maximumRequestTimeOut)
-        {
-            if ( sem_init(&hSemaphore, 1, 0) < SEM_SUCCESS )
-            {
-                perror("Error : sem_init.");
-                exit(0);
-            }
-            m_MaxTimeOut.tv_sec = maximumRequestTimeOut;
-        }
-
-        void wait()
-        {
-            sem_wait( &hSemaphore );
-        }
-
-        /**
-         * This is a function to release  semaphore
-         *
-         * @return  None
-         *
-         */
-        void release()
-        {
-            sem_post(&hSemaphore);
-        }
-
-};
-#endif
-
-/**
- *  @brief  SSMClient is a wrapper class to provide SoftSensorManager functionality to Application.
- *          Basically, SoftSensorManager is developed in Resource model (i.e. messaging with basic functions of put, get, and post).
- *          SSMClient abstracts the resource based operations from client applications and provides c++ style functions.
- */
-class SSMClient
-{
-    private:
-        SSMReturn m_retResponse;
-        CSemaphore m_sem;
-        /**
-         * @brief SoftSensorManager Resource.
-         */
-        std::shared_ptr< OCResource > m_SSMResource;
-        /**
-         * @brief attribute map .
-         */
-        AttributeMap m_responseAttributeMap;
-        /**
-         * @brief query engine.
-         */
-        std::string m_queryEngineId;
-        /**
-         * @brief app listener
-         */
-        ISSMClientListener *m_appListener;
-
-        /**
-         * @brief internal find resource function
-         */
-        void _findResource(void);
-
-        /**
-         * @brief internal Query engine function
-         */
-        void _createQueryEngine(void);
-
-        /**
-         * @brief internal release query function
-         */
-        void _releaseQueryEngine(std::string queryEngineId);
-
-    public:
-        /**
-         * Constructor for SSMClient.
-         */
-        SSMClient();
-        ~SSMClient();
-
-        /**
-         * This API sends query strings of applications to SoftSensorManager on Iotivity Base messaging.
-         *
-         * @param [in] queryString - A conditions query statement where the caller application specifies sensors for required data and conditions when the caller wants to get the data.
-         * @param [in] listener - The address of listener class.  When an application which inherits the ISSMClientListener calls this operation, it sends its address for the listener so that
-         *                          SSMClient can callback message to the application.
-         * @param [out] cqid - A query id generated from SoftSensorManager service for the queryString request.
-         * @return  SSMReturn
-
-         */
-        SSMReturn registerQuery(std::string queryString, ISSMClientListener *listener,
-                                std::string &cqid);
-        /**
-         * This API is to cancel the registered sends query strings of applications to SoftSensorManager on Iotivity Base messaging.
-         *
-         * @param [in] listener - The address of listener class.  When an application which inherits the ISSMClientListener calls this operation, it sends its address for the listener so that
-         *                          SSMClient can callback message to the application.
-         * @param [in] cqid - A query id generated from SoftSensorManager service for the queryString request.
-         * @return  SSMReturn
-         */
-        SSMReturn unregisterQuery(std::string cqid);
-
-        // friend option. for callback from SSMResource
-        void onFoundResource(std::shared_ptr< OCResource > resource);
-        void onCreateQueryEngine(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                                 const int eCode);
-        void onReleaseQueryEngine(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                                  const int eCode);
-        void onRegisterQuery(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                             const int eCode);
-        void onUnregisterQuery(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                               const int eCode);
-        void onObserve(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int &eCode,
-                       const int &sequenceNumber);
-};
-
-#endif /* RESOURCECLIENT_H_ */
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/CoreController.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/CoreController.java
new file mode 100644 (file)
index 0000000..38ff87c
--- /dev/null
@@ -0,0 +1,74 @@
+package org.iotivity.service.ssm;
+
+import java.util.List;
+
+import android.util.Log;
+
+public class CoreController 
+{
+       static
+       {
+               try
+               {
+                       String workingPath = System.getProperty( "user.dir" );
+                       
+                       Log.i("SSMTester", "loading ssm lib");
+                       
+                       // for android: not complete method
+                       if(System.getProperty("os.name").toLowerCase().equals("linux"))
+                       {
+                               //System.out.println("System load Android library");
+                               System.loadLibrary("SSMCore_Android");
+                       }
+                       else
+                       {
+                               //System.out.println("System load 32bit library");
+                               workingPath += "/../Outputs/";
+                               System.load( workingPath + "SSMCore_Windows.dll");
+                       }
+                       
+                       Log.i("SSMTester", "loading done");
+               }
+               catch(UnsatisfiedLinkError e)
+               {
+                       System.out.println(e.getMessage());
+               }
+       }
+       
+       static private CoreController coreController;
+       
+       public static CoreController getInstance()
+       {
+               if(coreController == null)
+                       coreController = new CoreController();
+               
+               return coreController;
+       }
+       
+       public native void InitializeSSMCore(String xmlDescription);
+       public native void StartSSMCore();
+       public native void StopSSMCore();
+       public native void TerminateSSMCore();
+       public native QueryEngine CreateQueryEngine();
+       public native int ReleaseQueryEngine(QueryEngine queryEngine);
+       
+       // QueryEngine
+       public native int ExecuteContextQuery(int pQueryEngineInstance, String contextQuery);
+       public native void RegisterQueryEvent(int pQueryEngineInstance, IQueryEngineEvent queryEngineEvent);
+       public native void KillContextQuery(int pQueryEngineInstance, int cqid);        
+               
+       //public native void UnregiterQueryEvent(int pQueryEngineInstance, IQueryEngineEvent queryEngineEvent);
+
+       //IModelData
+       public native int GetDataId(int pIModelDataInstance);   
+       public native int GetPropertyCount(int pIModelDataInstance);
+       public native String GetPropertyName(int pIModelDataInstance, int propertyIndex);
+       public native String GetPropertyValue(int pIModelDataInstance, int propertyIndex);
+               
+       //IDataReader
+       public native List<String> GetAffectedModels(int pDataReaderInstance);
+       public native int GetModelDataCount(int pDataReaderInstance, String modelName);
+       public native ModelData GetModelData(int pDataReaderInstance, String modelName, int dataIndex);
+       
+       public native void RegisterReportReceiver(IReportReceiver reportReceiver);
+}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/DataReader.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/DataReader.java
new file mode 100644 (file)
index 0000000..c963a25
--- /dev/null
@@ -0,0 +1,28 @@
+package org.iotivity.service.ssm;
+
+import java.util.List;
+
+public class DataReader {
+
+       private int pDataReaderInstance;
+       
+       public DataReader(int dataReaderInstance)
+       {
+               pDataReaderInstance = dataReaderInstance;
+       }
+       
+       public List<String> GetAffectedModels()
+       {
+               return CoreController.getInstance().GetAffectedModels(pDataReaderInstance);
+       }
+       
+       public int GetModelDataCount(String modelName)
+       {
+               return CoreController.getInstance().GetModelDataCount(pDataReaderInstance, modelName);
+       }
+       
+       public ModelData GetModelData(String modelName, int dataIndex)
+       {
+               return CoreController.getInstance().GetModelData(pDataReaderInstance, modelName, dataIndex);
+       }
+}
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IQueryEngineEvent.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IQueryEngineEvent.java
new file mode 100644 (file)
index 0000000..3dd46bf
--- /dev/null
@@ -0,0 +1,5 @@
+package org.iotivity.service.ssm;
+
+public interface IQueryEngineEvent {
+       public void OnQueryEngineEvent(int cqid, DataReader result);
+}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IReportReceiver.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/IReportReceiver.java
new file mode 100644 (file)
index 0000000..9a8aec1
--- /dev/null
@@ -0,0 +1,5 @@
+package org.iotivity.service.ssm;
+
+public interface IReportReceiver {
+       public void OnMessageReceived(String tag, String msg);
+}
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/ModelData.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/ModelData.java
new file mode 100644 (file)
index 0000000..c43e1df
--- /dev/null
@@ -0,0 +1,31 @@
+package org.iotivity.service.ssm;
+
+public class ModelData {
+       
+       private int pIModelDataInstance;
+       
+       public ModelData(int iModelDataInstance)
+       {
+               pIModelDataInstance = iModelDataInstance;
+       }
+       
+       public int GetDataId()
+       {
+               return CoreController.getInstance().GetDataId(pIModelDataInstance);
+       }
+       
+       public int GetPropertyCount()
+       {
+               return CoreController.getInstance().GetPropertyCount(pIModelDataInstance);
+       }
+       
+       public String GetPropertyName(int propertyIndex)
+       {
+               return CoreController.getInstance().GetPropertyName(pIModelDataInstance, propertyIndex);
+       }
+       
+       public String GetPropertyValue(int propertyIndex)
+       {
+               return CoreController.getInstance().GetPropertyValue(pIModelDataInstance, propertyIndex);
+       }
+}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/QueryEngine.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/QueryEngine.java
new file mode 100644 (file)
index 0000000..a14e640
--- /dev/null
@@ -0,0 +1,31 @@
+package org.iotivity.service.ssm;
+
+public class QueryEngine
+{
+       private int pQueryEngineInstance;
+       
+       public QueryEngine(int queryEngineInstance)
+       {
+               pQueryEngineInstance = queryEngineInstance;
+       }
+       
+       public int GetQueryEngineInstance()
+       {
+               return pQueryEngineInstance;
+       }
+       
+       public int ExecuteContextQuery(String contextQuery)
+       {
+               return CoreController.getInstance().ExecuteContextQuery(pQueryEngineInstance, contextQuery);
+       }
+       
+       public void RegisterQueryEvent(IQueryEngineEvent queryEngineEvent)
+       {
+               CoreController.getInstance().RegisterQueryEvent(pQueryEngineInstance, queryEngineEvent);
+       }
+       
+       public void KillContextQuery(int cqid)
+       {
+               CoreController.getInstance().KillContextQuery(pQueryEngineInstance, cqid);
+       }
+}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/SSMInterface.java b/service/soft-sensor-manager/SDK/java/org/iotivity/service/ssm/SSMInterface.java
new file mode 100644 (file)
index 0000000..8169548
--- /dev/null
@@ -0,0 +1,99 @@
+package org.iotivity.service.ssm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class SSMInterface {
+       private class QueryEngineEventReceiver implements IQueryEngineEvent
+       {
+        private Lock                                                           mMtxListener = new ReentrantLock();
+               private Map<Integer, IQueryEngineEvent>         mMapListener = new HashMap<Integer, IQueryEngineEvent>();
+               
+               public void OnQueryEngineEvent(int cqid, DataReader result)
+               {
+                       mMtxListener.lock();
+
+                       mMapListener.get(cqid).OnQueryEngineEvent(cqid, result);
+            
+                       mMtxListener.unlock();
+               }
+               void lockListener()
+        {
+                       mMtxListener.lock();
+        }
+
+        void unlockListener()
+        {
+               mMtxListener.unlock();
+        }
+
+        void addListener(int cqid, IQueryEngineEvent engineEvent)
+        {
+               mMapListener.put(cqid, engineEvent);
+        }
+
+        void removeListener(int cqid)
+        {
+               mMapListener.remove(cqid);
+        }
+       };
+       
+       private CoreController                          mSSMCore = null;
+       private QueryEngine                                     mQueryEngine = null;
+       private QueryEngineEventReceiver        mQueryEngineEventListenerReceiver = new QueryEngineEventReceiver();
+       private List<Integer>                           mRunningCQLs = new ArrayList<Integer>();
+       
+       public SSMInterface()
+       {               
+       }
+       
+       public void startSSMCore(String initConfig) throws Exception
+       {
+               mSSMCore = CoreController.getInstance();
+        mSSMCore.InitializeSSMCore(initConfig);
+        mSSMCore.StartSSMCore();
+        
+        mQueryEngine = mSSMCore.CreateQueryEngine();
+        
+        if(mQueryEngine == null)
+               throw new Exception("Create Query Engine failed");
+        
+        mQueryEngine.RegisterQueryEvent(mQueryEngineEventListenerReceiver);
+       }
+       
+       public void stopSSMCore()
+       {
+               mQueryEngine.RegisterQueryEvent(null);
+               mSSMCore.ReleaseQueryEngine(mQueryEngine);
+               mQueryEngineEventListenerReceiver = null;
+               mQueryEngine = null;
+               mSSMCore.StopSSMCore();
+               mSSMCore.TerminateSSMCore();
+       }
+       
+       public int registerQuery(String contextQuery, IQueryEngineEvent listener)
+       {
+               int cqid;
+               
+               mQueryEngineEventListenerReceiver.lockListener();
+               cqid = mQueryEngine.ExecuteContextQuery(contextQuery);
+               mQueryEngineEventListenerReceiver.addListener(cqid, listener);
+               mRunningCQLs.add(cqid);
+               mQueryEngineEventListenerReceiver.unlockListener();
+               
+               return cqid;
+       }
+       
+       public void unregisterQuery(int cqid)
+       {
+               mQueryEngineEventListenerReceiver.lockListener();
+               mQueryEngine.KillContextQuery(cqid);
+               mQueryEngineEventListenerReceiver.removeListener(cqid);
+               mRunningCQLs.remove(cqid);
+               mQueryEngineEventListenerReceiver.unlockListener();
+       }
+}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SDK/src/SSMClient.cpp b/service/soft-sensor-manager/SDK/src/SSMClient.cpp
deleted file mode 100644 (file)
index 4f0b574..0000000
+++ /dev/null
@@ -1,284 +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 <iostream>
-#include <string>
-
-#include "SSMClient.h"
-#include "OCPlatform.h"
-#include "OCApi.h"
-
-const char *SSM_RESOURCE_URI = "/service/SoftSensorManager";
-
-#define SSM_RESOURCE_TYPE       = "core.SoftSensorManager"
-
-#define COAP_SERVER_ADDR        "coap://224.0.1.187/oc/core?rt=core.SoftSensorManager"
-
-SSMClient::SSMClient()
-{
-    m_sem.create(100000);
-    m_appListener = NULL;
-    m_retResponse = SSM_ERROR;
-    _findResource();
-    _createQueryEngine();
-}
-
-SSMClient::~SSMClient()
-{
-    _releaseQueryEngine(m_queryEngineId);
-}
-
-void SSMClient::_findResource()
-{
-    // Create PlatformConfig object
-    PlatformConfig cfg(OC::ServiceType::InProc, OC::ModeType::Both,
-                       "0.0.0.0", 0, OC::QualityOfService::LowQos);
-
-    // Create a OCPlatform instance.
-    // Note: Platform creation is synchronous call.
-    try
-    {
-        OCPlatform::Configure(cfg);
-
-        // Find all resources
-        OCStackResult result;
-        if ((result = OCPlatform::findResource("", COAP_SERVER_ADDR,
-                                               std::bind(&SSMClient::onFoundResource, this, std::placeholders::_1)))
-            != OC_STACK_OK)
-        {
-            std::cout << "Faile to Find Resource... " << std::endl;
-            return;
-        }
-        std::cout << "Find Resource... " << std::endl;
-
-        m_sem.wait();
-
-    }
-    catch (OCException e)
-    {
-        //log(e.what());
-    }
-}
-
-void SSMClient::_createQueryEngine(void)
-{
-    OCRepresentation rep;
-
-    QueryParamsMap queryParamsMap;
-
-    rep.setValue("command", std::string("CreateQueryEngine"));
-
-    if (m_SSMResource->put(rep, queryParamsMap,
-                           std::bind(&SSMClient::onCreateQueryEngine, this, std::placeholders::_1,
-                                     std::placeholders::_2, std::placeholders::_3)) != OC_STACK_OK)
-    {
-        return;
-    }
-
-    m_sem.wait();
-}
-
-void SSMClient::_releaseQueryEngine(std::string queryEngineId)
-{
-    OCRepresentation rep;
-
-    QueryParamsMap queryParamsMap;
-
-    rep.setValue("command", std::string("ReleaseQueryEngine"));
-    rep.setValue("queryEngineId", queryEngineId);
-
-    m_SSMResource->put(rep, queryParamsMap,
-                       std::bind(&SSMClient::onReleaseQueryEngine, this, std::placeholders::_1,
-                                 std::placeholders::_2, std::placeholders::_3));
-
-    m_sem.wait();
-}
-
-SSMReturn SSMClient::registerQuery(std::string queryString, ISSMClientListener *listener,
-                                   std::string &cqid)
-{
-    OCRepresentation rep;
-
-    QueryParamsMap queryParamsMap;
-
-
-    rep.setValue("command", std::string("ExecuteContextQuery"));
-    rep.setValue("queryEngineId", m_queryEngineId);
-    rep.setValue("contextQuery", queryString);
-
-    m_appListener = listener;
-
-    if (m_SSMResource->put(rep, queryParamsMap,
-                           std::bind(&SSMClient::onRegisterQuery, this, std::placeholders::_1,
-                                     std::placeholders::_2, std::placeholders::_3)) != OC_STACK_OK)
-        return SSM_ERROR_NETWORK;
-
-    m_sem.wait();
-
-    if (m_retResponse == SSM_SUCCESS)
-    {
-        cqid = m_responseAttributeMap["CQID"];
-    }
-
-    return m_retResponse;
-}
-
-SSMReturn SSMClient::unregisterQuery(std::string cqid)
-{
-    OCRepresentation rep;
-
-    QueryParamsMap queryParamsMap;
-
-    rep.setValue("command", std::string("KillContextQuery"));
-    rep.setValue("queryEngineId", m_queryEngineId);
-    rep.setValue("CQID", cqid);
-
-    if (m_SSMResource->put(rep, queryParamsMap,
-                           std::bind(&SSMClient::onUnregisterQuery, this, std::placeholders::_1,
-                                     std::placeholders::_2, std::placeholders::_3)) != OC_STACK_OK)
-        return SSM_ERROR_NETWORK;
-
-    m_sem.wait();
-
-    return m_retResponse;
-}
-
-/**
- * Callback Function List.
- */
-// Callback to found resources
-void SSMClient::onFoundResource(std::shared_ptr< OCResource > resource)
-{
-    std::string resourceURI;
-    try
-    {
-        // Do some operations with resource object.
-        if (resource)
-        {
-            // Get the resource URI
-            resourceURI = resource->uri();
-
-            if (resourceURI.compare(SSM_RESOURCE_URI) == 0)
-            {
-                m_SSMResource = resource;
-            }
-        }
-    }
-    catch (std::exception &e)
-    {
-        //log(e.what());
-    }
-
-    m_sem.release();
-}
-
-void SSMClient::onCreateQueryEngine(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                                    const int eCode)
-{
-    if (eCode != 0)
-    {
-        m_retResponse = SSM_ERROR_NETWORK;
-        goto CLEANUP;
-    }
-
-    m_queryEngineId = rep.getValue<std::string>("queryEngineId");
-    m_retResponse = SSM_SUCCESS;
-
-CLEANUP: m_sem.release();
-}
-
-void SSMClient::onRegisterQuery(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                                const int eCode)
-{
-    QueryParamsMap queryParamsMap;
-
-    if (eCode != 0)
-    {
-        m_retResponse = SSM_ERROR_NETWORK;
-        goto CLEANUP;
-    }
-
-    m_responseAttributeMap = rep.getAttributeMap();
-
-    if (m_responseAttributeMap.find("error") != m_responseAttributeMap.end())
-    {
-        m_retResponse = SSM_ERROR_QUERY_PARSING;
-        goto CLEANUP;
-    }
-
-    m_SSMResource->observe(ObserveType::Observe, queryParamsMap,
-                           std::bind(&SSMClient::onObserve, this, std::placeholders::_1,
-                                     std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
-
-    m_retResponse = SSM_SUCCESS;
-
-CLEANUP: m_sem.release();
-}
-
-void SSMClient::onUnregisterQuery(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                                  const int eCode)
-{
-    if (eCode != 0)
-    {
-        m_retResponse = SSM_ERROR_NETWORK;
-        goto CLEANUP;
-    }
-
-    m_responseAttributeMap = rep.getAttributeMap();
-
-    if (m_responseAttributeMap.find("error") != m_responseAttributeMap.end())
-    {
-        m_retResponse = SSM_ERROR_NO_QUERY;
-        goto CLEANUP;
-    }
-
-    m_retResponse = SSM_SUCCESS;
-
-CLEANUP: m_sem.release();
-}
-
-void SSMClient::onReleaseQueryEngine(const HeaderOptions &headerOptions,
-                                     const OCRepresentation &rep, const int eCode)
-{
-    if (eCode != 0)
-    {
-        m_retResponse = SSM_ERROR_NETWORK;
-        goto CLEANUP;
-    }
-
-    m_responseAttributeMap = rep.getAttributeMap();
-
-    m_retResponse = SSM_SUCCESS;
-
-CLEANUP: m_sem.release();
-}
-
-void SSMClient::onObserve(const HeaderOptions &headerOptions, const OCRepresentation &rep,
-                          const int &eCode, const int &sequenceNumber)
-{
-    SSMReturn ret = SSM_SUCCESS;
-
-    if (eCode != 0)
-    {
-        ret = SSM_ERROR_NETWORK;
-    }
-
-    m_appListener->onRegisterQuery(rep.getAttributeMap(), ret);
-}
index f6a3f19..01d6453 100644 (file)
@@ -69,6 +69,7 @@ ${TARGET}: ${GCC_OBJLIST} ${CXX_OBJLIST}
 
 post_job:
        @echo " " 
+       cp -Rdp ${INC_PATH}/SSMInterface.h ${FD_SDK}/include/
        cp -Rdp ./${RST_NAME}/${TARGET} ${OUTPUTS_DIR}/
        cp -Rdp ${INC_PATH}/SSMInterface.h ${OUTPUTS_DIR}/
        cp -Rdp ${SRC_PATH}/SSMInterface/SSMModelDefinition.h ${OUTPUTS_DIR}/
index b126130..0085b3b 100644 (file)
 #include <string>
 #include <vector>
 
-enum SSMRESULT
+namespace OIC
 {
-    SSM_S_OK
-    , SSM_S_FALSE
-    , SSM_E_POINTER
-    , SSM_E_OUTOFMEMORY
-    , SSM_E_FAIL
-    , SSM_E_NOINTERFACE
-    , SSM_E_NOTIMPL
-};
+    enum SSMRESULT
+    {
+        SSM_S_OK
+        , SSM_S_FALSE
+        , SSM_E_POINTER
+        , SSM_E_OUTOFMEMORY
+        , SSM_E_FAIL
+        , SSM_E_NOINTERFACE
+        , SSM_E_NOTIMPL
+    };
 
-/**
-* @class    IModelData
-* @brief    IModelData Interface
-*            This class represents context model data package
-*
-* @see
-*/
-class IModelData
-{
-    public:
-        /**
-        * @fn     getDataId
-        * @brief Get affected DataId. ContextModel has plenty of data so \n
-        *         returned data is matched from given condition
-        *
-        * @param None
-        *
-        * @return int
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual int getDataId() = 0;
+    /**
+    * @class    IModelData
+    * @brief    This class represents context model data package
+    *
+    * @see
+    */
+    class IModelData
+    {
+        public:
+            /**
+            * @fn     getDataId
+            * @brief Get affected DataId. ContextModel has plenty of data so \n
+            *         returned data is matched from given condition
+            *
+            * @param None
+            *
+            * @return int
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual int getDataId() = 0;
 
-        /**
-        * @fn     GetPropertyCount
-        * @brief ContextModel has at least one property that contains data \n
-        *         property is described from its specification.
-        *
-        * @param None
-        *
-        * @return int
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual int getPropertyCount() = 0;
+            /**
+            * @fn     GetPropertyCount
+            * @brief ContextModel has at least one property that contains data \n
+            *         property is described from its specification.
+            *
+            * @param None
+            *
+            * @return int
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual int getPropertyCount() = 0;
 
-        /**
-        * @fn     getPropertyName
-        * @brief Retrieve propertyName
-        *
-        * @param [in] int propertyIndex - index of property to read
-        *
-        * @return std::string
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual std::string getPropertyName(int propertyIndex) = 0;
+            /**
+            * @fn     getPropertyName
+            * @brief Retrieve propertyName
+            *
+            * @param [in] int propertyIndex - index of property to read
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyName(int propertyIndex) = 0;
 
-        /**
-        * @fn     getPropertyValue
-        * @brief Retrieve propertyValue
-        *
-        * @param [in] int propertyIndex - index of property to read
-        *
-        * @return std::string
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual std::string getPropertyValue(int propertyIndex) = 0;
+            /**
+            * @fn     getPropertyValue
+            * @brief Retrieve propertyValue
+            *
+            * @param [in] int propertyIndex - index of property to read
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyValue(int propertyIndex) = 0;
 
-        /**
-        * @fn     getPropertyValueByName
-        * @brief Retrieve propertyValue using given name
-        *
-        * @param [in] std::string propertyName - property name looking for
-        *
-        * @return std::string
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual std::string getPropertyValueByName(std::string propertyName) = 0;
-    protected:
-        virtual ~IModelData() {};
-};
+            /**
+            * @fn     getPropertyValueByName
+            * @brief Retrieve propertyValue using given name
+            *
+            * @param [in] std::string propertyName - property name looking for
+            *
+            * @return std::string
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual std::string getPropertyValueByName(std::string propertyName) = 0;
+        protected:
+            virtual ~IModelData() {};
+    };
 
-/**
-* @class    IDataReader
-* @brief    IDataReader Interface
-*            This class represents context model data package's reader
-*
-* @see
-*/
-class IDataReader
-{
-    public:
-        /**
-        * @fn     getAffectedModels
-        * @brief Get affected ContextModels. The CQL can specify multiple ContextModels for retrieving data.
-        *
-        * @param [out] std::vector<std::string> *pAffectedModels - affected ContextModel list
-        *
-        * @return SSMRESULT
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual SSMRESULT getAffectedModels(std::vector<std::string> *pAffectedModels) = 0;
+    /**
+    * @class    IDataReader
+    * @brief    This class represents context model data package's reader
+    *
+    * @see
+    */
+    class IDataReader
+    {
+        public:
+            /**
+            * @fn     getAffectedModels
+            * @brief Get affected ContextModels. The CQL can specify multiple ContextModels for retrieving data.
+            *
+            * @param [in, out] std::vector<std::string> *pAffectedModels - affected ContextModel list
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getAffectedModels(std::vector<std::string> *pAffectedModels) = 0;
 
-        /**
-        * @fn     getModelDataCount
-        * @brief Get affected data count. There are multiple data can exist from given condition.
-        *
-        * @param [in] std::string modelName - affected ContextModel name
-        *
-        * @param [out] int *pDataCount - affected dataId count
-        *
-        * @return SSMRESULT
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual SSMRESULT getModelDataCount(std::string modelName, int *pDataCount) = 0;
+            /**
+            * @fn     getModelDataCount
+            * @brief Get affected data count. There are multiple data can exist from given condition.
+            *
+            * @param [in] std::string modelName - affected ContextModel name
+            *
+            * @param [in, out] int *pDataCount - affected dataId count
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getModelDataCount(std::string modelName, int *pDataCount) = 0;
 
-        /**
-        * @fn     getModelData
-        * @brief Get actual Context Model data
-        *
-        * @param [in] std::string modelName - affected ContextModel name
-        *
-        *
-        * @param [in] int dataIndex - affected dataId index
-        *
-        *
-        * @param [out] IModelData **ppModelData - affected ContextModel data reader
-        *
-        * @return SSMRESULT
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual SSMRESULT getModelData(std::string modelName, int dataIndex, IModelData **ppModelData) = 0;
-    protected:
-        virtual ~IDataReader() {};
-};
+            /**
+            * @fn     getModelData
+            * @brief Get actual Context Model data
+            *
+            * @param [in] std::string modelName - affected ContextModel name
+            *
+            *
+            * @param [in] int dataIndex - affected dataId index
+            *
+            *
+            * @param [out] IModelData **ppModelData - affected ContextModel data reader
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT getModelData(std::string modelName, int dataIndex, IModelData **ppModelData) = 0;
+        protected:
+            virtual ~IDataReader() {};
+    };
 
-/**
-* @class    IQueryEngineEvent
-* @brief    IQueryEngineEvent Interface
-*            This class represents Query Engine's event that contains results
-*
-* @see
-*/
-class IQueryEngineEvent
-{
-    public:
-        /**
-        * @fn     onQueryEngineEvent
-        * @brief Transmit result of SSMCore to Application layer
-        *
-        * @param [in] int cqid - entered ContextQuery ID
-        *
-        * @param [in] IDataReader *pResult - result of SSMCore
-        *
-        * @return SSMRESULT
-        * @warning
-        * @exception
-        * @see
-        */
-        virtual SSMRESULT onQueryEngineEvent(int cqid, IDataReader *pResult) = 0;
-    protected:
-        virtual ~IQueryEngineEvent() {};
-};
+    /**
+    * @class    IQueryEngineEvent
+    * @brief    This class represents Query Engine's event that contains results
+    *
+    * @see
+    */
+    class IQueryEngineEvent
+    {
+        public:
+            /**
+            * @fn     onQueryEngineEvent
+            * @brief Transmit result of SSMCore to Application layer
+            *
+            * @param [in] int cqid - entered ContextQuery ID
+            *
+            * @param [in] IDataReader *pResult - result of SSMCore
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            virtual SSMRESULT onQueryEngineEvent(int cqid, IDataReader *pResult) = 0;
+        protected:
+            virtual ~IQueryEngineEvent() {};
+    };
 
-class SSMInterface
-{
-    public:
-        SSMInterface();
-        ~SSMInterface();
+    /**
+    * @class    SSMInterface
+    * @brief    This class represents main class for querying Soft Sensors
+    *
+    * @see
+    */
+    class SSMInterface
+    {
+        public:
+            SSMInterface();
+            ~SSMInterface();
+
+            /**
+            * @fn     registerQuery
+            * @brief Execute ContextQuery and return ContextQuery ID
+            *
+            * @param [in] std::string queryString - query for requesting data
+            *
+            * @param [in] IQueryEngineEvent listener - listener for receiving data related to query
+            *
+            * @param [in, out] int &cqid - ID of ContextQuery
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            SSMRESULT registerQuery(std::string queryString, IQueryEngineEvent *listener, int &cqid);
+
+            /**
+            * @fn    unregisterQuery
+            * @brief unregister registered ContextQuery according to cqid
+            *
+            * @param [in] int cqid - Context query corresponding to the cqid will be terminated
+            *
+            * @return SSMRESULT
+            * @warning
+            * @exception
+            * @see
+            */
+            SSMRESULT unregisterQuery(int cqid);
+    };
 
-        SSMRESULT registerQuery(std::string queryString, IQueryEngineEvent *listener, int &cqid);
-        SSMRESULT unregisterQuery(int cqid);
-};
+}
 #endif
\ No newline at end of file
index b2517e7..373734e 100644 (file)
@@ -56,11 +56,17 @@ const OID OID_IBase = {0x3b465976, 0x6486, 0x4c1f, {0x84, 0xb9, 0xeb, 0x80, 0x79
 */
 inline int IsEqualOID(const OID &oid1, const OID &oid2)
 {
-    return (
-               ((unsigned long *) &oid1)[0] == ((unsigned long *) &oid2)[0] &&
-               ((unsigned long *) &oid1)[1] == ((unsigned long *) &oid2)[1] &&
-               ((unsigned long *) &oid1)[2] == ((unsigned long *) &oid2)[2] &&
-               ((unsigned long *) &oid1)[3] == ((unsigned long *) &oid2)[3]);
+    return (( oid1.data1 ==  oid2.data1) &&
+            ( oid1.data2 ==  oid2.data2) &&
+            ( oid1.data3 ==  oid2.data3) &&
+            ( oid1.data4[0] ==  oid2.data4[0]) &&
+            ( oid1.data4[1] ==  oid2.data4[1]) &&
+            ( oid1.data4[2] ==  oid2.data4[2]) &&
+            ( oid1.data4[3] ==  oid2.data4[3]) &&
+            ( oid1.data4[4] ==  oid2.data4[4]) &&
+            ( oid1.data4[5] ==  oid2.data4[5]) &&
+            ( oid1.data4[6] ==  oid2.data4[6]) &&
+            ( oid1.data4[7] ==  oid2.data4[7]));
 }
 
 /**
index 531e1be..5e458e0 100644 (file)
 #include <map>
 #include <fstream>
 
-#define LOCATION_SSM_DB ":memory:"
-#define RAPIDXML_STATIC_POOL_SIZE 4*1024
-
 #if defined(WIN32)
+
 #include <Windows.h>
 #include <Shlwapi.h>
-
 #pragma comment(lib, "Shlwapi.lib")
 #pragma comment(lib, "../Outputs/sqlite3.lib")
 
 #elif defined(LINUX)
+
 #include <stdio.h>
 #include <errno.h>
 #include <sys/time.h>
 #include <dlfcn.h>
 #include <semaphore.h>
 
-#elif defined(ANDROID)
+#if defined(ANDROID)
+
 #include <android/log.h>
 
 #elif defined(TIZEN)
-#include <FBase.h>
 
 #endif
 
-#define DEFAULT_PATH_SOFT_SENSORS "SoftSensorDescription.xml"
+#endif
 
-//#define LOCATION_SSM_DB_DUMP "myBackup.db"
+
+#define LOCATION_SSM_DB ":memory:"
+#define RAPIDXML_STATIC_POOL_SIZE 4*1024
+#define DEFAULT_PATH_SOFT_SENSORS "SoftSensorDescription.xml"
 #define LOCATION_SSM_DB_DUMP ""
+//#define LOCATION_SSM_DB_DUMP "myBackup.db"
 
-#if defined(WIN32) || defined(LINUX)
 
-#define REPORT_MESSAGE(tag, msg) {printf("[%s] %s\n", tag, msg);}
+#if defined(WIN32)
 
-#define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
-    { \
-    if(!(Exp)) \
-        { \
-        printf("[SSM] %s:%d Return message: %s\n", __FUNCTION__, __LINE__, STRErrorMsg); \
-        assert(0); \
-        return; \
-        } \
-    }
+#define PRINT_LOG(strError) printf("[SSM] %s:%d %s\n", __FUNCTION__, __LINE__, strError)
+#define REPORT_MESSAGE(tag, msg) printf("[%s] %s\n", tag, msg)
 
-#define SSM_RESULT_ASSERT(Exp, STRErrorMsg, Result) \
-    { \
-    if(!(Exp)) \
-        { \
-        printf("[SSM] %s:%d Return message: %s\n", __FUNCTION__, __LINE__, STRErrorMsg); \
-        assert(0); \
-        return Result; \
-        } \
-    }
+#elif defined(LINUX)
 
-#define SSM_CLEANUP_ASSERT(Exp) \
-    { \
-    if((res = (Exp)) != SSM_S_OK) \
-        { \
-        printf("[SSM] %s:%d Return message: %s\n", __FUNCTION__, __LINE__, GetSSMError(res)); \
-        assert(0); \
-        goto CLEANUP; \
-        } \
-    }
+#if defined(ANDROID)
 
-#define SSM_CLEANUP_COND_ASSERT(Exp, Cond, STRErrorMsg) \
-    { \
-    if(Exp != Cond) \
-        { \
-        printf("[SSM] %s:%d Return message: %s\n", __FUNCTION__, __LINE__, STRErrorMsg); \
-        assert(0); \
-        goto CLEANUP; \
-        } \
-    }
+void ReportMessage(const char *tag, const char *msg);
+#define REPORT_MESSAGE(tag, msg) ReportMessage(tag, msg)
+#define PRINT_LOG(strError) __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d %s", __PRETTY_FUNCTION__, __LINE__, strError)
 
-#define SSM_CLEANUP_NULL_ASSERT(Val) \
-    { \
-    if(!(Val)) \
-        { \
-        printf("[SSM] %s:%d Return message: NULL value\n", __FUNCTION__, __LINE__); \
-        assert(Val); \
-        goto CLEANUP; \
-        } \
-    }
+#elif defined(TIZEN)
 
-#elif defined(ANDROID)
+#define REPORT_MESSAGE(tag, msg) printf("[%s] %s\n", tag, msg)
+#define PRINT_LOG(strError) printf("[SSM] %s:%d %s\n", __FUNCTION__, __LINE__, strError)
 
-void ReportMessage(const char *tag, const char *msg);
-#define REPORT_MESSAGE(tag, msg) {ReportMessage(tag, msg);}
+#else //Default linux
 
-#define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
-    { \
-        if(!(Exp)) \
-        { \
-            __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d Return message: %s", __PRETTY_FUNCTION__, __LINE__, STRErrorMsg); \
-            assert(0); \
-            return; \
-        } \
-    }
+#define REPORT_MESSAGE(tag, msg) printf("[%s] %s\n", tag, msg)
+#define PRINT_LOG(strError) printf("[SSM] %s:%d %s\n", __FUNCTION__, __LINE__, strError)
 
-#define SSM_RESULT_ASSERT(Exp, STRErrorMsg, Result) \
-    { \
-        if(!(Exp)) \
-        { \
-            __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d Return message: %s", __PRETTY_FUNCTION__, __LINE__, STRErrorMsg); \
-            assert(0); \
-            return Result; \
-        } \
-    }
-
-#define SSM_CLEANUP_ASSERT(Exp) \
-    { \
-        if((res = (Exp)) != SSM_S_OK) \
-        { \
-            __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d Return message: %s", __PRETTY_FUNCTION__, __LINE__, GetSSMError(res)); \
-            assert(0); \
-            goto CLEANUP; \
-        } \
-    }
+#endif
 
-#define SSM_CLEANUP_COND_ASSERT(Exp, Cond, STRErrorMsg) \
-    { \
-        if(Exp != Cond) \
-        { \
-            __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d Return message: %s", __PRETTY_FUNCTION__, __LINE__, STRErrorMsg); \
-            assert(0); \
-            goto CLEANUP; \
-        } \
-    }
+#endif
 
-#define SSM_CLEANUP_NULL_ASSERT(Val) \
-    { \
-        if(!(Val)) \
-        { \
-            __android_log_print(ANDROID_LOG_ERROR, "[SSM]", "%s:%d Return message: NULL value", __PRETTY_FUNCTION__, __LINE__); \
-            assert(Val); \
-            goto CLEANUP; \
-        } \
-    }
 
-#elif defined(TIZEN)
-#define REPORT_MESSAGE(tag, msg)
 
 #define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
     { \
     if(!(Exp)) \
         { \
-        AppLog("%s", STRErrorMsg); \
+        PRINT_LOG(STRErrorMsg); \
         assert(0); \
         return; \
         } \
@@ -172,7 +92,7 @@ void ReportMessage(const char *tag, const char *msg);
     { \
     if(!(Exp)) \
         { \
-        AppLog("%s", STRErrorMsg); \
+        PRINT_LOG(STRErrorMsg); \
         assert(0); \
         return Result; \
         } \
@@ -182,7 +102,7 @@ void ReportMessage(const char *tag, const char *msg);
     { \
     if((res = (Exp)) != SSM_S_OK) \
         { \
-        AppLog("%s", GetSSMError(res)); \
+        PRINT_LOG(GetSSMError(res)); \
         assert(0); \
         goto CLEANUP; \
         } \
@@ -192,7 +112,7 @@ void ReportMessage(const char *tag, const char *msg);
     { \
     if(Exp != Cond) \
         { \
-        AppLog("%s", STRErrorMsg); \
+        PRINT_LOG(STRErrorMsg); \
         assert(0); \
         goto CLEANUP; \
         } \
@@ -202,14 +122,12 @@ void ReportMessage(const char *tag, const char *msg);
     { \
     if(!(Val)) \
         { \
-        AppLog("NULL value"); \
+        PRINT_LOG("NULL value"); \
         assert(Val); \
         goto CLEANUP; \
         } \
     }
 
-#endif
-
 #define CLEAN_STACKVARIABLE(val) memset(&val, 0, sizeof(val))
 #define SAFE_RELEASE(p) {if(p != NULL){p->release();p = NULL;}else{;/*NULL*/}}
 #define SAFE_DELETE(p) {if(p != NULL){delete p;p = NULL;}else{;/*NULL*/}}
index e398838..d697b68 100644 (file)
@@ -135,8 +135,8 @@ extern "C" {
 ** function is provided for use in DLLs since DLL users usually do not have
 ** direct access to string constants within the DLL.  ^The
 ** sqlite3_libversion_number() function returns an integer equal to
-** [SQLITE_VERSION_NUMBER].  ^The sqlite3_sourceid() function returns 
-** a pointer to a string constant whose value is the same as the 
+** [SQLITE_VERSION_NUMBER].  ^The sqlite3_sourceid() function returns
+** a pointer to a string constant whose value is the same as the
 ** [SQLITE_SOURCE_ID] C preprocessor macro.
 **
 ** See also: [sqlite_version()] and [sqlite_source_id()].
@@ -149,20 +149,20 @@ SQLITE_API int sqlite3_libversion_number(void);
 /*
 ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
 **
-** ^The sqlite3_compileoption_used() function returns 0 or 1 
-** indicating whether the specified option was defined at 
-** compile time.  ^The SQLITE_ prefix may be omitted from the 
-** option name passed to sqlite3_compileoption_used().  
+** ^The sqlite3_compileoption_used() function returns 0 or 1
+** indicating whether the specified option was defined at
+** compile time.  ^The SQLITE_ prefix may be omitted from the
+** option name passed to sqlite3_compileoption_used().
 **
 ** ^The sqlite3_compileoption_get() function allows iterating
 ** over the list of options that were defined at compile time by
 ** returning the N-th compile time option string.  ^If N is out of range,
-** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_ 
-** prefix is omitted from any strings returned by 
+** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_
+** prefix is omitted from any strings returned by
 ** sqlite3_compileoption_get().
 **
 ** ^Support for the diagnostic functions sqlite3_compileoption_used()
-** and sqlite3_compileoption_get() may be omitted by specifying the 
+** and sqlite3_compileoption_get() may be omitted by specifying the
 ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
 **
 ** See also: SQL functions [sqlite_compileoption_used()] and
@@ -183,7 +183,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
 ** SQLite can be compiled with or without mutexes.  When
 ** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
 ** are enabled and SQLite is threadsafe.  When the
-** [SQLITE_THREADSAFE] macro is 0, 
+** [SQLITE_THREADSAFE] macro is 0,
 ** the mutexes are omitted.  Without the mutexes, it is not safe
 ** to use SQLite concurrently from more than one thread.
 **
@@ -240,18 +240,18 @@ typedef struct sqlite3 sqlite3;
 **
 ** ^The sqlite3_int64 and sqlite_int64 types can store integer values
 ** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
-** sqlite3_uint64 and sqlite_uint64 types can store integer values 
+** sqlite3_uint64 and sqlite_uint64 types can store integer values
 ** between 0 and +18446744073709551615 inclusive.
 */
 #ifdef SQLITE_INT64_TYPE
-  typedef SQLITE_INT64_TYPE sqlite_int64;
-  typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+typedef SQLITE_INT64_TYPE sqlite_int64;
+typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
 #elif defined(_MSC_VER) || defined(__BORLANDC__)
-  typedef __int64 sqlite_int64;
-  typedef unsigned __int64 sqlite_uint64;
+typedef __int64 sqlite_int64;
+typedef unsigned __int64 sqlite_uint64;
 #else
-  typedef long long int sqlite_int64;
-  typedef unsigned long long int sqlite_uint64;
+typedef long long int sqlite_int64;
+typedef unsigned long long int sqlite_uint64;
 #endif
 typedef sqlite_int64 sqlite3_int64;
 typedef sqlite_uint64 sqlite3_uint64;
@@ -285,7 +285,7 @@ typedef sqlite_uint64 sqlite3_uint64;
 ** destructors are called is arbitrary.
 **
 ** Applications should [sqlite3_finalize | finalize] all [prepared statements],
-** [sqlite3_blob_close | close] all [BLOB handles], and 
+** [sqlite3_blob_close | close] all [BLOB handles], and
 ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
 ** with the [sqlite3] object prior to attempting to close the object.  ^If
 ** sqlite3_close_v2() is called on a [database connection] that still has
@@ -305,15 +305,15 @@ typedef sqlite_uint64 sqlite3_uint64;
 ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
 ** argument is a harmless no-op.
 */
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3 *);
+SQLITE_API int sqlite3_close_v2(sqlite3 *);
 
 /*
 ** The type for a callback function.
 ** This is legacy and deprecated.  It is included for historical
 ** compatibility and is not documented.
 */
-typedef int (*sqlite3_callback)(void*,int,char**, char**);
+typedef int (*sqlite3_callback)(void *, int, char **, char **);
 
 /*
 ** CAPI3REF: One-Step Query Execution Interface
@@ -321,7 +321,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 ** The sqlite3_exec() interface is a convenience wrapper around
 ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
 ** that allows an application to run multiple statements of SQL
-** without having to use a lot of C code. 
+** without having to use a lot of C code.
 **
 ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
 ** semicolon-separate SQL statements passed into its 2nd argument,
@@ -361,7 +361,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 ** from [sqlite3_column_name()].
 **
 ** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
-** to an empty string, or a pointer that contains only whitespace and/or 
+** to an empty string, or a pointer that contains only whitespace and/or
 ** SQL comments, then no SQL statements are evaluated and the database
 ** is not changed.
 **
@@ -377,11 +377,11 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 ** </ul>
 */
 SQLITE_API int sqlite3_exec(
-  sqlite3*,                                  /* An open database */
-  const char *sql,                           /* SQL to be evaluated */
-  int (*callback)(void*,int,char**,char**),  /* Callback function */
-  void *,                                    /* 1st argument to callback */
-  char **errmsg                              /* Error msg written here */
+    sqlite3 *,                                 /* An open database */
+    const char *sql,                           /* SQL to be evaluated */
+    int (*callback)(void *, int, char **, char **), /* Callback function */
+    void *,                                    /* 1st argument to callback */
+    char **errmsg                              /* Error msg written here */
 );
 
 /*
@@ -614,7 +614,7 @@ SQLITE_API int sqlite3_exec(
 /*
 ** CAPI3REF: OS Interface Open File Handle
 **
-** An [sqlite3_file] object represents an open file in the 
+** An [sqlite3_file] object represents an open file in the
 ** [sqlite3_vfs | OS interface layer].  Individual OS interface
 ** implementations will
 ** want to subclass this object by appending additional fields
@@ -623,8 +623,9 @@ SQLITE_API int sqlite3_exec(
 ** I/O operations on the open file.
 */
 typedef struct sqlite3_file sqlite3_file;
-struct sqlite3_file {
-  const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
+struct sqlite3_file
+{
+    const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
 };
 
 /*
@@ -636,7 +637,7 @@ struct sqlite3_file {
 ** This object defines the methods used to perform various operations
 ** against the open file represented by the [sqlite3_file] object.
 **
-** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element 
+** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element
 ** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
 ** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed.  The
 ** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
@@ -718,30 +719,31 @@ struct sqlite3_file {
 ** database corruption.
 */
 typedef struct sqlite3_io_methods sqlite3_io_methods;
-struct sqlite3_io_methods {
-  int iVersion;
-  int (*xClose)(sqlite3_file*);
-  int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
-  int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
-  int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
-  int (*xSync)(sqlite3_file*, int flags);
-  int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
-  int (*xLock)(sqlite3_file*, int);
-  int (*xUnlock)(sqlite3_file*, int);
-  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
-  int (*xFileControl)(sqlite3_file*, int op, void *pArg);
-  int (*xSectorSize)(sqlite3_file*);
-  int (*xDeviceCharacteristics)(sqlite3_file*);
-  /* Methods above are valid for version 1 */
-  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
-  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
-  void (*xShmBarrier)(sqlite3_file*);
-  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
-  /* Methods above are valid for version 2 */
-  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
-  int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
-  /* Methods above are valid for version 3 */
-  /* Additional methods may be added in future releases */
+struct sqlite3_io_methods
+{
+    int iVersion;
+    int (*xClose)(sqlite3_file *);
+    int (*xRead)(sqlite3_file *, void *, int iAmt, sqlite3_int64 iOfst);
+    int (*xWrite)(sqlite3_file *, const void *, int iAmt, sqlite3_int64 iOfst);
+    int (*xTruncate)(sqlite3_file *, sqlite3_int64 size);
+    int (*xSync)(sqlite3_file *, int flags);
+    int (*xFileSize)(sqlite3_file *, sqlite3_int64 *pSize);
+    int (*xLock)(sqlite3_file *, int);
+    int (*xUnlock)(sqlite3_file *, int);
+    int (*xCheckReservedLock)(sqlite3_file *, int *pResOut);
+    int (*xFileControl)(sqlite3_file *, int op, void *pArg);
+    int (*xSectorSize)(sqlite3_file *);
+    int (*xDeviceCharacteristics)(sqlite3_file *);
+    /* Methods above are valid for version 1 */
+    int (*xShmMap)(sqlite3_file *, int iPg, int pgsz, int, void volatile **);
+    int (*xShmLock)(sqlite3_file *, int offset, int n, int flags);
+    void (*xShmBarrier)(sqlite3_file *);
+    int (*xShmUnmap)(sqlite3_file *, int deleteFlag);
+    /* Methods above are valid for version 2 */
+    int (*xFetch)(sqlite3_file *, sqlite3_int64 iOfst, int iAmt, void **pp);
+    int (*xUnfetch)(sqlite3_file *, sqlite3_int64 iOfst, void *p);
+    /* Methods above are valid for version 3 */
+    /* Additional methods may be added in future releases */
 };
 
 /*
@@ -770,7 +772,7 @@ struct sqlite3_io_methods {
 ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
 ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
 ** extends and truncates the database file in chunks of a size specified
-** by the user. The fourth argument to [sqlite3_file_control()] should 
+** by the user. The fourth argument to [sqlite3_file_control()] should
 ** point to an integer (type int) containing the new chunk-size to use
 ** for the nominated database. Allocating database file space in large
 ** chunks (say 1MB at a time), may reduce file-system fragmentation and
@@ -787,11 +789,11 @@ struct sqlite3_io_methods {
 ** SQLite and sent to all VFSes in place of a call to the xSync method
 ** when the database connection has [PRAGMA synchronous] set to OFF.)^
 ** Some specialized VFSes need this signal in order to operate correctly
-** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
+** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
 ** VFSes do not need this signal and should silently ignore this opcode.
 ** Applications should not call [sqlite3_file_control()] with this
 ** opcode as doing so may disrupt the operation of the specialized VFSes
-** that do require it.  
+** that do require it.
 **
 ** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
@@ -838,13 +840,13 @@ struct sqlite3_io_methods {
 ** <li>[[SQLITE_FCNTL_OVERWRITE]]
 ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
 ** a write transaction to indicate that, unless it is rolled back for some
-** reason, the entire database file will be overwritten by the current 
+** reason, the entire database file will be overwritten by the current
 ** transaction. This is used by VACUUM operations.
 **
 ** <li>[[SQLITE_FCNTL_VFSNAME]]
 ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
 ** all [VFSes] in the VFS stack.  The names are of all VFS shims and the
-** final bottom-level VFS are written into memory obtained from 
+** final bottom-level VFS are written into memory obtained from
 ** [sqlite3_malloc()] and the result is stored in the char* variable
 ** that the fourth parameter of [sqlite3_file_control()] points to.
 ** The caller is responsible for freeing the memory when done.  As with
@@ -854,7 +856,7 @@ struct sqlite3_io_methods {
 ** is intended for diagnostic use only.
 **
 ** <li>[[SQLITE_FCNTL_PRAGMA]]
-** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] 
+** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
 ** file control is sent to the open [sqlite3_file] object corresponding
 ** to the database file to which the pragma statement refers. ^The argument
 ** to the [SQLITE_FCNTL_PRAGMA] file control is an array of
@@ -865,7 +867,7 @@ struct sqlite3_io_methods {
 ** of the char** argument point to a string obtained from [sqlite3_mprintf()]
 ** or the equivalent and that string will become the result of the pragma or
 ** the error message if the pragma fails. ^If the
-** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal 
+** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal
 ** [PRAGMA] processing continues.  ^If the [SQLITE_FCNTL_PRAGMA]
 ** file control returns [SQLITE_OK], then the parser assumes that the
 ** VFS has handled the PRAGMA itself and the parser generates a no-op
@@ -903,7 +905,7 @@ struct sqlite3_io_methods {
 ** The argument is a pointer to a value of type sqlite3_int64 that
 ** is an advisory maximum number of bytes in the file to memory map.  The
 ** pointer is overwritten with the old value.  The limit is not changed if
-** the value originally pointed to is negative, and so the current limit 
+** the value originally pointed to is negative, and so the current limit
 ** can be queried by passing in a pointer to a negative number.  This
 ** file-control is used internally to implement [PRAGMA mmap_size].
 **
@@ -987,14 +989,14 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** the [sqlite3_file] can safely store a pointer to the
 ** filename if it needs to remember the filename for some reason.
 ** If the zFilename parameter to xOpen is a NULL pointer then xOpen
-** must invent its own temporary name for the file.  ^Whenever the 
+** must invent its own temporary name for the file.  ^Whenever the
 ** xFilename parameter is NULL it will also be the case that the
 ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
 **
 ** The flags argument to xOpen() includes all bits set in
 ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
 ** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. 
+** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
 ** If xOpen() opens a file read-only then it sets *pOutFlags to
 ** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
 **
@@ -1036,10 +1038,10 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
 ** with the [SQLITE_OPEN_CREATE] flag, which are both directly
 ** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
-** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
+** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
 ** SQLITE_OPEN_CREATE, is used to indicate that file should always
 ** be created, and that it is an error if it already exists.
-** It is <i>not</i> used to indicate the file should be opened 
+** It is <i>not</i> used to indicate the file should be opened
 ** for exclusive access.
 **
 ** ^At least szOsFile bytes of memory are allocated by SQLite
@@ -1077,16 +1079,16 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** method returns a Julian Day Number for the current date and time as
 ** a floating point value.
 ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
-** Day Number multiplied by 86400000 (the number of milliseconds in 
-** a 24-hour day).  
+** Day Number multiplied by 86400000 (the number of milliseconds in
+** a 24-hour day).
 ** ^SQLite will use the xCurrentTimeInt64() method to get the current
-** date and time if that method is available (if iVersion is 2 or 
+** date and time if that method is available (if iVersion is 2 or
 ** greater and the function pointer is not NULL) and will fall back
 ** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
 **
 ** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
 ** are not used by the SQLite core.  These optional interfaces are provided
-** by some VFSes to facilitate testing of the VFS code. By overriding 
+** by some VFSes to facilitate testing of the VFS code. By overriding
 ** system calls with functions under its control, a test program can
 ** simulate faults and error conditions that would otherwise be difficult
 ** or impossible to induce.  The set of system calls that can be overridden
@@ -1098,43 +1100,44 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 */
 typedef struct sqlite3_vfs sqlite3_vfs;
 typedef void (*sqlite3_syscall_ptr)(void);
-struct sqlite3_vfs {
-  int iVersion;            /* Structure version number (currently 3) */
-  int szOsFile;            /* Size of subclassed sqlite3_file */
-  int mxPathname;          /* Maximum file pathname length */
-  sqlite3_vfs *pNext;      /* Next registered VFS */
-  const char *zName;       /* Name of this virtual file system */
-  void *pAppData;          /* Pointer to application-specific data */
-  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
-               int flags, int *pOutFlags);
-  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
-  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
-  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
-  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
-  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
-  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
-  void (*xDlClose)(sqlite3_vfs*, void*);
-  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
-  int (*xSleep)(sqlite3_vfs*, int microseconds);
-  int (*xCurrentTime)(sqlite3_vfs*, double*);
-  int (*xGetLastError)(sqlite3_vfs*, int, char *);
-  /*
-  ** The methods above are in version 1 of the sqlite_vfs object
-  ** definition.  Those that follow are added in version 2 or later
-  */
-  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
-  /*
-  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
-  ** Those below are for version 3 and greater.
-  */
-  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
-  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
-  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
-  /*
-  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
-  ** New fields may be appended in figure versions.  The iVersion
-  ** value will increment whenever this happens. 
-  */
+struct sqlite3_vfs
+{
+    int iVersion;            /* Structure version number (currently 3) */
+    int szOsFile;            /* Size of subclassed sqlite3_file */
+    int mxPathname;          /* Maximum file pathname length */
+    sqlite3_vfs *pNext;      /* Next registered VFS */
+    const char *zName;       /* Name of this virtual file system */
+    void *pAppData;          /* Pointer to application-specific data */
+    int (*xOpen)(sqlite3_vfs *, const char *zName, sqlite3_file *,
+                 int flags, int *pOutFlags);
+    int (*xDelete)(sqlite3_vfs *, const char *zName, int syncDir);
+    int (*xAccess)(sqlite3_vfs *, const char *zName, int flags, int *pResOut);
+    int (*xFullPathname)(sqlite3_vfs *, const char *zName, int nOut, char *zOut);
+    void *(*xDlOpen)(sqlite3_vfs *, const char *zFilename);
+    void (*xDlError)(sqlite3_vfs *, int nByte, char *zErrMsg);
+    void (*(*xDlSym)(sqlite3_vfs *, void *, const char *zSymbol))(void);
+    void (*xDlClose)(sqlite3_vfs *, void *);
+    int (*xRandomness)(sqlite3_vfs *, int nByte, char *zOut);
+    int (*xSleep)(sqlite3_vfs *, int microseconds);
+    int (*xCurrentTime)(sqlite3_vfs *, double *);
+    int (*xGetLastError)(sqlite3_vfs *, int, char *);
+    /*
+    ** The methods above are in version 1 of the sqlite_vfs object
+    ** definition.  Those that follow are added in version 2 or later
+    */
+    int (*xCurrentTimeInt64)(sqlite3_vfs *, sqlite3_int64 *);
+    /*
+    ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
+    ** Those below are for version 3 and greater.
+    */
+    int (*xSetSystemCall)(sqlite3_vfs *, const char *zName, sqlite3_syscall_ptr);
+    sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs *, const char *zName);
+    const char *(*xNextSystemCall)(sqlite3_vfs *, const char *zName);
+    /*
+    ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
+    ** New fields may be appended in figure versions.  The iVersion
+    ** value will increment whenever this happens.
+    */
 };
 
 /*
@@ -1177,7 +1180,7 @@ struct sqlite3_vfs {
 ** </ul>
 **
 ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.  
+** was given no the corresponding lock.
 **
 ** The xShmLock method can transition between unlocked and SHARED or
 ** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
@@ -1319,14 +1322,14 @@ SQLITE_API int sqlite3_config(int, ...);
 ** [database connection] (specified in the first argument).
 **
 ** The second argument to sqlite3_db_config(D,V,...)  is the
-** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code 
+** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code
 ** that indicates what aspect of the [database connection] is being configured.
 ** Subsequent arguments vary depending on the configuration verb.
 **
 ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
 ** the call is considered successful.
 */
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3 *, int op, ...);
 
 /*
 ** CAPI3REF: Memory Allocation Routines
@@ -1337,7 +1340,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
 ** This object is used in only one place in the SQLite interface.
 ** A pointer to an instance of this object is the argument to
 ** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
+** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].
 ** By creating an instance of this object
 ** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
 ** during configuration, an application can specify an alternative
@@ -1367,7 +1370,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
 ** allocators round up memory allocations at least to the next multiple
 ** of 8.  Some allocators round up to a larger multiple or to a power of 2.
 ** Every memory allocation request coming in through [sqlite3_malloc()]
-** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
+** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0,
 ** that causes the corresponding memory allocation to fail.
 **
 ** The xInit method initializes the memory allocator.  (For example,
@@ -1392,15 +1395,16 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
 ** call to xShutdown().
 */
 typedef struct sqlite3_mem_methods sqlite3_mem_methods;
-struct sqlite3_mem_methods {
-  void *(*xMalloc)(int);         /* Memory allocation function */
-  void (*xFree)(void*);          /* Free a prior allocation */
-  void *(*xRealloc)(void*,int);  /* Resize an allocation */
-  int (*xSize)(void*);           /* Return the size of an allocation */
-  int (*xRoundup)(int);          /* Round up request size to allocation size */
-  int (*xInit)(void*);           /* Initialize the memory allocator */
-  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
-  void *pAppData;                /* Argument to xInit() and xShutdown() */
+struct sqlite3_mem_methods
+{
+    void *(*xMalloc)(int);         /* Memory allocation function */
+    void (*xFree)(void *);         /* Free a prior allocation */
+    void *(*xRealloc)(void *, int); /* Resize an allocation */
+    int (*xSize)(void *);          /* Return the size of an allocation */
+    int (*xRoundup)(int);          /* Round up request size to allocation size */
+    int (*xInit)(void *);          /* Initialize the memory allocator */
+    void (*xShutdown)(void *);     /* Deinitialize the memory allocator */
+    void *pAppData;                /* Argument to xInit() and xShutdown() */
 };
 
 /*
@@ -1425,7 +1429,7 @@ struct sqlite3_mem_methods {
 ** by a single thread.   ^If SQLite is compiled with
 ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
 ** it is not possible to change the [threading mode] from its default
-** value of Single-thread and so [sqlite3_config()] will return 
+** value of Single-thread and so [sqlite3_config()] will return
 ** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
 ** configuration option.</dd>
 **
@@ -1476,9 +1480,9 @@ struct sqlite3_mem_methods {
 ** tracks memory usage, for example. </dd>
 **
 ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd> ^This option takes single argument of type int, interpreted as a 
-** boolean, which enables or disables the collection of memory allocation 
-** statistics. ^(When memory allocation statistics are disabled, the 
+** <dd> ^This option takes single argument of type int, interpreted as a
+** boolean, which enables or disables the collection of memory allocation
+** statistics. ^(When memory allocation statistics are disabled, the
 ** following SQLite interfaces become non-operational:
 **   <ul>
 **   <li> [sqlite3_memory_used()]
@@ -1504,12 +1508,12 @@ struct sqlite3_mem_methods {
 ** N should be set to twice the expected maximum number of threads.
 ** ^SQLite will never require a scratch buffer that is more than 6
 ** times the database page size. ^If SQLite needs needs additional
-** scratch memory beyond what is provided by this configuration option, then 
+** scratch memory beyond what is provided by this configuration option, then
 ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
 **
 ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
 ** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implementation.  
+** the database page cache with the default page cache implementation.
 ** This configuration should not be used if an application-define page
 ** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
 ** There are three arguments to this option: A pointer to 8-byte aligned
@@ -1595,7 +1599,7 @@ struct sqlite3_mem_methods {
 ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
 ** global [error log].
 ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
-** function with a call signature of void(*)(void*,int,const char*), 
+** function with a call signature of void(*)(void*,int,const char*),
 ** and a pointer to void. ^If the function pointer is not NULL, it is
 ** invoked by [sqlite3_log()] to process each logging event.  ^If the
 ** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
@@ -1669,7 +1673,7 @@ struct sqlite3_mem_methods {
 ** [SQLITE_FCNTL_MMAP_SIZE] file control.  The maximum allowed mmap size
 ** cannot be changed at run-time.  Nor may the maximum allowed mmap size
 ** exceed the compile-time maximum mmap size set by the
-** [SQLITE_MAX_MMAP_SIZE] compile-time option.  
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.
 ** If either argument to this option is negative, then that argument is
 ** changed to its compile-time default.
 ** </dl>
@@ -1685,7 +1689,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
 #define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
 #define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
-/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ 
+/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
 #define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
 #define SQLITE_CONFIG_PCACHE       14  /* no-op */
 #define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
@@ -1712,7 +1716,7 @@ struct sqlite3_mem_methods {
 **
 ** <dl>
 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
-** <dd> ^This option takes three additional arguments that determine the 
+** <dd> ^This option takes three additional arguments that determine the
 ** [lookaside memory allocator] configuration for the [database connection].
 ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
 ** pointer to a memory buffer to use for lookaside memory.
@@ -1730,7 +1734,7 @@ struct sqlite3_mem_methods {
 ** when the "current value" returned by
 ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
 ** Any attempt to change the lookaside memory configuration when lookaside
-** memory is in use leaves the configuration unchanged and returns 
+** memory is in use leaves the configuration unchanged and returns
 ** [SQLITE_BUSY].)^</dd>
 **
 ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
@@ -1767,7 +1771,7 @@ struct sqlite3_mem_methods {
 ** [extended result codes] feature of SQLite. ^The extended result
 ** codes are disabled by default for historical compatibility.
 */
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3 *, int onoff);
 
 /*
 ** CAPI3REF: Last Insert Rowid
@@ -1789,7 +1793,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
 ** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
 ** method, then this routine will return the [rowid] of the inserted
 ** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned 
+** But once the trigger or virtual table method ends, the value returned
 ** by this routine reverts to what it was before the trigger or virtual
 ** table method began.)^
 **
@@ -1816,7 +1820,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
 ** unpredictable and might not equal either the old or the new
 ** last insert [rowid].
 */
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3 *);
 
 /*
 ** CAPI3REF: Count The Number Of Rows Modified
@@ -1840,7 +1844,7 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
 ** mechanisms do not count as direct row changes.)^
 **
 ** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger]. 
+** ends with the script of a [CREATE TRIGGER | trigger].
 ** Most SQL statements are
 ** evaluated outside of any trigger.  This is the "top level"
 ** trigger context.  If a trigger fires from the top level, a
@@ -1870,7 +1874,7 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
 ** while [sqlite3_changes()] is running then the value returned
 ** is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3 *);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified
@@ -1883,7 +1887,7 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** the count does not include changes used to implement [REPLACE] constraints,
 ** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
 ** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes 
+** though if the INSTEAD OF trigger makes changes of its own, those changes
 ** are counted.)^
 ** ^The sqlite3_total_changes() function counts the changes as soon as
 ** the statement that makes them is completed (when the statement handle
@@ -1896,7 +1900,7 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** while [sqlite3_total_changes()] is running then the value
 ** returned is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3 *);
 
 /*
 ** CAPI3REF: Interrupt A Long-Running Query
@@ -1923,7 +1927,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
 **
 ** ^The sqlite3_interrupt(D) call is in effect until all currently running
 ** SQL statements on [database connection] D complete.  ^Any new SQL statements
-** that are started after the sqlite3_interrupt() call and before the 
+** that are started after the sqlite3_interrupt() call and before the
 ** running statements reaches zero are interrupted as if they had been
 ** running prior to the sqlite3_interrupt() call.  ^New SQL statements
 ** that are started after the running statement count reaches zero are
@@ -1935,7 +1939,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
 ** If the database connection closes while [sqlite3_interrupt()]
 ** is running then bad things will likely happen.
 */
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3 *);
 
 /*
 ** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -1958,7 +1962,7 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
 ** ^These routines do not parse the SQL statements thus
 ** will not detect syntactically incorrect SQL.
 **
-** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior 
+** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
 ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
 ** automatically by sqlite3_complete16().  If that initialization fails,
 ** then the return value from sqlite3_complete16() will be non-zero
@@ -2033,11 +2037,11 @@ SQLITE_API int sqlite3_complete16(const void *sql);
 ** The busy callback should not take any actions which modify the
 ** database connection that invoked the busy handler.  Any such actions
 ** result in undefined behavior.
-** 
+**
 ** A busy handler must not close the database connection
 ** or [prepared statement] that invoked the busy handler.
 */
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3 *, int(*)(void *, int), void *);
 
 /*
 ** CAPI3REF: Set A Busy Timeout
@@ -2057,7 +2061,7 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 ** was defined  (using [sqlite3_busy_handler()]) prior to calling
 ** this routine, that other busy handler is cleared.)^
 */
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3 *, int ms);
 
 /*
 ** CAPI3REF: Convenience Routines For Running Queries
@@ -2132,12 +2136,12 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
 ** [sqlite3_errmsg()].
 */
 SQLITE_API int sqlite3_get_table(
-  sqlite3 *db,          /* An open database */
-  const char *zSql,     /* SQL to be evaluated */
-  char ***pazResult,    /* Results of the query */
-  int *pnRow,           /* Number of result rows written here */
-  int *pnColumn,        /* Number of result columns written here */
-  char **pzErrmsg       /* Error msg written here */
+    sqlite3 *db,          /* An open database */
+    const char *zSql,     /* SQL to be evaluated */
+    char ***pazResult,    /* Results of the query */
+    int *pnRow,           /* Number of result rows written here */
+    int *pnColumn,        /* Number of result columns written here */
+    char **pzErrmsg       /* Error msg written here */
 );
 SQLITE_API void sqlite3_free_table(char **result);
 
@@ -2235,10 +2239,10 @@ SQLITE_API void sqlite3_free_table(char **result);
 ** addition that after the string has been read and copied into
 ** the result, [sqlite3_free()] is called on the input string.)^
 */
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char *, ...);
+SQLITE_API char *sqlite3_vmprintf(const char *, va_list);
+SQLITE_API char *sqlite3_snprintf(int, char *, const char *, ...);
+SQLITE_API char *sqlite3_vsnprintf(int, char *, const char *, va_list);
 
 /*
 ** CAPI3REF: Memory Allocation Subsystem
@@ -2311,8 +2315,8 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** [sqlite3_free()] or [sqlite3_realloc()].
 */
 SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
+SQLITE_API void *sqlite3_realloc(void *, int);
+SQLITE_API void sqlite3_free(void *);
 
 /*
 ** CAPI3REF: Memory Allocator Statistics
@@ -2383,7 +2387,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
 ** requested is ok.  ^When the callback returns [SQLITE_DENY], the
 ** [sqlite3_prepare_v2()] or equivalent call that triggered the
 ** authorizer will fail with an error message explaining that
-** access is denied. 
+** access is denied.
 **
 ** ^The first parameter to the authorizer callback is a copy of the third
 ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
@@ -2430,7 +2434,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
 ** database connections for the meaning of "modify" in this paragraph.
 **
 ** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be re-prepared during [sqlite3_step()] due to a 
+** statement might be re-prepared during [sqlite3_step()] due to a
 ** schema change.  Hence, the application should ensure that the
 ** correct authorizer callback remains in place during the [sqlite3_step()].
 **
@@ -2441,9 +2445,9 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
 ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
 */
 SQLITE_API int sqlite3_set_authorizer(
-  sqlite3*,
-  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
-  void *pUserData
+    sqlite3 *,
+    int (*xAuth)(void *, int, const char *, const char *, const char *, const char *),
+    void *pUserData
 );
 
 /*
@@ -2543,9 +2547,9 @@ SQLITE_API int sqlite3_set_authorizer(
 ** sqlite3_profile() function is considered experimental and is
 ** subject to change in future versions of SQLite.
 */
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
-   void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
+SQLITE_API void *sqlite3_trace(sqlite3 *, void(*xTrace)(void *, const char *), void *);
+SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3 *,
+        void(*xProfile)(void *, const char *, sqlite3_uint64), void *);
 
 /*
 ** CAPI3REF: Query Progress Callbacks
@@ -2556,8 +2560,8 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** database connection D.  An example use for this
 ** interface is to keep a GUI updated during a large query.
 **
-** ^The parameter P is passed through as the only parameter to the 
-** callback function X.  ^The parameter N is the number of 
+** ^The parameter P is passed through as the only parameter to the
+** callback function X.  ^The parameter N is the number of
 ** [virtual machine instructions] that are evaluated between successive
 ** invocations of the callback X.
 **
@@ -2577,12 +2581,12 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** database connections for the meaning of "modify" in this paragraph.
 **
 */
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3 *, int, int(*)(void *), void *);
 
 /*
 ** CAPI3REF: Opening A New Database Connection
 **
-** ^These routines open an SQLite database file as specified by the 
+** ^These routines open an SQLite database file as specified by the
 ** filename argument. ^The filename argument is interpreted as UTF-8 for
 ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
 ** order for sqlite3_open16(). ^(A [database connection] handle is usually
@@ -2607,7 +2611,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** except that it accepts two additional parameters for additional control
 ** over the new database connection.  ^(The flags parameter to
 ** sqlite3_open_v2() can take one of
-** the following three values, optionally combined with the 
+** the following three values, optionally combined with the
 ** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
 ** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
 **
@@ -2675,17 +2679,17 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** information.
 **
 ** URI filenames are parsed according to RFC 3986. ^If the URI contains an
-** authority, then it must be either an empty string or the string 
-** "localhost". ^If the authority is not an empty string or "localhost", an 
-** error is returned to the caller. ^The fragment component of a URI, if 
+** authority, then it must be either an empty string or the string
+** "localhost". ^If the authority is not an empty string or "localhost", an
+** error is returned to the caller. ^The fragment component of a URI, if
 ** present, is ignored.
 **
 ** ^SQLite uses the path component of the URI as the name of the disk file
-** which contains the database. ^If the path begins with a '/' character, 
-** then it is interpreted as an absolute path. ^If the path does not begin 
+** which contains the database. ^If the path begins with a '/' character,
+** then it is interpreted as an absolute path. ^If the path does not begin
 ** with a '/' (meaning that the authority section is omitted from the URI)
-** then the path is interpreted as a relative path. 
-** ^On windows, the first component of an absolute path 
+** then the path is interpreted as a relative path.
+** ^On windows, the first component of an absolute path
 ** is a drive specification (e.g. "C:").
 **
 ** [[core URI query parameters]]
@@ -2704,13 +2708,13 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **
 **   <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
 **     "rwc", or "memory". Attempting to set it to any other value is
-**     an error)^. 
-**     ^If "ro" is specified, then the database is opened for read-only 
-**     access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the 
-**     third argument to sqlite3_open_v2(). ^If the mode option is set to 
-**     "rw", then the database is opened for read-write (but not create) 
-**     access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had 
-**     been set. ^Value "rwc" is equivalent to setting both 
+**     an error)^.
+**     ^If "ro" is specified, then the database is opened for read-only
+**     access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
+**     third argument to sqlite3_open_v2(). ^If the mode option is set to
+**     "rw", then the database is opened for read-write (but not create)
+**     access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
+**     been set. ^Value "rwc" is equivalent to setting both
 **     SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE.  ^If the mode option is
 **     set to "memory" then a pure [in-memory database] that never reads
 **     or writes from disk is used. ^It is an error to specify a value for
@@ -2720,7 +2724,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **   <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
 **     "private". ^Setting it to "shared" is equivalent to setting the
 **     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
-**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
+**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is
 **     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
 **     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
 **     a URI filename, its value overrides any behavior requested by setting
@@ -2736,35 +2740,35 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **
 ** <table border="1" align=center cellpadding=5>
 ** <tr><th> URI filenames <th> Results
-** <tr><td> file:data.db <td> 
+** <tr><td> file:data.db <td>
 **          Open the file "data.db" in the current directory.
 ** <tr><td> file:/home/fred/data.db<br>
-**          file:///home/fred/data.db <br> 
-**          file://localhost/home/fred/data.db <br> <td> 
+**          file:///home/fred/data.db <br>
+**          file://localhost/home/fred/data.db <br> <td>
 **          Open the database file "/home/fred/data.db".
-** <tr><td> file://darkstar/home/fred/data.db <td> 
+** <tr><td> file://darkstar/home/fred/data.db <td>
 **          An error. "darkstar" is not a recognized authority.
-** <tr><td style="white-space:nowrap"> 
+** <tr><td style="white-space:nowrap">
 **          file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
 **     <td> Windows only: Open the file "data.db" on fred's desktop on drive
-**          C:. Note that the %20 escaping in this example is not strictly 
+**          C:. Note that the %20 escaping in this example is not strictly
 **          necessary - space characters can be used literally
 **          in URI filenames.
-** <tr><td> file:data.db?mode=ro&cache=private <td> 
+** <tr><td> file:data.db?mode=ro&cache=private <td>
 **          Open file "data.db" in the current directory for read-only access.
 **          Regardless of whether or not shared-cache mode is enabled by
 **          default, use a private cache.
 ** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
 **          Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
-** <tr><td> file:data.db?mode=readonly <td> 
+** <tr><td> file:data.db?mode=readonly <td>
 **          An error. "readonly" is not a valid option for the "mode" parameter.
 ** </table>
 **
 ** ^URI hexadecimal escape sequences (%HH) are supported within the path and
 ** query components of a URI. A hexadecimal escape sequence consists of a
-** percent sign - "%" - followed by exactly two hexadecimal digits 
+** percent sign - "%" - followed by exactly two hexadecimal digits
 ** specifying an octet value. ^Before the path or query components of a
-** URI filename are interpreted, they are encoded using UTF-8 and all 
+** URI filename are interpreted, they are encoded using UTF-8 and all
 ** hexadecimal escape sequences replaced by a single byte containing the
 ** corresponding octet. If this process generates an invalid UTF-8 encoding,
 ** the results are undefined.
@@ -2782,33 +2786,33 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** See also: [sqlite3_temp_directory]
 */
 SQLITE_API int sqlite3_open(
-  const char *filename,   /* Database filename (UTF-8) */
-  sqlite3 **ppDb          /* OUT: SQLite db handle */
+    const char *filename,   /* Database filename (UTF-8) */
+    sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
 SQLITE_API int sqlite3_open16(
-  const void *filename,   /* Database filename (UTF-16) */
-  sqlite3 **ppDb          /* OUT: SQLite db handle */
+    const void *filename,   /* Database filename (UTF-16) */
+    sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
 SQLITE_API int sqlite3_open_v2(
-  const char *filename,   /* Database filename (UTF-8) */
-  sqlite3 **ppDb,         /* OUT: SQLite db handle */
-  int flags,              /* Flags */
-  const char *zVfs        /* Name of VFS module to use */
+    const char *filename,   /* Database filename (UTF-8) */
+    sqlite3 **ppDb,         /* OUT: SQLite db handle */
+    int flags,              /* Flags */
+    const char *zVfs        /* Name of VFS module to use */
 );
 
 /*
 ** CAPI3REF: Obtain Values For URI Parameters
 **
 ** These are utility routines, useful to VFS implementations, that check
-** to see if a database file was a URI that contained a specific query 
+** to see if a database file was a URI that contained a specific query
 ** parameter, and if so obtains the value of that query parameter.
 **
-** If F is the database filename pointer passed into the xOpen() method of 
-** a VFS implementation when the flags parameter to xOpen() has one or 
+** If F is the database filename pointer passed into the xOpen() method of
+** a VFS implementation when the flags parameter to xOpen() has one or
 ** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
 ** P is the name of the query parameter, then
 ** sqlite3_uri_parameter(F,P) returns the value of the P
-** parameter if it exists or a NULL pointer if P does not appear as a 
+** parameter if it exists or a NULL pointer if P does not appear as a
 ** query parameter on F.  If P is a query parameter of F
 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
 ** a pointer to an empty string.
@@ -2817,7 +2821,7 @@ SQLITE_API int sqlite3_open_v2(
 ** parameter and returns true (1) or false (0) according to the value
 ** of P.  The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
 ** value of query parameter P is one of "yes", "true", or "on" in any
-** case or if the value begins with a non-zero number.  The 
+** case or if the value begins with a non-zero number.  The
 ** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
 ** query parameter P is one of "no", "false", or "off" in any case or
 ** if the value begins with a numeric zero.  If P is not a query
@@ -2828,7 +2832,7 @@ SQLITE_API int sqlite3_open_v2(
 ** 64-bit signed integer and returns that integer, or D if P does not
 ** exist.  If the value of P is something other than an integer, then
 ** zero is returned.
-** 
+**
 ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
 ** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
 ** is not a database file pathname pointer that SQLite passed into the xOpen
@@ -2837,7 +2841,7 @@ SQLITE_API int sqlite3_open_v2(
 */
 SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
 SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char *, const char *, sqlite3_int64);
 
 
 /*
@@ -2848,7 +2852,7 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
 ** associated with a [database connection]. If a prior API call failed
 ** but the most recent API call succeeded, the return value from
 ** sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
-** interface is the same except that it always returns the 
+** interface is the same except that it always returns the
 ** [extended result code] even when extended result codes are
 ** disabled.
 **
@@ -2880,8 +2884,8 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
 */
 SQLITE_API int sqlite3_errcode(sqlite3 *db);
 SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errmsg(sqlite3 *);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3 *);
 SQLITE_API const char *sqlite3_errstr(int);
 
 /*
@@ -2921,7 +2925,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
 ** new limit for that construct.)^
 **
 ** ^If the new limit is a negative number, the limit is unchanged.
-** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a 
+** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a
 ** [limits | hard upper bound]
 ** set at compile-time by a C preprocessor macro called
 ** [limits | SQLITE_MAX_<i>NAME</i>].
@@ -2929,7 +2933,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
 ** ^Attempts to increase a limit above its hard upper bound are
 ** silently truncated to the hard upper bound.
 **
-** ^Regardless of whether or not the limit was changed, the 
+** ^Regardless of whether or not the limit was changed, the
 ** [sqlite3_limit()] interface returns the prior value of the limit.
 ** ^Hence, to find the current value of a limit without changing it,
 ** simply invoke this interface with the third parameter set to -1.
@@ -2949,7 +2953,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
 **
 ** New run-time limit categories may be added in future releases.
 */
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3 *, int id, int newVal);
 
 /*
 ** CAPI3REF: Run-Time Limit Categories
@@ -3084,46 +3088,46 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** </li>
 **
 ** <li>
-** ^If the specific value bound to [parameter | host parameter] in the 
+** ^If the specific value bound to [parameter | host parameter] in the
 ** WHERE clause might influence the choice of query plan for a statement,
-** then the statement will be automatically recompiled, as if there had been 
+** then the statement will be automatically recompiled, as if there had been
 ** a schema change, on the first  [sqlite3_step()] call following any change
-** to the [sqlite3_bind_text | bindings] of that [parameter]. 
-** ^The specific value of WHERE-clause [parameter] might influence the 
+** to the [sqlite3_bind_text | bindings] of that [parameter].
+** ^The specific value of WHERE-clause [parameter] might influence the
 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
 ** or [GLOB] operator or if the parameter is compared to an indexed column
 ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
-** the 
+** the
 ** </li>
 ** </ol>
 */
 SQLITE_API int sqlite3_prepare(
-  sqlite3 *db,            /* Database handle */
-  const char *zSql,       /* SQL statement, UTF-8 encoded */
-  int nByte,              /* Maximum length of zSql in bytes. */
-  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
-  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+    sqlite3 *db,            /* Database handle */
+    const char *zSql,       /* SQL statement, UTF-8 encoded */
+    int nByte,              /* Maximum length of zSql in bytes. */
+    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+    const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
 SQLITE_API int sqlite3_prepare_v2(
-  sqlite3 *db,            /* Database handle */
-  const char *zSql,       /* SQL statement, UTF-8 encoded */
-  int nByte,              /* Maximum length of zSql in bytes. */
-  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
-  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+    sqlite3 *db,            /* Database handle */
+    const char *zSql,       /* SQL statement, UTF-8 encoded */
+    int nByte,              /* Maximum length of zSql in bytes. */
+    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+    const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
 SQLITE_API int sqlite3_prepare16(
-  sqlite3 *db,            /* Database handle */
-  const void *zSql,       /* SQL statement, UTF-16 encoded */
-  int nByte,              /* Maximum length of zSql in bytes. */
-  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
-  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+    sqlite3 *db,            /* Database handle */
+    const void *zSql,       /* SQL statement, UTF-16 encoded */
+    int nByte,              /* Maximum length of zSql in bytes. */
+    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+    const void **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
 SQLITE_API int sqlite3_prepare16_v2(
-  sqlite3 *db,            /* Database handle */
-  const void *zSql,       /* SQL statement, UTF-16 encoded */
-  int nByte,              /* Maximum length of zSql in bytes. */
-  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
-  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+    sqlite3 *db,            /* Database handle */
+    const void *zSql,       /* SQL statement, UTF-16 encoded */
+    int nByte,              /* Maximum length of zSql in bytes. */
+    sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+    const void **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
 
 /*
@@ -3143,8 +3147,8 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
 ** the content of the database file.
 **
 ** Note that [application-defined SQL functions] or
-** [virtual tables] might change the database indirectly as a side effect.  
-** ^(For example, if an application defines a function "eval()" that 
+** [virtual tables] might change the database indirectly as a side effect.
+** ^(For example, if an application defines a function "eval()" that
 ** calls [sqlite3_exec()], then the following SQL statement would
 ** change the database file through side-effects:
 **
@@ -3158,10 +3162,10 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
 ** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
 ** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
 ** since the statements themselves do not actually modify the database but
-** rather they control the timing of when other statements modify the 
+** rather they control the timing of when other statements modify the
 ** database.  ^The [ATTACH] and [DETACH] statements also cause
 ** sqlite3_stmt_readonly() to return true since, while those statements
-** change the configuration of a database connection, they do not make 
+** change the configuration of a database connection, they do not make
 ** changes to the content of the database files on disk.
 */
 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
@@ -3170,20 +3174,20 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
 **
 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
-** [prepared statement] S has been stepped at least once using 
-** [sqlite3_step(S)] but has not run to completion and/or has not 
+** [prepared statement] S has been stepped at least once using
+** [sqlite3_step(S)] but has not run to completion and/or has not
 ** been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
-** interface returns false if S is a NULL pointer.  If S is not a 
+** interface returns false if S is a NULL pointer.  If S is not a
 ** NULL pointer and is not a pointer to a valid [prepared statement]
 ** object, then the behavior is undefined and probably undesirable.
 **
 ** This interface can be used in combination [sqlite3_next_stmt()]
-** to locate all prepared statements associated with a database 
+** to locate all prepared statements associated with a database
 ** connection that are in need of being reset.  This can be used,
-** for example, in diagnostic routines to search for prepared 
+** for example, in diagnostic routines to search for prepared
 ** statements that are holding a transaction open.
 */
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *);
 
 /*
 ** CAPI3REF: Dynamically Typed Value Object
@@ -3205,7 +3209,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
 ** sqlite3_value object but no mutex is held for an unprotected
 ** sqlite3_value object.  If SQLite is compiled to be single-threaded
 ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-** or if SQLite is run in one of reduced mutex modes 
+** or if SQLite is run in one of reduced mutex modes
 ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
 ** then there is no distinction between protected and unprotected
 ** sqlite3_value objects and they can be used interchangeably.  However,
@@ -3290,7 +3294,7 @@ typedef struct sqlite3_context sqlite3_context;
 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
 ** or sqlite3_bind_text16() then that parameter must be the byte offset
 ** where the NUL terminator would occur assuming the string were NUL
-** terminated.  If any NUL characters occur at byte offsets less than 
+** terminated.  If any NUL characters occur at byte offsets less than
 ** the value of the fourth parameter then the resulting string value will
 ** contain embedded NULs.  The result of expressions involving strings
 ** with embedded NULs is undefined.
@@ -3299,7 +3303,7 @@ typedef struct sqlite3_context sqlite3_context;
 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
+** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
 ** information is in static, unmanaged space and does not need to be freed.
@@ -3333,15 +3337,15 @@ typedef struct sqlite3_context sqlite3_context;
 ** See also: [sqlite3_bind_parameter_count()],
 ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt *, int, const void *, int n, void(*)(void *));
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt *, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt *, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt *, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt *, int, const char *, int n, void(*)(void *));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt *, int, const void *, int, void(*)(void *));
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt *, int, const sqlite3_value *);
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *, int, int n);
 
 /*
 ** CAPI3REF: Number Of SQL Parameters
@@ -3361,7 +3365,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 ** [sqlite3_bind_parameter_name()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *);
 
 /*
 ** CAPI3REF: Name Of A Host Parameter
@@ -3388,7 +3392,7 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *, int);
 
 /*
 ** CAPI3REF: Index Of A Parameter With A Given Name
@@ -3404,7 +3408,7 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *, const char *zName);
 
 /*
 ** CAPI3REF: Reset All Bindings On A Prepared Statement
@@ -3413,7 +3417,7 @@ SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
 ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
 ** ^Use this routine to reset all host parameters to NULL.
 */
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *);
 
 /*
 ** CAPI3REF: Number Of Columns In A Result Set
@@ -3452,8 +3456,8 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
 ** then the name of the column is unspecified and may change from
 ** one release of SQLite to the next.
 */
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *, int N);
 
 /*
 ** CAPI3REF: Source Of Data In A Query Result
@@ -3500,12 +3504,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
 ** for the same [prepared statement] and result column
 ** at the same time then the results are undefined.
 */
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *, int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *, int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *, int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *, int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *, int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *, int);
 
 /*
 ** CAPI3REF: Declared Datatype Of A Query Result
@@ -3536,8 +3540,8 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
 ** is associated with individual values, not with the containers
 ** used to hold those values.
 */
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *, int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *, int);
 
 /*
 ** CAPI3REF: Evaluate An SQL Statement
@@ -3595,7 +3599,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 ** For all versions of SQLite up to and including 3.6.23.1, a call to
 ** [sqlite3_reset()] was required after sqlite3_step() returned anything
 ** other than [SQLITE_ROW] before any subsequent invocation of
-** sqlite3_step().  Failure to reset the prepared statement using 
+** sqlite3_step().  Failure to reset the prepared statement using
 ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
 ** sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
 ** calling [sqlite3_reset()] automatically in this circumstance rather
@@ -3616,7 +3620,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 ** then the more specific [error codes] are returned directly
 ** by sqlite3_step().  The use of the "v2" interface is recommended.
 */
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt *);
 
 /*
 ** CAPI3REF: Number of columns in a result set
@@ -3725,7 +3729,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 ** the number of bytes in that string.
 ** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
 **
-** ^The values returned by [sqlite3_column_bytes()] and 
+** ^The values returned by [sqlite3_column_bytes()] and
 ** [sqlite3_column_bytes16()] do not include the zero terminators at the end
 ** of the string.  ^For clarity: the values returned by
 ** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
@@ -3832,16 +3836,16 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 ** pointer.  Subsequent calls to [sqlite3_errcode()] will return
 ** [SQLITE_NOMEM].)^
 */
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt *, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt *, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt *, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt *, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *, int iCol);
 
 /*
 ** CAPI3REF: Destroy A Prepared Statement Object
@@ -3918,7 +3922,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** ^The second parameter is the name of the SQL function to be created or
 ** redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
 ** representation, exclusive of the zero-terminator.  ^Note that the name
-** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.  
+** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.
 ** ^Any attempt to create a function with a longer name
 ** will result in [SQLITE_MISUSE] being returned.
 **
@@ -3955,13 +3959,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** callbacks.
 **
 ** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
-** then it is destructor for the application data pointer. 
+** then it is destructor for the application data pointer.
 ** The destructor is invoked when the function is deleted, either by being
 ** overloaded or when the database connection closes.)^
 ** ^The destructor is also invoked if the call to
 ** sqlite3_create_function_v2() fails.
 ** ^When the destructor callback of the tenth parameter is invoked, it
-** is passed a single argument which is a copy of the application data 
+** is passed a single argument which is a copy of the application data
 ** pointer which was the fifth parameter to sqlite3_create_function_v2().
 **
 ** ^It is permitted to register multiple implementations of the same
@@ -3972,7 +3976,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** nArg parameter is a better match than a function implementation with
 ** a negative nArg.  ^A function where the preferred text encoding
 ** matches the database encoding is a better
-** match than a function where the encoding is different.  
+** match than a function where the encoding is different.
 ** ^A function where the encoding difference is between UTF16le and UTF16be
 ** is a closer match than a function where the encoding difference is
 ** between UTF8 and UTF16.
@@ -3985,35 +3989,35 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** statement in which the function is running.
 */
 SQLITE_API int sqlite3_create_function(
-  sqlite3 *db,
-  const char *zFunctionName,
-  int nArg,
-  int eTextRep,
-  void *pApp,
-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
-  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
-  void (*xFinal)(sqlite3_context*)
+    sqlite3 *db,
+    const char *zFunctionName,
+    int nArg,
+    int eTextRep,
+    void *pApp,
+    void (*xFunc)(sqlite3_context *, int, sqlite3_value **),
+    void (*xStep)(sqlite3_context *, int, sqlite3_value **),
+    void (*xFinal)(sqlite3_context *)
 );
 SQLITE_API int sqlite3_create_function16(
-  sqlite3 *db,
-  const void *zFunctionName,
-  int nArg,
-  int eTextRep,
-  void *pApp,
-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
-  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
-  void (*xFinal)(sqlite3_context*)
+    sqlite3 *db,
+    const void *zFunctionName,
+    int nArg,
+    int eTextRep,
+    void *pApp,
+    void (*xFunc)(sqlite3_context *, int, sqlite3_value **),
+    void (*xStep)(sqlite3_context *, int, sqlite3_value **),
+    void (*xFinal)(sqlite3_context *)
 );
 SQLITE_API int sqlite3_create_function_v2(
-  sqlite3 *db,
-  const char *zFunctionName,
-  int nArg,
-  int eTextRep,
-  void *pApp,
-  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
-  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
-  void (*xFinal)(sqlite3_context*),
-  void(*xDestroy)(void*)
+    sqlite3 *db,
+    const char *zFunctionName,
+    int nArg,
+    int eTextRep,
+    void *pApp,
+    void (*xFunc)(sqlite3_context *, int, sqlite3_value **),
+    void (*xStep)(sqlite3_context *, int, sqlite3_value **),
+    void (*xFinal)(sqlite3_context *),
+    void(*xDestroy)(void *)
 );
 
 /*
@@ -4034,19 +4038,19 @@ SQLITE_API int sqlite3_create_function_v2(
 ** DEPRECATED
 **
 ** These functions are [deprecated].  In order to maintain
-** backwards compatibility with older code, these functions continue 
+** backwards compatibility with older code, these functions continue
 ** to be supported.  However, new applications should avoid
 ** the use of these functions.  To help encourage people to avoid
 ** using these functions, we are not going to tell you what they do.
 */
 #ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context *);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt *);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt *, sqlite3_stmt *);
 SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
 SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
-                      void*,sqlite3_int64);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void *, sqlite3_int64, int),
+        void *, sqlite3_int64);
 #endif
 
 /*
@@ -4094,18 +4098,18 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the [sqlite3_value*] parameters.
 */
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value *);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value *);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value *);
+SQLITE_API double sqlite3_value_double(sqlite3_value *);
+SQLITE_API int sqlite3_value_int(sqlite3_value *);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value *);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value *);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *);
+SQLITE_API int sqlite3_value_type(sqlite3_value *);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *);
 
 /*
 ** CAPI3REF: Obtain Aggregate Function Context
@@ -4113,7 +4117,7 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** Implementations of aggregate SQL functions use this
 ** routine to allocate memory for storing their state.
 **
-** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
+** ^The first time the sqlite3_aggregate_context(C,N) routine is called
 ** for a particular aggregate function, SQLite
 ** allocates N of memory, zeroes out that memory, and returns a pointer
 ** to the new memory. ^On second and subsequent calls to
@@ -4126,7 +4130,7 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** In those cases, sqlite3_aggregate_context() might be called for the
 ** first time from within xFinal().)^
 **
-** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer 
+** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
 ** when first called if N is less than or equal to zero or if a memory
 ** allocate error occurs.
 **
@@ -4135,10 +4139,10 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** value of N in subsequent call to sqlite3_aggregate_context() within
 ** the same aggregate function instance will not resize the memory
 ** allocation.)^  Within the xFinal callback, it is customary to set
-** N=0 in calls to sqlite3_aggregate_context(C,N) so that no 
+** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
 ** pointless memory allocations occur.
 **
-** ^SQLite automatically frees the memory allocated by 
+** ^SQLite automatically frees the memory allocated by
 ** sqlite3_aggregate_context() when the aggregate query concludes.
 **
 ** The first parameter must be a copy of the
@@ -4149,7 +4153,7 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** This routine must be called from the same thread in which
 ** the aggregate SQL function is running.
 */
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *, int nBytes);
 
 /*
 ** CAPI3REF: User Data For Functions
@@ -4163,7 +4167,7 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 ** This routine must be called from the same thread in which
 ** the application-defined function is running.
 */
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context *);
 
 /*
 ** CAPI3REF: Database Connection For Functions
@@ -4174,7 +4178,7 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function.
 */
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *);
 
 /*
 ** CAPI3REF: Function Auxiliary Data
@@ -4218,8 +4222,8 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 ** These routines must be called from the same thread in which
 ** the SQL function is running.
 */
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context *, int N, void *, void (*)(void *));
 
 
 /*
@@ -4236,7 +4240,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
 ** The typedef is necessary to work around problems in certain
 ** C++ compilers.
 */
-typedef void (*sqlite3_destructor_type)(void*);
+typedef void (*sqlite3_destructor_type)(void *);
 #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
 #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
 
@@ -4350,22 +4354,22 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** than the one containing the application-defined function that received
 ** the [sqlite3_context] pointer, the results are undefined.
 */
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API void sqlite3_result_blob(sqlite3_context *, const void *, int, void(*)(void *));
+SQLITE_API void sqlite3_result_double(sqlite3_context *, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context *, const char *, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context *, const void *, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context *, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context *, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context *, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context *);
+SQLITE_API void sqlite3_result_text(sqlite3_context *, const char *, int, void(*)(void *));
+SQLITE_API void sqlite3_result_text16(sqlite3_context *, const void *, int, void(*)(void *));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context *, const void *, int, void(*)(void *));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context *, const void *, int, void(*)(void *));
+SQLITE_API void sqlite3_result_value(sqlite3_context *, sqlite3_value *);
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *, int n);
 
 /*
 ** CAPI3REF: Define New Collating Sequences
@@ -4405,7 +4409,7 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
 ** deleted.  ^When all collating functions having the same name are deleted,
 ** that collation is no longer usable.
 **
-** ^The collating function callback is invoked with a copy of the pArg 
+** ^The collating function callback is invoked with a copy of the pArg
 ** application data pointer and with two strings in the encoding specified
 ** by the eTextRep argument.  The collating function must return an
 ** integer that is negative, zero, or positive
@@ -4435,38 +4439,38 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
 ** calls to the collation creation functions or when the
 ** [database connection] is closed using [sqlite3_close()].
 **
-** ^The xDestroy callback is <u>not</u> called if the 
+** ^The xDestroy callback is <u>not</u> called if the
 ** sqlite3_create_collation_v2() function fails.  Applications that invoke
-** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should 
+** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should
 ** check the return code and dispose of the application data pointer
 ** themselves rather than expecting SQLite to deal with it for them.
-** This is different from every other SQLite interface.  The inconsistency 
-** is unfortunate but cannot be changed without breaking backwards 
+** This is different from every other SQLite interface.  The inconsistency
+** is unfortunate but cannot be changed without breaking backwards
 ** compatibility.
 **
 ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
 */
 SQLITE_API int sqlite3_create_collation(
-  sqlite3*, 
-  const char *zName, 
-  int eTextRep, 
-  void *pArg,
-  int(*xCompare)(void*,int,const void*,int,const void*)
+    sqlite3 *,
+    const char *zName,
+    int eTextRep,
+    void *pArg,
+    int(*xCompare)(void *, int, const void *, int, const void *)
 );
 SQLITE_API int sqlite3_create_collation_v2(
-  sqlite3*, 
-  const char *zName, 
-  int eTextRep, 
-  void *pArg,
-  int(*xCompare)(void*,int,const void*,int,const void*),
-  void(*xDestroy)(void*)
+    sqlite3 *,
+    const char *zName,
+    int eTextRep,
+    void *pArg,
+    int(*xCompare)(void *, int, const void *, int, const void *),
+    void(*xDestroy)(void *)
 );
 SQLITE_API int sqlite3_create_collation16(
-  sqlite3*, 
-  const void *zName,
-  int eTextRep, 
-  void *pArg,
-  int(*xCompare)(void*,int,const void*,int,const void*)
+    sqlite3 *,
+    const void *zName,
+    int eTextRep,
+    void *pArg,
+    int(*xCompare)(void *, int, const void *, int, const void *)
 );
 
 /*
@@ -4496,14 +4500,14 @@ SQLITE_API int sqlite3_create_collation16(
 ** [sqlite3_create_collation_v2()].
 */
 SQLITE_API int sqlite3_collation_needed(
-  sqlite3*, 
-  void*, 
-  void(*)(void*,sqlite3*,int eTextRep,const char*)
+    sqlite3 *,
+    void *,
+    void(*)(void *, sqlite3 *, int eTextRep, const char *)
 );
 SQLITE_API int sqlite3_collation_needed16(
-  sqlite3*, 
-  void*,
-  void(*)(void*,sqlite3*,int eTextRep,const void*)
+    sqlite3 *,
+    void *,
+    void(*)(void *, sqlite3 *, int eTextRep, const void *)
 );
 
 #ifdef SQLITE_HAS_CODEC
@@ -4515,8 +4519,8 @@ SQLITE_API int sqlite3_collation_needed16(
 ** of SQLite.
 */
 SQLITE_API int sqlite3_key(
-  sqlite3 *db,                   /* Database to be rekeyed */
-  const void *pKey, int nKey     /* The key */
+    sqlite3 *db,                   /* Database to be rekeyed */
+    const void *pKey, int nKey     /* The key */
 );
 
 /*
@@ -4528,26 +4532,26 @@ SQLITE_API int sqlite3_key(
 ** of SQLite.
 */
 SQLITE_API int sqlite3_rekey(
-  sqlite3 *db,                   /* Database to be rekeyed */
-  const void *pKey, int nKey     /* The new key */
+    sqlite3 *db,                   /* Database to be rekeyed */
+    const void *pKey, int nKey     /* The new key */
 );
 
 /*
-** Specify the activation key for a SEE database.  Unless 
+** Specify the activation key for a SEE database.  Unless
 ** activated, none of the SEE routines will work.
 */
 SQLITE_API void sqlite3_activate_see(
-  const char *zPassPhrase        /* Activation phrase */
+    const char *zPassPhrase        /* Activation phrase */
 );
 #endif
 
 #ifdef SQLITE_ENABLE_CEROD
 /*
-** Specify the activation key for a CEROD database.  Unless 
+** Specify the activation key for a CEROD database.  Unless
 ** activated, none of the CEROD routines will work.
 */
 SQLITE_API void sqlite3_activate_cerod(
-  const char *zPassPhrase        /* Activation phrase */
+    const char *zPassPhrase        /* Activation phrase */
 );
 #endif
 
@@ -4592,7 +4596,7 @@ SQLITE_API int sqlite3_sleep(int);
 ** ^The [temp_store_directory pragma] may modify this variable and cause
 ** it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
 ** the [temp_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from 
+** that this variable points to is held in memory obtained from
 ** [sqlite3_malloc] and the pragma may attempt to free that memory
 ** using [sqlite3_free].
 ** Hence, if this variable is modified directly, either it should be
@@ -4644,7 +4648,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
 ** ^The [data_store_directory pragma] may modify this variable and cause
 ** it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
 ** the [data_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from 
+** that this variable points to is held in memory obtained from
 ** [sqlite3_malloc] and the pragma may attempt to free that memory
 ** using [sqlite3_free].
 ** Hence, if this variable is modified directly, either it should be
@@ -4674,7 +4678,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
 ** connection while this routine is running, then the return value
 ** is undefined.
 */
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3 *);
 
 /*
 ** CAPI3REF: Find The Database Handle Of A Prepared Statement
@@ -4686,7 +4690,7 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
 ** create the statement in the first place.
 */
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *);
 
 /*
 ** CAPI3REF: Return The Filename For A Database Connection
@@ -4774,8 +4778,8 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 **
 ** See also the [sqlite3_update_hook()] interface.
 */
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3 *, int(*)(void *), void *);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3 *, void(*)(void *), void *);
 
 /*
 ** CAPI3REF: Data Change Notification Callbacks
@@ -4824,9 +4828,9 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 ** interfaces.
 */
 SQLITE_API void *sqlite3_update_hook(
-  sqlite3*, 
-  void(*)(void *,int ,char const *,char const *,sqlite3_int64),
-  void*
+    sqlite3 *,
+    void(*)(void *, int , char const *, char const *, sqlite3_int64),
+    void *
 );
 
 /*
@@ -4887,7 +4891,7 @@ SQLITE_API int sqlite3_release_memory(int);
 **
 ** See also: [sqlite3_release_memory()]
 */
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3 *);
 
 /*
 ** CAPI3REF: Impose A Limit On Heap Size
@@ -4899,7 +4903,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
 ** as heap memory usages approaches the limit.
 ** ^The soft heap limit is "soft" because even though SQLite strives to stay
 ** below the limit, it will exceed the limit rather than generate
-** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
+** an [SQLITE_NOMEM] error.  In other words, the soft heap limit
 ** is advisory only.
 **
 ** ^The return value from sqlite3_soft_heap_limit64() is the size of
@@ -5016,15 +5020,15 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
 */
 SQLITE_API int sqlite3_table_column_metadata(
-  sqlite3 *db,                /* Connection handle */
-  const char *zDbName,        /* Database name or NULL */
-  const char *zTableName,     /* Table name */
-  const char *zColumnName,    /* Column name */
-  char const **pzDataType,    /* OUTPUT: Declared data type */
-  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
-  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
-  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
-  int *pAutoinc               /* OUTPUT: True if column is auto-increment */
+    sqlite3 *db,                /* Connection handle */
+    const char *zDbName,        /* Database name or NULL */
+    const char *zTableName,     /* Table name */
+    const char *zColumnName,    /* Column name */
+    char const **pzDataType,    /* OUTPUT: Declared data type */
+    char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
+    int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
+    int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
+    int *pAutoinc               /* OUTPUT: True if column is auto-increment */
 );
 
 /*
@@ -5062,10 +5066,10 @@ SQLITE_API int sqlite3_table_column_metadata(
 ** See also the [load_extension() SQL function].
 */
 SQLITE_API int sqlite3_load_extension(
-  sqlite3 *db,          /* Load the extension into this database connection */
-  const char *zFile,    /* Name of the shared library containing extension */
-  const char *zProc,    /* Entry point.  Derived from zFile if 0 */
-  char **pzErrMsg       /* Put error message here if not 0 */
+    sqlite3 *db,          /* Load the extension into this database connection */
+    const char *zFile,    /* Name of the shared library containing extension */
+    const char *zProc,    /* Entry point.  Derived from zFile if 0 */
+    char **pzErrMsg       /* Put error message here if not 0 */
 );
 
 /*
@@ -5149,8 +5153,8 @@ typedef struct sqlite3_module sqlite3_module;
 ** CAPI3REF: Virtual Table Object
 ** KEYWORDS: sqlite3_module {virtual table module}
 **
-** This structure, sometimes called a "virtual table module", 
-** defines the implementation of a [virtual tables].  
+** This structure, sometimes called a "virtual table module",
+** defines the implementation of a [virtual tables].
 ** This structure consists mostly of methods for the module.
 **
 ** ^A virtual table module is created by filling in a persistent
@@ -5161,39 +5165,40 @@ typedef struct sqlite3_module sqlite3_module;
 ** of this structure must not change while it is registered with
 ** any database connection.
 */
-struct sqlite3_module {
-  int iVersion;
-  int (*xCreate)(sqlite3*, void *pAux,
-               int argc, const char *const*argv,
-               sqlite3_vtab **ppVTab, char**);
-  int (*xConnect)(sqlite3*, void *pAux,
-               int argc, const char *const*argv,
-               sqlite3_vtab **ppVTab, char**);
-  int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
-  int (*xDisconnect)(sqlite3_vtab *pVTab);
-  int (*xDestroy)(sqlite3_vtab *pVTab);
-  int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
-  int (*xClose)(sqlite3_vtab_cursor*);
-  int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
-                int argc, sqlite3_value **argv);
-  int (*xNext)(sqlite3_vtab_cursor*);
-  int (*xEof)(sqlite3_vtab_cursor*);
-  int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
-  int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
-  int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
-  int (*xBegin)(sqlite3_vtab *pVTab);
-  int (*xSync)(sqlite3_vtab *pVTab);
-  int (*xCommit)(sqlite3_vtab *pVTab);
-  int (*xRollback)(sqlite3_vtab *pVTab);
-  int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
-                       void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
-                       void **ppArg);
-  int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
-  /* The methods above are in version 1 of the sqlite_module object. Those 
-  ** below are for version 2 and greater. */
-  int (*xSavepoint)(sqlite3_vtab *pVTab, int);
-  int (*xRelease)(sqlite3_vtab *pVTab, int);
-  int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
+struct sqlite3_module
+{
+    int iVersion;
+    int (*xCreate)(sqlite3 *, void *pAux,
+                   int argc, const char *const *argv,
+                   sqlite3_vtab **ppVTab, char **);
+    int (*xConnect)(sqlite3 *, void *pAux,
+                    int argc, const char *const *argv,
+                    sqlite3_vtab **ppVTab, char **);
+    int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info *);
+    int (*xDisconnect)(sqlite3_vtab *pVTab);
+    int (*xDestroy)(sqlite3_vtab *pVTab);
+    int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
+    int (*xClose)(sqlite3_vtab_cursor *);
+    int (*xFilter)(sqlite3_vtab_cursor *, int idxNum, const char *idxStr,
+                   int argc, sqlite3_value **argv);
+    int (*xNext)(sqlite3_vtab_cursor *);
+    int (*xEof)(sqlite3_vtab_cursor *);
+    int (*xColumn)(sqlite3_vtab_cursor *, sqlite3_context *, int);
+    int (*xRowid)(sqlite3_vtab_cursor *, sqlite3_int64 *pRowid);
+    int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
+    int (*xBegin)(sqlite3_vtab *pVTab);
+    int (*xSync)(sqlite3_vtab *pVTab);
+    int (*xCommit)(sqlite3_vtab *pVTab);
+    int (*xRollback)(sqlite3_vtab *pVTab);
+    int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
+                         void (**pxFunc)(sqlite3_context *, int, sqlite3_value **),
+                         void **ppArg);
+    int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
+    /* The methods above are in version 1 of the sqlite_module object. Those
+    ** below are for version 2 and greater. */
+    int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+    int (*xRelease)(sqlite3_vtab *pVTab, int);
+    int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
 };
 
 /*
@@ -5249,30 +5254,34 @@ struct sqlite3_module {
 ** a cost of N.  A binary search of a table of N entries should have a
 ** cost of approximately log(N).
 */
-struct sqlite3_index_info {
-  /* Inputs */
-  int nConstraint;           /* Number of entries in aConstraint */
-  struct sqlite3_index_constraint {
-     int iColumn;              /* Column on left-hand side of constraint */
-     unsigned char op;         /* Constraint operator */
-     unsigned char usable;     /* True if this constraint is usable */
-     int iTermOffset;          /* Used internally - xBestIndex should ignore */
-  } *aConstraint;            /* Table of WHERE clause constraints */
-  int nOrderBy;              /* Number of terms in the ORDER BY clause */
-  struct sqlite3_index_orderby {
-     int iColumn;              /* Column number */
-     unsigned char desc;       /* True for DESC.  False for ASC. */
-  } *aOrderBy;               /* The ORDER BY clause */
-  /* Outputs */
-  struct sqlite3_index_constraint_usage {
-    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
-    unsigned char omit;      /* Do not code a test for this constraint */
-  } *aConstraintUsage;
-  int idxNum;                /* Number used to identify the index */
-  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
-  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
-  int orderByConsumed;       /* True if output is already ordered */
-  double estimatedCost;      /* Estimated cost of using this index */
+struct sqlite3_index_info
+{
+    /* Inputs */
+    int nConstraint;           /* Number of entries in aConstraint */
+    struct sqlite3_index_constraint
+    {
+        int iColumn;              /* Column on left-hand side of constraint */
+        unsigned char op;         /* Constraint operator */
+        unsigned char usable;     /* True if this constraint is usable */
+        int iTermOffset;          /* Used internally - xBestIndex should ignore */
+    } *aConstraint;            /* Table of WHERE clause constraints */
+    int nOrderBy;              /* Number of terms in the ORDER BY clause */
+    struct sqlite3_index_orderby
+    {
+        int iColumn;              /* Column number */
+        unsigned char desc;       /* True for DESC.  False for ASC. */
+    } *aOrderBy;               /* The ORDER BY clause */
+    /* Outputs */
+    struct sqlite3_index_constraint_usage
+    {
+        int argvIndex;           /* if >0, constraint is part of argv to xFilter */
+        unsigned char omit;      /* Do not code a test for this constraint */
+    } *aConstraintUsage;
+    int idxNum;                /* Number used to identify the index */
+    char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
+    int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
+    int orderByConsumed;       /* True if output is already ordered */
+    double estimatedCost;      /* Estimated cost of using this index */
 };
 
 /*
@@ -5299,7 +5308,7 @@ struct sqlite3_index_info {
 ** preexisting [virtual table] for the module.
 **
 ** ^The module name is registered on the [database connection] specified
-** by the first parameter.  ^The name of the module is given by the 
+** by the first parameter.  ^The name of the module is given by the
 ** second parameter.  ^The third parameter is a pointer to
 ** the implementation of the [virtual table module].   ^The fourth
 ** parameter is an arbitrary client data pointer that is passed through
@@ -5316,17 +5325,17 @@ struct sqlite3_index_info {
 ** destructor.
 */
 SQLITE_API int sqlite3_create_module(
-  sqlite3 *db,               /* SQLite connection to register module with */
-  const char *zName,         /* Name of the module */
-  const sqlite3_module *p,   /* Methods for the module */
-  void *pClientData          /* Client data for xCreate/xConnect */
+    sqlite3 *db,               /* SQLite connection to register module with */
+    const char *zName,         /* Name of the module */
+    const sqlite3_module *p,   /* Methods for the module */
+    void *pClientData          /* Client data for xCreate/xConnect */
 );
 SQLITE_API int sqlite3_create_module_v2(
-  sqlite3 *db,               /* SQLite connection to register module with */
-  const char *zName,         /* Name of the module */
-  const sqlite3_module *p,   /* Methods for the module */
-  void *pClientData,         /* Client data for xCreate/xConnect */
-  void(*xDestroy)(void*)     /* Module destructor function */
+    sqlite3 *db,               /* SQLite connection to register module with */
+    const char *zName,         /* Name of the module */
+    const sqlite3_module *p,   /* Methods for the module */
+    void *pClientData,         /* Client data for xCreate/xConnect */
+    void(*xDestroy)(void *)    /* Module destructor function */
 );
 
 /*
@@ -5347,11 +5356,12 @@ SQLITE_API int sqlite3_create_module_v2(
 ** is delivered up to the client application, the string will be automatically
 ** freed by sqlite3_free() and the zErrMsg field will be zeroed.
 */
-struct sqlite3_vtab {
-  const sqlite3_module *pModule;  /* The module for this virtual table */
-  int nRef;                       /* NO LONGER USED */
-  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
-  /* Virtual table implementations will typically add additional fields */
+struct sqlite3_vtab
+{
+    const sqlite3_module *pModule;  /* The module for this virtual table */
+    int nRef;                       /* NO LONGER USED */
+    char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
+    /* Virtual table implementations will typically add additional fields */
 };
 
 /*
@@ -5371,9 +5381,10 @@ struct sqlite3_vtab {
 ** This superclass exists in order to define fields of the cursor that
 ** are common to all implementations.
 */
-struct sqlite3_vtab_cursor {
-  sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
-  /* Virtual table implementations will typically add additional fields */
+struct sqlite3_vtab_cursor
+{
+    sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
+    /* Virtual table implementations will typically add additional fields */
 };
 
 /*
@@ -5384,13 +5395,13 @@ struct sqlite3_vtab_cursor {
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
 */
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3 *, const char *zSQL);
 
 /*
 ** CAPI3REF: Overload A Function For A Virtual Table
 **
 ** ^(Virtual tables can provide alternative implementations of functions
-** using the [xFindFunction] method of the [virtual table module].  
+** using the [xFindFunction] method of the [virtual table module].
 ** But global versions of those functions
 ** must exist in order to be overloaded.)^
 **
@@ -5402,7 +5413,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 ** purpose is to be a placeholder function that can be overloaded
 ** by a [virtual table].
 */
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3 *, const char *zFuncName, int nArg);
 
 /*
 ** The interface to the virtual-table mechanism defined above (back up
@@ -5441,8 +5452,8 @@ typedef struct sqlite3_blob sqlite3_blob;
 **
 ** ^If the flags parameter is non-zero, then the BLOB is opened for read
 ** and write access. ^If it is zero, the BLOB is opened for read access.
-** ^It is not possible to open a column that is part of an index or primary 
-** key for writing. ^If [foreign key constraints] are enabled, it is 
+** ^It is not possible to open a column that is part of an index or primary
+** key for writing. ^If [foreign key constraints] are enabled, it is
 ** not possible to open a column that is part of a [child key] for writing.
 **
 ** ^Note that the database name is not the filename that contains
@@ -5485,13 +5496,13 @@ typedef struct sqlite3_blob sqlite3_blob;
 ** be released by a call to [sqlite3_blob_close()].
 */
 SQLITE_API int sqlite3_blob_open(
-  sqlite3*,
-  const char *zDb,
-  const char *zTable,
-  const char *zColumn,
-  sqlite3_int64 iRow,
-  int flags,
-  sqlite3_blob **ppBlob
+    sqlite3 *,
+    const char *zDb,
+    const char *zTable,
+    const char *zColumn,
+    sqlite3_int64 iRow,
+    int flags,
+    sqlite3_blob **ppBlob
 );
 
 /*
@@ -5545,7 +5556,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
 /*
 ** CAPI3REF: Return The Size Of An Open BLOB
 **
-** ^Returns the size in bytes of the BLOB accessible via the 
+** ^Returns the size in bytes of the BLOB accessible via the
 ** successfully opened [BLOB handle] in its only argument.  ^The
 ** incremental blob I/O routines can only read or overwriting existing
 ** blob content; they cannot change the size of a blob.
@@ -5653,8 +5664,8 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
 ** the default.  The choice for the new VFS is arbitrary.)^
 */
 SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *);
 
 /*
 ** CAPI3REF: Mutexes
@@ -5770,10 +5781,10 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
 */
 SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *);
 
 /*
 ** CAPI3REF: Mutex Methods Object
@@ -5841,16 +5852,17 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 ** prior to returning.
 */
 typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
-struct sqlite3_mutex_methods {
-  int (*xMutexInit)(void);
-  int (*xMutexEnd)(void);
-  sqlite3_mutex *(*xMutexAlloc)(int);
-  void (*xMutexFree)(sqlite3_mutex *);
-  void (*xMutexEnter)(sqlite3_mutex *);
-  int (*xMutexTry)(sqlite3_mutex *);
-  void (*xMutexLeave)(sqlite3_mutex *);
-  int (*xMutexHeld)(sqlite3_mutex *);
-  int (*xMutexNotheld)(sqlite3_mutex *);
+struct sqlite3_mutex_methods
+{
+    int (*xMutexInit)(void);
+    int (*xMutexEnd)(void);
+    sqlite3_mutex *(*xMutexAlloc)(int);
+    void (*xMutexFree)(sqlite3_mutex *);
+    void (*xMutexEnter)(sqlite3_mutex *);
+    int (*xMutexTry)(sqlite3_mutex *);
+    void (*xMutexLeave)(sqlite3_mutex *);
+    int (*xMutexHeld)(sqlite3_mutex *);
+    int (*xMutexNotheld)(sqlite3_mutex *);
 };
 
 /*
@@ -5883,8 +5895,8 @@ struct sqlite3_mutex_methods {
 ** interface should also return 1 when given a NULL pointer.
 */
 #ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *);
 #endif
 
 /*
@@ -5911,13 +5923,13 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
 /*
 ** CAPI3REF: Retrieve the mutex for a database connection
 **
-** ^This interface returns a pointer the [sqlite3_mutex] object that 
+** ^This interface returns a pointer the [sqlite3_mutex] object that
 ** serializes access to the [database connection] given in the argument
 ** when the [threading mode] is Serialized.
 ** ^If the [threading mode] is Single-thread or Multi-thread then this
 ** routine returns a NULL pointer.
 */
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *);
 
 /*
 ** CAPI3REF: Low-Level Control Of Database Files
@@ -5951,7 +5963,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
 **
 ** See also: [SQLITE_FCNTL_LOCKSTATE]
 */
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3 *, const char *zDbName, int op, void *);
 
 /*
 ** CAPI3REF: Testing Interface
@@ -6055,7 +6067,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 ** <dd>This parameter records the largest memory allocation request
 ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
 ** internal equivalents).  Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.  
+** *pHighwater parameter to [sqlite3_status()] is of interest.
 ** The value written into the *pCurrent parameter is undefined.</dd>)^
 **
 ** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
@@ -6064,11 +6076,11 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 **
 ** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
 ** <dd>This parameter returns the number of pages used out of the
-** [pagecache memory allocator] that was configured using 
+** [pagecache memory allocator] that was configured using
 ** [SQLITE_CONFIG_PAGECACHE].  The
 ** value returned is in pages, not in bytes.</dd>)^
 **
-** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] 
+** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]]
 ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
 ** <dd>This parameter returns the number of bytes of page cache
 ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
@@ -6081,7 +6093,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
 ** <dd>This parameter records the largest memory allocation request
 ** handed to [pagecache memory allocator].  Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.  
+** *pHighwater parameter to [sqlite3_status()] is of interest.
 ** The value written into the *pCurrent parameter is undefined.</dd>)^
 **
 ** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
@@ -6105,7 +6117,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 ** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
 ** <dd>This parameter records the largest memory allocation request
 ** handed to [scratch memory allocator].  Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.  
+** *pHighwater parameter to [sqlite3_status()] is of interest.
 ** The value written into the *pCurrent parameter is undefined.</dd>)^
 **
 ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
@@ -6129,12 +6141,12 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 /*
 ** CAPI3REF: Database Connection Status
 **
-** ^This interface is used to retrieve runtime status information 
+** ^This interface is used to retrieve runtime status information
 ** about a single [database connection].  ^The first argument is the
 ** database connection object to be interrogated.  ^The second argument
 ** is an integer constant, taken from the set of
 ** [SQLITE_DBSTATUS options], that
-** determines the parameter to interrogate.  The set of 
+** determines the parameter to interrogate.  The set of
 ** [SQLITE_DBSTATUS options] is likely
 ** to grow in future releases of SQLite.
 **
@@ -6148,7 +6160,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 **
 ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
 */
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3 *, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for database connections
@@ -6169,7 +6181,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** checked out.</dd>)^
 **
 ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
-** <dd>This parameter returns the number malloc attempts that were 
+** <dd>This parameter returns the number malloc attempts that were
 ** satisfied using lookaside memory. Only the high-water value is meaningful;
 ** the current value is always zero.)^
 **
@@ -6197,7 +6209,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
 ** <dd>This parameter returns the approximate number of of bytes of heap
 ** memory used to store the schema for all databases associated
-** with the connection - main, temp, and any [ATTACH]-ed databases.)^ 
+** with the connection - main, temp, and any [ATTACH]-ed databases.)^
 ** ^The full amount of memory used by the schemas is reported, even if the
 ** schema memory is shared with other database connections due to
 ** [shared cache mode] being enabled.
@@ -6212,13 +6224,13 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 **
 ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
 ** <dd>This parameter returns the number of pager cache hits that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT 
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
 ** is always 0.
 ** </dd>
 **
 ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
 ** <dd>This parameter returns the number of pager cache misses that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS 
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
 ** is always 0.
 ** </dd>
 **
@@ -6257,7 +6269,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** statements.  For example, if the number of table steps greatly exceeds
 ** the number of table searches or result rows, that would tend to indicate
 ** that the prepared statement is using a full table scan rather than
-** an index.  
+** an index.
 **
 ** ^(This interface is used to retrieve and reset counter values from
 ** a [prepared statement].  The first argument is the prepared statement
@@ -6270,7 +6282,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 **
 ** See also: [sqlite3_status()] and [sqlite3_db_status()].
 */
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *, int op, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for prepared statements
@@ -6284,7 +6296,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 ** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
 ** <dd>^This is the number of times that SQLite has stepped forward in
 ** a table as part of a full table scan.  Large numbers for this counter
-** may indicate opportunities for performance improvement through 
+** may indicate opportunities for performance improvement through
 ** careful use of indices.</dd>
 **
 ** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
@@ -6328,9 +6340,10 @@ typedef struct sqlite3_pcache sqlite3_pcache;
 ** See [sqlite3_pcache_methods2] for additional information.
 */
 typedef struct sqlite3_pcache_page sqlite3_pcache_page;
-struct sqlite3_pcache_page {
-  void *pBuf;        /* The content of the page */
-  void *pExtra;      /* Extra information associated with the page */
+struct sqlite3_pcache_page
+{
+    void *pBuf;        /* The content of the page */
+    void *pExtra;      /* Extra information associated with the page */
 };
 
 /*
@@ -6338,15 +6351,15 @@ struct sqlite3_pcache_page {
 ** KEYWORDS: {page cache}
 **
 ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
-** register an alternative page cache implementation by passing in an 
+** register an alternative page cache implementation by passing in an
 ** instance of the sqlite3_pcache_methods2 structure.)^
-** In many applications, most of the heap memory allocated by 
+** In many applications, most of the heap memory allocated by
 ** SQLite is used for the page cache.
-** By implementing a 
+** By implementing a
 ** custom page cache using this API, an application can better control
-** the amount of memory consumed by SQLite, the way in which 
-** that memory is allocated and released, and the policies used to 
-** determine exactly which parts of a database file are cached and for 
+** the amount of memory consumed by SQLite, the way in which
+** that memory is allocated and released, and the policies used to
+** determine exactly which parts of a database file are cached and for
 ** how long.
 **
 ** The alternative page cache mechanism is an
@@ -6359,19 +6372,19 @@ struct sqlite3_pcache_page {
 ** [sqlite3_config()] returns.)^
 **
 ** [[the xInit() page cache method]]
-** ^(The xInit() method is called once for each effective 
+** ^(The xInit() method is called once for each effective
 ** call to [sqlite3_initialize()])^
 ** (usually only once during the lifetime of the process). ^(The xInit()
 ** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
-** The intent of the xInit() method is to set up global data structures 
-** required by the custom page cache implementation. 
-** ^(If the xInit() method is NULL, then the 
+** The intent of the xInit() method is to set up global data structures
+** required by the custom page cache implementation.
+** ^(If the xInit() method is NULL, then the
 ** built-in default page cache is used instead of the application defined
 ** page cache.)^
 **
 ** [[the xShutdown() page cache method]]
 ** ^The xShutdown() method is called by [sqlite3_shutdown()].
-** It can be used to clean up 
+** It can be used to clean up
 ** any outstanding resources before process shutdown, if required.
 ** ^The xShutdown() method may be NULL.
 **
@@ -6390,7 +6403,7 @@ struct sqlite3_pcache_page {
 ** though this is not guaranteed. ^The
 ** first parameter, szPage, is the size in bytes of the pages that must
 ** be allocated by the cache.  ^szPage will always a power of two.  ^The
-** second parameter szExtra is a number of bytes of extra storage 
+** second parameter szExtra is a number of bytes of extra storage
 ** associated with each page cache entry.  ^The szExtra parameter will
 ** a number less than 250.  SQLite will use the
 ** extra szExtra bytes on each page to store metadata about the underlying
@@ -6403,7 +6416,7 @@ struct sqlite3_pcache_page {
 ** it is purely advisory.  ^On a cache where bPurgeable is false, SQLite will
 ** never invoke xUnpin() except to deliberately delete a page.
 ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
-** false will always have the "discard" flag set to true.  
+** false will always have the "discard" flag set to true.
 ** ^Hence, a cache created with bPurgeable false will
 ** never contain any unpinned pages.
 **
@@ -6418,12 +6431,12 @@ struct sqlite3_pcache_page {
 ** [[the xPagecount() page cache methods]]
 ** The xPagecount() method must return the number of pages currently
 ** stored in the cache, both pinned and unpinned.
-** 
+**
 ** [[the xFetch() page cache methods]]
-** The xFetch() method locates a page in the cache and returns a pointer to 
+** The xFetch() method locates a page in the cache and returns a pointer to
 ** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
 ** The pBuf element of the returned sqlite3_pcache_page object will be a
-** pointer to a buffer of szPage bytes used to store the content of a 
+** pointer to a buffer of szPage bytes used to store the content of a
 ** single database page.  The pExtra element of sqlite3_pcache_page will be
 ** a pointer to the szExtra bytes of extra storage that SQLite has requested
 ** for each entry in the page cache.
@@ -6462,8 +6475,8 @@ struct sqlite3_pcache_page {
 ** page cache implementation. ^The page cache implementation
 ** may choose to evict unpinned pages at any time.
 **
-** The cache must not perform any reference counting. A single 
-** call to xUnpin() unpins the page regardless of the number of prior calls 
+** The cache must not perform any reference counting. A single
+** call to xUnpin() unpins the page regardless of the number of prior calls
 ** to xFetch().
 **
 ** [[the xRekey() page cache methods]]
@@ -6493,21 +6506,22 @@ struct sqlite3_pcache_page {
 ** do their best.
 */
 typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
-struct sqlite3_pcache_methods2 {
-  int iVersion;
-  void *pArg;
-  int (*xInit)(void*);
-  void (*xShutdown)(void*);
-  sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
-  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
-  int (*xPagecount)(sqlite3_pcache*);
-  sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
-  void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
-  void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, 
-      unsigned oldKey, unsigned newKey);
-  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
-  void (*xDestroy)(sqlite3_pcache*);
-  void (*xShrink)(sqlite3_pcache*);
+struct sqlite3_pcache_methods2
+{
+    int iVersion;
+    void *pArg;
+    int (*xInit)(void *);
+    void (*xShutdown)(void *);
+    sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
+    void (*xCachesize)(sqlite3_pcache *, int nCachesize);
+    int (*xPagecount)(sqlite3_pcache *);
+    sqlite3_pcache_page *(*xFetch)(sqlite3_pcache *, unsigned key, int createFlag);
+    void (*xUnpin)(sqlite3_pcache *, sqlite3_pcache_page *, int discard);
+    void (*xRekey)(sqlite3_pcache *, sqlite3_pcache_page *,
+                   unsigned oldKey, unsigned newKey);
+    void (*xTruncate)(sqlite3_pcache *, unsigned iLimit);
+    void (*xDestroy)(sqlite3_pcache *);
+    void (*xShrink)(sqlite3_pcache *);
 };
 
 /*
@@ -6516,18 +6530,19 @@ struct sqlite3_pcache_methods2 {
 ** retained in the header file for backwards compatibility only.
 */
 typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
-struct sqlite3_pcache_methods {
-  void *pArg;
-  int (*xInit)(void*);
-  void (*xShutdown)(void*);
-  sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
-  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
-  int (*xPagecount)(sqlite3_pcache*);
-  void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
-  void (*xUnpin)(sqlite3_pcache*, void*, int discard);
-  void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
-  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
-  void (*xDestroy)(sqlite3_pcache*);
+struct sqlite3_pcache_methods
+{
+    void *pArg;
+    int (*xInit)(void *);
+    void (*xShutdown)(void *);
+    sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
+    void (*xCachesize)(sqlite3_pcache *, int nCachesize);
+    int (*xPagecount)(sqlite3_pcache *);
+    void *(*xFetch)(sqlite3_pcache *, unsigned key, int createFlag);
+    void (*xUnpin)(sqlite3_pcache *, void *, int discard);
+    void (*xRekey)(sqlite3_pcache *, void *, unsigned oldKey, unsigned newKey);
+    void (*xTruncate)(sqlite3_pcache *, unsigned iLimit);
+    void (*xDestroy)(sqlite3_pcache *);
 };
 
 
@@ -6548,7 +6563,7 @@ typedef struct sqlite3_backup sqlite3_backup;
 **
 ** The backup API copies the content of one database into another.
 ** It is useful either for creating backups of databases or
-** for copying in-memory databases to or from persistent files. 
+** for copying in-memory databases to or from persistent files.
 **
 ** See Also: [Using the SQLite Online Backup API]
 **
@@ -6559,28 +6574,28 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** ^Thus, the backup may be performed on a live source database without
 ** preventing other database connections from
 ** reading or writing to the source database while the backup is underway.
-** 
-** ^(To perform a backup operation: 
+**
+** ^(To perform a backup operation:
 **   <ol>
 **     <li><b>sqlite3_backup_init()</b> is called once to initialize the
-**         backup, 
-**     <li><b>sqlite3_backup_step()</b> is called one or more times to transfer 
+**         backup,
+**     <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
 **         the data between the two databases, and finally
-**     <li><b>sqlite3_backup_finish()</b> is called to release all resources 
-**         associated with the backup operation. 
+**     <li><b>sqlite3_backup_finish()</b> is called to release all resources
+**         associated with the backup operation.
 **   </ol>)^
 ** There should be exactly one call to sqlite3_backup_finish() for each
 ** successful call to sqlite3_backup_init().
 **
 ** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
 **
-** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the 
-** [database connection] associated with the destination database 
+** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
+** [database connection] associated with the destination database
 ** and the database name, respectively.
 ** ^The database name is "main" for the main database, "temp" for the
 ** temporary database, or the name specified after the AS keyword in
 ** an [ATTACH] statement for an attached database.
-** ^The S and M arguments passed to 
+** ^The S and M arguments passed to
 ** sqlite3_backup_init(D,N,S,M) identify the [database connection]
 ** and database name of the source database, respectively.
 ** ^The source and destination [database connections] (parameters S and D)
@@ -6596,14 +6611,14 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** ^A successful call to sqlite3_backup_init() returns a pointer to an
 ** [sqlite3_backup] object.
 ** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
-** sqlite3_backup_finish() functions to perform the specified backup 
+** sqlite3_backup_finish() functions to perform the specified backup
 ** operation.
 **
 ** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
 **
-** ^Function sqlite3_backup_step(B,N) will copy up to N pages between 
+** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
 ** the source and destination databases specified by [sqlite3_backup] object B.
-** ^If N is negative, all remaining source pages are copied. 
+** ^If N is negative, all remaining source pages are copied.
 ** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
 ** are still more pages to be copied, then the function returns [SQLITE_OK].
 ** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
@@ -6625,8 +6640,8 @@ typedef struct sqlite3_backup sqlite3_backup;
 **
 ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
 ** the [sqlite3_busy_handler | busy-handler function]
-** is invoked (if one is specified). ^If the 
-** busy-handler returns non-zero before the lock is available, then 
+** is invoked (if one is specified). ^If the
+** busy-handler returns non-zero before the lock is available, then
 ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
 ** sqlite3_backup_step() can be retried later. ^If the source
 ** [database connection]
@@ -6634,15 +6649,15 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
 ** case the call to sqlite3_backup_step() can be retried later on. ^(If
 ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
-** [SQLITE_READONLY] is returned, then 
-** there is no point in retrying the call to sqlite3_backup_step(). These 
-** errors are considered fatal.)^  The application must accept 
-** that the backup operation has failed and pass the backup operation handle 
+** [SQLITE_READONLY] is returned, then
+** there is no point in retrying the call to sqlite3_backup_step(). These
+** errors are considered fatal.)^  The application must accept
+** that the backup operation has failed and pass the backup operation handle
 ** to the sqlite3_backup_finish() to release associated resources.
 **
 ** ^The first call to sqlite3_backup_step() obtains an exclusive lock
-** on the destination file. ^The exclusive lock is not released until either 
-** sqlite3_backup_finish() is called or the backup operation is complete 
+** on the destination file. ^The exclusive lock is not released until either
+** sqlite3_backup_finish() is called or the backup operation is complete
 ** and sqlite3_backup_step() returns [SQLITE_DONE].  ^Every call to
 ** sqlite3_backup_step() obtains a [shared lock] on the source database that
 ** lasts for the duration of the sqlite3_backup_step() call.
@@ -6651,18 +6666,18 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** through the backup process.  ^If the source database is modified by an
 ** external process or via a database connection other than the one being
 ** used by the backup operation, then the backup will be automatically
-** restarted by the next call to sqlite3_backup_step(). ^If the source 
+** restarted by the next call to sqlite3_backup_step(). ^If the source
 ** database is modified by the using the same database connection as is used
 ** by the backup operation, then the backup database is automatically
 ** updated at the same time.
 **
 ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
 **
-** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the 
+** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
 ** application wishes to abandon the backup operation, the application
 ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
 ** ^The sqlite3_backup_finish() interfaces releases all
-** resources associated with the [sqlite3_backup] object. 
+** resources associated with the [sqlite3_backup] object.
 ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
 ** active write-transaction on the destination database is rolled back.
 ** The [sqlite3_backup] object is invalid
@@ -6702,8 +6717,8 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** connections, then the source database connection may be used concurrently
 ** from within other threads.
 **
-** However, the application must guarantee that the destination 
-** [database connection] is not passed to any other API (by any thread) after 
+** However, the application must guarantee that the destination
+** [database connection] is not passed to any other API (by any thread) after
 ** sqlite3_backup_init() is called and before the corresponding call to
 ** sqlite3_backup_finish().  SQLite does not currently check to see
 ** if the application incorrectly accesses the destination [database connection]
@@ -6714,11 +6729,11 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** If running in [shared cache mode], the application must
 ** guarantee that the shared cache used by the destination database
 ** is not accessed while the backup is running. In practice this means
-** that the application must guarantee that the disk file being 
+** that the application must guarantee that the disk file being
 ** backed up to is not accessed by any connection within the process,
 ** not just the specific connection that was passed to sqlite3_backup_init().
 **
-** The [sqlite3_backup] object itself is partially threadsafe. Multiple 
+** The [sqlite3_backup] object itself is partially threadsafe. Multiple
 ** threads may safely make multiple concurrent calls to sqlite3_backup_step().
 ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
 ** APIs are not strictly speaking threadsafe. If they are invoked at the
@@ -6726,10 +6741,10 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** possible that they return invalid values.
 */
 SQLITE_API sqlite3_backup *sqlite3_backup_init(
-  sqlite3 *pDest,                        /* Destination database handle */
-  const char *zDestName,                 /* Destination database name */
-  sqlite3 *pSource,                      /* Source database handle */
-  const char *zSourceName                /* Source database name */
+    sqlite3 *pDest,                        /* Destination database handle */
+    const char *zDestName,                 /* Destination database name */
+    sqlite3 *pSource,                      /* Source database handle */
+    const char *zSourceName                /* Source database name */
 );
 SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
 SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
@@ -6742,8 +6757,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** ^When running in shared-cache mode, a database operation may fail with
 ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
 ** individual tables within the shared-cache cannot be obtained. See
-** [SQLite Shared-Cache Mode] for a description of shared-cache locking. 
-** ^This API may be used to register a callback that SQLite will invoke 
+** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
+** ^This API may be used to register a callback that SQLite will invoke
 ** when the connection currently holding the required lock relinquishes it.
 ** ^This API is only available if the library was compiled with the
 ** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
@@ -6751,14 +6766,14 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** See Also: [Using the SQLite Unlock Notification Feature].
 **
 ** ^Shared-cache locks are released when a database connection concludes
-** its current transaction, either by committing it or rolling it back. 
+** its current transaction, either by committing it or rolling it back.
 **
 ** ^When a connection (known as the blocked connection) fails to obtain a
 ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
 ** identity of the database connection (the blocking connection) that
-** has locked the required resource is stored internally. ^After an 
+** has locked the required resource is stored internally. ^After an
 ** application receives an SQLITE_LOCKED error, it may call the
-** sqlite3_unlock_notify() method with the blocked connection handle as 
+** sqlite3_unlock_notify() method with the blocked connection handle as
 ** the first argument to register for a callback that will be invoked
 ** when the blocking connections current transaction is concluded. ^The
 ** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
@@ -6772,15 +6787,15 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 **
 ** ^If the blocked connection is attempting to obtain a write-lock on a
 ** shared-cache table, and more than one other connection currently holds
-** a read-lock on the same table, then SQLite arbitrarily selects one of 
+** a read-lock on the same table, then SQLite arbitrarily selects one of
 ** the other connections to use as the blocking connection.
 **
-** ^(There may be at most one unlock-notify callback registered by a 
+** ^(There may be at most one unlock-notify callback registered by a
 ** blocked connection. If sqlite3_unlock_notify() is called when the
 ** blocked connection already has a registered unlock-notify callback,
 ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
 ** called with a NULL pointer as its second argument, then any existing
-** unlock-notify callback is canceled. ^The blocked connections 
+** unlock-notify callback is canceled. ^The blocked connections
 ** unlock-notify callback may also be canceled by closing the blocked
 ** connection using [sqlite3_close()].
 **
@@ -6793,7 +6808,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 **
 ** <b>Callback Invocation Details</b>
 **
-** When an unlock-notify callback is registered, the application provides a 
+** When an unlock-notify callback is registered, the application provides a
 ** single void* pointer that is passed to the callback when it is invoked.
 ** However, the signature of the callback function allows SQLite to pass
 ** it an array of void* context pointers. The first argument passed to
@@ -6806,12 +6821,12 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** same callback function, then instead of invoking the callback function
 ** multiple times, it is invoked once with the set of void* context pointers
 ** specified by the blocked connections bundled together into an array.
-** This gives the application an opportunity to prioritize any actions 
+** This gives the application an opportunity to prioritize any actions
 ** related to the set of unblocked database connections.
 **
 ** <b>Deadlock Detection</b>
 **
-** Assuming that after registering for an unlock-notify callback a 
+** Assuming that after registering for an unlock-notify callback a
 ** database waits for the callback to be issued before taking any further
 ** action (a reasonable assumption), then using this API may cause the
 ** application to deadlock. For example, if connection X is waiting for
@@ -6834,7 +6849,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 **
 ** <b>The "DROP TABLE" Exception</b>
 **
-** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost 
+** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
 ** always appropriate to call sqlite3_unlock_notify(). There is however,
 ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
 ** SQLite checks if there are any currently executing SELECT statements
@@ -6847,13 +6862,13 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** One way around this problem is to check the extended error code returned
 ** by an sqlite3_step() call. ^(If there is a blocking connection, then the
 ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
-** the special "DROP TABLE/INDEX" case, the extended error code is just 
+** the special "DROP TABLE/INDEX" case, the extended error code is just
 ** SQLITE_LOCKED.)^
 */
 SQLITE_API int sqlite3_unlock_notify(
-  sqlite3 *pBlocked,                          /* Waiting connection */
-  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
-  void *pNotifyArg                            /* Argument to pass to xNotify */
+    sqlite3 *pBlocked,                          /* Waiting connection */
+    void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
+    void *pNotifyArg                            /* Argument to pass to xNotify */
 );
 
 
@@ -6912,10 +6927,10 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
 ** will be invoked each time a database connection commits data to a
 ** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]). 
+** [journal_mode | journal_mode=WAL mode]).
 **
-** ^The callback is invoked by SQLite after the commit has taken place and 
-** the associated write-lock on the database released, so the implementation 
+** ^The callback is invoked by SQLite after the commit has taken place and
+** the associated write-lock on the database released, so the implementation
 ** may read, write or [checkpoint] the database as required.
 **
 ** ^The first parameter passed to the callback function when it is invoked
@@ -6934,7 +6949,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 ** that does not correspond to any valid SQLite error code, the results
 ** are undefined.
 **
-** A single database handle may have at most a single write-ahead log callback 
+** A single database handle may have at most a single write-ahead log callback
 ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
 ** previously registered write-ahead log callback. ^Note that the
 ** [sqlite3_wal_autocheckpoint()] interface and the
@@ -6942,9 +6957,9 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 ** those overwrite any prior [sqlite3_wal_hook()] settings.
 */
 SQLITE_API void *sqlite3_wal_hook(
-  sqlite3*, 
-  int(*)(void *,sqlite3*,const char*,int),
-  void*
+    sqlite3 *,
+    int(*)(void *, sqlite3 *, const char *, int),
+    void *
 );
 
 /*
@@ -6954,7 +6969,7 @@ SQLITE_API void *sqlite3_wal_hook(
 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
 ** to automatically [checkpoint]
 ** after committing a transaction if there are N or
-** more frames in the [write-ahead log] file.  ^Passing zero or 
+** more frames in the [write-ahead log] file.  ^Passing zero or
 ** a negative value as the nFrame parameter disables automatic
 ** checkpoints entirely.
 **
@@ -6995,15 +7010,15 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 /*
 ** CAPI3REF: Checkpoint a database
 **
-** Run a checkpoint operation on WAL database zDb attached to database 
-** handle db. The specific operation is determined by the value of the 
+** Run a checkpoint operation on WAL database zDb attached to database
+** handle db. The specific operation is determined by the value of the
 ** eMode parameter:
 **
 ** <dl>
 ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
-**   Checkpoint as many frames as possible without waiting for any database 
+**   Checkpoint as many frames as possible without waiting for any database
 **   readers or writers to finish. Sync the db file if all frames in the log
-**   are checkpointed. This mode is the same as calling 
+**   are checkpointed. This mode is the same as calling
 **   sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
 **
 ** <dt>SQLITE_CHECKPOINT_FULL<dd>
@@ -7014,10 +7029,10 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 **   but not database readers.
 **
 ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
-**   This mode works the same way as SQLITE_CHECKPOINT_FULL, except after 
+**   This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
 **   checkpointing the log file it blocks (calls the busy-handler callback)
-**   until all readers are reading from the database file only. This ensures 
-**   that the next client to write to the database file restarts the log file 
+**   until all readers are reading from the database file only. This ensures
+**   that the next client to write to the database file restarts the log file
 **   from the beginning. This call blocks database writers while it is running,
 **   but not database readers.
 ** </dl>
@@ -7031,30 +7046,30 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 ** before returning to communicate this to the caller.
 **
 ** All calls obtain an exclusive "checkpoint" lock on the database file. If
-** any other process is running a checkpoint operation at the same time, the 
-** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a 
+** any other process is running a checkpoint operation at the same time, the
+** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a
 ** busy-handler configured, it will not be invoked in this case.
 **
-** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive 
+** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive
 ** "writer" lock on the database file. If the writer lock cannot be obtained
 ** immediately, and a busy-handler is configured, it is invoked and the writer
 ** lock retried until either the busy-handler returns 0 or the lock is
 ** successfully obtained. The busy-handler is also invoked while waiting for
 ** database readers as described above. If the busy-handler returns 0 before
 ** the writer lock is obtained or while waiting for database readers, the
-** checkpoint operation proceeds from that point in the same way as 
-** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible 
+** checkpoint operation proceeds from that point in the same way as
+** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
 ** without blocking any further. SQLITE_BUSY is returned in this case.
 **
 ** If parameter zDb is NULL or points to a zero length string, then the
 ** specified operation is attempted on all WAL databases. In this case the
-** values written to output parameters *pnLog and *pnCkpt are undefined. If 
-** an SQLITE_BUSY error is encountered when processing one or more of the 
-** attached WAL databases, the operation is still attempted on any remaining 
-** attached databases and SQLITE_BUSY is returned to the caller. If any other 
-** error occurs while processing an attached database, processing is abandoned 
-** and the error code returned to the caller immediately. If no error 
-** (SQLITE_BUSY or otherwise) is encountered while processing the attached 
+** values written to output parameters *pnLog and *pnCkpt are undefined. If
+** an SQLITE_BUSY error is encountered when processing one or more of the
+** attached WAL databases, the operation is still attempted on any remaining
+** attached databases and SQLITE_BUSY is returned to the caller. If any other
+** error occurs while processing an attached database, processing is abandoned
+** and the error code returned to the caller immediately. If no error
+** (SQLITE_BUSY or otherwise) is encountered while processing the attached
 ** databases, SQLITE_OK is returned.
 **
 ** If database zDb is the name of an attached database that is not in WAL
@@ -7063,11 +7078,11 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 ** attached database, SQLITE_ERROR is returned to the caller.
 */
 SQLITE_API int sqlite3_wal_checkpoint_v2(
-  sqlite3 *db,                    /* Database handle */
-  const char *zDb,                /* Name of attached database (or NULL) */
-  int eMode,                      /* SQLITE_CHECKPOINT_* value */
-  int *pnLog,                     /* OUT: Size of WAL log in frames */
-  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
+    sqlite3 *db,                    /* Database handle */
+    const char *zDb,                /* Name of attached database (or NULL) */
+    int eMode,                      /* SQLITE_CHECKPOINT_* value */
+    int *pnLog,                     /* OUT: Size of WAL log in frames */
+    int *pnCkpt                     /* OUT: Total number of frames checkpointed */
 );
 
 /*
@@ -7096,7 +7111,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
 ** may be added in the future.
 */
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3 *, int op, ...);
 
 /*
 ** CAPI3REF: Virtual Table Configuration Options
@@ -7120,20 +7135,20 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
 ** If X is non-zero, then the virtual table implementation guarantees
 ** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
 ** any modifications to internal or persistent data structures have been made.
-** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite 
+** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite
 ** is able to roll back a statement or database transaction, and abandon
-** or continue processing the current SQL statement as appropriate. 
+** or continue processing the current SQL statement as appropriate.
 ** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
 ** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
 ** had been ABORT.
 **
 ** Virtual table implementations that are required to handle OR REPLACE
-** must do so within the [xUpdate] method. If a call to the 
-** [sqlite3_vtab_on_conflict()] function indicates that the current ON 
-** CONFLICT policy is REPLACE, the virtual table implementation should 
+** must do so within the [xUpdate] method. If a call to the
+** [sqlite3_vtab_on_conflict()] function indicates that the current ON
+** CONFLICT policy is REPLACE, the virtual table implementation should
 ** silently replace the appropriate rows within the xUpdate callback and
 ** return SQLITE_OK. Or, if this is not possible, it may return
-** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT 
+** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT
 ** constraint handling.
 ** </dl>
 */
@@ -7213,14 +7228,14 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
 **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
 */
 SQLITE_API int sqlite3_rtree_geometry_callback(
-  sqlite3 *db,
-  const char *zGeom,
+    sqlite3 *db,
+    const char *zGeom,
 #ifdef SQLITE_RTREE_INT_ONLY
-  int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
+    int (*xGeom)(sqlite3_rtree_geometry *, int n, sqlite3_int64 *a, int *pRes),
 #else
-  int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
+    int (*xGeom)(sqlite3_rtree_geometry *, int n, double *a, int *pRes),
 #endif
-  void *pContext
+    void *pContext
 );
 
 
@@ -7228,12 +7243,13 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
 ** A pointer to a structure of the following type is passed as the first
 ** argument to callbacks registered using rtree_geometry_callback().
 */
-struct sqlite3_rtree_geometry {
-  void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
-  int nParam;                     /* Size of array aParam[] */
-  double *aParam;                 /* Parameters passed to SQL geom function */
-  void *pUser;                    /* Callback implementation user data */
-  void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
+struct sqlite3_rtree_geometry
+{
+    void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
+    int nParam;                     /* Size of array aParam[] */
+    double *aParam;                 /* Parameters passed to SQL geom function */
+    void *pUser;                    /* Callback implementation user data */
+    void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
 };
 
 
index 93502c2..20029b1 100644 (file)
@@ -92,7 +92,7 @@ CLEANUP:
 void CContextModel::registerSSMResource(IN ActivationType activationType, IN int targetDeviceDataId,
                                         IN ISSMResource *pSSMResource)
 {
-    int     *pData = NULL;
+    intptr_t     *pData = NULL;
 
     m_mtxActivationCount.lock();
     switch (activationType)
@@ -100,9 +100,9 @@ void CContextModel::registerSSMResource(IN ActivationType activationType, IN int
         case ACTIVATION_TYPE_SUBSCRIBE:
             if (m_mapSubscribedDevice.find(targetDeviceDataId) == m_mapSubscribedDevice.end())
             {
-                pData = new int[2];
+                pData = new intptr_t  [2];
                 pData[0] = STATUS_ACTIVATE;
-                pData[1] = (int)pSSMResource;
+                pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
                 m_pTasker->addTask(this, (void *)pData);
                 m_mapSubscribedDevice[targetDeviceDataId] = 1;
             }
@@ -117,9 +117,9 @@ void CContextModel::registerSSMResource(IN ActivationType activationType, IN int
             {
                 if (m_mapGetDevice.find(targetDeviceDataId) == m_mapGetDevice.end())
                 {
-                    pData = new int[2];
+                    pData = new intptr_t[2];
                     pData[0] = STATUS_START_READ_VALUE;
-                    pData[1] = (int)pSSMResource;
+                    pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
                     m_pTasker->addTask(this, (void *)pData);
                     m_mapGetDevice[targetDeviceDataId] = 1;
                 }
@@ -139,7 +139,7 @@ void CContextModel::registerSSMResource(IN ActivationType activationType, IN int
 void CContextModel::unregisterSSMResource(IN ActivationType activationType,
         IN int targetDeviceDataId, IN ISSMResource *pSSMResource)
 {
-    int     *pData = NULL;
+    intptr_t     *pData = NULL;
 
     m_mtxActivationCount.lock();
     switch (activationType)
@@ -149,9 +149,9 @@ void CContextModel::unregisterSSMResource(IN ActivationType activationType,
             {
                 if (--m_mapSubscribedDevice[targetDeviceDataId] == 0)
                 {
-                    pData = new int[2];
+                    pData = new intptr_t [2];
                     pData[0] = STATUS_DEACTIVATE;
-                    pData[1] = (int)pSSMResource;
+                    pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
                     m_pTasker->addTask(this, (void *)pData);
                     m_mapSubscribedDevice.erase(targetDeviceDataId);
                 }
@@ -163,9 +163,9 @@ void CContextModel::unregisterSSMResource(IN ActivationType activationType,
             {
                 if (--m_mapGetDevice[targetDeviceDataId] == 0)
                 {
-                    pData = new int[2];
+                    pData = new intptr_t [2];
                     pData[0] = STATUS_STOP_READ_VALUE;
-                    pData[1] = (int)pSSMResource;
+                    pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
                     m_pTasker->addTask(this, (void *)pData);
                 }
             }
@@ -213,7 +213,7 @@ SSMRESULT CContextModel::registerContextModelEvent(IN IContextModelEvent *pConte
 
 void CContextModel::onExecute(IN void *pArg)
 {
-    int *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
 
     if (m_pContextModelEvent)
     {
@@ -223,7 +223,7 @@ void CContextModel::onExecute(IN void *pArg)
 
 void CContextModel::onTerminate(IN void *pArg)
 {
-    int *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
     SAFE_ARRAY_DELETE(pData);
 }
 
index 55238ba..1e102c2 100644 (file)
@@ -83,7 +83,7 @@ void CEvaluationEngine::onSQLTrigger(IN sqlite3_context *context, IN int argc,
 void CEvaluationEngine::onExecute(IN void *pArg)
 {
     std::map<int, IEvaluationEngineEvent *>::iterator itor;
-    int     *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
 
     m_mtxTriggerId.lock();
     itor = m_mapTriggers.find(pData[0]);
@@ -97,13 +97,13 @@ void CEvaluationEngine::onExecute(IN void *pArg)
 
 void CEvaluationEngine::onTerminate(IN void *pArg)
 {
-    int *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
     SAFE_ARRAY_DELETE(pData);
 }
 
 SSMRESULT CEvaluationEngine::onWatcherTriggered(IN int triggerId, IN int dataId)
 {
-    int     *pData = new int[2];
+    intptr_t     *pData = new intptr_t[2];
     pData[0] = triggerId;
     pData[1] = dataId;
     m_pTasker->addTask(this, (void *)pData);
@@ -912,14 +912,14 @@ SSMRESULT CEvaluationEngine::watchModelData(IN int modelId, IN ModelConditionVec
     sstream << "CREATE TRIGGER WatchInsertModel" << m_iTriggerId << " AFTER INSERT ON [ModelData" <<
             modelId << "] WHEN ";
     sstream << sstreamCondition.str().c_str() << " BEGIN SELECT OnSQLTrigger(" <<
-            (int)this << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
+            reinterpret_cast<intptr_t>(this) << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
     sstream.str("");
 
     sstream << "CREATE TRIGGER WatchUpdateModel" << m_iTriggerId << " AFTER UPDATE ON [ModelData" <<
             modelId << "] WHEN ";
     sstream << sstreamCondition.str().c_str() << " BEGIN SELECT OnSQLTrigger(" <<
-            (int)this << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
+            reinterpret_cast<intptr_t>(this) << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
 
     m_mtxTriggerId.lock();
index 58d2df4..91423e6 100644 (file)
@@ -364,7 +364,7 @@ void CPropagationEngine::onExecute(IN void *pArg)
 {
     SSMRESULT res = SSM_E_FAIL;
 
-    int         *pMessage = (int *)pArg;
+    intptr_t         *pMessage = (intptr_t *)pArg;
 
     RESOURCE_EVENT_TYPE eventType = (RESOURCE_EVENT_TYPE)pMessage[0];
     ISSMResource            *pResource = (ISSMResource *)pMessage[1];
@@ -395,7 +395,7 @@ CLEANUP:
 
 void CPropagationEngine::onTerminate(IN void *pArg)
 {
-    int         *pMessage = (int *)pArg;
+    intptr_t         *pMessage = (intptr_t *)pArg;
 
     delete[] pMessage;
 }
@@ -403,10 +403,10 @@ void CPropagationEngine::onTerminate(IN void *pArg)
 int CPropagationEngine::onResourceEvent(IN RESOURCE_EVENT_TYPE eventType,
                                         IN ISSMResource *pSSMResource, IN std::string info)
 {
-    int         *pMessage = new int[2];
+    intptr_t          *pMessage = new intptr_t [2];
 
     pMessage[0] = eventType;
-    pMessage[1] = (int)pSSMResource;
+    pMessage[1] = reinterpret_cast<intptr_t>(pSSMResource);
     return (int)m_pTasker->addTask(this, (void *)pMessage);
 }
 
index 62d8eca..100de71 100644 (file)
@@ -71,7 +71,7 @@ SSMRESULT CQueryEngine::processQueryResult(IN int userTriggerId,
     IContextModel           *temp_contextmodel = NULL;
     IContextModel           *temp_contextmodel2 = NULL;
 
-    int             *pData = NULL;
+    intptr_t             *pData = NULL;
 
     CDataReader *pDataReader = NULL;
 
@@ -160,10 +160,10 @@ SSMRESULT CQueryEngine::processQueryResult(IN int userTriggerId,
 
         SSM_CLEANUP_ASSERT(pDataReader->addModelData((result_model_data_id)[i].modelName, &modelDataSet));
     }
-    pData = new int[3];
+    pData = new intptr_t [3];
     pData[0] = EVENT_TYPE_OUTER;
     pData[1] = userTriggerId;
-    pData[2] = (int)pDataReader;
+    pData[2] = reinterpret_cast<intptr_t>(pDataReader);
 
     m_pTasker->addTask(this, (void *)pData);
 
@@ -234,7 +234,7 @@ CLEANUP:
 
 void CQueryEngine::onExecute(void *pArg)
 {
-    int *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
 
     switch (pData[0])
     {
@@ -256,7 +256,7 @@ void CQueryEngine::onExecute(void *pArg)
 
 void CQueryEngine::onTerminate(void *pArg)
 {
-    int *pData = (int *)pArg;
+    intptr_t *pData = (intptr_t *)pArg;
     std::vector<result_model>   *pResult = NULL;
     CDataReader                 *pDataReader = NULL;
 
@@ -329,10 +329,10 @@ SSMRESULT CQueryEngine::executeContextQuery(IN std::string contextQuery, OUT int
         if (validateQueryResult(pConditionedQueryResult, pResult) == SSM_S_OK)
         {
             //We have valid data, let's deliver to application.
-            int *pData = new int[3];
+            intptr_t  *pData = new intptr_t [3];
             pData[0] = EVENT_TYPE_INNER;
             pData[1] = m_cqid;
-            pData[2] = (int)pResult;
+            pData[2] = reinterpret_cast<intptr_t>(pResult);
 
             m_pTasker->addTask(this, (void *)pData);
         }
index 1217284..4c690d4 100644 (file)
@@ -21,6 +21,9 @@
 #define _SSMCore_H_
 
 #include "SSMInterface.h"
+
+using namespace OIC;
+
 #include "SSMModelDefinition.h"
 
 #define IN
index 19dd122..de15320 100644 (file)
@@ -24,7 +24,7 @@
 #include "Common/InternalInterface.h"
 using namespace OC;
 
-static std::vector< OC::AttributeMap > g_vecQueryEventResults;
+static std::vector< std::map<std::string, std::string> > g_vecQueryEventResults;
 
 class CQueryEngineEvent: public IQueryEngineEvent
 {
@@ -46,7 +46,7 @@ class CQueryEngineEvent: public IQueryEngineEvent
             IModelData *pModelData = NULL;
             std::vector < std::string > affectedModels;
 
-            AttributeMap queryEventResult;
+            std::map<std::string, std::string> queryEventResult;
 
             std::stringstream sstream;
 
@@ -169,8 +169,8 @@ int SSMResourceServer::createResource()
     // This will internally create and register the resource.
     OCStackResult result = OCPlatform::registerResource(m_hSSMResource, resourceURI,
                            resourceTypeName, resourceInterface,
-                           std::bind(&SSMResourceServer::entityHandler, this, std::placeholders::_1,
-                                     std::placeholders::_2), resourceProperty);
+                           std::bind(&SSMResourceServer::entityHandler, this, std::placeholders::_1
+                                    ), resourceProperty);
 
     if (OC_STACK_OK != result)
     {
@@ -180,17 +180,21 @@ int SSMResourceServer::createResource()
     return 0;
 }
 
-OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResourceRequest > request,
-        std::shared_ptr< OCResourceResponse > response)
+OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResourceRequest > request)
 {
     SSMRESULT res = SSM_E_FAIL;
 
+    auto response = std::make_shared<OC::OCResourceResponse>();
+
     if (request)
     {
         // Get the request type and request flag
         std::string requestType = request->getRequestType();
         int requestFlag = request->getRequestHandlerFlag();
 
+        response->setRequestHandle(request->getRequestHandle());
+        response->setResourceHandle(request->getResourceHandle());
+
         if (requestFlag & RequestHandlerFlag::InitFlag)
         {
             // entity handler to perform resource initialization operations
@@ -203,7 +207,7 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
             // If the request type is GET
             if (requestType == "GET")
             {
-                AttributeMap responseAttributeMap;
+                std::map<std::string, std::string> responseAttributeMap;
 
                 OCRepresentation rep = request->getResourceRepresentation();
 
@@ -215,7 +219,12 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
 
                 if (response)
                 {
-                    rep.setAttributeMap(responseAttributeMap);
+                    for (std::map<std::string, std::string>::iterator itor =
+                             responseAttributeMap.begin(); itor != responseAttributeMap.end();
+                         ++itor)
+                    {
+                        rep.setValue(itor->first, itor->second);
+                    }
 
                     response->setErrorCode(200);
                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
@@ -225,16 +234,12 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
             {
                 OCRepresentation rep = request->getResourceRepresentation();
 
-                AttributeMap requestAttributeMap = rep.getAttributeMap();
-
                 IQueryEngine *pQueryEngine = NULL;
 
                 std::stringstream sstream;
 
-                AttributeMap responseAttributeMap;
-
                 // Process query params and do required operations ..
-                if (requestAttributeMap["command"] == "CreateQueryEngine")
+                if (rep.getValue<std::string>("command") == "CreateQueryEngine")
                 {
                     CQueryEngineEvent *queryEngineEvent = NULL;
 
@@ -242,19 +247,18 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
 
                     if (res != SSM_S_OK)
                     {
-                        responseAttributeMap["error"] = "CreateQueryEngine failed";
+                        rep.setValue("error", "CreateQueryEngine failed");
                         goto CLEANUP;
                     }
 
-                    sstream << (int) pQueryEngine;
+                    sstream << reinterpret_cast<intptr_t>(pQueryEngine);
 
                     // Register QueryEngineEvent
                     queryEngineEvent = new CQueryEngineEvent(sstream.str(), m_hSSMResource);
 
                     if (queryEngineEvent == NULL)
                     {
-                        responseAttributeMap["error"] =
-                            "QueryEngineEvent create failed";
+                        rep.setValue("error", "QueryEngineEvent create failed");
                         goto CLEANUP;
                     }
 
@@ -262,49 +266,49 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
 
                     if (res != SSM_S_OK)
                     {
-                        responseAttributeMap["error"] = "RegisterQueryEvent failed";
+                        rep.setValue("error", "RegisterQueryEvent failed");
                         goto CLEANUP;
                     }
 
-                    responseAttributeMap["queryEngineId"] = sstream.str();
+                    rep.setValue("queryEngineId", sstream.str());
                 }
-                else if (requestAttributeMap["command"] == "ReleaseQueryEngine")
+                else if (rep.getValue<std::string>("command") == "ReleaseQueryEngine")
                 {
                     pQueryEngine = (IQueryEngine *) std::stoi(
-                                       requestAttributeMap["queryEngineId"]);
+                                       rep.getValue<std::string>("queryEngineId"));
 
                     ReleaseQueryEngine(pQueryEngine);
                 }
-                else if (requestAttributeMap["command"] == "ExecuteContextQuery")
+                else if (rep.getValue<std::string>("command") == "ExecuteContextQuery")
                 {
                     int CQID = 0;
 
                     pQueryEngine = (IQueryEngine *) std::stoi(
-                                       requestAttributeMap["queryEngineId"]);
+                                       rep.getValue<std::string>("queryEngineId"));
 
                     res = pQueryEngine->executeContextQuery(
-                              requestAttributeMap["contextQuery"], &CQID);
+                              rep.getValue<std::string>("contextQuery"), &CQID);
 
                     if (res != SSM_S_OK)
                     {
-                        responseAttributeMap["error"] = "ExecuteContextQuery failed";
+                        rep.setValue("error", "ExecuteContextQuery failed");
                         goto CLEANUP;
                     }
 
                     sstream << CQID;
 
-                    responseAttributeMap["CQID"] = sstream.str();
+                    rep.setValue("CQID", sstream.str());
                 }
-                else if (requestAttributeMap["command"] == "KillContextQuery")
+                else if (rep.getValue<std::string>("command") == "KillContextQuery")
                 {
                     pQueryEngine = (IQueryEngine *) std::stoi(
-                                       requestAttributeMap["queryEngineId"]);
+                                       rep.getValue<std::string>("queryEngineId"));
 
-                    res = pQueryEngine->killContextQuery(std::stoi(requestAttributeMap["CQID"]));
+                    res = pQueryEngine->killContextQuery(std::stoi(rep.getValue<std::string>("CQID")));
 
                     if (res != SSM_S_OK)
                     {
-                        responseAttributeMap["error"] = "KillContextQuery failed";
+                        rep.setValue("error", "KillContextQuery failed");
                         goto CLEANUP;
                     }
                 }
@@ -312,8 +316,6 @@ OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResour
 CLEANUP:
                 if (response)
                 {
-                    rep.setAttributeMap(responseAttributeMap);
-
                     response->setErrorCode(200);
                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
                 }
@@ -334,5 +336,5 @@ CLEANUP:
         }
     }
 
-    return OC_EH_OK;
+    return OCPlatform::sendResponse(response) == OC_STACK_OK ? OC_EH_OK : OC_EH_ERROR;
 }
index 5206e40..71c5258 100644 (file)
@@ -34,8 +34,7 @@ class SSMResourceServer
         int initializeManager(std::string &xmlDescription);
         int terminateManager();
 
-        OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest > request,
-                                            std::shared_ptr< OC::OCResourceResponse > response);
+        OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest > request);
 
     private:
         OCResourceHandle m_hSSMResource;
index 2fbcd84..668421f 100644 (file)
@@ -150,7 +150,7 @@ void CContextExecutor::registerContext(TypeofEvent callType, ISSMResource *pSSMR
 
 void CContextExecutor::onExecute(IN void *pArg)
 {
-    int         *pMessage = (int *)pArg;
+    intptr_t         *pMessage = (intptr_t *)pArg;
 
     RESOURCE_EVENT_TYPE     eventType = (RESOURCE_EVENT_TYPE)pMessage[0];
     ISSMResource            *pResource = (ISSMResource *)pMessage[1];
@@ -191,7 +191,7 @@ void CContextExecutor::onExecute(IN void *pArg)
 
 void CContextExecutor::onTerminate(IN void *pArg)
 {
-    int         *pMessage = (int *)pArg;
+    intptr_t         *pMessage = (intptr_t *)pArg;
 
     delete[] pMessage;
 }
@@ -199,10 +199,10 @@ void CContextExecutor::onTerminate(IN void *pArg)
 int CContextExecutor::onResourceEvent(RESOURCE_EVENT_TYPE eventType, ISSMResource *pSSMResource,
                                       std::string info)
 {
-    int         *pMessage = new int[2];
+    intptr_t          *pMessage = new intptr_t [2];
 
     pMessage[0] = eventType;
-    pMessage[1] = (int)pSSMResource;
+    pMessage[1] = reinterpret_cast<intptr_t>(pSSMResource);
     return (int)m_pTasker->addTask(this, (void *)pMessage);
 }
 
index ce571d6..d4b133d 100644 (file)
@@ -322,54 +322,46 @@ SSMRESULT CContextRepository::loadSoftSensor(std::string softSensorName, ICtxDel
     InitContext InitializeContextFunction = NULL;
 
     // load dll(so)
-    res = SSM_E_FAIL;
-    for (unsigned int i = 1; i <= SSM_MODEL_RETRY; ++i)
-    {
-        sstream.str("");
 
 #ifdef WIN32
-        sstream << m_pathSoftSensors << softSensorName.c_str() << ".dll" << std::ends;
+    sstream << m_pathSoftSensors << softSensorName.c_str() << ".dll" << std::ends;
 
-        HINSTANCE hModule = NULL;
-        hModule = LoadLibraryA(sstream.str().c_str());
+    HINSTANCE hModule = NULL;
+    hModule = LoadLibraryA(sstream.str().c_str());
 
-        if (hModule != NULL)
-        {
-            InitializeContextFunction = (InitContext)GetProcAddress(hModule, "InitializeContext");
-        }
-#elif defined(LINUX)
-        sstream << m_pathSoftSensors << "lib" << softSensorName.c_str() << ".so" << std::ends;
+    if (hModule != NULL)
+    {
+        InitializeContextFunction = (InitContext)GetProcAddress(hModule, "InitializeContext");
+    }
+#else
+    //sstream << "/data/data/com.example.javaproject/lib/lib" << modelName <<".so" << std::ends;
+    sstream << m_pathSoftSensors << "lib" << softSensorName.c_str() << ".so" << std::ends;
 
-        void *hModule = NULL;
-        hModule = dlopen(sstream.str().c_str(), RTLD_LOCAL | RTLD_LAZY);
+    void *hModule = NULL;
+    hModule = dlopen(sstream.str().c_str(), RTLD_LOCAL | RTLD_LAZY);
 
-        if (hModule != NULL)
-        {
-            InitializeContextFunction = (InitContext)dlsym(hModule, "InitializeContext");
-        }
+    if (hModule != NULL)
+    {
+        InitializeContextFunction = (InitContext)dlsym(hModule, "InitializeContext");
+    }
 #endif
-        if (hModule == NULL)
-        {
-            //load library failed. raise error
-            SSM_CLEANUP_ASSERT(SSM_E_FAIL);
-            //InitializeContextFunction = NULL;
-            //continue;
-        }
-
-        if (InitializeContextFunction != NULL)
-        {
-            InitializeContextFunction(pDelegate);
-            *hSoftSensor = hModule;
-            res = SSM_S_OK;
-        }
-        else
-        {
-            //Unload module and return error
-            SSM_CLEANUP_ASSERT(unloadSoftSensor(hModule));
-            SSM_CLEANUP_ASSERT(SSM_E_FAIL);
-        }
+    if (hModule == NULL)
+    {
+        //load library failed. raise error
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+    }
 
-        break;
+    if (InitializeContextFunction != NULL)
+    {
+        InitializeContextFunction(pDelegate);
+        *hSoftSensor = hModule;
+        res = SSM_S_OK;
+    }
+    else
+    {
+        //Unload module and return error
+        SSM_CLEANUP_ASSERT(unloadSoftSensor(hModule));
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
     }
 
 CLEANUP:
@@ -419,6 +411,8 @@ SSMRESULT CContextRepository::GetCurrentPath(std::string *path)
         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
     }
 
+    buffer[length] = '\0';
+
     strPath = strrchr(buffer, '/');
 
     if (strPath == NULL)
index 0fc67b3..57dbe2c 100644 (file)
@@ -1,30 +1,30 @@
 /******************************************************************
-*
-* 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 "ResourceFinder.h"
 
 SSMRESULT CResourceFinder::finalConstruct()
 {
     SSMRESULT res = SSM_E_FAIL;
 
-    OC::PlatformConfig cfg(OC::ServiceType::InProc, OC::ModeType::Both,
-                           "0.0.0.0", 0, OC::QualityOfService::LowQos);
+    OC::PlatformConfig cfg(OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0,
+                           OC::QualityOfService::LowQos);
 
     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
 
@@ -46,31 +46,97 @@ SSMRESULT CResourceFinder::registerResourceFinderEvent(IN IResourceFinderEvent *
     return SSM_S_OK;
 }
 
-void CResourceFinder::onResourceFound(std::shared_ptr<OC::OCResource> resource)
+void CResourceFinder::onResourceFound(std::shared_ptr< OC::OCResource > resource)
 {
     if (resource)
     {
-        int     *pMessage = new int[2];
+        std::string path = resource->host() + resource->uri();
+
+        if (m_mapResourceHandler.find(path) != m_mapResourceHandler.end())
+            return;
+
+        intptr_t      *pMessage = new intptr_t [2];
         pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE;
-        pMessage[1] = (int)new std::shared_ptr<OC::OCResource>(resource);
+        pMessage[1] = reinterpret_cast<intptr_t> (new  std::shared_ptr<OC::OCResource>(resource));
 
-        std::string path = resource->host() + resource->uri();
+        std::cout << "Resource Found !! >> " << path << std::endl;
 
         m_pTasker->addTask(this, pMessage);
     }
 }
 
+void CResourceFinder::presenceHandler(OCStackResult result, const unsigned int nonce,
+                                      const std::string &hostAddress)
+{
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+    intptr_t *pMessage = NULL;
+
+    switch (result)
+    {
+        case OC_STACK_OK:
+            ret = OC::OCPlatform::findResource("",
+                                               "coap://" + hostAddress + "/oc/core?rt=SoftSensorManager.Sensor",
+                                               std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
+
+            if (ret != OC_STACK_OK)
+                SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+            break;
+
+        case OC_STACK_PRESENCE_STOPPED:
+        case OC_STACK_PRESENCE_TIMEOUT:
+            if (m_mapResources.find(hostAddress) != m_mapResources.end())
+            {
+                while (!m_mapResources[hostAddress].empty())
+                {
+                    pMessage = new intptr_t[2];
+                    pMessage[0] = RESOURCE_DISCOVER_UNINSTALL_RESOURCE;
+                    pMessage[1] = reinterpret_cast<intptr_t> (m_mapResourceHandler[m_mapResources[hostAddress].back()]);
+                    m_mapResources[hostAddress].pop_back();
+                    m_pTasker->addTask(this, pMessage);
+                }
+
+                m_mapResources.erase(hostAddress);
+            }
+            break;
+
+        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
+            break;
+
+        default:
+            break;
+    }
+
+CLEANUP:
+    ;
+}
+
 SSMRESULT CResourceFinder::startResourceFinder()
 {
-    OCStackResult res = OC_STACK_ERROR;
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+
+    OC::OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
-    res = OC::OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=SoftSensorManager.Sensor",
+    ret = OC::OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=SoftSensorManager.Sensor",
                                        std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
 
-    if (res != OC_STACK_OK)
-        return SSM_E_FAIL;
+    if (ret != OC_STACK_OK)
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
 
-    return SSM_S_OK;
+    ret = OC::OCPlatform::subscribePresence(presenceHandle, "coap://224.0.1.187",
+                                            "SoftSensorManager.Sensor",
+                                            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);
+
+    res = SSM_S_OK;
+
+CLEANUP:
+    return res;
 }
 
 SSMRESULT CResourceFinder::startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent)
@@ -86,24 +152,75 @@ SSMRESULT CResourceFinder::stopObserveResource(IN ISSMResource *pSensor)
 void CResourceFinder::onExecute(IN void *pArg)
 {
     SSMRESULT res = SSM_E_FAIL;
-    OC::QueryParamsMap  queryParams;
-    OICResourceHandler  *pResourceHandler = NULL;
-    int                 *pMessage = (int *)pArg;
-    std::shared_ptr<OC::OCResource> *pResource = NULL;
+    OCStackResult ret = OC_STACK_ERROR;
+    OC::QueryParamsMap queryParams;
+    OICResourceHandler *pResourceHandler = NULL;
+    intptr_t                 *pMessage =  reinterpret_cast<intptr_t *>(pArg);
+    std::shared_ptr< OC::OCResource > *pResource = NULL;
+    OC::OCPlatform::OCPresenceHandle presenceHandle = NULL;
+
+    std::string resourceHostAddress = "";
+    std::string resourceFullPath = "";
 
     switch (pMessage[0])
     {
         case RESOURCE_DISCOVER_REQUESTPROFILE:
-            pResource = (std::shared_ptr<OC::OCResource> *)pMessage[1];
+            pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
             pResourceHandler = new OICResourceHandler();
             SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
-            m_mapResourceHandler[pResource->get()->host() + pResource->get()->uri()] = pResourceHandler;
-            pResource->get()->get(queryParams, std::bind(&OICResourceHandler::onGetResourceProfile,
-                                  pResourceHandler, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+            resourceFullPath = pResource->get()->host() + pResource->get()->uri();
+
+            resourceHostAddress = pResource->get()->host();
+            resourceHostAddress.erase(0, 7);        // erase 'coap://'
+
+            m_mapResourceHandler[resourceFullPath] = pResourceHandler;
+
+            m_mapResources[resourceHostAddress].push_back(resourceFullPath);
+
+            ret = pResource->get()->get(queryParams,
+                                        std::bind(&OICResourceHandler::onGetResourceProfile, pResourceHandler,
+                                                  std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+            if (ret != OC_STACK_OK)
+                SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+            break;
+
+        case RESOURCE_DISCOVER_INSTALL_RESOURCE:
+            if (m_mapResourcePresenceHandles.find(((ISSMResource *)pMessage[1])->ip) ==
+                m_mapResourcePresenceHandles.end())
+            {
+                ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
+                                                        "SoftSensorManager.Sensor",
+                                                        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);
+
+                m_mapResourcePresenceHandles[((ISSMResource *)pMessage[1])->ip] = presenceHandle;
+            }
+
+            m_pResourceFinderEvent->onResourceFound((ISSMResource *) pMessage[1]);
             break;
 
-        case RESOURCE_DISCOVER_SETUP_RESOURCE:
-            m_pResourceFinderEvent->onResourceFound((ISSMResource *)pMessage[1]);
+        case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
+            m_pResourceFinderEvent->onResourceLost(&((OICResourceHandler *) pMessage[1])->m_SSMResource);
+
+            if (m_mapResourcePresenceHandles.find(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip) !=
+                m_mapResourcePresenceHandles.end())
+            {
+                ret = OC::OCPlatform::unsubscribePresence(
+                          m_mapResourcePresenceHandles[((OICResourceHandler *)pMessage[1])->m_SSMResource.ip]);
+
+                if (ret != OC_STACK_OK)
+                    SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+                m_mapResourcePresenceHandles.erase(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip);
+            }
+
+            m_mapResourceHandler.erase(((OICResourceHandler *) pMessage[1])->m_SSMResource.name);
             break;
     }
 
@@ -113,17 +230,20 @@ CLEANUP:
 
 void CResourceFinder::onTerminate(IN void *pArg)
 {
-    std::shared_ptr<OC::OCResource>     *pResource = NULL;
-    int                 *pMessage = (int *)pArg;
+    std::shared_ptr< OC::OCResource > *pResource = NULL;
+    intptr_t *pMessage = (intptr_t *)pArg;
 
     switch (pMessage[0])
     {
         case RESOURCE_DISCOVER_REQUESTPROFILE:
-            pResource = (std::shared_ptr<OC::OCResource> *)pMessage[1];
+            pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
             delete pResource;
             break;
 
-        case RESOURCE_DISCOVER_SETUP_RESOURCE:
+        case RESOURCE_DISCOVER_INSTALL_RESOURCE:
+            break;
+
+        case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
             break;
     }
 
index 0c73dc3..1ad2ccf 100644 (file)
@@ -1,22 +1,22 @@
 /******************************************************************
-*
-* 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.
+ *
+ ******************************************************************/
 #ifndef _ResourceFinder_H_
 #define _ResourceFinder_H_
 
 #include "OCPlatform.h"
 #include "OCApi.h"
 
-class CResourceFinder :
-    public CObjectRoot<CObjectMultiThreadModel>
-    , public IResourceFinder
-    , public IThreadClient
+class CResourceFinder: public CObjectRoot< CObjectMultiThreadModel >,
+    public IResourceFinder,
+    public IThreadClient
 {
     public:
         SSMRESULT queryInterface(const OID &objectID, IBase **ppObject)
@@ -39,7 +38,7 @@ class CResourceFinder :
 
             if (IsEqualOID(objectID, OID_IResourceFinder))
             {
-                IBase *pBase = (IResourceFinder *)this;
+                IBase *pBase = (IResourceFinder *) this;
                 pBase->addRef();
                 *ppObject = pBase;
                 return SSM_S_OK;
@@ -52,7 +51,9 @@ class CResourceFinder :
         void finalRelease();
 
         SSMRESULT registerResourceFinderEvent(IN IResourceFinderEvent *pEvent);
-        void onResourceFound(std::shared_ptr<OC::OCResource> resource);
+        void onResourceFound(std::shared_ptr< OC::OCResource > resource);
+        void presenceHandler(OCStackResult result, const unsigned int nonce,
+                             const std::string &hostAddress);
         SSMRESULT startResourceFinder();
 
         SSMRESULT startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent);
@@ -65,22 +66,24 @@ class CResourceFinder :
         class OICResourceHandler
         {
             public:
+                ISSMResource m_SSMResource;
+
                 OICResourceHandler()
                 {
                     m_pEvent = NULL;
                     m_pResourceFinderClient = NULL;
                 }
 
-                SSMRESULT initHandler(std::shared_ptr<OC::OCResource> resource, IN IThreadClient    *pThreadClient)
+                SSMRESULT initHandler(std::shared_ptr< OC::OCResource > resource,
+                                      IN IThreadClient *pThreadClient)
                 {
-                    SSMRESULT   res = SSM_E_FAIL;
+                    SSMRESULT res = SSM_E_FAIL;
 
                     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
                     m_pResource = resource;
                     m_pResourceFinderClient = pThreadClient;
 
-CLEANUP:
-                    return res;
+CLEANUP: return res;
                 }
 
                 SSMRESULT startObserve(IEvent *pEvent)
@@ -90,8 +93,9 @@ CLEANUP:
                     m_pEvent = pEvent;
 
                     m_pResource.get()->observe(OC::ObserveType::Observe, queryParams,
-                                               std::bind(&OICResourceHandler::onResourceDataReceived,
-                                                         this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
+                                               std::bind(&OICResourceHandler::onResourceDataReceived, this,
+                                                         std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                                                         std::placeholders::_4));
 
                     return SSM_S_OK;
                 }
@@ -104,29 +108,28 @@ CLEANUP:
                 }
 
                 void onResourceDataReceived(const OC::HeaderOptions headerOptions,
-                                            const OC::OCRepresentation &representation,
-                                            const int &eCode, const int &sequenceNumber)
+                                            const OC::OCRepresentation &representation, const int &eCode,
+                                            const int &sequenceNumber)
                 {
                     if (eCode == 0)
                     {
-                        std::vector<ContextData>        lstCtxData;
-                        ContextData             ctxData;
-                        std::map<std::string, std::string>  outputProperty;
-                        OC::AttributeMap            attributeMap = representation.getAttributeMap();
+                        std::vector< ContextData > lstCtxData;
+                        ContextData ctxData;
+                        std::map< std::string, std::string > outputProperty;
 
                         //Bind data
                         ctxData.rootName = m_pResource->uri().substr(1);
 
                         //TODO: Temporally used for json parsing limitation
-                        ctxData.outputPropertyCount = attributeMap.size() / 3;
+                        ctxData.outputPropertyCount = representation.numberOfAttributes() / 3;
 
                         if (ctxData.outputPropertyCount > 0)
                         {
-                            for (size_t i = 0; i < attributeMap.size() / 3; i++)
+                            for (int i = 0; i < ctxData.outputPropertyCount; i++)
                             {
-                                outputProperty["name"] = attributeMap.find(toString(i * 3))->second;
-                                outputProperty["type"] = attributeMap.find(toString(i * 3 + 1))->second;
-                                outputProperty["value"] = attributeMap.find(toString(i * 3 + 2))->second;
+                                outputProperty["name"] = representation.getValue<std::string>(toString(i * 3));
+                                outputProperty["type"] = representation.getValue<std::string>(toString(i * 3 + 1));
+                                outputProperty["value"] = representation.getValue<std::string>(toString(i * 3 + 2));
                                 ctxData.outputProperty.push_back(outputProperty);
                             }
 
@@ -136,7 +139,7 @@ CLEANUP:
                         }
                         else
                         {
-                            ;//Payload is empty!!
+                            ; //Payload is empty!!
                         }
                     }
                 }
@@ -147,44 +150,42 @@ CLEANUP:
                     //unpack attributeMap
 
                     //Create SSMResource using OCResource attributeMap
-                    std::map<std::string, std::string>      outputProperty;
-                    OC::AttributeMap                    attributeMap = representation.getAttributeMap();
-                    ISSMResource        *pSSMResource = new ISSMResource();
-                    pSSMResource->location = SENSOR_LOCATION_REMOTE;
-                    pSSMResource->name = m_pResource->host() + m_pResource->uri();
-                    pSSMResource->type = m_pResource->uri().substr(1);
-                    pSSMResource->ip = m_pResource->host();
+                    std::map< std::string, std::string > outputProperty;
+                    m_SSMResource.location = SENSOR_LOCATION_REMOTE;
+                    m_SSMResource.name = m_pResource->host() + m_pResource->uri();
+                    m_SSMResource.type = m_pResource->uri().substr(1);
+                    m_SSMResource.ip = m_pResource->host();
 
                     //bind default properties
                     outputProperty["name"] = "lifetime";
                     outputProperty["type"] = "int";
                     outputProperty["value"] = "0";
-                    pSSMResource->outputProperty.push_back(outputProperty);
+                    m_SSMResource.outputProperty.push_back(outputProperty);
 
                     //bind default primitive sensor property, value to resource class for schema creating
 
                     //TODO: Temporally used for json parsing limitation
-                    for (size_t i = 0; i < attributeMap.size() / 3; i++)
+                    for (int i = 0; i < representation.numberOfAttributes() / 3; i++)
                     {
-                        outputProperty["name"] = attributeMap.find(toString(i * 3))->second;
-                        outputProperty["type"] = attributeMap.find(toString(i * 3 + 1))->second;
-                        outputProperty["value"] = attributeMap.find(toString(i * 3 + 2))->second;
-                        pSSMResource->outputProperty.push_back(outputProperty);
+                        outputProperty["name"] = representation.getValue<std::string>(toString(i * 3));
+                        outputProperty["type"] = representation.getValue<std::string>(toString(i * 3 + 1));
+                        outputProperty["value"] = representation.getValue<std::string>(toString(i * 3 + 2));
+                        m_SSMResource.outputProperty.push_back(outputProperty);
                     }
                     /////////////////////////////////////////////////////
                     //
-                    int     *pMessage = new int[2];
-                    pMessage[0] = RESOURCE_DISCOVER_SETUP_RESOURCE;
-                    pMessage[1] = (int)pSSMResource;
+                    intptr_t      *pMessage = new intptr_t [2];
+                    pMessage[0] = RESOURCE_DISCOVER_INSTALL_RESOURCE;
+                    pMessage[1] = reinterpret_cast<intptr_t>(&m_SSMResource);
 
-                    m_pTasker->addTask(m_pResourceFinderClient, (void *)pMessage);
+                    m_pTasker->addTask(m_pResourceFinderClient, (void *) pMessage);
                 }
 
             private:
-                CObjectPtr<ITasker>                 m_pTasker;
-                std::shared_ptr<OC::OCResource>     m_pResource;
-                IThreadClient                       *m_pResourceFinderClient;
-                IEvent                              *m_pEvent;
+                CObjectPtr< ITasker > m_pTasker;
+                std::shared_ptr< OC::OCResource > m_pResource;
+                IThreadClient *m_pResourceFinderClient;
+                IEvent *m_pEvent;
 
                 std::string toString(int t)
                 {
@@ -194,10 +195,19 @@ CLEANUP:
                 }
         };
 
-        enum RESOURCE_DISCOVER_STATE {RESOURCE_DISCOVER_REQUESTPROFILE, RESOURCE_DISCOVER_SETUP_RESOURCE};
-        IResourceFinderEvent                *m_pResourceFinderEvent;
-        CObjectPtr<ITasker>             m_pTasker;
-        std::map<std::string , OICResourceHandler *> m_mapResourceHandler;
+        enum RESOURCE_DISCOVER_STATE
+        {
+            RESOURCE_DISCOVER_REQUESTPROFILE,
+            RESOURCE_DISCOVER_INSTALL_RESOURCE,
+            RESOURCE_DISCOVER_UNINSTALL_RESOURCE
+        };
+        IResourceFinderEvent *m_pResourceFinderEvent;
+        CObjectPtr< ITasker > m_pTasker;
+        std::map< std::string, OICResourceHandler * > m_mapResourceHandler;
+        std::map< std::string, std::vector<std::string> >
+        m_mapResources;    // <hostaddress, std::vector<resources> >
+        std::map< std::string, OC::OCPlatform::OCPresenceHandle >
+        m_mapResourcePresenceHandles;     // <hostaddress, presence handler>
 };
 
 #endif
index 925f281..545d993 100644 (file)
@@ -5,8 +5,9 @@
 Import('env')
 
 # Add third party libraries
-SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons')
-sample_env = env.Clone()
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+sample_env = lib_env.Clone()
 target_os = env.get('TARGET_OS')
 
 ######################################################################
@@ -18,7 +19,6 @@ target_os = env.get('TARGET_OS')
 ######################################################################
 if target_os == 'linux' :
        # Build linux sample app
-       SConscript('linux/ClientApp/SConscript')
+       SConscript('linux/SSMTesterApp/SConscript')
        SConscript('linux/THSensorApp/SConscript')
        SConscript('linux/THSensorApp1/SConscript')
-
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/build/makefile b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/build/makefile
new file mode 100644 (file)
index 0000000..6df468b
--- /dev/null
@@ -0,0 +1,130 @@
+# //******************************************************************
+# //
+# // 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 ../../../../build/arduino/environment.mk
+ARDUINO_DIR = /usr/share/arduino
+
+BUILD := release
+PLATFORM := arduinomega
+ARDUINO_PORT := ttyACM0
+
+SRCLIST=${wildcard ${SRC_PATH}/*.cpp}
+OBJPATH=${SRCLIST:.cpp=.o}
+OBJLIST=${notdir ${OBJPATH}}
+
+SRC_PATH=../src
+# override with `make PLATFORM=arduinomega ARDUINOWIFI=1` to enable Arduino WiFi shield
+ARDUINOWIFI := 0
+
+APP_NAME := reference
+
+TB_DIR = ../../../../../../resource/csdk
+LOGGER_DIR = $(TB_DIR)/logger
+OC_LOG_DIR = $(TB_DIR)/../oc_logger
+TBSTACK_DIR = $(TB_DIR)/stack
+TBSOCKET_DIR = $(TB_DIR)/ocsocket
+
+include $(TB_DIR)/local.properties
+include $(TB_DIR)/$(PLATFORM).properties
+
+VPATH := $(SDIR_ARD_PLATFORM)
+
+#include directories
+OCSOCK_DIR = $(TB_DIR)/ocsocket
+LOGGER_DIR = $(TB_DIR)/logger
+STACK_DIR  = $(TB_DIR)/stack
+INC_DIRS = -I$(OCSOCK_DIR)/include/ -I$(OC_LOG_DIR)/include -I$(LOGGER_DIR)/include -I$(STACK_DIR)/include -I../include
+
+CC_FLAGS.debug         := -O1 -g3 -Wall -c -fmessage-length=0 -pedantic -fpic
+CC_FLAGS.release       := -Os -Wall -c -fmessage-length=0 -fpic
+
+CFLAGS := $(CC_FLAGS.$(BUILD)) -DTB_LOG
+
+ifeq ($(ARDUINOWIFI),1)
+       CFLAGS += -DARDUINOWIFI
+       ARDUINO_SHIELD_TYPE := "/wifi_shield"
+       TRANSPORT_OBJS = $(WIFI_COBJ)
+else
+       ARDUINO_SHIELD_TYPE := "/ethernet_shield"
+       TRANSPORT_OBJS = $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ)
+endif
+
+OUT_DIR := $(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)
+
+OBJ_DIR := $(OUT_DIR)/bin
+
+all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
+
+core.a: $(PLATFORM_OBJS)
+       @cd $(OBJ_DIR) && $(AR) -x ../../../../$(TB_DIR)/$(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)/liboctbstack.a
+       $(AR) rcs $(OBJ_DIR)/$@ $(foreach obj, $^, $(OBJ_DIR)/$(obj)) $(OBJ_DIR)/*.o
+       @cd $(OBJ_DIR) && $(RANLIB) $@
+
+prep_dirs:
+       -mkdir $(PLATFORM)
+       -mkdir $(PLATFORM)/$(ARDUINO_SHIELD_TYPE)
+       -mkdir $(OUT_DIR)
+       -mkdir $(OBJ_DIR)
+
+%.o: %.c
+       $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+%.o: %.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@ 
+%.o: ${SRC_PATH}/%.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+
+$(APP_NAME).elf: $(OBJLIST) core.a
+ifeq ($(PLATFORM),arduinomega)
+       $(CC) -Os -Wl,--gc-sections,--relax $(CFLAGS_PLATFORM) $(foreach obj, $^, $(OBJ_DIR)/$(obj)) -lm -o $(OBJ_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(CXX) -Os -Wl,--gc-sections -mcpu=cortex-m3 -T/$(SDIR_ARD_CORE_3)/linker_scripts/gcc/flash.ld -Wl,-Map,$(APP_NAME).map -o $(OBJ_DIR)/$@ -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group $(foreach obj, $(APP_NAME).o $(SYSCALLS_SAM3_OBJ) $(SPI_OBJ) $(TRANSPORT_OBJS) $(VARIANT_OBJ) core.a, $(OBJ_DIR)/$(obj)) $(SDIR_ARD_CORE_3)/libsam_sam3x8e_gcc_rel.a -Wl,--end-group
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+$(APP_NAME).hex: $(APP_NAME).elf
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(OBJ_DIR)/$< $(OBJ_DIR)/$(APP_NAME).eep
+       $(AVR_OBJCOPY) -O ihex -R .eeprom $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(ARDUINO_TOOLS_DIR)/arm-none-eabi-objcopy -O binary $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+install: all
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_PROGRAMMER) -C$(ARDUINO_DIR)/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P/dev/$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(OUT_DIR)/$(APP_NAME).hex:i
+else ifeq ($(PLATFORM),arduinodue)
+       stty -F /dev/$(ARDUINO_PORT) speed 1200 cs8 -cstopb -parenb
+       $(ARDUINO_DIR)/hardware/tools/bossac -i -d --port=$(ARDUINO_PORT) -U false -e -w -v -b $(OUT_DIR)/$(APP_NAME).hex -R
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+.PHONY: clean
+
+clean: legacy_clean
+       rm -rf arduinomega
+       rm -rf arduinodue
+
+legacy_clean:
+       @rm -rf bin
+       @rm -f *.o *.d *.elf *.eep *.a *.hex *.bin *.map *-
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/bleLib.h b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/bleLib.h
new file mode 100644 (file)
index 0000000..8356098
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * bleLib.h
+ *
+ *  Created on: 2014. 11. 5.
+ *      Author: eunseok
+ */
+
+#ifndef BLELIB_H_
+#define BLELIB_H_
+
+#include "Arduino.h"
+
+#define BLE_NOCHANGE   -1
+#define BLE_MASTER             1
+#define BLE_SLAVER             0
+
+#define BLE_DISCON             200
+#define BLE_NODATA             100
+
+
+/***************************************
+ *
+ *     HM-10 BLE Module Control Class.
+ *     Target Board : Arduino-Mega.
+ *
+ **************************************/
+class Cble
+{
+public :
+       /***
+        * BLE Control Function.
+        */
+       // BLE initialization ( COM baud rate , BLE Master , Slave setting. )
+       void init(long baudRate, int ble_mode, char* SelfMaxAddr);
+
+       void StatusRead( void );
+
+       bool IsSelfArduino( void );
+
+       bool IsConnected( void );
+
+       bool pollingConnect( const char* maxAddr );
+
+       void pollingDisconnect( void );
+       // Get RSSI by BLE communication. (polling method.)
+       int pollingGetRSSI( void );
+       // Send Request to BLE Module. And, Get the response. (polling method.)
+       bool pollingRequest(const char* request, char* data, int dataLen);
+
+       int mustHaveRequest(const char* request, char* data, int dataLen);
+
+       void streamDummy( char* data, int dataLen);
+
+       /***
+        * Debug COM port to BLE COM port.
+        * BLE COM port to Debug COM port.
+        */
+       // BLE Module to Debug Serial port.
+       void BLE2Debug( int autoDiscon );
+       // Debug Serial port to BLE Module.
+       char* Debug2BLE( int BLEwrite );
+
+       /***
+        * If you first setting, you need next-function.
+        */
+       // Restore to factory setting data.
+       void FactoryReset( void );
+       // First setting of COM port.
+       void firstUartSetting( void );
+};
+
+
+
+#if 0
+#define debug_printf(...)      {                                                       \
+       char* __temp__ = (char*)malloc(sizeof(char)*2048);              \
+       sprintf(__temp__, __VA_ARGS__ );                                        \
+       Serial.print(__temp__);                                                                 \
+       free(__temp__);                                                                                                 \
+}
+#else
+#define debug_printf(...)
+#endif
+
+
+
+#endif /* BLELIB_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/oic_lanLib.h b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/include/oic_lanLib.h
new file mode 100644 (file)
index 0000000..41556f6
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * oic_lanLib.h
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#ifndef OIC_LANLIB_H_
+#define OIC_LANLIB_H_
+
+
+int ConnectToNetwork();
+
+
+#endif /* OIC_WIFILIB_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/bleLib.cpp b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/bleLib.cpp
new file mode 100644 (file)
index 0000000..c4e12d3
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * blsLib.cpp
+ *
+ *  Created on: 2014. 11. 5.
+ *      Author: eunseok
+ */
+
+#include "bleLib.h"
+#include <stdarg.h>
+
+#define ARDUINO                        1
+//#define __INTERNAL_DEBUG__           1
+
+
+#define LIMIT_COUNT                    100
+#define DUMMY_SIZE                     30
+#define DEBUG_SIZE                     DUMMY_SIZE
+#if (ARDUINO != 0)
+#define SERIAL_SIZE                    100
+#endif
+
+#define BLE            Serial2
+
+bool isConnected = false;
+int SerialCnt=0;
+int BLECnt=0;
+char SelfMaxaddr[19] = {0,};
+
+char debugD[DEBUG_SIZE]={0,};
+
+#if (ARDUINO != 0)
+char SerialData[SERIAL_SIZE]={0,};
+char BLEData[SERIAL_SIZE]={0,};
+#endif
+
+// baudRate이 115200이면, 주의해야한다.
+// Arduino Chip은 16bit Process 이므로 int형의 사이즈가 4byte형 signed int이다.
+void Cble::init(long baudRate, int ble_mode, char* SelfMaxAddr)
+{
+       debug_printf("BLE shiled is initialed.-\r\n");
+
+       if(SelfMaxAddr == NULL && ble_mode != BLE_NOCHANGE )
+       {
+               debug_printf("Error : Insert Maxaddress of Arduino BLE shiled.\r\n");
+               exit(-1);
+       }
+       sprintf(SelfMaxaddr, "%s",SelfMaxAddr);
+
+       BLE.begin(baudRate);
+       BLE.setTimeout(1);
+       delay(1000);
+
+       memset(debugD,0,DEBUG_SIZE);
+
+       if( ble_mode != BLE_NOCHANGE )
+       {
+               while( IsSelfArduino() == false )
+                       this->pollingDisconnect();
+       }
+
+       if( ble_mode == BLE_MASTER )
+       {
+               pollingRequest("AT+ROLE1", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+MODE0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+NOTI0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+       }
+       else if ( ble_mode == BLE_SLAVER )
+       {
+               pollingRequest("AT+ROLE0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+MODE2", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+NOTI0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+       }
+
+       if( ble_mode != BLE_NOCHANGE )
+       {
+               while( IsSelfArduino() == false )
+                       this->pollingDisconnect();
+       }
+
+       delay(250);
+}
+
+void Cble::StatusRead( void )
+{
+       debug_printf("StatusRead function called.\r\n");
+
+       pollingRequest("AT+ROLE?", debugD, 9);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+MODE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+IMME?", debugD, 9);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+TYPE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+POWE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+NOTI?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+PIO1?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+}
+
+bool Cble::IsConnected( void )
+{
+       return isConnected;
+}
+
+bool Cble::IsSelfArduino( void )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("IsSelfArduino is called.\r\n");
+#endif
+       int length=mustHaveRequest("AT+ADDR?", debugD, 20);
+
+       if( strstr(debugD, SelfMaxaddr) )
+       {
+               isConnected = false;
+               memset(debugD,0,length);
+               return true;
+       }
+       else
+       {
+               isConnected = true;
+               memset(debugD,0,length);
+               return false;
+       }
+}
+
+bool Cble::pollingConnect( const char* maxAddr )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("pollingConnect is called.\r\n");
+#endif
+
+#define CONNECT_SIZE           20
+
+       char cmd[CONNECT_SIZE]= {0,};
+
+       // is Connected Address ?
+       pollingRequest("AT+ADDR?", debugD, 20);
+       if( strstr(debugD, maxAddr) )
+       {
+               isConnected = true;
+               memset(debugD,0,DEBUG_SIZE);
+               return isConnected;
+       }
+       memset(debugD,0,DEBUG_SIZE);
+
+       // Try Connection.
+       sprintf(cmd, "AT+CON%s",maxAddr);
+       if( pollingRequest(cmd, debugD, 8) == false )
+       {
+               debug_printf("Error : %s command is failed.\r\n",cmd );
+               memset(debugD,0,DEBUG_SIZE);
+               pollingDisconnect();
+               return false;
+       }
+       else if( strstr(debugD,"OK+CONNA") )
+       {
+               isConnected = true;
+               memset(debugD,0,DEBUG_SIZE);
+       }
+       else
+       {
+               memset(debugD,0,DEBUG_SIZE);
+               pollingDisconnect();
+               return false;
+       }
+
+       // Confirm Connected Address.
+       pollingRequest("AT+ADDR?", debugD, 20);
+
+       if( strstr(debugD, maxAddr) == 0 )
+       {
+               isConnected = false;
+               if ( strstr(debugD, "OK+CONNF") )
+               {
+                       memset(debugD,0,DEBUG_SIZE);
+                       streamDummy(debugD, 8);
+               }
+       }
+       memset(debugD,0,DEBUG_SIZE);
+       delay(5);
+
+       return isConnected;
+
+#undef CONNECT_SIZE
+}
+
+
+#define  CMD_DISCONNECT                "(CMD_DISCON)"
+void Cble::pollingDisconnect( void )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("pollingDisconnect is called.\r\n");
+#endif
+       int length=0;
+#if (ARDUINO == 0)
+       pollingRequest("\r\n" CMD_DISCONNECT "\r\n", NULL, NULL);
+       delay(5);
+
+       length=mustHaveRequest("AT", debugD, 2);
+       if( strstr(debugD,"OK") )
+               isConnected = false;
+
+       memset(debugD,0,length);
+#else
+       if( BLE.available() )
+       {
+               if( BLE.findUntil(CMD_DISCONNECT, "\r\n") == true )
+               {
+                       debug_printf("pollingDisconnect : Detected %s command.\r\n", CMD_DISCONNECT);
+
+                       do {
+                               debug_printf("pollingDisconnect : Send AT message.\r\n");
+                               if( length )
+                                       memset(debugD, 0, length);
+
+                               length=mustHaveRequest("AT", debugD, 2);
+                       }while( strstr(debugD,"OK") == NULL );
+
+                       debug_printf("pollingDisconnect() is Success.\r\n");
+                       memset(debugD, 0, length);
+               }
+       }
+#endif
+
+       delay(5);
+}
+
+int Cble::pollingGetRSSI( void )
+{
+#define RSSI_SIZE              11
+#define RSSI_POS               7
+
+       long time_cnt=0;
+       char c=0;
+       char index=0;
+       char rssi_res[RSSI_SIZE] = {0,};
+
+       streamDummy(NULL, NULL);
+
+       if( isConnected == true )
+       {
+               BLE.write("AT+RSSI?");
+               BLE.flush();
+               delay(5);
+
+               while(1)
+               {
+                       if ( BLE.available() )
+                               c = (char)BLE.read();
+                       else
+                       {
+                               c = 0;
+                               time_cnt++;
+                       }
+
+                       if( c )
+                       {
+                               rssi_res[index] = c;
+                               index++;
+                               if( index == RSSI_SIZE-1 )
+                               {
+                                       rssi_res[index] = '\0';
+                                       goto RESULT;
+                               }
+                       }
+
+                       if( time_cnt == 0xFFFFF )
+                       {
+                               debug_printf("Error : Time Out GetRSSI().\r\n");
+                               return BLE_NODATA;
+                       }
+
+               }
+
+       RESULT :
+#ifdef __INTERNAL_DEBUG__
+               debug_printf("res= %s \r\n",rssi_res);
+#endif
+               char* Srssi = &(rssi_res[RSSI_POS]);
+               int rssi = atoi(Srssi);
+
+               return rssi;
+       }
+
+       return BLE_DISCON;
+
+#undef RSSI_POS
+#undef RSSI_SIZE
+}
+
+int Cble::mustHaveRequest(const char* request, char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       BLE.write(request);
+       BLE.flush();
+       delay(150);
+
+READ_STREAM :
+       while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+       {
+               cnt++;
+               delay(10);
+
+               if ( cnt >= LIMIT_COUNT/10 )
+               {
+#ifdef __INTERNAL_DEBUG__
+                       debug_printf("=====> Retry Request command Send. <=========\r\n");
+#endif
+                       cnt = 0;
+                       BLE.write(request);
+                       BLE.flush();
+
+                       required_length = dataLen;
+                       data_index = data;
+                       length = 0;
+                       delay(50);
+               }
+       }
+
+       required_length -= length;
+       if( required_length != 0 )
+       {
+               data_index = data_index + length;
+               length = 0;
+               goto READ_STREAM;
+       }
+
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("[ %s ] %s\r\n\r\n", request, data);
+#endif
+       return dataLen;
+}
+
+bool Cble::pollingRequest(const char* request, char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       BLE.write(request);
+       BLE.flush();
+
+       if( data_index )
+       {
+               delay(250);
+
+READ_STREAM :
+               while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                       {
+                               debug_printf("[ %s ] TimeOut : No data.\r\n\r\n", request);
+                               return false;
+                       }
+               }
+
+               required_length -= length;
+               if( required_length != 0 )
+               {
+                       data_index = data_index + length;
+                       length = 0;
+                       goto READ_STREAM;
+               }
+
+#ifdef __INTERNAL_DEBUG__
+               debug_printf("[ %s ] %s\r\n\r\n", request, data);
+#endif
+       }
+       return true;
+}
+
+void Cble::streamDummy( char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       if( data && required_length )
+       {
+READ_STREAM :
+               while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                       {
+                               debug_printf("[ streamDummy ] TimeOut : No data.\r\n\r\n");
+                               return ;
+                       }
+               }
+
+               required_length -= length;
+               if( required_length != 0 )
+               {
+                       data_index = data_index + length;
+                       length = 0;
+                       goto READ_STREAM;
+               }
+
+               debug_printf("[ streamDummy ] %s\r\n\r\n", data);
+       }
+       else
+       {
+               if( BLE.available() )
+               {
+                       BLE.readBytes(debugD, DEBUG_SIZE);
+#ifdef __INTERNAL_DEBUG__
+                       debug_printf("[ streamDummy ] %s\r\n\r\n", debugD);
+#endif
+                       memset(debugD, 0, DEBUG_SIZE);
+               }
+       }
+
+}
+
+#if (ARDUINO != 0)
+
+#define REGARD_DISCON                  5000
+int needDiscon = 0;
+unsigned long global_cnt = 0;
+
+void Cble::BLE2Debug( int autoDiscon )
+{
+       int cnt=0;
+       uint8_t length=0;
+
+       if( BLE.available() )
+       {
+               while( (length=BLE.readBytes(BLEData, SERIAL_SIZE)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                               return ;
+               }
+
+               global_cnt = 0;
+               needDiscon = 0;
+
+               Serial.println(BLEData);
+               memset(BLEData, 0, length);
+       }
+       else if ( autoDiscon )
+       {
+               global_cnt++;
+//             debug_printf("global_cnt=%u , ", global_cnt );
+//             debug_printf("needDiscon=%d\r\n", needDiscon);
+               if( !needDiscon && global_cnt >= REGARD_DISCON )
+               {
+                       needDiscon = 1;
+                       debug_printf("result : global_cnt=%u , ", global_cnt );
+                       debug_printf("needDiscon=%d\r\n", needDiscon);
+               }
+
+               if ( needDiscon )
+               {
+                       debug_printf("Auto Discon : global_cnt=%u , ", global_cnt );
+                       debug_printf("needDiscon=%d\r\n", needDiscon);
+                       if( pollingRequest("AT", debugD, 2) == true )
+                       {
+                               global_cnt = 0;
+                               needDiscon = 0;
+                       }
+               }
+       }
+}
+
+char* Cble::Debug2BLE( int BLEwrite )
+{
+       char* result = NULL;
+
+       if( Serial.available() )
+       {
+               char c = (char)Serial.read();
+
+               switch(c)
+               {
+               case '\0':
+                       return result;
+               case '\r':
+               case '\n':
+                       debug_printf("\r\n");
+                       if(BLEwrite && SerialCnt)
+                       {
+                               BLE.write(SerialData);
+                               BLE.flush();
+                       }
+
+                       result = (char*)malloc(sizeof(char)*(SerialCnt+1));
+                       memcpy(result, SerialData, SerialCnt );
+                       result[SerialCnt] = NULL;
+
+                       memset(SerialData, 0, SerialCnt+1);
+                       SerialCnt=0;
+                       break;
+               default :
+                       SerialData[SerialCnt] = c;
+                       SerialCnt++;
+                       Serial.print(c);
+                       break;
+               }
+       }
+
+       return result;
+}
+#else
+void Cble::BLE2Debug( int autoDiscon )
+{
+       ;
+}
+
+char* Cble::Debug2BLE( int BLEwrite )
+{
+        return NULL;
+}
+#endif
+
+void Cble::FactoryReset( void )
+{
+       debug_printf("FactoryReset is called.\r\n");
+
+       pollingRequest("AT+RENEW", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+}
+
+
+void Cble::firstUartSetting( void )
+{
+       debug_printf("firstUartSetting is called.\r\n");
+
+       Serial.begin(9600);
+       BLE.begin(9600);
+       BLE.setTimeout(1);
+       delay(1000);
+
+       pollingRequest("AT+BAUD4", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+
+       debug_printf("Please Power off and on.\r\n");
+       BLE.end();
+//     delay(1000);
+//
+//     BLE.begin(115200);
+//     delay(1000);
+//
+//     pollingRequest("AT", debugD, DEBUG_SIZE);
+//     memset(debugD, 0, DEBUG_SIZE);
+
+
+       exit(0);
+}
+
+
+
+
+
+
+
+
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/oic_lanLib.cpp b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/oic_lanLib.cpp
new file mode 100644 (file)
index 0000000..c4a4f26
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * oic_wifiLib.cpp
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+// proximity code e
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+
+PROGMEM const char TAG[] = "ReferenceSensor";
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+// Note : Arduino WiFi Shield currently does NOT support multicast and therefore
+// this server will NOT be listening on 224.0.1.187 multicast address.
+
+/// WiFi Shield firmware with Intel patches
+static const char INTEL_WIFI_SHIELD_FW_VER[] = "1.2.0";
+
+/// WiFi network info and credentials
+char ssid[] = "SoftSensor_AP";
+char pass[] = "1234567890";
+//char ssid[] = "SoftSensor_2.4G";
+//char pass[] = "12344321";
+
+int ConnectToNetwork()
+{
+    char *fwVersion;
+    int status = WL_IDLE_STATUS;
+    // check for the presence of the shield:
+    if (WiFi.status() == WL_NO_SHIELD)
+    {
+        OC_LOG(ERROR, TAG, PCF("WiFi shield not present"));
+        return -1;
+    }
+
+    // Verify that WiFi Shield is running the firmware with all UDP fixes
+    fwVersion = WiFi.firmwareVersion();
+    OC_LOG_V(INFO, TAG, "WiFi Shield Firmware version %s", fwVersion);
+    if ( strncmp(fwVersion, INTEL_WIFI_SHIELD_FW_VER, sizeof(INTEL_WIFI_SHIELD_FW_VER)) !=0 )
+    {
+        OC_LOG(DEBUG, TAG, PCF("!!!!! Upgrade WiFi Shield Firmware version !!!!!!"));
+        return -1;
+    }
+
+    // attempt to connect to Wifi network:
+    while (status != WL_CONNECTED)
+    {
+        OC_LOG_V(INFO, TAG, "Attempting to connect to SSID: %s", ssid);
+        status = WiFi.begin(ssid,pass);
+
+        // wait 10 seconds for connection:
+        delay(10000);
+    }
+    OC_LOG(DEBUG, TAG, PCF("Connected to wifi"));
+
+    IPAddress ip = WiFi.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    return 0;
+}
+#else
+// Arduino Ethernet Shield
+int ConnectToNetwork()
+{
+    // Note: ****Update the MAC address here with your shield's MAC address****
+    uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xB8, 0xAC};
+
+    uint8_t error = Ethernet.begin(ETHERNET_MAC);
+    if (error  == 0)
+    {
+        OC_LOG_V(ERROR, TAG, "error is: %d", error);
+        return -1;
+    }
+    IPAddress ip = Ethernet.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    return 0;
+}
+#endif //ARDUINOWIFI
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/readme.txt b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/readme.txt
new file mode 100644 (file)
index 0000000..7c041e1
--- /dev/null
@@ -0,0 +1,19 @@
+
+Followings should be done befor building Arudno applications 
+
+1. Applications on arduino conform  the Iotivity Base released on 22-Aug-2014.
+   (Ver. 22th Aug(oic-resource: commit: cdeeed62bd9b11beb2cdd340168e766088c18dac [cdeeed6]))
+
+   For successful execution, you have to copy the file, local.properties, into the following pathes:
+    - oic-resource/csdk/
+    - oic-resource/csdk/libcoap-4.1.1
+
+
+2. Time.c, Time.h should be copied in your machine and they should be refered in the Makefile as followings
+
+   Makefile path:  / oic-resource / csdk / libcoap-4.1.1 / makefile
+
+   path to be modified: 
+  
+     - INCD_ARD_TIME = -I$(ARDUINO_DIR)/libraries/Time ---> for Time.h
+     - SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time ---> for Time.c
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/reference.cpp b/service/soft-sensor-manager/SampleApp/arduino/Reference_Thing/src/reference.cpp
new file mode 100644 (file)
index 0000000..953032e
--- /dev/null
@@ -0,0 +1,308 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+#include "bleLib.h"
+#include <stdio.h>
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#include "oic_lanLib.h"
+
+#define ARDUINO_AVR_MEGA2560 1
+/// This is the port which Arduino Server will use for all unicast communication with it's peers
+#define OC_WELL_KNOWN_PORT 5683
+
+#define JSON_BASE00 "{\"href\":\"\",\"rep\":{"
+#define JSON_BASE01 "\"0\":\"MAC\",\"1\":\"string\",\"2\":\""
+#define JSON_BASE02 "\",\"3\":\"SERVICETYPE\",\"4\":\"string\",\"5\":\""
+#define JSON_BASE03 "\"}}"
+
+typedef struct REFERRESOURCE {
+    OCResourceHandle m_handle;
+    char* m_macaddress;
+    char* m_servicetype;
+} REFERResource;
+
+PROGMEM const char TAG[] = "ReferenceSensor";
+
+REFERResource REFER;
+Cble ble;
+
+char macaddress[13]={"9059AF1704D7"};
+char servicetype[15]={"BOOK"};
+
+int g_REFERUnderObservation = 0;
+
+const char *getResult(OCStackResult result);
+void createREFERResource();
+
+#define LENGTH_VAR             100
+static int base_length = 0;
+
+bool JsonGenerator( REFERResource& ref, char* jsonBuf, uint16_t buf_length )
+{
+       if( (buf_length - base_length) < LENGTH_VAR )
+       {
+               OC_LOG_V(ERROR, TAG, "Error : length is very long.");
+               return false;
+       }
+
+       sprintf(jsonBuf, JSON_BASE00 JSON_BASE01"%s",ref.m_macaddress);
+       sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03, ref.m_servicetype);
+
+       Serial.println(jsonBuf);
+
+       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.
+// See here for more details :
+// http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
+void PrintArduinoMemoryStats()
+{
+#ifdef ARDUINO_AVR_MEGA2560
+    //This var is declared in avr-libc/stdlib/malloc.c
+    //It keeps the largest address not allocated for heap
+    extern char *__brkval;
+    //address of tmp gives us the current stack boundry
+    int tmp;
+    OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
+    OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
+             ((unsigned int)&tmp - (unsigned int)__brkval));
+#endif
+}
+
+// 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 ehRet = OC_EH_OK;
+    OCEntityHandlerResponse response = {0};
+    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
+    {
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        if(OC_REST_GET == entityHandlerRequest->method)
+        {
+                if(JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
+                {
+                }
+           else
+            {
+                ehRet = OC_EH_ERROR;
+            }
+        }
+        if(OC_REST_PUT == entityHandlerRequest->method)
+        {
+            //Do something with the 'put' payload
+            if (JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
+            {
+            }
+            else
+            {
+                ehRet = OC_EH_ERROR;
+            }
+         }
+    }
+
+    if (ehRet == OC_EH_OK)
+   {
+          // Format the response.  Note this requires some info about the request
+          response.requestHandle = entityHandlerRequest->requestHandle;
+          response.resourceHandle = entityHandlerRequest->resource;
+          response.ehResult = ehRet;
+          response.payload = (unsigned char *)payload;
+          response.payloadSize = strlen(payload);
+          response.numSendVendorSpecificHeaderOptions = 0;
+          memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+          memset(response.resourceUri, 0, sizeof response.resourceUri);
+          // Indicate that response is NOT in a persistent buffer
+          response.persistentBufferFlag = 0;
+
+          // Send the response
+          if (OCDoResponse(&response) != OC_STACK_OK)
+          {
+                  OC_LOG(ERROR, TAG, "Error sending response");
+                  ehRet = OC_EH_ERROR;
+          }
+    }
+
+    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_REFERUnderObservation = 1;
+        }
+        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+        {
+            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+        }
+    }
+
+    return ehRet;
+}
+
+
+char tempdata[200];
+void ChangeREFERRepresentation (void *param)
+{
+       (void)param;
+       OCStackResult result = OC_STACK_ERROR;
+       result = OCNotifyAllObservers (REFER.m_handle, OC_NA_QOS);
+
+       OC_LOG_V(INFO, TAG, "%s", JsonGenerator( REFER, tempdata, 200));
+
+       if (OC_STACK_NO_OBSERVERS == result)
+       {
+               OC_LOG_V(INFO, TAG, "g_REFERUnderObservation is 0." );
+               g_REFERUnderObservation = 0;
+       }
+}
+
+//The setup function is called once at startup of the sketch
+void setup()
+{
+       Serial.begin(115200);
+
+   REFER.m_macaddress = macaddress;
+   REFER.m_servicetype = servicetype;
+
+       // Add your initialization code here
+       OC_LOG_INIT();
+
+       OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
+
+       // Connect to Ethernet or WiFi network
+       if (ConnectToNetwork() != 0)
+       {
+               OC_LOG(ERROR, TAG, "Unable to connect to network");
+               return;
+       }
+
+       // Initialize the OC Stack in Server mode
+       if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
+       {
+               OC_LOG(ERROR, TAG, PCF("OCStack init error"));
+               return;
+       }
+
+    OCStartPresence(60);
+       // Declare and create the example resource: PROXI
+       createREFERResource();
+
+       ble.init( (long)115200, BLE_SLAVER,  REFER.m_macaddress);
+
+//     ble.StatusRead();
+
+       char str0[] = JSON_BASE00;
+       char str1[] = JSON_BASE01;
+       char str2[] = JSON_BASE02;
+       char str3[] = JSON_BASE03;
+
+       base_length = strlen(str0)+ strlen(str1)+ strlen(str2)+ strlen(str3);
+
+       OC_LOG_V(INFO, TAG, "Program Start-\r\n");
+}
+
+// The loop function is called in an endless loop
+void loop()
+{
+    // This artificial delay is kept here to avoid endless spinning
+    // of Arduino microcontroller. Modify it as per specfic application needs.
+
+    // This call displays the amount of free SRAM available on Arduino
+    PrintArduinoMemoryStats();
+       delay(5000);
+       if (OCProcess() != OC_STACK_OK)
+       {
+               OC_LOG(ERROR, TAG, PCF("OCStack process error"));
+               return;
+       }
+       ChangeREFERRepresentation(NULL);
+
+       char* user_msg = NULL;
+       user_msg = ble.Debug2BLE( true );
+       ble.BLE2Debug( true );
+
+       if ( user_msg )
+       {
+               free( user_msg );
+               user_msg = NULL;
+       }
+}
+
+void createREFERResource() {
+
+    OCStackResult res = OCCreateResource(&REFER.m_handle,
+                                         "SoftSensorManager.Sensor",
+                                         "oc.mi.def",
+                                         "/Reference_Thing",
+                                         OCEntityHandlerCb,
+                                         OC_DISCOVERABLE|OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created REFER resource with result: %s", getResult(res));
+}
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    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_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
diff --git a/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/Makefile b/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/Makefile
deleted file mode 100644 (file)
index df3988f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
--include ../../../../build/arduino/environment.mk
-
-ARDUINO_DIR = /usr/share/arduino
-SRC_PATH=../src
-
-# override with `make PLATFORM=arduinomega ARDUINOWIFI=1` to enable Arduino WiFi shield
-ARDUINOWIFI := 0
-
-APP_NAME := thserver
-
-BUILD := release
-#BUILD := debug
-PLATFORM := arduinomega
-ARDUINO_PORT := /dev/ttyACM0
-
-OBJ_DIR := ./bin
-
-TB_DIR = ${IOT_BASE}/csdk
-BUILD_DIR = $(TB_DIR)/build/arduino
-LOGGER_DIR = $(TB_DIR)/logger
-TBSTACK_DIR = $(TB_DIR)/stack
-TBSOCKET_DIR = $(TB_DIR)/ocsocket
-
-include $(TB_DIR)/local.properties
-include $(TB_DIR)/$(PLATFORM).properties
-
-VPATH := $(SDIR_ARD_PLATFORM)
-
-#include directories
-OCSOCK_DIR = $(TB_DIR)/ocsocket
-LOGGER_DIR = $(TB_DIR)/logger
-STACK_DIR  = $(TB_DIR)/stack
-INC_DIRS = -I$(OCSOCK_DIR)/include/ -I$(LOGGER_DIR)/include -I$(STACK_DIR)/include
-
-CFLAGS := -Os -Wall -c -DTB_LOG
-
-ifeq ($(ARDUINOWIFI),1)
-       CFLAGS += -DARDUINOWIFI
-endif
-
-#all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
-all: preclean prebuild precopy prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
-
-precopy:
-#      @cd $(TB_DIR) && mkdir -p ${BUILD} && cp -Rdp release/liboctbstack.a ${BUILD}/
-
-preclean: 
-       @cd $(BUILD_DIR) && make deepclean 
-       
-prebuild:
-       @cd $(BUILD_DIR) && make PLATFORM=arduinomega ARDUINOWIFI=0
-
-core.a: $(PLATFORM_OBJS)
-       @cd $(OBJ_DIR) && $(AR) -x $(TB_DIR)/build/arduino/$(BUILD)/liboctbstack.a
-       $(AR) rcs $@ $^ $(OBJ_DIR)/*.o
-       $(RANLIB) $@
-
-prep_dirs:
-       -mkdir $(OBJ_DIR)
-
-%.o: %.c
-       $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $@
-
-%.o: %.cpp
-       $(CCPLUS) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $@
-
-%.o: ${SRC_PATH}/%.cpp
-       $(CCPLUS) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $@
-
-$(APP_NAME).elf: $(APP_NAME).o core.a
-       $(CC) -Os -Wl,--gc-sections,--relax $(CFLAGS_PLATFORM) $^ -lm -o $@
-
-$(APP_NAME).hex: $(APP_NAME).elf
-       $(AVR_OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $< $(APP_NAME).eep
-       $(AVR_OBJCOPY) -O ihex -R .eeprom $< $@
-
-install: all
-       $(AVR_PROGRAMMER) -C$(ARDUINO_DIR)/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(APP_NAME).hex:i
-
-.PHONY: clean
-
-clean:
-       @rm -f *.o *.d *.elf *.eep *.a *.hex *.bin *.map *-
-       @rm -rf $(OBJ_DIR)
-
diff --git a/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/makefile b/service/soft-sensor-manager/SampleApp/arduino/THSensorApp/build/makefile
new file mode 100644 (file)
index 0000000..0d7011d
--- /dev/null
@@ -0,0 +1,126 @@
+# //******************************************************************
+# //
+# // 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 ../../../../build/arduino/environment.mk
+ARDUINO_DIR = /usr/share/arduino
+
+BUILD := release
+PLATFORM := arduinomega
+ARDUINO_PORT := ttyACM0
+
+SRC_PATH=../src
+# override with `make PLATFORM=arduinomega ARDUINOWIFI=1` to enable Arduino WiFi shield
+ARDUINOWIFI := 0
+
+APP_NAME := thserver
+
+TB_DIR = ../../../../../../resource/csdk
+LOGGER_DIR = $(TB_DIR)/logger
+OC_LOG_DIR = $(TB_DIR)/../oc_logger
+TBSTACK_DIR = $(TB_DIR)/stack
+TBSOCKET_DIR = $(TB_DIR)/ocsocket
+
+include $(TB_DIR)/local.properties
+include $(TB_DIR)/$(PLATFORM).properties
+
+VPATH := $(SDIR_ARD_PLATFORM)
+
+#include directories
+OCSOCK_DIR = $(TB_DIR)/ocsocket
+LOGGER_DIR = $(TB_DIR)/logger
+STACK_DIR  = $(TB_DIR)/stack
+INC_DIRS = -I$(OCSOCK_DIR)/include/ -I$(OC_LOG_DIR)/include -I$(LOGGER_DIR)/include -I$(STACK_DIR)/include
+
+CC_FLAGS.debug         := -O1 -g3 -Wall -c -fmessage-length=0 -pedantic -fpic
+CC_FLAGS.release       := -Os -Wall -c -fmessage-length=0 -fpic
+
+CFLAGS := $(CC_FLAGS.$(BUILD)) -DTB_LOG
+
+ifeq ($(ARDUINOWIFI),1)
+       CFLAGS += -DARDUINOWIFI
+       ARDUINO_SHIELD_TYPE := "/wifi_shield"
+       TRANSPORT_OBJS = $(WIFI_COBJ)
+else
+       ARDUINO_SHIELD_TYPE := "/ethernet_shield"
+       TRANSPORT_OBJS = $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ)
+endif
+
+OUT_DIR := $(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)
+
+OBJ_DIR := $(OUT_DIR)/bin
+
+all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
+
+core.a: $(PLATFORM_OBJS)
+       @cd $(OBJ_DIR) && $(AR) -x ../../../../$(TB_DIR)/$(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)/liboctbstack.a
+       $(AR) rcs $(OBJ_DIR)/$@ $(foreach obj, $^, $(OBJ_DIR)/$(obj)) $(OBJ_DIR)/*.o
+       @cd $(OBJ_DIR) && $(RANLIB) $@
+
+prep_dirs:
+       -mkdir $(PLATFORM)
+       -mkdir $(PLATFORM)/$(ARDUINO_SHIELD_TYPE)
+       -mkdir $(OUT_DIR)
+       -mkdir $(OBJ_DIR)
+
+%.o: %.c
+       $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+%.o: %.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@ 
+%.o: ${SRC_PATH}/%.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+
+$(APP_NAME).elf: $(APP_NAME).o core.a
+ifeq ($(PLATFORM),arduinomega)
+       $(CC) -Os -Wl,--gc-sections,--relax $(CFLAGS_PLATFORM) $(foreach obj, $^, $(OBJ_DIR)/$(obj)) -lm -o $(OBJ_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(CXX) -Os -Wl,--gc-sections -mcpu=cortex-m3 -T/$(SDIR_ARD_CORE_3)/linker_scripts/gcc/flash.ld -Wl,-Map,$(APP_NAME).map -o $(OBJ_DIR)/$@ -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group $(foreach obj, $(APP_NAME).o $(SYSCALLS_SAM3_OBJ) $(SPI_OBJ) $(TRANSPORT_OBJS) $(VARIANT_OBJ) core.a, $(OBJ_DIR)/$(obj)) $(SDIR_ARD_CORE_3)/libsam_sam3x8e_gcc_rel.a -Wl,--end-group
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+$(APP_NAME).hex: $(APP_NAME).elf
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(OBJ_DIR)/$< $(OBJ_DIR)/$(APP_NAME).eep
+       $(AVR_OBJCOPY) -O ihex -R .eeprom $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(ARDUINO_TOOLS_DIR)/arm-none-eabi-objcopy -O binary $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+install: all
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_PROGRAMMER) -C$(ARDUINO_DIR)/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P/dev/$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(OUT_DIR)/$(APP_NAME).hex:i
+else ifeq ($(PLATFORM),arduinodue)
+       stty -F /dev/$(ARDUINO_PORT) speed 1200 cs8 -cstopb -parenb
+       $(ARDUINO_DIR)/hardware/tools/bossac -i -d --port=$(ARDUINO_PORT) -U false -e -w -v -b $(OUT_DIR)/$(APP_NAME).hex -R
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+.PHONY: clean
+
+clean: legacy_clean
+       rm -rf arduinomega
+       rm -rf arduinodue
+
+legacy_clean:
+       @rm -rf bin
+       @rm -f *.o *.d *.elf *.eep *.a *.hex *.bin *.map *-
index 572d372..fe41441 100644 (file)
@@ -58,14 +58,35 @@ typedef struct THRESOURCE
 
 static THResource TH;
 
-String g_responsePayloadPut =
-    "{\"href\":\"\",\"rep\":{\"0\":\"temperature\",\"1\":\"int\",\"2\":\"0\",\"3\":\"humidity\",\"4\":\"int\",\"5\":\"0\"}}";
-String g_responsePayloadGet =
-    "{\"href\":\"\",\"rep\":{\"0\":\"temperature\",\"1\":\"int\",\"2\":\"0\",\"3\":\"humidity\",\"4\":\"int\",\"5\":\"0\"}}";
-
 /// This is the port which Arduino Server will use for all unicast communication with it's peers
 static uint16_t OC_WELL_KNOWN_PORT = 5683;
 
+#define JSON_BASE00 "{\"href\":\"\",\"rep\":{"
+#define JSON_BASE01 "\"0\":\"temperature\",\"1\":\"int\",\"2\":\""
+#define JSON_BASE02 "\",\"3\":\"humidity\",\"4\":\"int\",\"5\":\""
+#define JSON_BASE03 "\"}}"
+
+char temp[100];
+
+#define LENGTH_VAR             100
+static int base_length = 0;
+
+bool JsonGenerator( THResource& th, char* jsonBuf, uint16_t buf_length )
+{
+       if( (buf_length - base_length) < LENGTH_VAR )
+       {
+               OC_LOG_V(ERROR, TAG, "Error : length is very long.");
+               return false;
+       }
+
+       sprintf(jsonBuf, JSON_BASE00 JSON_BASE01"%d",th.m_temp);
+       sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE02"%d"JSON_BASE03, th.m_humid);
+
+       Serial.println(jsonBuf);
+
+       return true;
+}
+
 byte read_dht11_dat()
 {
     byte i = 0;
@@ -93,6 +114,9 @@ static const char INTEL_WIFI_SHIELD_FW_VER[] = "1.2.0";
 char ssid[] = "SoftSensor_AP";
 char pass[] = "1234567890";
 
+//char ssid[] = "Iotivity-1";
+//char pass[] = "1234567890";
+
 int ConnectToNetwork()
 {
     char *fwVersion;
@@ -141,7 +165,8 @@ int ConnectToNetwork()
         OC_LOG_V(ERROR, TAG, "error is: %d", error);
         return -1;
     }
-    OC_LOG_V(INFO, TAG, "IPAddress : %s", Serial.print(Ethernet.localIP()));
+    IPAddress ip = Ethernet.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
     return 0;
 }
 #endif //ARDUINOWIFI
@@ -159,90 +184,84 @@ void PrintArduinoMemoryStats()
     extern char *__brkval;
     //address of tmp gives us the current stack boundry
     int tmp;
+    OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
     OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
              ((unsigned int)&tmp - (unsigned int)__brkval));
 #endif
 }
 
+
 // 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 )
 {
     OCEntityHandlerResult ehRet = OC_EH_OK;
-    const char *typeOfMessage;
-
-    switch (flag)
-    {
-        case OC_INIT_FLAG:
-            typeOfMessage = "OC_INIT_FLAG";
-            break;
-        case OC_REQUEST_FLAG:
-            typeOfMessage = "OC_REQUEST_FLAG";
-            break;
-        case OC_OBSERVE_FLAG:
-            typeOfMessage = "OC_OBSERVE_FLAG";
-            break;
-        default:
-            typeOfMessage = "UNKNOWN";
-    }
-    OC_LOG_V(INFO, TAG, "Receiving message type: %s", typeOfMessage);
+    OCEntityHandlerResponse response = {0};
+    char payload[MAX_RESPONSE_LENGTH] = {0};
 
-    if (entityHandlerRequest && flag == OC_REQUEST_FLAG)
+    if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
     {
-        if (OC_REST_GET == entityHandlerRequest->method)
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        if(OC_REST_GET == entityHandlerRequest->method)
         {
-            int str_len = g_responsePayloadGet.length() + 1;
-            char charBuf[str_len + 1];
-
-            g_responsePayloadGet.toCharArray(charBuf, str_len);
-
-            if (strlen(charBuf) < entityHandlerRequest->resJSONPayloadLen)
+               if(JsonGenerator( TH, payload, MAX_RESPONSE_LENGTH))
+                {
+                }
+           else
             {
-                strncpy((char *)entityHandlerRequest->resJSONPayload, charBuf,
-                        entityHandlerRequest->resJSONPayloadLen);
-            }
-            else
                 ehRet = OC_EH_ERROR;
+            }
         }
-        if (OC_REST_PUT == entityHandlerRequest->method)
+        if(OC_REST_PUT == entityHandlerRequest->method)
         {
-
-            int str_len1 = g_responsePayloadPut.length() + 1;
-            char charBuf1[str_len1];
-
-            g_responsePayloadPut.toCharArray(charBuf1, str_len1);
-
-            if (strlen(charBuf1) < entityHandlerRequest->resJSONPayloadLen)
+            //Do something with the 'put' payload
+            if (JsonGenerator( TH, payload, MAX_RESPONSE_LENGTH))
             {
-                strncpy((char *)entityHandlerRequest->resJSONPayload, charBuf1,
-                        entityHandlerRequest->resJSONPayloadLen);
             }
             else
+            {
                 ehRet = OC_EH_ERROR;
-        }
+            }
+         }
+
+        if (ehRet == OC_EH_OK)
+               {
+                       // Format the response.  Note this requires some info about the request
+                       response.requestHandle = entityHandlerRequest->requestHandle;
+                       response.resourceHandle = entityHandlerRequest->resource;
+                       response.ehResult = ehRet;
+                       response.payload = (unsigned char *)payload;
+                       response.payloadSize = strlen(payload);
+                       response.numSendVendorSpecificHeaderOptions = 0;
+                       memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+                       memset(response.resourceUri, 0, sizeof response.resourceUri);
+                       // Indicate that response is NOT in a persistent buffer
+                       response.persistentBufferFlag = 0;
+
+                       // Send the response
+                       if (OCDoResponse(&response) != OC_STACK_OK)
+                       {
+                               OC_LOG(ERROR, TAG, "Error sending response");
+                               ehRet = OC_EH_ERROR;
+                       }
+               }
     }
-    else if (entityHandlerRequest && flag == OC_OBSERVE_FLAG)
+    if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
     {
-        g_THUnderObservation = 1;
+        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
+        {
+            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
+            g_THUnderObservation = 1;
+        }
+        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+        {
+            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+        }
     }
 
     return ehRet;
 }
 
-/* Json Generator */
-String JsonGenerator(THResource TH)
-{
-    String a = "{\"href\":\"\",\"rep\":{\"0\":\"temperature\",\"1\":\"int\",\"2\":\"";
-    String b = "\",\"3\":\"humidity\",\"4\":\"int\",\"5\":\"";
-    String c = "\"}}";
-
-    String ss;
-
-    ss = a + TH.m_temp + b + TH.m_humid + c;
-    return ss;
-}
-
 // This method is used to display 'Observe' functionality of OC Stack.
 static uint8_t modCounter = 0;
 void *ChangeTHRepresentation (void *param)
@@ -297,18 +316,15 @@ void *ChangeTHRepresentation (void *param)
         Serial.print(dht11_dat[2], DEC);
         Serial.println("C  ");
 
-// delay(2000); //fresh time
         TH.m_humid = dht11_dat[0];
         TH.m_temp = dht11_dat[2];
 
-        g_responsePayloadGet = JsonGenerator(TH);
-
-        if (g_THUnderObservation)
+           if (g_THUnderObservation)
         {
             OC_LOG_V(INFO, TAG, " =====> Notifying stack of new humid level %d\n", TH.m_humid);
             OC_LOG_V(INFO, TAG, " =====> Notifying stack of new temp level %d\n", TH.m_temp);
 
-            result = OCNotifyObservers (TH.m_handle);
+            result = OCNotifyAllObservers (TH.m_handle, OC_NA_QOS);
 
             if (OC_STACK_NO_OBSERVERS == result)
             {
@@ -346,7 +362,7 @@ void setup()
         OC_LOG(ERROR, TAG, PCF("OCStack init error"));
         return;
     }
-
+    OCStartPresence(60);
     // Declare and create the example resource: TH
     createTHResource();
 
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/build/makefile b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/build/makefile
new file mode 100644 (file)
index 0000000..d21b780
--- /dev/null
@@ -0,0 +1,130 @@
+# //******************************************************************
+# //
+# // 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 ../../../../build/arduino/environment.mk
+ARDUINO_DIR = /usr/share/arduino
+
+BUILD := release
+PLATFORM := arduinomega
+ARDUINO_PORT := ttyACM0
+
+SRCLIST=${wildcard ${SRC_PATH}/*.cpp}
+OBJPATH=${SRCLIST:.cpp=.o}
+OBJLIST=${notdir ${OBJPATH}}
+
+SRC_PATH=../src
+# override with `make PLATFORM=arduinomega ARDUINOWIFI=1` to enable Arduino WiFi shield
+ARDUINOWIFI := 0
+
+APP_NAME := trackee
+
+TB_DIR = ../../../../../../resource/csdk
+LOGGER_DIR = $(TB_DIR)/logger
+OC_LOG_DIR = $(TB_DIR)/../oc_logger
+TBSTACK_DIR = $(TB_DIR)/stack
+TBSOCKET_DIR = $(TB_DIR)/ocsocket
+
+include $(TB_DIR)/local.properties
+include $(TB_DIR)/$(PLATFORM).properties
+
+VPATH := $(SDIR_ARD_PLATFORM)
+
+#include directories
+OCSOCK_DIR = $(TB_DIR)/ocsocket
+LOGGER_DIR = $(TB_DIR)/logger
+STACK_DIR  = $(TB_DIR)/stack
+INC_DIRS = -I$(OCSOCK_DIR)/include/ -I$(OC_LOG_DIR)/include -I$(LOGGER_DIR)/include -I$(STACK_DIR)/include -I../include
+
+CC_FLAGS.debug         := -O1 -g3 -Wall -c -fmessage-length=0 -pedantic -fpic
+CC_FLAGS.release       := -Os -Wall -c -fmessage-length=0 -fpic
+
+CFLAGS := $(CC_FLAGS.$(BUILD)) -DTB_LOG
+
+ifeq ($(ARDUINOWIFI),1)
+       CFLAGS += -DARDUINOWIFI
+       ARDUINO_SHIELD_TYPE := "/wifi_shield"
+       TRANSPORT_OBJS = $(WIFI_COBJ)
+else
+       ARDUINO_SHIELD_TYPE := "/ethernet_shield"
+       TRANSPORT_OBJS = $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ)
+endif
+
+OUT_DIR := $(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)
+
+OBJ_DIR := $(OUT_DIR)/bin
+
+all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
+
+core.a: $(PLATFORM_OBJS)
+       @cd $(OBJ_DIR) && $(AR) -x ../../../../$(TB_DIR)/$(PLATFORM)$(ARDUINO_SHIELD_TYPE)/$(BUILD)/liboctbstack.a
+       $(AR) rcs $(OBJ_DIR)/$@ $(foreach obj, $^, $(OBJ_DIR)/$(obj)) $(OBJ_DIR)/*.o
+       @cd $(OBJ_DIR) && $(RANLIB) $@
+
+prep_dirs:
+       -mkdir $(PLATFORM)
+       -mkdir $(PLATFORM)/$(ARDUINO_SHIELD_TYPE)
+       -mkdir $(OUT_DIR)
+       -mkdir $(OBJ_DIR)
+
+%.o: %.c
+       $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+%.o: %.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@ 
+%.o: ${SRC_PATH}/%.cpp
+       $(CXX) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIRS) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@
+
+$(APP_NAME).elf: $(OBJLIST) core.a
+ifeq ($(PLATFORM),arduinomega)
+       $(CC) -Os -Wl,--gc-sections,--relax $(CFLAGS_PLATFORM) $(foreach obj, $^, $(OBJ_DIR)/$(obj)) -lm -o $(OBJ_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(CXX) -Os -Wl,--gc-sections -mcpu=cortex-m3 -T/$(SDIR_ARD_CORE_3)/linker_scripts/gcc/flash.ld -Wl,-Map,$(APP_NAME).map -o $(OBJ_DIR)/$@ -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group $(foreach obj, $(APP_NAME).o $(SYSCALLS_SAM3_OBJ) $(SPI_OBJ) $(TRANSPORT_OBJS) $(VARIANT_OBJ) core.a, $(OBJ_DIR)/$(obj)) $(SDIR_ARD_CORE_3)/libsam_sam3x8e_gcc_rel.a -Wl,--end-group
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+$(APP_NAME).hex: $(APP_NAME).elf
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(OBJ_DIR)/$< $(OBJ_DIR)/$(APP_NAME).eep
+       $(AVR_OBJCOPY) -O ihex -R .eeprom $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else ifeq ($(PLATFORM),arduinodue)
+       $(ARDUINO_TOOLS_DIR)/arm-none-eabi-objcopy -O binary $(OBJ_DIR)/$< $(OUT_DIR)/$@
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+install: all
+ifeq ($(PLATFORM),arduinomega)
+       $(AVR_PROGRAMMER) -C$(ARDUINO_DIR)/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P/dev/$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(OUT_DIR)/$(APP_NAME).hex:i
+else ifeq ($(PLATFORM),arduinodue)
+       stty -F /dev/$(ARDUINO_PORT) speed 1200 cs8 -cstopb -parenb
+       $(ARDUINO_DIR)/hardware/tools/bossac -i -d --port=$(ARDUINO_PORT) -U false -e -w -v -b $(OUT_DIR)/$(APP_NAME).hex -R
+else
+       $(error Wrong value for PLATFORM !!)
+endif
+
+.PHONY: clean
+
+clean: legacy_clean
+       rm -rf arduinomega
+       rm -rf arduinodue
+
+legacy_clean:
+       @rm -rf bin
+       @rm -f *.o *.d *.elf *.eep *.a *.hex *.bin *.map *-
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/bleLib.h b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/bleLib.h
new file mode 100644 (file)
index 0000000..8356098
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * bleLib.h
+ *
+ *  Created on: 2014. 11. 5.
+ *      Author: eunseok
+ */
+
+#ifndef BLELIB_H_
+#define BLELIB_H_
+
+#include "Arduino.h"
+
+#define BLE_NOCHANGE   -1
+#define BLE_MASTER             1
+#define BLE_SLAVER             0
+
+#define BLE_DISCON             200
+#define BLE_NODATA             100
+
+
+/***************************************
+ *
+ *     HM-10 BLE Module Control Class.
+ *     Target Board : Arduino-Mega.
+ *
+ **************************************/
+class Cble
+{
+public :
+       /***
+        * BLE Control Function.
+        */
+       // BLE initialization ( COM baud rate , BLE Master , Slave setting. )
+       void init(long baudRate, int ble_mode, char* SelfMaxAddr);
+
+       void StatusRead( void );
+
+       bool IsSelfArduino( void );
+
+       bool IsConnected( void );
+
+       bool pollingConnect( const char* maxAddr );
+
+       void pollingDisconnect( void );
+       // Get RSSI by BLE communication. (polling method.)
+       int pollingGetRSSI( void );
+       // Send Request to BLE Module. And, Get the response. (polling method.)
+       bool pollingRequest(const char* request, char* data, int dataLen);
+
+       int mustHaveRequest(const char* request, char* data, int dataLen);
+
+       void streamDummy( char* data, int dataLen);
+
+       /***
+        * Debug COM port to BLE COM port.
+        * BLE COM port to Debug COM port.
+        */
+       // BLE Module to Debug Serial port.
+       void BLE2Debug( int autoDiscon );
+       // Debug Serial port to BLE Module.
+       char* Debug2BLE( int BLEwrite );
+
+       /***
+        * If you first setting, you need next-function.
+        */
+       // Restore to factory setting data.
+       void FactoryReset( void );
+       // First setting of COM port.
+       void firstUartSetting( void );
+};
+
+
+
+#if 0
+#define debug_printf(...)      {                                                       \
+       char* __temp__ = (char*)malloc(sizeof(char)*2048);              \
+       sprintf(__temp__, __VA_ARGS__ );                                        \
+       Serial.print(__temp__);                                                                 \
+       free(__temp__);                                                                                                 \
+}
+#else
+#define debug_printf(...)
+#endif
+
+
+
+#endif /* BLELIB_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/oic_lanLib.h b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/oic_lanLib.h
new file mode 100644 (file)
index 0000000..41556f6
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * oic_lanLib.h
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#ifndef OIC_LANLIB_H_
+#define OIC_LANLIB_H_
+
+
+int ConnectToNetwork();
+
+
+#endif /* OIC_WIFILIB_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/proximity.h b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/proximity.h
new file mode 100644 (file)
index 0000000..8e8666a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * proximity.h
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#ifndef PROXIMITY_H_
+#define PROXIMITY_H_
+
+
+#define arraysize      6
+#define RSSI_EA                3
+
+float CalculateExponentialAverage(int numberOfSamples, int* array, int startindex, int flag);
+
+float calculateDistance(float avgRSSI, float txPower);
+
+#endif /* PROXIMITY_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/trackee.h b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/include/trackee.h
new file mode 100644 (file)
index 0000000..4271904
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * trackee.h
+ *
+ *  Created on: 2014. 11. 18.
+ *      Author: eunseok
+ */
+
+#ifndef TRACKEE_H_
+#define TRACKEE_H_
+
+
+#define ARDUINO                0
+
+
+#endif /* TRACKEE_H_ */
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/bleLib.cpp b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/bleLib.cpp
new file mode 100644 (file)
index 0000000..31cf5da
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * blsLib.cpp
+ *
+ *  Created on: 2014. 11. 5.
+ *      Author: eunseok
+ */
+
+#include "bleLib.h"
+#include <stdarg.h>
+#include "trackee.h"
+
+//#define __INTERNAL_DEBUG__           1
+
+PROGMEM const char TAG[] = "TrackeeSensor";
+#define LIMIT_COUNT                    100
+#define DUMMY_SIZE                     30
+#define DEBUG_SIZE                     DUMMY_SIZE
+#if (ARDUINO != 0)
+#define SERIAL_SIZE                    100
+#endif
+
+#define BLE            Serial2
+
+bool isConnected = false;
+int SerialCnt=0;
+int BLECnt=0;
+char SelfMaxaddr[19] = {0,};
+
+char debugD[DEBUG_SIZE]={0,};
+
+#if (ARDUINO != 0)
+char SerialData[SERIAL_SIZE]={0,};
+char BLEData[SERIAL_SIZE]={0,};
+#endif
+
+// baudRate이 115200이면, 주의해야한다.
+// Arduino Chip은 16bit Process 이므로 int형의 사이즈가 4byte형 signed int이다.
+void Cble::init(long baudRate, int ble_mode, char* SelfMaxAddr)
+{
+       debug_printf("BLE shiled is initialed.-\r\n");
+
+       if(SelfMaxAddr == NULL && ble_mode != BLE_NOCHANGE )
+       {
+               debug_printf("Error : Insert Maxaddress of Arduino BLE shiled.\r\n");
+               exit(-1);
+       }
+       sprintf(SelfMaxaddr, "%s",SelfMaxAddr);
+
+       BLE.begin(baudRate);
+       BLE.setTimeout(1);
+       delay(1000);
+
+       memset(debugD,0,DEBUG_SIZE);
+
+       if( ble_mode != BLE_NOCHANGE )
+       {
+               while( IsSelfArduino() == false )
+                       this->pollingDisconnect();
+       }
+
+       if( ble_mode == BLE_MASTER )
+       {
+               pollingRequest("AT+ROLE1", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+MODE0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+NOTI0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+       }
+       else if ( ble_mode == BLE_SLAVER )
+       {
+               pollingRequest("AT+ROLE0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+MODE2", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+               delay(150);
+               pollingRequest("AT+NOTI0", debugD, 8);
+               memset(debugD, 0, DEBUG_SIZE);
+       }
+
+       if( ble_mode != BLE_NOCHANGE )
+       {
+               while( IsSelfArduino() == false )
+                       this->pollingDisconnect();
+       }
+
+       delay(250);
+}
+
+void Cble::StatusRead( void )
+{
+       debug_printf("StatusRead function called.\r\n");
+
+       pollingRequest("AT+ROLE?", debugD, 9);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+MODE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+IMME?", debugD, 9);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+TYPE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+POWE?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+NOTI?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+       pollingRequest("AT+PIO1?", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+       delay(150);
+}
+
+bool Cble::IsConnected( void )
+{
+       return isConnected;
+}
+
+bool Cble::IsSelfArduino( void )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("IsSelfArduino is called.\r\n");
+#endif
+       int length=mustHaveRequest("AT+ADDR?", debugD, 20);
+
+       if( strstr(debugD, SelfMaxaddr) )
+       {
+               isConnected = false;
+               memset(debugD,0,length);
+               return true;
+       }
+       else
+       {
+               isConnected = true;
+               memset(debugD,0,length);
+               return false;
+       }
+}
+
+bool Cble::pollingConnect( const char* maxAddr )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("pollingConnect is called.\r\n");
+#endif
+
+#define CONNECT_SIZE           20
+
+       char cmd[CONNECT_SIZE]= {0,};
+
+       // is Connected Address ?
+       pollingRequest("AT+ADDR?", debugD, 20);
+       if( strstr(debugD, maxAddr) )
+       {
+               isConnected = true;
+               memset(debugD,0,DEBUG_SIZE);
+               return isConnected;
+       }
+       memset(debugD,0,DEBUG_SIZE);
+
+       // Try Connection.
+       sprintf(cmd, "AT+CON%s",maxAddr);
+       if( pollingRequest(cmd, debugD, 8) == false )
+       {
+               debug_printf("Error : %s command is failed.\r\n",cmd );
+               memset(debugD,0,DEBUG_SIZE);
+               pollingDisconnect();
+               return false;
+       }
+       else if( strstr(debugD,"OK+CONNA") )
+       {
+               isConnected = true;
+               memset(debugD,0,DEBUG_SIZE);
+       }
+       else
+       {
+               memset(debugD,0,DEBUG_SIZE);
+               pollingDisconnect();
+               return false;
+       }
+       // Confirm Connected Address.
+       pollingRequest("AT+ADDR?", debugD, 20);
+
+       if( strstr(debugD, maxAddr) == 0 )
+       {
+               isConnected = false;
+               if ( strstr(debugD, "OK+CONNF") )
+               {
+                       memset(debugD,0,DEBUG_SIZE);
+                       streamDummy(debugD, 8);
+               }
+       }
+       memset(debugD,0,DEBUG_SIZE);
+       delay(5);
+
+       return isConnected;
+
+#undef CONNECT_SIZE
+}
+
+
+#define  CMD_DISCONNECT                "(CMD_DISCON)"
+void Cble::pollingDisconnect( void )
+{
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("pollingDisconnect is called.\r\n");
+#endif
+       int length=0;
+#if (ARDUINO == 0)
+       pollingRequest("\r\n" CMD_DISCONNECT "\r\n", NULL, NULL);
+       delay(5);
+
+       length=mustHaveRequest("AT", debugD, 2);
+       if( strstr(debugD,"OK") )
+               isConnected = false;
+
+       memset(debugD,0,length);
+#else
+       if( BLE.available() )
+       {
+               if( BLE.findUntil(CMD_DISCONNECT, "\r\n") == true )
+               {
+                       debug_printf("pollingDisconnect : Detected %s command.\r\n", CMD_DISCONNECT);
+
+                       do {
+                               debug_printf("pollingDisconnect : Send AT message.\r\n");
+                               if( length )
+                                       memset(debugD, 0, length);
+
+                               length=mustHaveRequest("AT", debugD, 2);
+                       }while( strstr(debugD,"OK") == NULL );
+
+                       debug_printf("pollingDisconnect() is Success.\r\n");
+                       memset(debugD, 0, length);
+               }
+       }
+#endif
+
+       delay(5);
+}
+
+int Cble::pollingGetRSSI( void )
+{
+#define RSSI_SIZE              11
+#define RSSI_POS               7
+
+       long time_cnt=0;
+       char c=0;
+       char index=0;
+       char rssi_res[RSSI_SIZE] = {0,};
+
+       streamDummy(NULL, NULL);
+
+       if( isConnected == true )
+       {
+               BLE.write("AT+RSSI?");
+               BLE.flush();
+               delay(5);
+
+               while(1)
+               {
+                       if ( BLE.available() )
+                               c = (char)BLE.read();
+                       else
+                       {
+                               c = 0;
+                               time_cnt++;
+                       }
+
+                       if( c )
+                       {
+                               rssi_res[index] = c;
+                               index++;
+                               if( index == RSSI_SIZE-1 )
+                               {
+                                       rssi_res[index] = '\0';
+                                       goto RESULT;
+                               }
+                       }
+
+       //              debug_printf("time_cnt=%d\r\n", time_cnt);
+                       if( time_cnt == 0xFFFFF )
+                       {
+                               debug_printf("Error : Time Out GetRSSI().\r\n");
+                               return BLE_NODATA;
+                       }
+
+               }
+
+       RESULT :
+#ifdef __INTERNAL_DEBUG__
+               debug_printf("res= %s \r\n",rssi_res);
+#endif
+               char* Srssi = &(rssi_res[RSSI_POS]);
+       //      debug_printf("[S] rssi=%s\r\n", Srssi);
+               int rssi = atoi(Srssi);
+       //      debug_printf("rssi=%d\r\n", rssi);
+
+               return rssi;
+       }
+
+       return BLE_DISCON;
+
+#undef RSSI_POS
+#undef RSSI_SIZE
+}
+
+int Cble::mustHaveRequest(const char* request, char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       BLE.write(request);
+       BLE.flush();
+       delay(150);
+
+READ_STREAM :
+       while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+       {
+               cnt++;
+               delay(10);
+
+               if ( cnt >= LIMIT_COUNT/10 )
+               {
+#ifdef __INTERNAL_DEBUG__
+                       debug_printf("=====> Retry Request command Send. <=========\r\n");
+#endif
+                       cnt = 0;
+                       BLE.write(request);
+                       BLE.flush();
+
+                       required_length = dataLen;
+                       data_index = data;
+                       length = 0;
+                       delay(50);
+               }
+       }
+
+       required_length -= length;
+       if( required_length != 0 )
+       {
+               data_index = data_index + length;
+               length = 0;
+               goto READ_STREAM;
+       }
+
+#ifdef __INTERNAL_DEBUG__
+       debug_printf("[ %s ] %s\r\n\r\n", request, data);
+#endif
+       return dataLen;
+}
+
+bool Cble::pollingRequest(const char* request, char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       BLE.write(request);
+       BLE.flush();
+
+       if( data_index )
+       {
+               delay(250);
+
+READ_STREAM :
+               while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                       {
+                               debug_printf("[ %s ] TimeOut : No data.\r\n\r\n", request);
+                               return false;
+                       }
+               }
+
+               required_length -= length;
+               if( required_length != 0 )
+               {
+                       data_index = data_index + length;
+                       length = 0;
+                       goto READ_STREAM;
+               }
+
+#ifdef __INTERNAL_DEBUG__
+               debug_printf("[ %s ] %s\r\n\r\n", request, data);
+#endif
+       }
+       return true;
+}
+
+void Cble::streamDummy( char* data, int dataLen)
+{
+       int cnt=0;
+       int length=0;
+       int required_length = dataLen;
+       char* data_index = data;
+
+       if( data && required_length )
+       {
+READ_STREAM :
+               while( (length=BLE.readBytes(data_index, required_length)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                       {
+                               debug_printf("[ streamDummy ] TimeOut : No data.\r\n\r\n");
+                               return ;
+                       }
+               }
+
+               required_length -= length;
+               if( required_length != 0 )
+               {
+                       data_index = data_index + length;
+                       length = 0;
+                       goto READ_STREAM;
+               }
+
+               debug_printf("[ streamDummy ] %s\r\n\r\n", data);
+       }
+       else
+       {
+               if( BLE.available() )
+               {
+                       BLE.readBytes(debugD, DEBUG_SIZE);
+#ifdef __INTERNAL_DEBUG__
+                       debug_printf("[ streamDummy ] %s\r\n\r\n", debugD);
+#endif
+                       memset(debugD, 0, DEBUG_SIZE);
+               }
+       }
+
+}
+
+#if (ARDUINO != 0)
+
+#define REGARD_DISCON                  5000
+int needDiscon = 0;
+unsigned long global_cnt = 0;
+
+void Cble::BLE2Debug( int autoDiscon )
+{
+       int cnt=0;
+       uint8_t length=0;
+
+       if( BLE.available() )
+       {
+               while( (length=BLE.readBytes(BLEData, SERIAL_SIZE)) == 0 )
+               {
+                       cnt++;
+                       if ( cnt >= LIMIT_COUNT )
+                               return ;
+               }
+
+               global_cnt = 0;
+               needDiscon = 0;
+
+               Serial.println(BLEData);
+               memset(BLEData, 0, length);
+       }
+       else if ( autoDiscon )
+       {
+               global_cnt++;
+//             debug_printf("global_cnt=%u , ", global_cnt );
+//             debug_printf("needDiscon=%d\r\n", needDiscon);
+               if( !needDiscon && global_cnt >= REGARD_DISCON )
+               {
+                       needDiscon = 1;
+                       debug_printf("result : global_cnt=%u , ", global_cnt );
+                       debug_printf("needDiscon=%d\r\n", needDiscon);
+               }
+
+               if ( needDiscon )
+               {
+                       debug_printf("Auto Discon : global_cnt=%u , ", global_cnt );
+                       debug_printf("needDiscon=%d\r\n", needDiscon);
+                       if( pollingRequest("AT", debugD, 2) == true )
+                       {
+                               global_cnt = 0;
+                               needDiscon = 0;
+                       }
+               }
+       }
+}
+
+char* Cble::Debug2BLE( int BLEwrite )
+{
+       char* result = NULL;
+
+       if( Serial.available() )
+       {
+               char c = (char)Serial.read();
+
+               switch(c)
+               {
+               case '\0':
+                       return result;
+               case '\r':
+               case '\n':
+                       debug_printf("\r\n");
+                       if(BLEwrite && SerialCnt)
+                       {
+                               BLE.write(SerialData);
+                               BLE.flush();
+                       }
+
+                       result = (char*)malloc(sizeof(char)*(SerialCnt+1));
+                       memcpy(result, SerialData, SerialCnt );
+                       result[SerialCnt] = NULL;
+
+                       memset(SerialData, 0, SerialCnt+1);
+                       SerialCnt=0;
+                       break;
+               default :
+                       SerialData[SerialCnt] = c;
+                       SerialCnt++;
+                       Serial.print(c);
+                       break;
+               }
+       }
+
+       return result;
+}
+#else
+void Cble::BLE2Debug( int autoDiscon )
+{
+       ;
+}
+
+char* Cble::Debug2BLE( int BLEwrite )
+{
+        return NULL;
+}
+#endif
+
+void Cble::FactoryReset( void )
+{
+       debug_printf("FactoryReset is called.\r\n");
+
+       pollingRequest("AT+RENEW", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+}
+
+
+void Cble::firstUartSetting( void )
+{
+       debug_printf("firstUartSetting is called.\r\n");
+
+       Serial.begin(9600);
+       BLE.begin(9600);
+       BLE.setTimeout(1);
+       delay(1000);
+
+       pollingRequest("AT+BAUD4", debugD, 8);
+       memset(debugD, 0, DEBUG_SIZE);
+
+       debug_printf("Please Power off and on.\r\n");
+       BLE.end();
+//     delay(1000);
+//
+//     BLE.begin(115200);
+//     delay(1000);
+//
+//     pollingRequest("AT", debugD, DEBUG_SIZE);
+//     memset(debugD, 0, DEBUG_SIZE);
+
+
+       exit(0);
+}
+
+
+
+
+
+
+
+
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/oic_lanLib.cpp b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/oic_lanLib.cpp
new file mode 100644 (file)
index 0000000..432ee0d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * oic_wifiLib.cpp
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+// proximity code e
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+
+PROGMEM const char TAG[] = "TrackeeSensor";
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+// Note : Arduino WiFi Shield currently does NOT support multicast and therefore
+// this server will NOT be listening on 224.0.1.187 multicast address.
+
+/// WiFi Shield firmware with Intel patches
+static const char INTEL_WIFI_SHIELD_FW_VER[] = "1.2.0";
+
+/// WiFi network info and credentials
+char ssid[] = "SoftSensor_AP";
+char pass[] = "1234567890";
+//char ssid[] = "SoftSensor_2.4G";
+//char pass[] = "12344321";
+
+int ConnectToNetwork()
+{
+    char *fwVersion;
+    int status = WL_IDLE_STATUS;
+    // check for the presence of the shield:
+    if (WiFi.status() == WL_NO_SHIELD)
+    {
+        OC_LOG(ERROR, TAG, PCF("WiFi shield not present"));
+        return -1;
+    }
+
+    // Verify that WiFi Shield is running the firmware with all UDP fixes
+    fwVersion = WiFi.firmwareVersion();
+    OC_LOG_V(INFO, TAG, "WiFi Shield Firmware version %s", fwVersion);
+    if ( strncmp(fwVersion, INTEL_WIFI_SHIELD_FW_VER, sizeof(INTEL_WIFI_SHIELD_FW_VER)) !=0 )
+    {
+        OC_LOG(DEBUG, TAG, PCF("!!!!! Upgrade WiFi Shield Firmware version !!!!!!"));
+        return -1;
+    }
+
+    // attempt to connect to Wifi network:
+    while (status != WL_CONNECTED)
+    {
+        OC_LOG_V(INFO, TAG, "Attempting to connect to SSID: %s", ssid);
+        status = WiFi.begin(ssid,pass);
+
+        // wait 10 seconds for connection:
+        delay(10000);
+    }
+    OC_LOG(DEBUG, TAG, PCF("Connected to wifi"));
+
+    IPAddress ip = WiFi.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    return 0;
+}
+#else
+// Arduino Ethernet Shield
+int ConnectToNetwork()
+{
+    // Note: ****Update the MAC address here with your shield's MAC address****
+    uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xB8, 0xAC};
+
+    uint8_t error = Ethernet.begin(ETHERNET_MAC);
+    if (error  == 0)
+    {
+        OC_LOG_V(ERROR, TAG, "error is: %d", error);
+        return -1;
+    }
+    IPAddress ip = Ethernet.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+    return 0;
+}
+#endif //ARDUINOWIFI
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/proximity.cpp b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/proximity.cpp
new file mode 100644 (file)
index 0000000..351f930
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * proximity.cpp
+ *
+ *  Created on: 2014. 11. 13.
+ *      Author: eunseok
+ */
+
+#include "Arduino.h"
+#include "proximity.h"
+#include <math.h>
+
+// Proximity code start
+float CalculateExponentialAverage(int numberOfSamples, int* array, int startindex, int flag){
+       float numerator = 0;
+       float denominator = 0;
+
+       float average = 0.0;
+
+       if (flag < arraysize / RSSI_EA)   // first loop buffer full
+       {
+               for (int i = 0; i < startindex; i++)
+               {
+                       average += array[i];
+               }
+               if(startindex == 0){}
+               else{
+                       average = average / startindex;
+               }
+
+               Serial.print("average1 : ");
+               Serial.println(average);
+       }
+       else
+       {
+               for (int i = 0; i < arraysize; i++)
+               {
+                       average += array[i];
+               }
+
+               for (int i = startindex; i < startindex + RSSI_EA; i++)
+               {
+                       average -= array[i];
+               }
+               average = average / (arraysize - numberOfSamples);
+
+               Serial.print("average2 : ");
+               Serial.println(average);
+       }
+       //exponential moving average
+       int i = 0;
+       //CHANGE THIS FOR DIFFERENT SMOOTHING EFFECT
+       float beta=0.8f;
+       for (i = startindex + numberOfSamples - 1; i >= startindex; i--)
+       {
+               numerator += array[i]* pow(beta, startindex + numberOfSamples - i - 1);
+               denominator += pow(beta, startindex + numberOfSamples - i - 1);
+       }
+
+       int offset = 3;
+       if(average != 0.0){
+         numerator += average * pow(beta, offset + numberOfSamples);
+         denominator += pow(beta, offset + numberOfSamples);
+       }
+       return numerator / denominator;
+}
+
+
+float calculateDistance(float avgRSSI, float txPower)
+{
+       if (avgRSSI == 0)
+       {
+               return -1.0;
+       }
+
+       float ratio = avgRSSI*1.0/txPower;
+       if (ratio < 1.0)
+       {
+               return pow(ratio,10);
+       }
+       else
+       {
+               float distance =  (0.7)*pow(ratio,10) + 0.024;
+               return distance;
+       }
+}
+
+// proximity code end
+
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/readme.txt b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/readme.txt
new file mode 100644 (file)
index 0000000..7c041e1
--- /dev/null
@@ -0,0 +1,19 @@
+
+Followings should be done befor building Arudno applications 
+
+1. Applications on arduino conform  the Iotivity Base released on 22-Aug-2014.
+   (Ver. 22th Aug(oic-resource: commit: cdeeed62bd9b11beb2cdd340168e766088c18dac [cdeeed6]))
+
+   For successful execution, you have to copy the file, local.properties, into the following pathes:
+    - oic-resource/csdk/
+    - oic-resource/csdk/libcoap-4.1.1
+
+
+2. Time.c, Time.h should be copied in your machine and they should be refered in the Makefile as followings
+
+   Makefile path:  / oic-resource / csdk / libcoap-4.1.1 / makefile
+
+   path to be modified: 
+  
+     - INCD_ARD_TIME = -I$(ARDUINO_DIR)/libraries/Time ---> for Time.h
+     - SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time ---> for Time.c
\ No newline at end of file
diff --git a/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/trackee.cpp b/service/soft-sensor-manager/SampleApp/arduino/Trackee_Thing/src/trackee.cpp
new file mode 100644 (file)
index 0000000..8d78c5b
--- /dev/null
@@ -0,0 +1,443 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+
+// Do not remove the include below
+#include "Arduino.h"
+#include "bleLib.h"
+#include <stdio.h>
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#include "oic_lanLib.h"
+#include "trackee.h"
+
+// proximity code s
+#define DATA_EA                400
+#define SLAVER_EA      2
+
+#define ARDUINO_AVR_MEGA2560 1
+/// This is the port which Arduino Server will use for all unicast communication with it's peers
+#define OC_WELL_KNOWN_PORT 5683
+
+PROGMEM const char TAG[] = "TrackeeSensor";
+
+OCResourceHandle m_handle;             // OIC base를 handling하기위해서 필요한 handler.
+
+#if (ARDUINO == 0)
+#include "proximity.h"
+
+#define JSON_BASE "{\"href\":\"\",\"rep\":{"
+#define JSON_BASE00 "\"0\":\"trackeeID\",\"1\":\"string\",\"2\":\""
+#define JSON_BASE01 "\",\"3\":\"things\",\"4\":\"int\",\"5\":\""
+#define JSON_BASE02 "\",\"6\":\"ID\",\"7\":\"string\",\"8\":\""
+#define JSON_BASE03 "\",\"9\":\"distance\",\"10\":\"float\",\"11\":\""
+#define JSON_BASE04 "\",\"12\":\"proximity\",\"13\":\"int\",\"14\":\""
+#define JSON_BASE05 "\",\"15\":\"SD\",\"16\":\"float\",\"17\":\""
+#define JSON_BASE06 "\",\"18\":\"ID\",\"19\":\"string\",\"20\":\""
+#define JSON_BASE07 "\",\"21\":\"distance\",\"22\":\"float\",\"23\":\""
+#define JSON_BASE08 "\",\"24\":\"proximity\",\"25\":\"int\",\"26\":\""
+#define JSON_BASE09 "\",\"27\":\"SD\",\"28\":\"float\",\"29\":\""
+#define JSON_BASE10 "\"}}"
+
+typedef struct PROXIRESOURCE {
+    float m_distance[SLAVER_EA];
+    float m_proximity[SLAVER_EA];
+} PROXIResource;
+
+PROXIResource PROXI;
+
+int rssi[SLAVER_EA][arraysize];
+int rssicnt[SLAVER_EA] = {0,};
+int startindex[SLAVER_EA] = {0,};
+int flag[SLAVER_EA] = {0,};
+//#else
+//bool bleWrite = true;
+#endif
+
+Cble ble;
+
+char trackeeID[13] = "9059AF16FEF7";
+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 )
+{
+       if( g_PROXIUnderObservation == 1 )
+       {
+#if (ARDUINO == 0)
+               PROXIResource* ref = &PROXI;
+               int ref_cnt = SLAVER_EA;
+               uint16_t base_length = 0;
+               base_length = strlen(JSON_BASE)+ strlen(JSON_BASE00)+ strlen(JSON_BASE01)+ strlen(JSON_BASE02)+ strlen(JSON_BASE03)+\
+                                     strlen(JSON_BASE04)+ strlen(JSON_BASE05)+ strlen(JSON_BASE06)+ strlen(JSON_BASE07)+\
+                                     strlen(JSON_BASE08)+ strlen(JSON_BASE09)+ strlen(JSON_BASE10);
+
+               OC_LOG_V(INFO, TAG, "base length = %d, buf_length=%d", base_length, buf_length );
+
+               if( ((long)buf_length - (long)base_length) < LENGTH_VAR )
+               {
+                       OC_LOG_V(ERROR, TAG, "Error : length is very long.");
+                       return false;
+               }
+
+               sprintf(jsonBuf, JSON_BASE );
+               sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE00"%s"JSON_BASE01"%d", trackeeID, ref_cnt);
+               sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03"%d.%03d", slaveList[0], (int)ref->m_distance[0], (int)((ref->m_distance[0]-(int)ref->m_distance[0])*1000.0) );
+               sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE04"%d"JSON_BASE05"0.0", (int)ref->m_proximity[0] );
+               sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE06"%s"JSON_BASE07"%d.%03d", slaveList[1], (int)ref->m_distance[1], (int)((ref->m_distance[1]-(int)ref->m_distance[1])*1000.0) );
+               sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE08"%d"JSON_BASE09"0.0", (int)ref->m_proximity[1] );
+               strcpy(jsonBuf+strlen(jsonBuf), JSON_BASE10 );
+
+               OC_LOG_V(INFO, TAG, "json length = %u", strlen(jsonBuf) );
+
+               return true;
+
+#else          // Slave Json Code.
+
+               return true;
+#endif
+       }
+
+       OC_LOG_V(INFO, TAG, "Not Support Observer unfounded mode." );
+       return false;
+}
+
+
+// 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.
+// See here for more details :
+// http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
+void PrintArduinoMemoryStats()
+{
+#ifdef ARDUINO_AVR_MEGA2560
+    //This var is declared in avr-libc/stdlib/malloc.c
+    //It keeps the largest address not allocated for heap
+    extern char *__brkval;
+    //address of tmp gives us the current stack boundry
+    int tmp;
+    OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
+    OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
+             ((unsigned int)&tmp - (unsigned int)__brkval));
+#endif
+}
+
+// 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 ehRet = OC_EH_OK;
+    OCEntityHandlerResponse response = {0};
+    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
+    {
+        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+        if(OC_REST_GET == entityHandlerRequest->method)
+        {
+                if(JsonGenerator(payload, MAX_RESPONSE_LENGTH))
+                {
+                }
+           else
+            {
+                ehRet = OC_EH_ERROR;
+            }
+        }
+        if(OC_REST_PUT == entityHandlerRequest->method)
+        {
+            //Do something with the 'put' payload
+            if (JsonGenerator(payload, MAX_RESPONSE_LENGTH))
+            {
+            }
+            else
+            {
+                ehRet = OC_EH_ERROR;
+            }
+         }
+    }
+
+    if (ehRet == OC_EH_OK)
+   {
+          // Format the response.  Note this requires some info about the request
+          response.requestHandle = entityHandlerRequest->requestHandle;
+          response.resourceHandle = entityHandlerRequest->resource;
+          response.ehResult = ehRet;
+          response.payload = (unsigned char *)payload;
+          response.payloadSize = strlen(payload);
+          response.numSendVendorSpecificHeaderOptions = 0;
+          memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+          memset(response.resourceUri, 0, sizeof response.resourceUri);
+          // Indicate that response is NOT in a persistent buffer
+          response.persistentBufferFlag = 0;
+
+          // Send the response
+          if (OCDoResponse(&response) != OC_STACK_OK)
+          {
+                  OC_LOG(ERROR, TAG, "Error sending response");
+                  ehRet = OC_EH_ERROR;
+          }
+    }
+
+    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)
+        {
+            OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
+        }
+    }
+    return ehRet;
+}
+
+
+#if (ARDUINO == 0)
+void ChangePROXIRepresentation (void *param)
+{
+       (void)param;
+       OCStackResult result = OC_STACK_ERROR;
+       float avg[SLAVER_EA] = {0,};
+
+       for(int i = 0; i < SLAVER_EA; i++)
+       {
+                 if( rssicnt[i] > arraysize - 1)
+                 {
+                       rssicnt[i] = rssicnt[i] % arraysize;
+                 }
+
+               ble.streamDummy(NULL, NULL);
+
+               while(ble.pollingConnect(&slaveList[slaver_num][0]) == false){
+                       ble.streamDummy(NULL, NULL);
+               }
+
+               if( ble.IsConnected() == true )
+               {
+                       // print the string when a newline arrives:
+                       OC_LOG_V(INFO, TAG, "Connected. (%s)\r\n", slaveList[slaver_num]);
+
+                       for(int j=0; j < RSSI_EA; j++){
+                               rssi[i][rssicnt[i]] = ble.pollingGetRSSI();
+                               OC_LOG_V(INFO, TAG, "rssi val : %d \r\n", rssi[i][rssicnt[i]]);
+                          rssicnt[i]++;
+                       }
+
+                       while( ble.IsSelfArduino() == false )
+                               ble.pollingDisconnect();
+
+                       slaver_num++;
+                       slaver_num = slaver_num % SLAVER_EA;
+               }
+
+               avg[i] = CalculateExponentialAverage(RSSI_EA, rssi[i], startindex[i], flag[i]);
+               Serial.println(avg[i]);
+               Serial.print("distance : ");
+
+               PROXI.m_distance[i] = calculateDistance(avg[i], -58);
+
+               if(PROXI.m_distance[i] <= 1){
+                       PROXI.m_proximity[i] = 1;
+               }
+               else if(PROXI.m_distance[i] <= 2){
+                       PROXI.m_proximity[i] = 2;
+               }
+               else{
+                       PROXI.m_proximity[i] = 3;
+               }
+
+               Serial.println(PROXI.m_distance[i]);
+               Serial.println(PROXI.m_proximity[i]);
+
+               startindex[i] += RSSI_EA;
+
+               // This call displays the amount of free SRAM available on Arduino
+               PrintArduinoMemoryStats();
+
+               if(startindex[i] >= arraysize){
+                       startindex[i] = 0;
+               }
+
+               if(flag[i] < (arraysize / RSSI_EA))
+               {
+                       flag[i]++;
+               }
+       }
+
+       result = OCNotifyAllObservers (m_handle, OC_NA_QOS);
+
+       if (OC_STACK_NO_OBSERVERS == result)
+       {
+               OC_LOG_V(INFO, TAG, "g_PROXIUnderObservation is 0." );
+               g_PROXIUnderObservation = 0;
+       }
+
+}
+#endif
+
+
+
+
+//The setup function is called once at startup of the sketch
+void setup()
+{
+       Serial.begin(115200);
+
+       // Add your initialization code here
+       OC_LOG_INIT();
+
+       OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
+       //    uint16_t port = OC_WELL_KNOWN_PORT;
+
+       // Connect to Ethernet or WiFi network
+       if (ConnectToNetwork() != 0)
+       {
+               OC_LOG(ERROR, TAG, "Unable to connect to network");
+               return;
+       }
+
+       // Initialize the OC Stack in Server mode
+       if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
+       {
+               OC_LOG(ERROR, TAG, PCF("OCStack init error"));
+               return;
+       }
+
+    OCStartPresence(60);
+       // Declare and create the example resource
+       createResource();
+
+       // This call displays the amount of free SRAM available on Arduino
+       PrintArduinoMemoryStats();
+#if (ARDUINO == 0)
+       ble.init( (long)115200, BLE_MASTER, trackeeID);
+#elif (ARDUINO == 1)
+       ble.init( (long)115200, BLE_SLAVER, slaveList[0]);
+#elif (ARDUINO == 2)
+       ble.init( (long)115200, BLE_SLAVER, slaveList[1]);
+#endif
+
+//     ble.StatusRead();
+
+       OC_LOG_V(INFO, TAG, "Program Start-\r\n");
+}
+
+
+// The loop function is called in an endless loop
+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"));
+               return;
+       }
+#if (ARDUINO == 0)
+       ChangePROXIRepresentation(NULL);
+#else
+       char* user_cmd = NULL;
+
+//     ble.pollingDisconnect();
+
+       user_cmd = ble.Debug2BLE(true);
+       ble.BLE2Debug( true );
+
+       if( user_cmd )
+       {
+               free( user_cmd );
+               user_cmd = NULL;
+       }
+
+#endif
+}
+
+
+
+
+
+
+
+void createResource() {
+
+    OCStackResult res = OCCreateResource(&m_handle,
+                                         "SoftSensorManager.Sensor",
+                                         "oc.mi.def",
+                                         "/Tracker_Thing",
+                                         OCEntityHandlerCb,
+                                         OC_DISCOVERABLE|OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created PROXI resource with result: %s", getResult(res));
+}
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    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_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
diff --git a/service/soft-sensor-manager/SampleApp/linux/ClientApp/SConscript b/service/soft-sensor-manager/SampleApp/linux/ClientApp/SConscript
deleted file mode 100644 (file)
index 8ef6e46..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-##
-# linux sample app  build script
-##
-
-Import('env')
-
-# Add third party libraries
-SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons')
-linux_sample_env = env.Clone()
-
-######################################################################
-# Build flags
-######################################################################
-linux_sample_env.AppendUnique(CPPPATH = ['include/'])
-linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
-linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
-linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
-linux_sample_env.AppendUnique(LIBS = ['pthread'])
-
-######################################################################
-#build sampleapp
-######################################################################
-clientapp = linux_sample_env.Program('ClientApp', 'src/SSMTestApp.cpp')
-Alias("clientapp_sample", clientapp)
-env.AppendTarget('clientapp_sample')
diff --git a/service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/SConscript b/service/soft-sensor-manager/SampleApp/linux/SSMTesterApp/SConscript
new file mode 100644 (file)
index 0000000..30f44d6
--- /dev/null
@@ -0,0 +1,35 @@
+##
+# linux sample app  build script
+##
+
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../SDK/cpp/include'])
+linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
+linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['libSSMSDK'])
+#linux_sample_env.AppendUnique(LIBS = ['libSSMCORE'])
+linux_sample_env.AppendUnique(LIBS = ['libSSMCore'])
+linux_sample_env.AppendUnique(LIBS = ['oc'])
+linux_sample_env.AppendUnique(LIBS = ['octbstack'])
+linux_sample_env.AppendUnique(LIBS = ['libcoap'])
+linux_sample_env.AppendUnique(LIBS = ['liboc_logger'])
+linux_sample_env.AppendUnique(LIBS = ['dl'])
+linux_sample_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+#build sampleapp
+######################################################################
+ssmtesterapp = linux_sample_env.Program('SSMTesterApp', 'src/SSMTestApp.cpp')
+Alias("ssmtesterapp_sample", ssmtesterapp)
+env.AppendTarget('SSMTesterApp')
index 54a71c8..abf7cf7 100644 (file)
@@ -11,7 +11,7 @@ TARGET=SSMTesterApp
 
 CXX=g++
 CXX_FLAGS=-std=c++0x -Wall -DLINUX
-CXX_INC=-I${SRC_PATH}/ -I${INC_PATH}/ -I${OUTPUTS_DIR} -I${IOT_BASE}/include/ -I${IOT_LOG_DIR}/include/ -I${IOT_BASE}/csdk/stack/include -I${IOT_BASE}/csdk/ocsocket/include -I${IOT_BASE}/csdk/ocrandom/include -I${IOT_BASE}/csdk/logger/include -I${BOOST}
+CXX_INC=-I${SRC_PATH}/ -I${INC_PATH}/ -I${OUTPUTS_DIR} -I${BOOST}
 
 
 CXX_LIB+=${OUTPUTS_DIR}/${SSM_LIB} 
index 63b94c8..c68304d 100644 (file)
 
 #include <string>
 
-#include "OCResource.h"
-#include "OCPlatform.h"
 #include "SSMInterface.h"
-#include "SSMClient.h"
-#include "ISSMClientListener.h"
+
+using namespace OIC;
 
 namespace APPMenu
 {
@@ -47,11 +45,9 @@ typedef enum
     ALL_DISCOMPORT = 2, HALF_DISCOMPORT, LITTLE_DISCOMPORT, ALL_COMPORT
 } DIResult;
 
-class SSMTestApp: public ISSMClientListener
-    , public IQueryEngineEvent
+class SSMTestApp: public IQueryEngineEvent
 {
     private:
-        //SSMClient m_SSMClient;
         SSMInterface m_SSMClient;
 
     public:
@@ -63,7 +59,6 @@ class SSMTestApp: public ISSMClientListener
         void unregisterQuery();
 
         /* operations from listener interface */
-        void onRegisterQuery(const AttributeMap &attributeMap, SSMReturn &eCode);
         SSMRESULT onQueryEngineEvent(int cqid, IDataReader *pResult);
 };
 
index e4a0d1d..50ba8fc 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "SSMTestApp.h"
 
+using namespace std;
+
 SSMTestApp::SSMTestApp()
 {
 }
@@ -84,65 +86,6 @@ void SSMTestApp::unregisterQuery(void)
 }
 
 /* APP. Level Callback Function for Observer of client. */
-void SSMTestApp::onRegisterQuery(const AttributeMap &attributeMap, SSMReturn &eCode)
-{
-    if (eCode == SSM_SUCCESS)
-    {
-        printf("onListener!!!!\n");
-        printf("\n");
-        printf("T : dry bult temperature. (℃)\n");
-        printf("H : relative humidity. (%%)\n");
-        printf("Discomport level = 9/5 * T + 32 - 0.55*(1 - H/100)*(9/5 * T - 26) \n");
-        printf("\n");
-        printf("**************************************\n");
-        printf("* All    Discomport level : 80 over. *\n");
-        printf("* Half   Discomport level : 75 over. *\n");
-        printf("* Little Discomport level : 68 over. *\n");
-        printf("* All    Comport    level : 67 under.*\n");
-        printf("**************************************\n");
-        printf("\n");
-
-        for (AttributeMap::const_iterator itor = attributeMap.begin(); itor != attributeMap.end();
-             ++itor)
-        {
-            if (strcmp(itor->first.c_str(), "temperature") == 0)
-            {
-                std::cout << "* Temperature : " << itor->second.c_str() << "℃" << std::endl;
-            }
-            else if (strcmp(itor->first.c_str(), "humidity") == 0)
-            {
-                std::cout << "* Humidity : " << itor->second.c_str() << "%" << std::endl;
-            }
-            else if (strcmp(itor->first.c_str(), "discomfortIndex") == 0)
-            {
-                int DI = std::stoi(itor->second.c_str());
-
-                std::cout << "* DiscomfortIndex : " << DI << "%" << std::endl;
-
-                switch (DI)
-                {
-                    case ALL_DISCOMPORT:
-                        std::cout << "* [Result] All person Discomfort." << std::endl;
-                        break;
-                    case HALF_DISCOMPORT:
-                        std::cout << "* [Result] Half person Discomfort." << std::endl;
-                        break;
-                    case LITTLE_DISCOMPORT:
-                        std::cout << "* [Result] Little person Discomfort." << std::endl;
-                        break;
-                    case ALL_COMPORT:
-                        std::cout << "* [Result] All person Comfort." << std::endl;
-                        break;
-                }
-            }
-        }
-    }
-    else
-    {
-        std::cout << "Response error: " << eCode << std::endl;
-    }
-}
-
 SSMRESULT SSMTestApp::onQueryEngineEvent(int cqid, IDataReader *pResult)
 {
     int     dataCount = 0;
index accd6ef..9ea870c 100644 (file)
@@ -5,16 +5,21 @@
 Import('env')
 
 # Add third party libraries
-SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons')
-linux_sample_env = env.Clone()
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
 
 ######################################################################
 # Build flags
 ######################################################################
-linux_sample_env.AppendUnique(CPPPATH = ['include/'])
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
 linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
 linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
 linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['oc'])
+linux_sample_env.AppendUnique(LIBS = ['octbstack'])
+linux_sample_env.AppendUnique(LIBS = ['libcoap'])
+linux_sample_env.AppendUnique(LIBS = ['liboc_logger'])
 linux_sample_env.AppendUnique(LIBS = ['pthread'])
 
 ######################################################################
index d8b5dc8..712a83b 100644 (file)
@@ -60,7 +60,7 @@ class TemphumidResource
     public:
         /// Constructor
         TemphumidResource() :
-            m_humid(0), m_temp(0)
+            m_humid(0), m_temp(0), m_resourceHandle(0)
         {
             m_resourceUri = "/Thing_TempHumSensor";
             m_resourceTypes.push_back(COAP_TYPE_NAME);
index 2950101..73f43e7 100644 (file)
@@ -22,8 +22,7 @@
 
 int g_Observation = 0;
 
-OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request,
-                                    std::shared_ptr< OCResourceResponse > response);
+OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request);
 
 /*
  * TempResourceFunctions
@@ -113,17 +112,21 @@ void *TestSensorVal(void *param)
     return NULL;
 }
 
-OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request,
-                                    std::shared_ptr< OCResourceResponse > response)
+OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
 {
     cout << "\tIn Server CPP entity handler:\n";
 
+    auto response = std::make_shared<OC::OCResourceResponse>();
+
     if (request)
     {
         // Get the request type and request flag
         std::string requestType = request->getRequestType();
         int requestFlag = request->getRequestHandlerFlag();
 
+        response->setRequestHandle(request->getRequestHandle());
+        response->setResourceHandle(request->getResourceHandle());
+
         if (requestFlag & RequestHandlerFlag::InitFlag)
         {
             cout << "\t\trequestFlag : Init\n";
@@ -188,7 +191,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
         std::cout << "Request invalid" << std::endl;
     }
 
-    return OC_EH_OK;
+    return OCPlatform::sendResponse(response) == OC_STACK_OK ? OC_EH_OK : OC_EH_ERROR;
 }
 
 int main()
@@ -200,11 +203,15 @@ int main()
     {
         OC::OCPlatform::Configure(cfg);
 
+        OC::OCPlatform::startPresence(60);
+
         g_myResource.registerResource();
 
         int input = 0;
         cout << "Type any key to terminate" << endl;
         cin >> input;
+
+        OC::OCPlatform::stopPresence();
     }
     catch (std::exception e)
     {
index 6b5a0bf..a238dc0 100644 (file)
@@ -5,21 +5,26 @@
 Import('env')
 
 # Add third party libraries
-SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons')
-linux_sample_env = env.Clone()
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
 
 ######################################################################
 # Build flags
 ######################################################################
-linux_sample_env.AppendUnique(CPPPATH = ['include/'])
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
 linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
 linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
 linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['oc'])
+linux_sample_env.AppendUnique(LIBS = ['octbstack'])
+linux_sample_env.AppendUnique(LIBS = ['libcoap'])
+linux_sample_env.AppendUnique(LIBS = ['liboc_logger'])
 linux_sample_env.AppendUnique(LIBS = ['pthread'])
 
 ######################################################################
 #build sampleapp
 ######################################################################
-thsensorapp1 = linux_sample_env.Program('THSensorApp', 'src/ThingResourceServer1.cpp')
+thsensorapp1 = linux_sample_env.Program('THSensorApp1', 'src/ThingResourceServer1.cpp')
 Alias("thsensorapp1_sample", thsensorapp1)
 env.AppendTarget('thsensorapp1_sample')
index b32b589..c854f69 100644 (file)
@@ -60,7 +60,7 @@ class TemphumidResource
     public:
         /// Constructor
         TemphumidResource() :
-            m_humid(0), m_temp(0)
+            m_humid(0), m_temp(0), m_resourceHandle(0)
         {
             m_resourceUri = "/Thing_TempHumSensor1";
             m_resourceTypes.push_back(COAP_TYPE_NAME);
index 6652fef..93c8e0d 100644 (file)
@@ -22,8 +22,7 @@
 
 int g_Observation = 0;
 
-OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request,
-                                    std::shared_ptr< OCResourceResponse > response);
+OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request);
 
 /*
 * TempResourceFunctions
@@ -113,17 +112,21 @@ void *TestSensorVal(void *param)
     return NULL;
 }
 
-OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request,
-                                    std::shared_ptr< OCResourceResponse > response)
+OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
 {
     cout << "\tIn Server CPP entity handler:\n";
 
+    auto response = std::make_shared<OC::OCResourceResponse>();
+
     if (request)
     {
         // Get the request type and request flag
         std::string requestType = request->getRequestType();
         int requestFlag = request->getRequestHandlerFlag();
 
+        response->setRequestHandle(request->getRequestHandle());
+        response->setResourceHandle(request->getResourceHandle());
+
         if (requestFlag & RequestHandlerFlag::InitFlag)
         {
             cout << "\t\trequestFlag : Init\n";
@@ -188,7 +191,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
         std::cout << "Request invalid" << std::endl;
     }
 
-    return OC_EH_OK;
+    return OCPlatform::sendResponse(response) == OC_STACK_OK ? OC_EH_OK : OC_EH_ERROR;
 }
 
 int main()
@@ -200,11 +203,15 @@ int main()
     {
         OC::OCPlatform::Configure(cfg);
 
+        OC::OCPlatform::startPresence(60);
+
         g_myResource.registerResource();
 
         int input = 0;
         cout << "Type any key to terminate" << endl;
         cin >> input;
+
+        OC::OCPlatform::stopPresence();
     }
     catch (std::exception e)
     {
index c0aae0a..982cff1 100644 (file)
@@ -41,7 +41,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib)
 
 ADD_EXECUTABLE(${TESTAPP} ${SRCS})
-TARGET_LINK_LIBRARIES(${TESTAPP} ${pkgs_LDFLAGS} ssmcore oc octbstack oc_logger oc_logger_core pthread dl)
+TARGET_LINK_LIBRARIES(${TESTAPP} ${pkgs_LDFLAGS} ssmcore oc octbstack oc_logger pthread dl)
 
 INSTALL(TARGETS ${TESTAPP} DESTINATION ${BINDIR})
 
diff --git a/service/soft-sensor-manager/SoftSensorPlugin/DiscomfortIndexSensor/SoftSensorDescription.xml b/service/soft-sensor-manager/SoftSensorPlugin/DiscomfortIndexSensor/SoftSensorDescription.xml
deleted file mode 100644 (file)
index 7910214..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<softsensors>
-       
-  <softsensor>
-    <name>DiscomfortIndexSensor</name>
-    <attributes>
-      <attribute>
-        <name>version</name>
-        <type>string</type>
-        <value>1.0</value>
-      </attribute>
-      <attribute>
-        <name>lifetime</name>
-        <type>int</type>
-        <value>60</value>
-      </attribute>
-    </attributes>
-    <outputs>
-      <output>
-        <name>timestamp</name>
-        <type>string</type>
-      </output>
-      <output>
-        <name>temperature</name>
-        <type>string</type>
-      </output>
-      <output>
-        <name>humidity</name>
-        <type>string</type>
-      </output>
-      <output>
-        <name>discomfortIndex</name>
-        <type>int</type>
-      </output>
-    </outputs>
-    <inputs>
-      <input>Thing_TempHumSensor</input>
-      <input>Thing_TempHumSensor1</input>
-    </inputs>
-  </softsensor>
-  
-</softsensors>
index 4aae123..d87e604 100644 (file)
@@ -38,7 +38,7 @@ ${TARGET}: ${OBJLIST}
 post_job:
        @echo " " 
        cp -Rdp ./${RST_NAME}/lib${TARGET}.so ${OUTPUTS_DIR}/
-       cp -Rdp ../../${SSXML_NAME} ${OUTPUTS_DIR}/
+       cp -Rdp ../../../${SSXML_NAME} ${OUTPUTS_DIR}/
        @echo "-------------- ${TARGET} Build Successful. -------------"
        @echo "Enter to ${RST_NAME} folder."
        @echo " " 
diff --git a/service/soft-sensor-manager/SoftSensorPlugin/SoftSensorDescription.xml b/service/soft-sensor-manager/SoftSensorPlugin/SoftSensorDescription.xml
new file mode 100644 (file)
index 0000000..bdf8018
--- /dev/null
@@ -0,0 +1,98 @@
+<softsensors>
+       
+  <softsensor>
+    <name>DiscomfortIndexSensor</name>
+    <attributes>
+      <attribute>
+        <name>version</name>
+        <type>string</type>
+        <value>1.0</value>
+      </attribute>
+      <attribute>
+        <name>lifetime</name>
+        <type>int</type>
+        <value>60</value>
+      </attribute>
+    </attributes>
+    <outputs>
+      <output>
+        <name>timestamp</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>temperature</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>humidity</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>discomfortIndex</name>
+        <type>int</type>
+      </output>
+    </outputs>
+    <inputs>
+      <input>Thing_TempHumSensor</input>
+      <input>Thing_TempHumSensor1</input>
+    </inputs>
+  </softsensor>
+  
+  <softsensor>
+    <name>IndoorTrajectorySensor</name>
+    <attributes>
+      <attribute>
+        <name>version</name>
+        <type>string</type>
+        <value>1.0</value>
+      </attribute>
+      <attribute>
+        <name>lifetime</name>
+        <type>int</type>
+        <value>60</value>
+      </attribute>
+    </attributes>
+    <outputs>
+      <output>
+        <name>trackeeID</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>timeT0</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref01T0</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref02T0</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref03T0</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>timeT1</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref01T1</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref02T1</name>
+        <type>string</type>
+      </output>
+      <output>
+        <name>ref03T1</name>
+        <type>string</type>
+      </output>
+    </outputs>
+    <inputs>
+      <input>Tracker_Thing</input>
+    </inputs>
+  </softsensor>
+  
+</softsensors>
index 82dba85..1c3ae15 100644 (file)
@@ -1,4 +1,7 @@
+IOTIVITY_DIR=${shell cd ../../../../ && pwd}
+${shell echo "ROOT_DIR=${IOTIVITY_DIR}" > ./root_path.inc}
 
+-include ./root_path.inc
 -include ./environment.mk
 
 MAKE=make
@@ -24,13 +27,12 @@ pre_job:
        @echo "*********************************************************" 
        @mkdir -p ${RST_NAME}
        @echo " "
-#      @cd ${IOT_BASE} &&      ${MAKE};
-#      @cd ${CUR_DIR};
+
        
 build:
        @for subdir in ${MAKE_LIST} ; do \
        echo ">>>>>>>>>>>> $${subdir}/Makefile run <<<<<<<<<<<<<" ; \
-       ${MAKE} -C $${subdir} ; \
+       cd $${subdir} && ${MAKE} ${OPTION} ; \
        echo " " ; \
        done
        @echo " "
@@ -46,11 +48,7 @@ post_job:
        @echo " " 
 
 clean:
-       
-#      @cd ${CUR_DIR}/../../../resource/ && make clean
-#      @cd ${CUR_DIR}/../../../resource/csdk && make deepclean
-#      @cd ${CUR_DIR}/9_Arduino_THSensorApp && make clean
-#      @cd ${CUR_DIR} 
+
        rm -rf ./${RST_NAME}
        @for subdir in ${MAKE_LIST} ; do \
        echo ">>>>>>>>>>>> $${subdir}/Makefile clean run <<<<<<<<<<<<<<" ; \
index 7e16a38..2d8949e 100644 (file)
@@ -1,23 +1,25 @@
-# root path of each PC.
-ROOT_DIR=/home/choi/tmp/test/upload/Iotivity-Candidate
 
-# service folder path.
-FD_SSM=${ROOT_DIR}/service/SoftSensorManager
+# ioc-resource folder path.
+IOT_BASE=${ROOT_DIR}/resource
+IOT_MAKE_PATH=${IOT_BASE}
+IOT_RELEASE=${IOT_BASE}/release/obj
+IOT_CSDK_LINUX_RELEASE=${IOT_BASE}/csdk/linux/release
+IOT_CSDK_ARDUINOMEGA_RELEASE=${IOT_BASE}/csdk/arduinomega/release
+
+# oic-service folder path.
+FD_SSM=${ROOT_DIR}/service/soft-sensor-manager
 FD_SAMPLEAPP=${FD_SSM}/SampleApp
 FD_BUILD=${FD_SSM}/build
 
 # outputs directory path.
 OUTPUTS_DIR=${FD_BUILD}/arduino/release
 
-# ioc-resource folder path.
-# IOT_BASE=${FD_SAMPLEAPP}/arduino/resource_a
-IOT_BASE=${ROOT_DIR}/resource
-IOT_MAKE_PATH=${IOT_BASE}
-IOT_RELEASE=${IOT_BASE}/release/obj
-IOT_CSDK_RELEASE=${IOT_BASE}/csdk/release
-
+#OPTION=PLATFORM=arduinomega ARDUINOWIFI=1
 # SoftSensorManager makefile path
+MAKE_00=${FD_SAMPLEAPP}/arduino
 MAKE_01=${FD_SAMPLEAPP}/arduino/THSensorApp/build
+MAKE_03=${FD_SAMPLEAPP}/arduino/Trackee_Thing/build
+MAKE_04=${FD_SAMPLEAPP}/arduino/Reference_Thing/build
 
-MAKE_LIST=${MAKE_01}
+MAKE_LIST=${MAKE_01} ${MAKE_03} ${MAKE_04}
 
index 39184bd..e318153 100644 (file)
@@ -1,7 +1,2 @@
-#ARDUINO_DIR = /home/choi/devel/arduino-1.0.5
-ARDUINO_DIR = /home/choi/tmp/test/Arduino
-#ARDUINO_TOOLS_DIR = $(ARDUINO_DIR)/hardware/tools/avr/bin
-CC=avr-g++
-CCPLUS=avr-g++
-AR=avr-ar
-RANLIB=avr-ranlib
+ARDUINO_DIR = /usr/share/arduino
+ARDUINO_TOOLS_DIR = $(ARDUINO_DIR)/hardware/tools/avr/bin
index 6652271..500f7d1 100644 (file)
@@ -9,11 +9,11 @@ IOT_CSDK_RELEASE=${IOT_BASE}/csdk/linux/release
 IOT_LOG_DIR=${IOT_BASE}/oc_logger
 IOT_LIB=liboc.a
 IOT_CSDK_LIB=liboctbstack.a
-IOT_LOG_LIB=liboc_logger.a
+IOT_LOG_LIB=oc_logger.a
 
 # service folder path.
 FD_SSM=${ROOT_DIR}/service/soft-sensor-manager
-FD_SDK=${FD_SSM}/SDK
+FD_SDK=${FD_SSM}/SDK/cpp
 FD_SSMCORE=${FD_SSM}/SSMCore
 FD_SAMPLEAPP=${FD_SSM}/SampleApp
 FD_SOFTSENSOR=${FD_SSM}/SoftSensorPlugin
@@ -23,7 +23,7 @@ FD_BUILD=${FD_SSM}/build
 OUTPUTS_DIR=${FD_BUILD}/linux/release
 EXEC_DIR=${OUTPUTS_DIR}
 SSXML_NAME="SoftSensorDescription.xml"
-SSM_LIB = libSSM.a
+SSM_LIB = libSSMSDK.a
 SSMCORE_LIB=libSSMCore.a
 
 # SoftSensorManager makefile path
@@ -35,5 +35,4 @@ MAKE_05=${FD_SOFTSENSOR}/DiscomfortIndexSensor/build/linux
 MAKE_06=${FD_SOFTSENSOR}/IndoorTrajectorySensor/build/linux
 
 
-MAKE_LIST=${MAKE_01} ${MAKE_02} ${MAKE_05} ${MAKE_06} ${MAKE_03}
-#MAKE_LIST=${MAKE_01} ${MAKE_02} ${MAKE_05} ${MAKE_03}
+MAKE_LIST=${MAKE_01} ${MAKE_02} ${MAKE_03} ${MAKE_05} ${MAKE_06}
\ No newline at end of file
diff --git a/service/soft-sensor-manager/doc/SSM Developer s guide_v0.1.pdf b/service/soft-sensor-manager/doc/SSM Developer s guide_v0.1.pdf
deleted file mode 100644 (file)
index ce75a27..0000000
Binary files a/service/soft-sensor-manager/doc/SSM Developer s guide_v0.1.pdf and /dev/null differ
diff --git a/service/soft-sensor-manager/doc/SSM Getting Started_v0.1.pdf b/service/soft-sensor-manager/doc/SSM Getting Started_v0.1.pdf
deleted file mode 100644 (file)
index 3968a2f..0000000
Binary files a/service/soft-sensor-manager/doc/SSM Getting Started_v0.1.pdf and /dev/null differ
index 1fb3198..470b15f 100644 (file)
@@ -13,8 +13,7 @@ target_os = env.get('TARGET_OS')
 ######################################################################
 # Build flags
 ######################################################################
-things_manager_env.AppendUnique(CPPPATH = ['tgm/inc'])
-things_manager_env.AppendUnique(CPPPATH = ['sdk/inc'])
+things_manager_env.AppendUnique(CPPPATH = ['sdk/inc', 'sdk/src'])
 
 if target_os not in ['windows', 'winrt']:
        things_manager_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
@@ -28,9 +27,10 @@ if target_os == 'android':
 ######################################################################
 # Source files and Targets
 ######################################################################
-tgmsdk = things_manager_env.StaticLibrary('TGMSDKLibrary', 'sdk/src/TGMClient.cpp')
+tgm_src = env.Glob('sdk/src/*.cpp')
+tgmsdk = things_manager_env.StaticLibrary('TGMSDKLibrary', tgm_src)
 
 things_manager_env.InstallTarget(tgmsdk, 'libTGMSDK')
 
 #Go to build sample apps
-SConscript('sampleapp/SConscript')
\ No newline at end of file
+SConscript('sampleapp/SConscript')
diff --git a/service/things-manager/build/linux/Makefile b/service/things-manager/build/linux/Makefile
deleted file mode 100644 (file)
index 58009ec..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-.PHONY : pre resource sdk sampleapp
-
-#.PHONY : lib tgm sdk sampleapp 
-all: .PHONY
-
-pre:
-       -mkdir release
-
-resource:
-       cd ../../../../resource && $(MAKE)
-
-
-sdk:
-       cd ../../sdk/build/linux && $(MAKE)
-       cp -Rdp ../../sdk/build/linux/*.a release/
-
-
-sampleapp:
-       cd ../../sampleapp/linux/tgmclient && $(MAKE)
-       cp -Rdp ../../sampleapp/linux/tgmclient/tgmclient release/
-
-clean:
-       cd ../../sdk/build/linux && $(MAKE) clean
-       cd ../../sampleapp/linux/tgmclient && $(MAKE) clean
-
-       rm -rf ./release/*
diff --git a/service/things-manager/build/linux/makefile b/service/things-manager/build/linux/makefile
new file mode 100644 (file)
index 0000000..4fc7d7e
--- /dev/null
@@ -0,0 +1,32 @@
+.PHONY : pre resource sdk sampleapp
+#.PHONY : lib tgm sdk sampleapp
+all: .PHONY
+
+pre:
+       -mkdir release
+
+resource:
+       cd ../../../../resource && $(MAKE)
+
+
+sdk:
+       cd ../../sdk/build/linux && $(MAKE)
+       cp -Rdp ../../sdk/build/linux/*.a release/
+
+sampleapp:
+       cd ../../sampleapp/linux && $(MAKE)
+       cp -Rdp ../../sampleapp/linux/configuration/con-server release/
+       cp -Rdp ../../sampleapp/linux/configuration/con-client release/
+       cp -Rdp ../../sampleapp/linux/configuration/bootstrapserver release/
+       cp -Rdp ../../sampleapp/linux/groupaction/groupserver release/
+       cp -Rdp ../../sampleapp/linux/groupaction/bookmark release/
+       cp -Rdp ../../sampleapp/linux/groupaction/lightserver release/
+       cp -Rdp ../../sampleapp/linux/groupsyncaction/group release/
+       cp -Rdp ../../sampleapp/linux/groupsyncaction/musicplayer release/
+       cp -Rdp ../../sampleapp/linux/groupsyncaction/phone release/
+       cp -Rdp ../../sampleapp/linux/groupsyncaction/speaker release/
+
+clean:
+       cd ../../sdk/build/linux && $(MAKE) clean
+       cd ../../sampleapp/linux && $(MAKE) clean
+       rm -rf ./release
index bd1b631..7fe88ad 100644 (file)
@@ -4,6 +4,21 @@
 
 Import('env')
 
-if env.get('TARGET_OS') == 'linux':
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+sample_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+
+######################################################################
+# Source files and Targets
+######################################################################
+if target_os == 'linux' :
        # Build linux sample app
-       SConscript('linux/tgmclient/SConscript')
+       SConscript('linux/configuration/SConscript')
+       SConscript('linux/groupaction/SConscript')
+       SConscript('linux/groupsyncaction/SConscript')
diff --git a/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp
new file mode 100644 (file)
index 0000000..7ee28d1
--- /dev/null
@@ -0,0 +1,591 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+#include "ConfigurationCollection.h"
+
+using namespace OC;
+
+/// This function internally calls registerResource API.
+void ConfigurationCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_configurationHandle, m_configurationUri,
+            m_configurationTypes[0], m_configurationInterfaces[0], callback,
+            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (configuration) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_configurationHandle, m_configurationInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_configurationHandle, m_configurationInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_regionHandle, m_regionUri, m_regionTypes[0], m_regionInterfaces[0],
+            callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (region) was unsuccessful\n";
+    }
+
+    result = registerResource(m_timeHandle, m_timeUri, m_timeTypes[0], m_timeInterfaces[0],
+            callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (time) was unsuccessful\n";
+    }
+
+    result = registerResource(m_networkHandle, m_networkUri, m_networkTypes[0],
+            m_networkInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (network) was unsuccessful\n";
+    }
+
+    result = registerResource(m_securityHandle, m_securityUri, m_securityTypes[0],
+            m_securityInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (security) was unsuccessful\n";
+    }
+
+    result = bindResource(m_configurationHandle, m_regionHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding region resource to room was unsuccessful\n";
+    }
+
+    result = bindResource(m_configurationHandle, m_timeHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding time resource to room was unsuccessful\n";
+    }
+
+    result = bindResource(m_configurationHandle, m_networkHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding network resource to room was unsuccessful\n";
+    }
+
+    result = bindResource(m_configurationHandle, m_securityHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding security resource to room was unsuccessful\n";
+    }
+
+    std::cout << "Configuration Collection is Created!(URI: " << m_configurationUri << ") \n";
+
+    myTimeCollection->createResources(callback);
+    myNetworkCollection->createResources(callback);
+    mySecurityCollection->createResources(callback);
+
+}
+
+void ConfigurationCollection::setConfigurationRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_configurationValue = value;
+
+        std::cout << "\t\t\t\t" << "m_configurationValue: " << m_configurationValue << std::endl;
+    }
+}
+
+void ConfigurationCollection::setTimeRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("link", value))
+    {
+        // NOT ALLOWED
+
+        std::cout << "\t\t\t\t" << "link: " << m_timeLink << std::endl;
+    }
+}
+
+void ConfigurationCollection::setNetworkRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("link", value))
+    {
+        // NOT ALLOWED
+
+        std::cout << "\t\t\t\t" << "link: " << m_networkLink << std::endl;
+    }
+}
+
+void ConfigurationCollection::setSecurityRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("link", value))
+    {
+        // NOT ALLOWED
+
+        std::cout << "\t\t\t\t" << "link: " << m_securityLink << std::endl;
+    }
+}
+
+void ConfigurationCollection::setRegionRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_regionValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_regionValue << std::endl;
+    }
+}
+
+OCRepresentation ConfigurationCollection::getTimeRepresentation()
+{
+    m_timeRep.setValue("link", m_timeLink);
+
+    return m_timeRep;
+}
+
+OCRepresentation ConfigurationCollection::getNetworkRepresentation()
+{
+    m_networkRep.setValue("link", m_networkLink);
+
+    return m_networkRep;
+}
+
+OCRepresentation ConfigurationCollection::getSecurityRepresentation()
+{
+    m_securityRep.setValue("link", m_securityLink);
+
+    return m_securityRep;
+}
+
+OCRepresentation ConfigurationCollection::getRegionRepresentation()
+{
+    m_regionRep.setValue("value", m_regionValue);
+
+    return m_regionRep;
+}
+
+OCRepresentation ConfigurationCollection::getConfigurationRepresentation()
+{
+    m_configurationRep.clearChildren();
+
+    m_configurationRep.addChild(getRegionRepresentation());
+    m_configurationRep.addChild(getTimeRepresentation());
+    m_configurationRep.addChild(getNetworkRepresentation());
+    m_configurationRep.addChild(getSecurityRepresentation());
+
+    m_configurationRep.setValue("value", m_configurationValue);
+
+    return m_configurationRep;
+}
+
+std::string ConfigurationCollection::getConfigurationUri()
+{
+    return m_configurationUri;
+}
+
+std::string ConfigurationCollection::getTimeUri()
+{
+    return m_timeUri;
+}
+
+std::string ConfigurationCollection::getNetworkUri()
+{
+    return m_networkUri;
+}
+
+std::string ConfigurationCollection::getSecurityUri()
+{
+    return m_securityUri;
+}
+
+std::string ConfigurationCollection::getRegionUri()
+{
+    return m_regionUri;
+}
+
+void ConfigurationCollection::factoryReset()
+{
+    m_configurationValue = defaultConfigurationValue;
+    m_regionValue = defaultRegionValue;
+    m_timeLink = defaultTimeLink;
+    m_networkLink = defaultNetworkLink;
+    m_securityLink = defaultSecurityLink;
+
+    myTimeCollection->factoryReset();
+    myNetworkCollection->factoryReset();
+    mySecurityCollection->factoryReset();
+}
+
+/// This function internally calls registerResource API.
+void TimeCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_timeHandle, m_timeUri, m_timeTypes[0],
+            m_timeInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (time) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_timeHandle, m_timeInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_timeHandle, m_timeInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_currentTimeHandle, m_currentTimeUri, m_currentTimeTypes[0],
+            m_currentTimeInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (currentTime) was unsuccessful\n";
+    }
+
+    result = bindResource(m_timeHandle, m_currentTimeHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding currentTime resource to room was unsuccessful\n";
+    }
+
+    std::cout << "Time Collection is Created!(URI: " << m_timeUri << ") \n";
+}
+
+void TimeCollection::setTimeRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_timeValue = value;
+
+        std::cout << "\t\t\t\t" << "m_timeValue: " << m_timeValue << std::endl;
+    }
+}
+
+void TimeCollection::setCurrentTimeRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("currentTime", value))
+    {
+        m_currentTimeValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_currentTimeValue << std::endl;
+    }
+}
+
+OCRepresentation TimeCollection::getCurrentTimeRepresentation()
+{
+    m_currentTimeRep.setValue("value", m_currentTimeValue);
+
+    return m_currentTimeRep;
+}
+
+OCRepresentation TimeCollection::getTimeRepresentation()
+{
+    m_timeRep.clearChildren();
+
+    m_timeRep.addChild(getCurrentTimeRepresentation());
+
+    m_timeRep.setValue("value", m_timeValue);
+
+    return m_timeRep;
+}
+
+std::string TimeCollection::getTimeUri()
+{
+    return m_timeUri;
+}
+
+std::string TimeCollection::getCurrentTimeUri()
+{
+    return m_currentTimeUri;
+}
+
+void TimeCollection::factoryReset()
+{
+    m_timeValue = defaultTimeValue;
+    m_currentTimeValue = defaultCurrentTimeValue;
+}
+
+/// This function internally calls registerResource API.
+void NetworkCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_networkHandle, m_networkUri, m_networkTypes[0],
+            m_networkInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (network) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_networkHandle, m_networkInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_networkHandle, m_networkInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_IPAddressHandle, m_IPAddressUri, m_IPAddressTypes[0],
+            m_IPAddressInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (IPAddress) was unsuccessful\n";
+    }
+
+    result = bindResource(m_networkHandle, m_IPAddressHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding IPAddress resource to room was unsuccessful\n";
+    }
+
+    std::cout << "Network Collection is Created!(URI: " << m_networkUri << ") \n";
+}
+
+void NetworkCollection::setNetworkRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_networkValue = value;
+
+        std::cout << "\t\t\t\t" << "m_networkValue: " << m_networkValue << std::endl;
+    }
+}
+
+void NetworkCollection::setIPAddressRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("IPAddress", value))
+    {
+        m_IPAddressValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_IPAddressValue << std::endl;
+    }
+}
+OCRepresentation NetworkCollection::getIPAddressRepresentation()
+{
+    m_IPAddressRep.setValue("value", m_IPAddressValue);
+
+    return m_IPAddressRep;
+}
+
+OCRepresentation NetworkCollection::getNetworkRepresentation()
+{
+    m_networkRep.clearChildren();
+
+    m_networkRep.addChild(getIPAddressRepresentation());
+
+    m_networkRep.setValue("value", m_networkValue);
+
+    return m_networkRep;
+}
+
+std::string NetworkCollection::getNetworkUri()
+{
+    return m_networkUri;
+}
+
+std::string NetworkCollection::getIPAddressUri()
+{
+    return m_IPAddressUri;
+}
+
+void NetworkCollection::factoryReset()
+{
+    m_networkValue = defaultNetworkValue;
+    m_IPAddressValue = defaultIPAddressValue;
+}
+
+/// This function internally calls registerResource API.
+void SecurityCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_securityHandle, m_securityUri, m_securityTypes[0],
+            m_securityInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (security) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_securityHandle, m_securityInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_securityHandle, m_securityInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_modeHandle, m_modeUri, m_modeTypes[0], m_modeInterfaces[0],
+            callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (mode) was unsuccessful\n";
+    }
+
+    result = bindResource(m_securityHandle, m_modeHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding mode resource to room was unsuccessful\n";
+    }
+
+    std::cout << "Security Collection is Created!(URI: " << m_securityUri << ") \n";
+}
+
+void SecurityCollection::setSecurityRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_securityValue = value;
+
+        std::cout << "\t\t\t\t" << "m_securityValue: " << m_securityValue << std::endl;
+    }
+}
+
+void SecurityCollection::setModeRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("mode", value))
+    {
+        m_modeValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_modeValue << std::endl;
+    }
+}
+
+OCRepresentation SecurityCollection::getModeRepresentation()
+{
+    m_modeRep.setValue("value", m_modeValue);
+
+    return m_modeRep;
+}
+
+OCRepresentation SecurityCollection::getSecurityRepresentation()
+{
+    m_securityRep.clearChildren();
+
+    m_securityRep.addChild(getModeRepresentation());
+
+    m_securityRep.setValue("value", m_securityValue);
+
+    return m_securityRep;
+}
+
+std::string SecurityCollection::getSecurityUri()
+{
+    return m_securityUri;
+}
+
+std::string SecurityCollection::getModeUri()
+{
+    return m_modeUri;
+}
+
+void SecurityCollection::factoryReset()
+{
+    m_securityValue = defaultSecurityValue;
+    m_modeValue = defaultModeValue;
+}
+
diff --git a/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h
new file mode 100644 (file)
index 0000000..cbc1db5
--- /dev/null
@@ -0,0 +1,535 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+#pragma once
+
+using namespace OC;
+
+typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler;
+
+static std::string defaultURIPrefix = "/oic/con";
+static std::string defaultResourceTypePrefix = "oic.con";
+
+extern std::string defaultTimeValue;
+extern std::string defaultCurrentTimeValue;
+
+class TimeCollection
+{
+public:
+
+    // diagnostics members
+    std::string m_timeUri;
+    std::string m_timeValue;
+    std::vector< std::string > m_timeTypes;
+    std::vector< std::string > m_timeInterfaces;
+    OCResourceHandle m_timeHandle;
+    OCRepresentation m_timeRep;
+
+    // factory reset members
+    std::string m_currentTimeUri;
+    std::string m_currentTimeValue;
+    std::vector< std::string > m_currentTimeTypes;
+    std::vector< std::string > m_currentTimeInterfaces;
+    OCResourceHandle m_currentTimeHandle;
+    OCRepresentation m_currentTimeRep;
+
+public:
+    /// Constructor
+    TimeCollection() :
+            m_timeValue(defaultTimeValue), m_currentTimeValue(defaultCurrentTimeValue)
+    {
+        m_currentTimeUri = defaultURIPrefix + "/time/0/currentTime"; // URI of the resource
+        m_currentTimeTypes.push_back("oic.con.time.currentTime"); // resource type name.
+        m_currentTimeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_currentTimeRep.setUri(m_currentTimeUri);
+        m_currentTimeRep.setResourceTypes(m_currentTimeTypes);
+        m_currentTimeRep.setResourceInterfaces(m_currentTimeInterfaces);
+        m_currentTimeRep.setValue("value", m_currentTimeValue);
+        m_currentTimeHandle = NULL;
+
+        m_timeUri = defaultURIPrefix + "/time"; // URI of the resource
+        m_timeTypes.push_back("oic.con.time"); // resource type name.
+        m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_timeInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_timeInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_timeRep.setValue("value", m_timeValue);
+        m_timeRep.setUri(m_timeUri);
+        m_timeRep.setResourceTypes(m_timeTypes);
+        m_timeRep.setResourceInterfaces(m_timeInterfaces);
+        m_timeHandle = NULL;
+    }
+    ;
+
+    /// Constructor
+    TimeCollection(std::string URIPrefix, std::string ResourceTypePrefix) :
+            m_timeValue(defaultTimeValue), m_currentTimeValue(defaultCurrentTimeValue)
+    {
+        m_currentTimeUri = URIPrefix + "/time/0/currentTime"; // URI of the resource
+        m_currentTimeTypes.push_back(ResourceTypePrefix + ".time.currentTime"); // type name.
+        m_currentTimeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_currentTimeRep.setUri(m_currentTimeUri);
+        m_currentTimeRep.setResourceTypes(m_currentTimeTypes);
+        m_currentTimeRep.setResourceInterfaces(m_currentTimeInterfaces);
+        m_currentTimeRep.setValue("value", m_currentTimeValue);
+        m_currentTimeHandle = NULL;
+
+        m_timeUri = URIPrefix + "/time"; // URI of the resource
+        m_timeTypes.push_back(ResourceTypePrefix + ".time"); // resource type name.
+        m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_timeInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_timeInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_timeRep.setValue("value", m_timeValue);
+        m_timeRep.setUri(m_timeUri);
+        m_timeRep.setResourceTypes(m_timeTypes);
+        m_timeRep.setResourceInterfaces(m_timeInterfaces);
+        m_timeHandle = NULL;
+    }
+    ;
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setTimeRepresentation(OCRepresentation& rep);
+    void setCurrentTimeRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getTimeRepresentation();
+    OCRepresentation getCurrentTimeRepresentation();
+
+    std::string getTimeUri();
+    std::string getCurrentTimeUri();
+
+    void factoryReset();
+
+};
+
+extern std::string defaultNetworkValue;
+extern std::string defaultIPAddressValue;
+
+class NetworkCollection
+{
+public:
+
+    // diagnostics members
+    std::string m_networkUri;
+    std::string m_networkValue;
+    std::vector< std::string > m_networkTypes;
+    std::vector< std::string > m_networkInterfaces;
+    OCResourceHandle m_networkHandle;
+    OCRepresentation m_networkRep;
+
+    // factory reset members
+    std::string m_IPAddressUri;
+    std::string m_IPAddressValue;
+    std::vector< std::string > m_IPAddressTypes;
+    std::vector< std::string > m_IPAddressInterfaces;
+    OCResourceHandle m_IPAddressHandle;
+    OCRepresentation m_IPAddressRep;
+
+public:
+
+    /// Constructor
+    NetworkCollection() :
+            m_networkValue(defaultNetworkValue), m_IPAddressValue(defaultIPAddressValue)
+    {
+        m_IPAddressUri = defaultURIPrefix + "/network/0/IPAddress"; // URI of the resource
+        m_IPAddressTypes.push_back("oic.con.network.IPAddress"); // resource type name.
+        m_IPAddressInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_IPAddressRep.setUri(m_IPAddressUri);
+        m_IPAddressRep.setResourceTypes(m_IPAddressTypes);
+        m_IPAddressRep.setResourceInterfaces(m_IPAddressInterfaces);
+        m_IPAddressRep.setValue("value", m_IPAddressValue);
+        m_IPAddressHandle = NULL;
+
+        m_networkUri = defaultURIPrefix + "/network"; // URI of the resource
+        m_networkTypes.push_back("oic.con.network"); // resource type name.
+        m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_networkInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_networkInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_networkRep.setValue("value", m_networkValue);
+        m_networkRep.setUri(m_networkUri);
+        m_networkRep.setResourceTypes(m_networkTypes);
+        m_networkRep.setResourceInterfaces(m_networkInterfaces);
+        m_networkHandle = NULL;
+    }
+    ;
+
+    /// Constructor
+    NetworkCollection(std::string URIPrefix, std::string ResourceTypePrefix) :
+            m_networkValue(defaultNetworkValue), m_IPAddressValue(defaultIPAddressValue)
+    {
+        m_IPAddressUri = URIPrefix + "/network/0/IPAddress"; // URI of the resource
+        m_IPAddressTypes.push_back(ResourceTypePrefix + "network.IPAddress"); // resource type name.
+        m_IPAddressInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_IPAddressRep.setUri(m_IPAddressUri);
+        m_IPAddressRep.setResourceTypes(m_IPAddressTypes);
+        m_IPAddressRep.setResourceInterfaces(m_IPAddressInterfaces);
+        m_IPAddressRep.setValue("value", m_IPAddressValue);
+        m_IPAddressHandle = NULL;
+
+        m_networkUri = URIPrefix + "/network"; // URI of the resource
+        m_networkTypes.push_back(ResourceTypePrefix + ".network"); // resource type name.
+        m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_networkInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_networkInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_networkRep.setValue("value", m_networkValue);
+        m_networkRep.setUri(m_networkUri);
+        m_networkRep.setResourceTypes(m_networkTypes);
+        m_networkRep.setResourceInterfaces(m_networkInterfaces);
+        m_networkHandle = NULL;
+    }
+    ;
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setNetworkRepresentation(OCRepresentation& rep);
+    void setIPAddressRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getNetworkRepresentation();
+    OCRepresentation getIPAddressRepresentation();
+
+    std::string getNetworkUri();
+    std::string getIPAddressUri();
+
+    void factoryReset();
+
+};
+
+extern std::string defaultSecurityValue;
+extern std::string defaultModeValue;
+
+class SecurityCollection
+{
+public:
+
+    // diagnostics members
+    std::string m_securityUri;
+    std::string m_securityValue;
+    std::vector< std::string > m_securityTypes;
+    std::vector< std::string > m_securityInterfaces;
+    OCResourceHandle m_securityHandle;
+    OCRepresentation m_securityRep;
+
+    // factory reset members
+    std::string m_modeUri;
+    std::string m_modeValue;
+    std::vector< std::string > m_modeTypes;
+    std::vector< std::string > m_modeInterfaces;
+    OCResourceHandle m_modeHandle;
+    OCRepresentation m_modeRep;
+
+public:
+    /// Constructor
+    SecurityCollection() :
+            m_securityValue(defaultSecurityValue), m_modeValue(defaultModeValue)
+    {
+        m_modeUri = defaultURIPrefix + "/security/0/mode"; // URI of the resource
+        m_modeTypes.push_back("oic.con.security.mode"); // resource type name.
+        m_modeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_modeRep.setUri(m_modeUri);
+        m_modeRep.setResourceTypes(m_modeTypes);
+        m_modeRep.setResourceInterfaces(m_modeInterfaces);
+        m_modeRep.setValue("value", m_modeValue);
+        m_modeHandle = NULL;
+
+        m_securityUri = defaultURIPrefix + "/security"; // URI of the resource
+        m_securityTypes.push_back("oic.con.security"); // resource type name.
+        m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_securityInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_securityInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_securityRep.setValue("value", m_securityValue);
+        m_securityRep.setUri(m_securityUri);
+        m_securityRep.setResourceTypes(m_securityTypes);
+        m_securityRep.setResourceInterfaces(m_securityInterfaces);
+        m_securityHandle = NULL;
+    }
+    ;
+
+    /// Constructor
+    SecurityCollection(std::string URIPrefix, std::string ResourceTypePrefix) :
+            m_securityValue(defaultSecurityValue), m_modeValue(defaultModeValue)
+    {
+        m_modeUri = URIPrefix + "/security/0/mode"; // URI of the resource
+        m_modeTypes.push_back(ResourceTypePrefix + ".security.mode"); // resource type name.
+        m_modeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_modeRep.setUri(m_modeUri);
+        m_modeRep.setResourceTypes(m_modeTypes);
+        m_modeRep.setResourceInterfaces(m_modeInterfaces);
+        m_modeRep.setValue("value", m_modeValue);
+        m_modeHandle = NULL;
+
+        m_securityUri = URIPrefix + "/security"; // URI of the resource
+        m_securityTypes.push_back(ResourceTypePrefix + ".security"); // resource type name.
+        m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_securityInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_securityInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_securityRep.setValue("value", m_securityValue);
+        m_securityRep.setUri(m_securityUri);
+        m_securityRep.setResourceTypes(m_securityTypes);
+        m_securityRep.setResourceInterfaces(m_securityInterfaces);
+        m_securityHandle = NULL;
+    }
+    ;
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setSecurityRepresentation(OCRepresentation& rep);
+    void setModeRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getSecurityRepresentation();
+    OCRepresentation getModeRepresentation();
+
+    std::string getSecurityUri();
+    std::string getModeUri();
+
+    void factoryReset();
+
+};
+
+extern std::string defaultConfigurationValue;
+extern std::string defaultRegionValue;
+static std::string defaultTimeLink = "/con/con/0/time";
+static std::string defaultNetworkLink = "/con/con/0/network";
+static std::string defaultSecurityLink = "/con/con/0/security";
+
+class ConfigurationCollection
+{
+public:
+    TimeCollection *myTimeCollection;
+    NetworkCollection *myNetworkCollection;
+    SecurityCollection *mySecurityCollection;
+
+public:
+    // Configuration members
+    std::string m_configurationUri;
+    std::string m_configurationValue;
+    std::vector< std::string > m_configurationTypes;
+    std::vector< std::string > m_configurationInterfaces;
+    OCResourceHandle m_configurationHandle;
+    OCRepresentation m_configurationRep;
+
+    // Security members
+    std::string m_regionUri;
+    std::string m_regionValue;
+    std::vector< std::string > m_regionTypes;
+    std::vector< std::string > m_regionInterfaces;
+    OCResourceHandle m_regionHandle;
+    OCRepresentation m_regionRep;
+
+    // Time members
+    std::string m_timeUri;
+    std::string m_timeLink;
+    std::vector< std::string > m_timeTypes;
+    std::vector< std::string > m_timeInterfaces;
+    OCResourceHandle m_timeHandle;
+    OCRepresentation m_timeRep;
+
+    // Network members
+    std::string m_networkUri;
+    std::string m_networkLink;
+    std::vector< std::string > m_networkTypes;
+    std::vector< std::string > m_networkInterfaces;
+    OCResourceHandle m_networkHandle;
+    OCRepresentation m_networkRep;
+
+    // Security members
+    std::string m_securityUri;
+    std::string m_securityLink;
+    std::vector< std::string > m_securityTypes;
+    std::vector< std::string > m_securityInterfaces;
+    OCResourceHandle m_securityHandle;
+    OCRepresentation m_securityRep;
+
+public:
+    /// Constructor
+    ConfigurationCollection() :
+            m_configurationValue(defaultConfigurationValue), m_regionValue(defaultRegionValue), m_timeLink(
+                    defaultTimeLink), m_networkLink(defaultNetworkLink), m_securityLink(
+                    defaultSecurityLink)
+    {
+        m_regionUri = defaultURIPrefix + "/0/region"; // URI of the resource
+        m_regionTypes.push_back(defaultResourceTypePrefix + ".region"); // resource type name.
+        m_regionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_regionRep.setUri(m_regionUri);
+        m_regionRep.setResourceTypes(m_regionTypes);
+        m_regionRep.setResourceInterfaces(m_regionInterfaces);
+        m_regionRep.setValue("value", m_regionValue);
+        m_regionHandle = NULL;
+
+        m_timeUri = defaultURIPrefix + "/0/time"; // URI of the resource
+        m_timeTypes.push_back(defaultResourceTypePrefix + ".time"); // resource type name.
+        m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_timeRep.setUri(m_timeUri);
+        m_timeRep.setResourceTypes(m_timeTypes);
+        m_timeRep.setResourceInterfaces(m_timeInterfaces);
+        m_timeRep.setValue("link", m_timeLink);
+        m_timeHandle = NULL;
+
+        m_networkUri = defaultURIPrefix + "/0/net"; // URI of the resource
+        m_networkTypes.push_back(defaultResourceTypePrefix + ".net"); // resource type name.
+        m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_networkRep.setUri(m_networkUri);
+        m_networkRep.setResourceTypes(m_networkTypes);
+        m_networkRep.setResourceInterfaces(m_networkInterfaces);
+        m_networkRep.setValue("link", m_networkLink);
+        m_networkHandle = NULL;
+
+        m_securityUri = defaultURIPrefix + "/0/sec"; // URI of the resource
+        m_securityTypes.push_back(defaultResourceTypePrefix + ".sec"); // resource type name.
+        m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_securityRep.setUri(m_securityUri);
+        m_securityRep.setResourceTypes(m_securityTypes);
+        m_securityRep.setResourceInterfaces(m_securityInterfaces);
+        m_securityRep.setValue("link", m_securityLink);
+        m_securityHandle = NULL;
+
+        m_configurationUri = defaultURIPrefix + ""; // URI of the resource
+        m_configurationTypes.push_back(defaultResourceTypePrefix + ""); // resource type name.
+        m_configurationInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_configurationInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_configurationInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_configurationRep.setValue("value", m_configurationValue);
+        m_configurationRep.setUri(m_configurationUri);
+        m_configurationRep.setResourceTypes(m_configurationTypes);
+        m_configurationRep.setResourceInterfaces(m_configurationInterfaces);
+        m_configurationHandle = NULL;
+
+        myTimeCollection = new TimeCollection();
+        myNetworkCollection = new NetworkCollection();
+        mySecurityCollection = new SecurityCollection();
+    }
+    ;
+
+    /// Constructor
+    ConfigurationCollection(std::string URIPrefix, std::string ResourceTypePrefix) :
+            m_configurationValue(defaultConfigurationValue), m_regionValue(defaultRegionValue), m_timeLink(
+                    defaultTimeLink), m_networkLink(defaultNetworkLink), m_securityLink(
+                    defaultSecurityLink)
+    {
+        m_regionUri = URIPrefix + "/0/region"; // URI of the resource
+        m_regionTypes.push_back(ResourceTypePrefix + ".region"); // type name.
+        m_regionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_regionRep.setUri(m_regionUri);
+        m_regionRep.setResourceTypes(m_regionTypes);
+        m_regionRep.setResourceInterfaces(m_regionInterfaces);
+        m_regionRep.setValue("value", m_regionValue);
+        m_regionHandle = NULL;
+
+        m_timeUri = URIPrefix + "/0/time"; // URI of the resource
+        m_timeTypes.push_back(ResourceTypePrefix + ".time"); // resource type name.
+        m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_timeRep.setUri(m_timeUri);
+        m_timeRep.setResourceTypes(m_timeTypes);
+        m_timeRep.setResourceInterfaces(m_timeInterfaces);
+        m_timeRep.setValue("link", m_timeLink);
+        m_timeHandle = NULL;
+
+        m_networkUri = URIPrefix + "/0/net"; // URI of the resource
+        m_networkTypes.push_back(ResourceTypePrefix + ".net"); // resource type name.
+        m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_networkRep.setUri(m_networkUri);
+        m_networkRep.setResourceTypes(m_networkTypes);
+        m_networkRep.setResourceInterfaces(m_networkInterfaces);
+        m_networkRep.setValue("link", m_networkLink);
+        m_networkHandle = NULL;
+
+        m_securityUri = URIPrefix + "/0/sec"; // URI of the resource
+        m_securityTypes.push_back(ResourceTypePrefix + ".sec"); // resource type name.
+        m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_securityRep.setUri(m_securityUri);
+        m_securityRep.setResourceTypes(m_securityTypes);
+        m_securityRep.setResourceInterfaces(m_securityInterfaces);
+        m_securityRep.setValue("link", m_securityLink);
+        m_securityHandle = NULL;
+
+        m_configurationUri = URIPrefix + ""; // URI of the resource
+        m_configurationTypes.push_back(ResourceTypePrefix + ""); // resource type name.
+        m_configurationInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_configurationInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_configurationInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_configurationRep.setValue("value", m_configurationValue);
+        m_configurationRep.setUri(m_configurationUri);
+        m_configurationRep.setResourceTypes(m_configurationTypes);
+        m_configurationRep.setResourceInterfaces(m_configurationInterfaces);
+        m_configurationHandle = NULL;
+
+        myTimeCollection = new TimeCollection(URIPrefix, ResourceTypePrefix);
+        myNetworkCollection = new NetworkCollection(URIPrefix, ResourceTypePrefix);
+        mySecurityCollection = new SecurityCollection(URIPrefix, ResourceTypePrefix);
+    }
+    ;
+
+    ~ConfigurationCollection()
+    {
+        free(myTimeCollection);
+        free(myNetworkCollection);
+        free(mySecurityCollection);
+    }
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setConfigurationRepresentation(OCRepresentation& rep);
+    void setTimeRepresentation(OCRepresentation& rep);
+    void setNetworkRepresentation(OCRepresentation& rep);
+    void setSecurityRepresentation(OCRepresentation& rep);
+    void setRegionRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getTimeRepresentation();
+    OCRepresentation getNetworkRepresentation();
+    OCRepresentation getSecurityRepresentation();
+    OCRepresentation getRegionRepresentation();
+    OCRepresentation getConfigurationRepresentation();
+
+    std::string getConfigurationUri();
+    std::string getTimeUri();
+    std::string getNetworkUri();
+    std::string getSecurityUri();
+    std::string getRegionUri();
+
+    void factoryReset();
+
+};
diff --git a/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp
new file mode 100644 (file)
index 0000000..31eaf1e
--- /dev/null
@@ -0,0 +1,245 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+#include "DiagnosticsCollection.h"
+
+using namespace OC;
+
+/// This function internally calls registerResource API.
+void DiagnosticsCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_diagnosticsHandle, m_diagnosticsUri,
+            m_diagnosticsTypes[0], m_diagnosticsInterfaces[0], callback,
+            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (diagnostics) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_diagnosticsHandle, m_diagnosticsInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_diagnosticsHandle, m_diagnosticsInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_factoryResetHandle, m_factoryResetUri, m_factoryResetTypes[0],
+            m_factoryResetInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (factoryReset) was unsuccessful\n";
+    }
+
+    result = registerResource(m_rebootHandle, m_rebootUri, m_rebootTypes[0], m_rebootInterfaces[0],
+            callback, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (reboot) was unsuccessful\n";
+    }
+
+    result = registerResource(m_startCollectionHandle, m_startCollectionUri,
+            m_startCollectionTypes[0], m_startCollectionInterfaces[0], callback,
+            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (startCollection) was unsuccessful\n";
+    }
+
+    result = bindResource(m_diagnosticsHandle, m_factoryResetHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding installedLocation resource to room was unsuccessful\n";
+    }
+
+    result = bindResource(m_diagnosticsHandle, m_rebootHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding time resource to room was unsuccessful\n";
+    }
+
+    result = bindResource(m_diagnosticsHandle, m_startCollectionHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding network resource to room was unsuccessful\n";
+    }
+
+    thread exec(
+            std::function< void(int second) >(
+                    std::bind(&DiagnosticsCollection::diagnosticsMonitor, this,
+                            std::placeholders::_1)), 10); // every 10 seconds
+    exec.detach();
+
+    std::cout << "Diagnostics Collection is Created!\n";
+}
+
+void DiagnosticsCollection::setDiagnosticsRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_diagnosticsValue = value;
+
+        std::cout << "\t\t\t\t" << "m_diagnosticsValue: " << m_diagnosticsValue << std::endl;
+    }
+}
+
+void DiagnosticsCollection::setFactoryResetRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_factoryResetValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_factoryResetValue << std::endl;
+    }
+}
+
+void DiagnosticsCollection::setRebootRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_rebootValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_rebootValue << std::endl;
+    }
+}
+
+void DiagnosticsCollection::setStartCollectionRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_startCollectionValue = value;
+
+        std::cout << "\t\t\t\t" << "value: " << m_startCollectionValue << std::endl;
+    }
+}
+
+OCRepresentation DiagnosticsCollection::getFactoryResetRepresentation()
+{
+    m_factoryResetRep.setValue("value", m_factoryResetValue);
+
+    return m_factoryResetRep;
+}
+
+OCRepresentation DiagnosticsCollection::getRebootRepresentation()
+{
+    m_rebootRep.setValue("value", m_rebootValue);
+
+    return m_rebootRep;
+}
+
+OCRepresentation DiagnosticsCollection::getStartCollectionRepresentation()
+{
+    m_startCollectionRep.setValue("value", m_startCollectionValue);
+
+    return m_startCollectionRep;
+}
+
+OCRepresentation DiagnosticsCollection::getDiagnosticsRepresentation()
+{
+    m_diagnosticsRep.clearChildren();
+
+    m_diagnosticsRep.addChild(getFactoryResetRepresentation());
+    m_diagnosticsRep.addChild(getRebootRepresentation());
+    m_diagnosticsRep.addChild(getStartCollectionRepresentation());
+
+    m_diagnosticsRep.setValue("value", m_diagnosticsValue);
+
+    return m_diagnosticsRep;
+}
+
+std::string DiagnosticsCollection::getDiagnosticsUri()
+{
+    return m_diagnosticsUri;
+}
+
+std::string DiagnosticsCollection::getFactoryResetUri()
+{
+    return m_factoryResetUri;
+}
+
+std::string DiagnosticsCollection::getRebootUri()
+{
+    return m_rebootUri;
+}
+
+std::string DiagnosticsCollection::getStartCollectionUri()
+{
+    return m_startCollectionUri;
+}
+
+void DiagnosticsCollection::diagnosticsMonitor(int second)
+{
+    while (1)
+    {
+        sleep(second);
+
+        if (m_rebootValue == "true")
+        {
+            int res;
+            std::cout << "Reboot will be soon..." << std::endl;
+            m_rebootValue = defaultReboot;
+            res = system("sudo reboot"); // System reboot
+
+            std::cout << "return: " << res << std::endl;
+
+        }
+        else if (m_factoryResetValue == "true")
+        {
+            std::cout << "Factory Reset will be soon..." << std::endl;
+            m_factoryResetValue = defaultFactoryReset;
+            factoryReset();
+        }
+    }
+}
diff --git a/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h
new file mode 100644 (file)
index 0000000..df4c83e
--- /dev/null
@@ -0,0 +1,150 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+#pragma once
+
+using namespace OC;
+
+typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler;
+
+static std::string defaultDiagnosticsValue = "false";
+static std::string defaultFactoryReset = "false";
+static std::string defaultReboot = "false";
+static std::string defaultStartCollection = "false";
+
+class DiagnosticsCollection
+{
+public:
+
+    // diagnostics members
+    std::string m_diagnosticsUri;
+    std::string m_diagnosticsValue;
+    std::vector< std::string > m_diagnosticsTypes;
+    std::vector< std::string > m_diagnosticsInterfaces;
+    OCResourceHandle m_diagnosticsHandle;
+    OCRepresentation m_diagnosticsRep;
+
+    // factory reset members
+    std::string m_factoryResetUri;
+    std::string m_factoryResetValue;
+    std::vector< std::string > m_factoryResetTypes;
+    std::vector< std::string > m_factoryResetInterfaces;
+    OCResourceHandle m_factoryResetHandle;
+    OCRepresentation m_factoryResetRep;
+
+    // reboot members
+    std::string m_rebootUri;
+    std::string m_rebootValue;
+    std::vector< std::string > m_rebootTypes;
+    std::vector< std::string > m_rebootInterfaces;
+    OCResourceHandle m_rebootHandle;
+    OCRepresentation m_rebootRep;
+
+    // startcollection members
+    std::string m_startCollectionUri;
+    std::string m_startCollectionValue;
+    std::vector< std::string > m_startCollectionTypes;
+    std::vector< std::string > m_startCollectionInterfaces;
+    OCResourceHandle m_startCollectionHandle;
+    OCRepresentation m_startCollectionRep;
+
+public:
+    /// Constructor
+    DiagnosticsCollection() :
+            m_diagnosticsValue(defaultDiagnosticsValue), m_factoryResetValue(defaultFactoryReset), m_rebootValue(
+                    defaultReboot), m_startCollectionValue(defaultStartCollection)
+    {
+        m_factoryResetUri = "/oic/diag/0/factoryReset"; // URI of the resource
+        m_factoryResetTypes.push_back("oic.diag.factoryReset"); // resource type name.
+        m_factoryResetInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_factoryResetRep.setUri(m_factoryResetUri);
+        m_factoryResetRep.setResourceTypes(m_factoryResetTypes);
+        m_factoryResetRep.setResourceInterfaces(m_factoryResetInterfaces);
+        m_factoryResetRep.setValue("value", m_factoryResetValue);
+        m_factoryResetHandle = NULL;
+
+        m_rebootUri = "/oic/diag/0/reboot"; // URI of the resource
+        m_rebootTypes.push_back("oic.diag.reboot"); // resource type name.
+        m_rebootInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_rebootRep.setUri(m_rebootUri);
+        m_rebootRep.setResourceTypes(m_rebootTypes);
+        m_rebootRep.setResourceInterfaces(m_rebootInterfaces);
+        m_rebootRep.setValue("value", m_rebootValue);
+        m_rebootHandle = NULL;
+
+        m_startCollectionUri = "/oic/diag/0/startCollection"; // URI of the resource
+        m_startCollectionTypes.push_back("oic.diag.startCollection"); // resource type name.
+        m_startCollectionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_startCollectionRep.setUri(m_startCollectionUri);
+        m_startCollectionRep.setResourceTypes(m_startCollectionTypes);
+        m_startCollectionRep.setResourceInterfaces(m_startCollectionInterfaces);
+        m_startCollectionRep.setValue("value", m_startCollectionValue);
+        m_startCollectionHandle = NULL;
+
+        m_diagnosticsUri = "/oic/diag"; // URI of the resource
+        m_diagnosticsTypes.push_back("oic.diag"); // resource type name.
+        m_diagnosticsInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_diagnosticsInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_diagnosticsInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_diagnosticsRep.setValue("value", m_diagnosticsValue);
+        m_diagnosticsRep.setUri(m_diagnosticsUri);
+        m_diagnosticsRep.setResourceTypes(m_diagnosticsTypes);
+        m_diagnosticsRep.setResourceInterfaces(m_diagnosticsInterfaces);
+        m_diagnosticsHandle = NULL;
+    }
+    ;
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setDiagnosticsRepresentation(OCRepresentation& rep);
+    void setFactoryResetRepresentation(OCRepresentation& rep);
+    void setRebootRepresentation(OCRepresentation& rep);
+    void setStartCollectionRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getDiagnosticsRepresentation();
+    OCRepresentation getFactoryResetRepresentation();
+    OCRepresentation getRebootRepresentation();
+    OCRepresentation getStartCollectionRepresentation();
+
+    std::string getDiagnosticsUri();
+    std::string getFactoryResetUri();
+    std::string getRebootUri();
+    std::string getStartCollectionUri();
+
+    void diagnosticsMonitor(int second);
+
+    std::function< void() > factoryReset;
+};
+
diff --git a/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp
new file mode 100644 (file)
index 0000000..d050096
--- /dev/null
@@ -0,0 +1,141 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+#include "FactorySetCollection.h"
+
+using namespace OC;
+
+/// This function internally calls registerResource API.
+void FactorySetCollection::createResources(ResourceEntityHandler callback)
+{
+    using namespace OC::OCPlatform;
+
+    if (callback == NULL)
+    {
+        std::cout << "callback should be binded\t";
+        return;
+    }
+
+    // This will internally create and register the resource.
+    OCStackResult result = registerResource(m_factorySetHandle, m_factorySetUri,
+            m_factorySetTypes[0], m_factorySetInterfaces[0], callback,
+            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (configuration) was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_factorySetHandle, m_factorySetInterfaces[1]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = bindInterfaceToResource(m_factorySetHandle, m_factorySetInterfaces[2]);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding TypeName to Resource was unsuccessful\n";
+    }
+
+    result = registerResource(m_configurationCollectionHandle, m_configurationCollectionUri,
+            m_configurationCollectionTypes[0], m_configurationCollectionInterfaces[0], callback,
+            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Resource creation (installedLocation) was unsuccessful\n";
+    }
+
+    result = bindResource(m_factorySetHandle, m_configurationCollectionHandle);
+    if (OC_STACK_OK != result)
+    {
+        std::cout << "Binding installedLocation resource to room was unsuccessful\n";
+    }
+
+    defaultConfigurationCollection = new ConfigurationCollection(defaultConfigurationURIPrefix,
+            defaultConfigurationResourceTypePrefix);
+    //defaultConfigurationCollection->bindEntityHander(callback);
+    defaultConfigurationCollection->createResources(callback);
+
+    std::cout << "FactorySet Collection is Created!\n";
+}
+
+void FactorySetCollection::setFactorySetRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("value", value))
+    {
+        m_factorySetValue = value;
+
+        std::cout << "\t\t\t\t" << "m_factorySetValue: " << m_factorySetValue << std::endl;
+    }
+}
+
+void FactorySetCollection::setConfigurationCollectionRepresentation(OCRepresentation& rep)
+{
+    string value;
+
+    if (rep.getValue("link", value))
+    {
+        // NOT ALLOWED
+
+        std::cout << "\t\t\t\t" << "link: " << m_configurationCollectionLink << std::endl;
+    }
+}
+
+OCRepresentation FactorySetCollection::getConfigurationCollectionRepresentation()
+{
+    m_configurationCollectionRep.setValue("link", m_configurationCollectionLink);
+
+    return m_configurationCollectionRep;
+}
+
+OCRepresentation FactorySetCollection::getFactorySetRepresentation()
+{
+    m_factorySetRep.clearChildren();
+
+    m_factorySetRep.addChild(getConfigurationCollectionRepresentation());
+
+    m_factorySetRep.setValue("value", m_factorySetValue);
+
+    return m_factorySetRep;
+}
+
+std::string FactorySetCollection::getFactorySetUri()
+{
+    return m_factorySetUri;
+}
+
+std::string FactorySetCollection::getConfigurationCollectionUri()
+{
+    return m_configurationCollectionUri;
+}
diff --git a/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h
new file mode 100644 (file)
index 0000000..bc20a71
--- /dev/null
@@ -0,0 +1,120 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+#include "ConfigurationCollection.h"
+
+#pragma once
+
+using namespace OC;
+
+typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler;
+
+extern std::string defaultFactorySetValue;
+static std::string defaultConfigurationCollectionLink = "/factorySet/oic/con";
+
+static std::string defaultConfigurationURIPrefix = "/factorySet/oic/con";
+static std::string defaultConfigurationResourceTypePrefix = "factorySet.oic.con";
+
+class FactorySetCollection
+{
+public:
+
+    ConfigurationCollection *defaultConfigurationCollection;
+
+public:
+
+    // diagnostics members
+    std::string m_factorySetUri;
+    std::string m_factorySetValue;
+    std::vector< std::string > m_factorySetTypes;
+    std::vector< std::string > m_factorySetInterfaces;
+    OCResourceHandle m_factorySetHandle;
+    OCRepresentation m_factorySetRep;
+
+    // Configuration members
+    std::string m_configurationCollectionUri;
+    std::string m_configurationCollectionLink;
+    std::vector< std::string > m_configurationCollectionTypes;
+    std::vector< std::string > m_configurationCollectionInterfaces;
+    OCResourceHandle m_configurationCollectionHandle;
+    OCRepresentation m_configurationCollectionRep;
+
+public:
+    /// Constructor
+    FactorySetCollection() :
+            m_factorySetValue(defaultFactorySetValue), m_configurationCollectionLink(
+                    defaultConfigurationCollectionLink)
+    {
+        m_configurationCollectionUri = "/factorySet/0/con"; // URI of the resource
+        m_configurationCollectionTypes.push_back("factorySet.con"); // resource type name.
+        m_configurationCollectionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+
+        m_configurationCollectionRep.setUri(m_configurationCollectionUri);
+        m_configurationCollectionRep.setResourceTypes(m_configurationCollectionTypes);
+        m_configurationCollectionRep.setResourceInterfaces(m_configurationCollectionInterfaces);
+        m_configurationCollectionRep.setValue("link", m_configurationCollectionLink);
+        m_configurationCollectionHandle = NULL;
+
+        m_factorySetUri = "/factorySet"; // URI of the resource
+        m_factorySetTypes.push_back("factorySet"); // resource type name.
+        m_factorySetInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_factorySetInterfaces.push_back(BATCH_INTERFACE); // resource interface.
+        m_factorySetInterfaces.push_back(LINK_INTERFACE); // resource interface.
+        m_factorySetRep.setValue("value", m_factorySetValue);
+        m_factorySetRep.setUri(m_factorySetUri);
+        m_factorySetRep.setResourceTypes(m_factorySetTypes);
+        m_factorySetRep.setResourceInterfaces(m_factorySetInterfaces);
+        m_factorySetHandle = NULL;
+
+        defaultConfigurationCollection = NULL;
+    }
+    ;
+
+    ~FactorySetCollection()
+    {
+        if (defaultConfigurationCollection != NULL)
+            free(defaultConfigurationCollection);
+    }
+    ;
+
+    /// This function internally calls registerResource API.
+    void createResources(ResourceEntityHandler callback);
+
+    void setFactorySetRepresentation(OCRepresentation& rep);
+    void setConfigurationCollectionRepresentation(OCRepresentation& rep);
+
+    OCRepresentation getFactorySetRepresentation();
+    OCRepresentation getConfigurationCollectionRepresentation();
+
+    std::string getFactorySetUri();
+    std::string getConfigurationCollectionUri();
+
+};
+
diff --git a/service/things-manager/sampleapp/linux/configuration/SConscript b/service/things-manager/sampleapp/linux/configuration/SConscript
new file mode 100644 (file)
index 0000000..d4a8c5d
--- /dev/null
@@ -0,0 +1,34 @@
+##
+# linux sample app  build script
+##
+
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src'])
+linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
+linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread'])
+
+######################################################################
+#build sampleapp
+######################################################################
+conserver = linux_sample_env.Program('con-server', ['ConfigurationCollection.cpp', 'DiagnosticsCollection.cpp', 'FactorySetCollection.cpp', 'con-server.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("BootstrapServerApp", bootstrapserver)
+env.AppendTarget('ConServerApp')
+env.AppendTarget('ConClientApp')
+env.AppendTarget('BootstrapServerApp')
diff --git a/service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp b/service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp
new file mode 100644 (file)
index 0000000..e53f61c
--- /dev/null
@@ -0,0 +1,237 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+
+#include <pthread.h>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace std;
+
+// Forward declaring the entityHandler (bootstrap)
+bool prepareResponse(std::shared_ptr< OCResourceRequest > request);
+OCStackResult sendResponse(std::shared_ptr< OCResourceRequest > pRequest);
+OCEntityHandlerResult entityHandlerBootstrap(std::shared_ptr< OCResourceRequest > request);
+
+#define DefaultConfigurationValue "Configuration Collection"
+#define DefaultRegionValue "Seoul, Korea"
+#define DefaultTimeValue "Time Collection"
+#define DefaultCurrentTimeValue "00:00:00"
+#define DefaultNetworkValue "Network Collection"
+#define DefaultIPAddressValue "192.168.0.2"
+#define DefaultSecurityValue "SecurityValue"
+#define DefaultModeValue "NoSec"
+#define DefaultFactorySetValue "FactorySet Value"
+
+class BootstrapResource
+{
+public:
+    // Room members
+    std::string m_bootstrapUri;
+    std::vector< std::string > m_bootstrapTypes;
+    std::vector< std::string > m_bootstrapInterfaces;
+    OCResourceHandle m_bootstrapHandle;
+    OCRepresentation m_bootstrapRep;
+
+public:
+    /// Constructor
+    BootstrapResource()
+    {
+        m_bootstrapUri = "/bootstrap"; // URI of the resource
+        m_bootstrapTypes.push_back("bootstrap"); // resource type name. In this case, it is light
+        m_bootstrapInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
+        m_bootstrapRep.setUri(m_bootstrapUri);
+        m_bootstrapRep.setResourceTypes(m_bootstrapTypes);
+        m_bootstrapRep.setResourceInterfaces(m_bootstrapInterfaces);
+        m_bootstrapHandle = NULL;
+    }
+
+    /// This function internally calls registerResource API.
+    void createResources()
+    {
+        using namespace OC::OCPlatform;
+        // This will internally create and register the resource.
+        OCStackResult result = registerResource(m_bootstrapHandle, m_bootstrapUri,
+                m_bootstrapTypes[0], m_bootstrapInterfaces[0], entityHandlerBootstrap,
+                OC_DISCOVERABLE | OC_OBSERVABLE);
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation (room) was unsuccessful\n";
+        }
+    }
+
+    void setBootstrapRepresentation(OCRepresentation& rep)
+    {
+        // Not allowed
+    }
+
+    OCRepresentation getBootstrapRepresentation()
+    {
+        m_bootstrapRep.setValue< std::string >("regionValue", DefaultRegionValue);
+        m_bootstrapRep.setValue< std::string >("timeValue", DefaultTimeValue);
+        m_bootstrapRep.setValue< std::string >("currentTimeValue", DefaultCurrentTimeValue);
+        m_bootstrapRep.setValue< std::string >("networkValue", DefaultNetworkValue);
+        m_bootstrapRep.setValue< std::string >("IPAddressValue", DefaultIPAddressValue);
+        m_bootstrapRep.setValue< std::string >("securityValue", DefaultSecurityValue);
+        m_bootstrapRep.setValue< std::string >("modeValue", DefaultModeValue);
+        m_bootstrapRep.setValue< std::string >("configurationValue", DefaultConfigurationValue);
+        m_bootstrapRep.setValue< std::string >("factorySetValue", DefaultFactorySetValue);
+
+        return m_bootstrapRep;
+    }
+};
+
+// Create the instance of the resource class (in this case instance of class 'RoomResource').
+BootstrapResource myBootstrapResource;
+
+// This function prepares a response for any incoming request to Light resource.
+bool prepareResponse(std::shared_ptr< OCResourceRequest > request)
+{
+    cout << "\tIn Server CPP prepareResponse:\n";
+    bool result = false;
+    if (request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if (requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if (requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\t\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if (requestType == "GET")
+            {
+                cout << "\t\t\trequestType : GET\n";
+                // GET operations are directly handled while sending the response
+                // in the sendLightResponse function
+                result = true;
+            }
+            else if (requestType == "PUT")
+            {
+                cout << "\t\t\trequestType : PUT\n";
+
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                // Do related operations related to PUT request
+                myBootstrapResource.setBootstrapRepresentation(rep);
+                result = true;
+            }
+            else if (requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if (requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\t\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+
+    return result;
+}
+
+OCStackResult sendResponse(std::shared_ptr< OCResourceRequest > pRequest)
+{
+    auto pResponse = std::make_shared< OC::OCResourceResponse >();
+    pResponse->setRequestHandle(pRequest->getRequestHandle());
+    pResponse->setResourceHandle(pRequest->getResourceHandle());
+    pResponse->setResourceRepresentation(myBootstrapResource.getBootstrapRepresentation());
+    pResponse->setErrorCode(200);
+    pResponse->setResponseResult(OC_EH_OK);
+
+    return OCPlatform::sendResponse(pResponse);
+}
+
+OCEntityHandlerResult entityHandlerBootstrap(std::shared_ptr< OCResourceRequest > request)
+{
+    cout << "\tIn Server CPP (entityHandlerBootstrap) entity handler:\n";
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    if (prepareResponse(request))
+    {
+        if (OC_STACK_OK == sendResponse(request))
+        {
+            ehResult = OC_EH_OK;
+        }
+        else
+        {
+            std::cout << "sendResponse failed." << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "PrepareResponse failed." << std::endl;
+    }
+    return ehResult;
+}
+
+int main()
+{
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0",
+    // By setting to "0.0.0.0", it binds to all available interfaces
+            0,// Uses randomly available port
+            OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+
+        myBootstrapResource.createResources();
+
+        // Perform app tasks
+        while (true)
+        {
+            // some tasks
+        }
+    }
+    catch (OCException e)
+    {
+        std::cout << "Exception in main: " << e.what();
+    }
+
+    // No explicit call to stop the platform.
+    // When OCPlatform destructor is invoked, internally we do platform cleanup
+}
+
diff --git a/service/things-manager/sampleapp/linux/configuration/con-client.cpp b/service/things-manager/sampleapp/linux/configuration/con-client.cpp
new file mode 100644 (file)
index 0000000..278c3e2
--- /dev/null
@@ -0,0 +1,449 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// OCClient.cpp : Defines the entry point for the console application.
+//
+#include <string>
+#include <cstdlib>
+#include <pthread.h>
+#include <map>
+#include <vector>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+using namespace OC;
+using namespace OIC;
+
+int g_Steps = 0;
+int isWaiting = 0; //0: none to wait, 1: wait for the response of "getConfigurationValue"
+
+static ThingsManager* g_thingsmanager;
+
+OCResourceHandle configurationCollectionHandle;
+std::shared_ptr< OCResource > g_configurationCollection; // for a group of multiple resources
+std::shared_ptr< OCResource > g_configurationResource; // For a single resource
+
+OCResourceHandle diagnosticsCollectionHandle;
+std::shared_ptr< OCResource > g_diagnosticsCollection; // for a group of multiple resources
+std::shared_ptr< OCResource > g_diagnosticsResource; // For a single resource
+
+OCResourceHandle setCollectionHandle;
+std::shared_ptr< OCResource > g_setCollection; // for a group of multiple resources
+std::shared_ptr< OCResource > g_setResource; // For a single resource
+
+std::map< std::string, std::shared_ptr< OCResource > > resourceTable;
+std::vector< OCResourceHandle > resourceHandleVector;
+
+typedef std::function<
+        void(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode) > ConfigurationCallback;
+typedef std::function<
+        void(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode) > DiagnosticsCallback;
+
+typedef std::string ConfigurationName;
+typedef std::string ConfigurationValue;
+
+void onReboot(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+    std::cout << "\t\tReboot:" << rep.getValue< std::string >("value") << std::endl;
+
+    isWaiting = 0;
+}
+
+void onFactoryReset(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+        const int eCode)
+{
+    std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+    std::cout << "\t\tFactoryReset:" << rep.getValue< std::string >("value") << std::endl;
+    isWaiting = 0;
+}
+
+void onUpdate(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+    std::cout << "\t\tvalue:" << rep.getValue< std::string >("value") << std::endl;
+
+    isWaiting = 0;
+}
+
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+    if (rep.hasAttribute("value"))
+        std::cout << "\t\tvalue:" << rep.getValue< std::string >("value") << std::endl;
+    else if (rep.hasAttribute("link"))
+        std::cout << "\t\tlink:" << rep.getValue< std::string >("link") << std::endl;
+
+    std::vector< OCRepresentation > children = rep.getChildren();
+
+    for (auto oit = children.begin(); oit != children.end(); ++oit)
+    {
+        std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+
+        if (oit->hasAttribute("value"))
+            std::cout << "\t\tvalue:" << oit->getValue< std::string >("value") << std::endl;
+        else if (oit->hasAttribute("link"))
+            std::cout << "\t\tlink:" << oit->getValue< std::string >("link") << std::endl;
+    }
+
+    isWaiting = 0;
+}
+
+// Callback to found collection resource
+void onFoundCollectionResource(std::vector< std::shared_ptr< OCResource > > resources)
+{
+
+    std::string resourceURI;
+    std::string hostAddress;
+    try
+    {
+        // Do some operations with resource object.
+        for (unsigned int i = 0; i < resources.size(); ++i)
+        {
+            std::shared_ptr< OCResource > resource = resources.at(i);
+
+            if (resource)
+            {
+                if (resource->uri() == "/core/a/configuration/resourceset")
+                    g_configurationCollection = resource;
+                else if (resource->uri() == "/core/a/diagnostics/resourceset")
+                    g_diagnosticsCollection = resource;
+                else if (resource->uri() == "/core/a/factoryset/resourceset")
+                    g_setCollection = resource;
+                else
+                {
+                    isWaiting = 0;
+                    return;
+                }
+            }
+            else
+            {
+                // Resource is invalid
+                std::cout << "Resource is invalid" << std::endl;
+            }
+        }
+
+    }
+    catch (std::exception& e)
+    {
+        //log(e.what());
+    }
+
+    if (g_configurationCollection != NULL && g_diagnosticsCollection != NULL
+            && g_setCollection != NULL)
+        isWaiting = 0;
+}
+
+// Callback to found resources
+void onFoundCandidateCollection(std::vector< std::shared_ptr< OCResource > > resources)
+{
+
+    std::string resourceURI;
+    std::string hostAddress;
+
+    static bool flagForCon = false, flagForDiag = false, flagForSet = false;
+
+    try
+    {
+        // Do some operations with resource object.
+        for (unsigned int i = 0; i < resources.size(); ++i)
+        {
+            std::shared_ptr< OCResource > resource = resources.at(i);
+
+            if (resource)
+            {
+                // Check if the resource is new one. If so, store it.
+
+                std::map< std::string, std::shared_ptr< OCResource > >::iterator iter =
+                        resourceTable.find(resource->host() + resource->uri());
+
+                if (iter == resourceTable.end()) // new one
+                {
+                    resourceTable[resource->host() + resource->uri()] = resource;
+
+                    OCResourceHandle foundResourceHandle;
+                    OCStackResult result = OCPlatform::registerResource(foundResourceHandle,
+                            resource);
+                    std::cout << "\tResource ( " << resource->host() << " ) is registed!\t"
+                            << std::endl;
+                    if (result == OC_STACK_OK)
+                    {
+                        if (resource->uri() == "/oic/con")
+                        {
+                            flagForCon = true;
+                            OCPlatform::bindResource(configurationCollectionHandle,
+                                    foundResourceHandle);
+                            if (g_configurationResource == NULL)
+                                g_configurationResource = resource;
+                        }
+                        else if (resource->uri() == "/oic/diag")
+                        {
+                            flagForDiag = true;
+                            OCPlatform::bindResource(diagnosticsCollectionHandle,
+                                    foundResourceHandle);
+                            if (g_diagnosticsResource == NULL)
+                                g_diagnosticsResource = resource;
+                        }
+                        else if (resource->uri() == "/factorySet")
+                        {
+                            flagForSet = true;
+                            OCPlatform::bindResource(setCollectionHandle, foundResourceHandle);
+                            if (g_setResource == NULL)
+                                g_setResource = resource;
+                        }
+
+                        resourceHandleVector.push_back(foundResourceHandle);
+                    }
+                    else
+                    {
+                        cout << "\tresource Error!" << endl;
+                    }
+
+                }
+
+            }
+            else
+            {
+                // Resource is invalid
+                std::cout << "Resource is invalid" << std::endl;
+            }
+        }
+
+    }
+    catch (std::exception& e)
+    {
+        //log(e.what());
+    }
+
+    if (flagForCon && flagForDiag && flagForSet)
+        isWaiting = 0;
+}
+
+int main(int argc, char* argv[])
+{
+
+    //**************************************************************
+    // STEP 0
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    g_thingsmanager = new ThingsManager();
+
+    //**************************************************************
+
+    while (true)
+    {
+
+        if (isWaiting > 0)
+            continue;
+
+        isWaiting = 0;
+
+        cout << endl << endl << "(0) Quit" << std::endl;
+        cout << "(1) Find all resources(URI: /oic/con, /oic/diag, /factoryset)" << std::endl;
+        cout << "(2) Find all groups" << std::endl;
+        cout << "(3) Get a new value (of \"Configuration\" Collection)" << std::endl;
+        cout << "(4) Update a value (of \"Region\" Resource)" << std::endl;
+        cout << "(5) Get a value (for \"Region\" Resource)" << std::endl;
+        cout << "(6) FactoryReset (for the group)" << std::endl;
+        cout << "(7) Reboot (for the group)" << std::endl;
+        cout << "(10) Show Configuration Units" << std::endl;
+
+        cin >> g_Steps;
+        //
+        if (g_Steps == 0)
+            break;
+        else if (g_Steps == 1)
+        {
+            std::vector< std::string > types;
+            { // For Registering a collection resource for configuration resources
+
+                string resourceURI = "/core/a/configuration/resourceset";
+                string resourceTypeName = "core.configuration.resourceset";
+                string resourceInterface = BATCH_INTERFACE;
+
+                if (configurationCollectionHandle != NULL)
+                {
+                    std::cout << "already exists" << std::endl;
+                    continue;
+                }
+
+                OCPlatform::registerResource(configurationCollectionHandle, resourceURI,
+                        resourceTypeName, resourceInterface, NULL,
+                        //&entityHandler, // entityHandler
+                        OC_DISCOVERABLE);
+
+                OCPlatform::bindInterfaceToResource(configurationCollectionHandle, GROUP_INTERFACE);
+                OCPlatform::bindInterfaceToResource(configurationCollectionHandle,
+                        DEFAULT_INTERFACE);
+
+                // instead of registration
+                types.push_back("oic.con");
+                std::cout << "Finding Configuration Resource... " << std::endl;
+            }
+
+            { // For Registering a collection resource for diagnostics resources
+
+                string resourceURI = "/core/a/diagnostics/resourceset";
+                string resourceTypeName = "core.diagnostics.resourceset";
+                string resourceInterface = BATCH_INTERFACE;
+
+                if (diagnosticsCollectionHandle != NULL)
+                {
+                    std::cout << "already exists" << std::endl;
+                    continue;
+                }
+
+                OCPlatform::registerResource(diagnosticsCollectionHandle, resourceURI,
+                        resourceTypeName, resourceInterface, NULL,
+                        //&entityHandler, // entityHandler
+                        OC_DISCOVERABLE);
+
+                OCPlatform::bindInterfaceToResource(diagnosticsCollectionHandle, GROUP_INTERFACE);
+                OCPlatform::bindInterfaceToResource(diagnosticsCollectionHandle, DEFAULT_INTERFACE);
+
+                // instead of registration
+                types.push_back("oic.diag");
+                std::cout << "Finding Diagnostics Resource... " << std::endl;
+
+            }
+
+            { // For Registering a collection resource for set resources
+
+                string resourceURI = "/core/a/factoryset/resourceset";
+                string resourceTypeName = "core.factoryset.resourceset";
+                string resourceInterface = BATCH_INTERFACE;
+
+                if (setCollectionHandle != NULL)
+                {
+                    std::cout << "already exists" << std::endl;
+                    continue;
+                }
+
+                OCPlatform::registerResource(setCollectionHandle, resourceURI, resourceTypeName,
+                        resourceInterface, NULL,
+                        //&entityHandler, // entityHandler
+                        OC_DISCOVERABLE);
+
+                OCPlatform::bindInterfaceToResource(setCollectionHandle, GROUP_INTERFACE);
+                OCPlatform::bindInterfaceToResource(setCollectionHandle, DEFAULT_INTERFACE);
+
+                // instead of registration
+                types.push_back("factorySet");
+                std::cout << "Finding Set Resource... " << std::endl;
+            }
+
+            g_thingsmanager->findCandidateResources(types, &onFoundCandidateCollection, 5);
+
+            isWaiting = 1;
+        }
+        else if (g_Steps == 2) // make a group with found things
+        {
+            std::vector< std::string > types;
+            types.push_back("core.configuration.resourceset");
+            types.push_back("core.diagnostics.resourceset");
+            types.push_back("core.factoryset.resourceset");
+
+            g_thingsmanager->findCandidateResources(types, &onFoundCollectionResource, 5);
+
+            std::cout << "Finding Collection resource... " << std::endl;
+            isWaiting = 1;
+
+        }
+        else if (g_Steps == 3)
+        {
+            // get a value
+
+            ConfigurationName name = "configuration";
+
+            std::cout << "For example, get configuration collection's value" << std::endl;
+
+            std::vector< ConfigurationName > configurations;
+
+            configurations.push_back(name);
+
+            if (g_thingsmanager->getConfigurations(g_configurationResource, configurations, &onGet)
+                    != OC_STACK_ERROR)
+                isWaiting = 1;
+        }
+        else if (g_Steps == 4)
+        {
+            ConfigurationName name = "region";
+            ConfigurationValue value = "U.S.A (new region)";
+
+            std::cout << "For example, change region resource's value" << std::endl;
+            std::cout << g_configurationCollection->uri() << std::endl;
+
+            std::map< ConfigurationName, ConfigurationValue > configurations;
+
+            configurations.insert(std::make_pair(name, value));
+
+            if (g_thingsmanager->updateConfigurations(g_configurationCollection, configurations,
+                    &onUpdate) != OC_STACK_ERROR)
+                isWaiting = 1;
+        }
+        else if (g_Steps == 5)
+        {
+            // get a value
+
+            ConfigurationName name = "region";
+
+            std::cout << "For example, get region resource's value" << std::endl;
+
+            std::vector< ConfigurationName > configurations;
+
+            configurations.push_back(name);
+
+            if (g_thingsmanager->getConfigurations(g_configurationCollection, configurations,
+                    &onGet) != OC_STACK_ERROR)
+                isWaiting = 1;
+        }
+        else if (g_Steps == 6)
+        {
+            // factory reset
+            if (g_thingsmanager->factoryReset(g_diagnosticsCollection, &onFactoryReset)
+                    != OC_STACK_ERROR)
+                isWaiting = 1;
+        }
+        else if (g_Steps == 7)
+        {
+            // reboot
+            if (g_thingsmanager->reboot(g_diagnosticsCollection, &onReboot) != OC_STACK_ERROR)
+                isWaiting = 1;
+        }
+        else if (g_Steps == 10)
+        {
+            std::cout << g_thingsmanager->getListOfSupportedConfigurationUnits() << std::endl;
+
+        }
+
+    }
+
+    return 0;
+}
+
diff --git a/service/things-manager/sampleapp/linux/configuration/con-server.cpp b/service/things-manager/sampleapp/linux/configuration/con-server.cpp
new file mode 100644 (file)
index 0000000..6b26437
--- /dev/null
@@ -0,0 +1,356 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+#include <thread>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+#include "ConfigurationCollection.h"
+#include "DiagnosticsCollection.h"
+#include "FactorySetCollection.h"
+
+using namespace OC;
+using namespace OIC;
+
+const int SUCCESS_RESPONSE = 0;
+int g_Steps = 0;
+int isWaiting = 0;
+
+// Default system configuration value's variables
+// The variable's names should be same as the names of "extern" variables defined in
+// "ConfigurationCollection.h"
+std::string defaultRegionValue;
+std::string defaultTimeValue;
+std::string defaultCurrentTimeValue;
+std::string defaultNetworkValue;
+std::string defaultIPAddressValue;
+std::string defaultSecurityValue;
+std::string defaultModeValue;
+std::string defaultConfigurationValue;
+std::string defaultFactorySetValue;
+
+static ThingsManager* g_thingsmanager;
+
+// Forward declaring the entityHandler (Configuration)
+bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request);
+OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest);
+OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request);
+
+ConfigurationCollection *myConfigurationCollection;
+DiagnosticsCollection *myDiagnosticsCollection;
+FactorySetCollection *myFactorySetCollection;
+
+typedef std::function< void(OCRepresentation&) > putFunc;
+typedef std::function< OCRepresentation(void) > getFunc;
+
+getFunc getGetFunction(std::string uri)
+{
+    getFunc res = NULL;
+
+    if (uri == myConfigurationCollection->getTimeUri())
+    {
+        res = std::bind(&ConfigurationCollection::getTimeRepresentation, myConfigurationCollection);
+    }
+    else if (uri == myConfigurationCollection->getConfigurationUri())
+    {
+        res = std::bind(&ConfigurationCollection::getConfigurationRepresentation,
+                myConfigurationCollection);
+    }
+    else if (uri == myConfigurationCollection->myTimeCollection->getCurrentTimeUri())
+    {
+        res = std::bind(&TimeCollection::getCurrentTimeRepresentation,
+                myConfigurationCollection->myTimeCollection);
+    }
+    else if (uri == myConfigurationCollection->getRegionUri())
+    {
+        res = std::bind(&ConfigurationCollection::getRegionRepresentation,
+                myConfigurationCollection);
+    }
+    else if (uri == myDiagnosticsCollection->getFactoryResetUri())
+    {
+        res = std::bind(&DiagnosticsCollection::getFactoryResetRepresentation,
+                myDiagnosticsCollection);
+    }
+    else if (uri == myDiagnosticsCollection->getRebootUri())
+    {
+        res = std::bind(&DiagnosticsCollection::getRebootRepresentation, myDiagnosticsCollection);
+    }
+
+    return res;
+}
+
+putFunc getPutFunction(std::string uri)
+{
+    putFunc res = NULL;
+
+    if (uri == myConfigurationCollection->getRegionUri())
+    {
+        res = std::bind(&ConfigurationCollection::setRegionRepresentation,
+                myConfigurationCollection, std::placeholders::_1);
+    }
+    else if (uri == myConfigurationCollection->myTimeCollection->getCurrentTimeUri())
+    {
+        res = std::bind(&TimeCollection::setCurrentTimeRepresentation,
+                myConfigurationCollection->myTimeCollection, std::placeholders::_1);
+    }
+    else if (uri == myDiagnosticsCollection->getFactoryResetUri())
+    {
+        res = std::bind(&DiagnosticsCollection::setFactoryResetRepresentation,
+                myDiagnosticsCollection, std::placeholders::_1);
+    }
+    else if (uri == myDiagnosticsCollection->getRebootUri())
+    {
+        res = std::bind(&DiagnosticsCollection::setRebootRepresentation, myDiagnosticsCollection,
+                std::placeholders::_1);
+    }
+
+    return res;
+}
+
+// This function prepares a response for any incoming request to Light resource.
+bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request)
+{
+    std::cout << "\tIn Server CPP prepareResponseForResource:\n";
+    bool result = false;
+    if (request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if (requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            std::cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if (requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            std::cout << "\t\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if (requestType == "GET")
+            {
+                std::cout << "\t\t\trequestType : GET\n";
+                // GET operations are directly handled while sending the response
+                // in the sendLightResponse function
+                result = true;
+            }
+            else if (requestType == "PUT")
+            {
+                std::cout << "\t\t\trequestType : PUT\n";
+                putFunc putFunction;
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                putFunction = getPutFunction(request->getResourceUri());
+
+                // Do related operations related to PUT request
+                putFunction(rep);
+                result = true;
+            }
+            else if (requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if (requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            std::cout << "\t\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+
+    return result;
+}
+
+OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest)
+{
+    auto pResponse = std::make_shared< OC::OCResourceResponse >();
+
+    // Check for query params (if any)
+    QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
+
+    pResponse->setRequestHandle(pRequest->getRequestHandle());
+    pResponse->setResourceHandle(pRequest->getResourceHandle());
+
+    getFunc getFunction;
+    getFunction = getGetFunction(pRequest->getResourceUri());
+
+    OCRepresentation rep;
+    rep = getFunction();
+
+    auto findRes = queryParamsMap.find("if");
+
+    if (findRes != queryParamsMap.end())
+    {
+        pResponse->setResourceRepresentation(rep, findRes->second);
+    }
+    else
+    {
+        pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+    }
+
+    pResponse->setErrorCode(200);
+    pResponse->setResponseResult(OC_EH_OK);
+
+    return OCPlatform::sendResponse(pResponse);
+}
+
+OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request)
+{
+    std::cout << "\tIn Server CPP (entityHandlerForResource) entity handler:\n";
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    if (prepareResponseForResource(request))
+    {
+        if (OC_STACK_OK == sendResponseForResource(request))
+        {
+            ehResult = OC_EH_OK;
+        }
+        else
+        {
+            std::cout << "sendResponse failed." << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "PrepareResponse failed." << std::endl;
+    }
+    return ehResult;
+}
+
+// callback handler on GET request
+void onBootstrap(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "\n\nGET request was successful" << std::endl;
+        std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+        defaultRegionValue = rep.getValue< std::string >("regionValue");
+        defaultTimeValue = rep.getValue< std::string >("timeValue");
+        defaultCurrentTimeValue = rep.getValue< std::string >("currentTimeValue");
+        defaultNetworkValue = rep.getValue< std::string >("networkValue");
+        defaultIPAddressValue = rep.getValue< std::string >("IPAddressValue");
+        defaultSecurityValue = rep.getValue< std::string >("securityValue");
+        defaultModeValue = rep.getValue< std::string >("modeValue");
+        defaultConfigurationValue = rep.getValue< std::string >("configurationValue");
+        defaultFactorySetValue = rep.getValue< std::string >("factorySetValue");
+
+        std::cout << "\tregionValue : " << defaultRegionValue << std::endl;
+        std::cout << "\ttimeValue : " << defaultTimeValue << std::endl;
+        std::cout << "\tcurrentTimeValue : " << defaultCurrentTimeValue << std::endl;
+        std::cout << "\tnetworkValue : " << defaultNetworkValue << std::endl;
+        std::cout << "\tIPAddressValue : " << defaultIPAddressValue << std::endl;
+        std::cout << "\tsecurityValue : " << defaultSecurityValue << std::endl;
+        std::cout << "\tmodeValue : " << defaultModeValue << std::endl;
+        std::cout << "\tconfigurationValue : " << defaultConfigurationValue << std::endl;
+        std::cout << "\tfactorySetValue : " << defaultFactorySetValue << std::endl;
+
+    }
+    else
+    {
+        std::cout << "onGET Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+    isWaiting = 0;
+}
+
+int main()
+{
+    //**************************************************************
+    // STEP 0
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    g_thingsmanager = new ThingsManager();
+    //**************************************************************
+
+    if (getuid() != 0)
+    {
+        std::cout << "NOTE: You may gain the root privilege (e.g, reboot)\n";
+        std::cout << "NOTE: Now, you don't have it.\n";
+    }
+
+    try
+    {
+        // Perform app tasks
+        while (true)
+        {
+
+            if (isWaiting > 0)
+                continue;
+
+            isWaiting = 0;
+
+            std::cout << endl << endl << "(0) Quit" << std::endl;
+            std::cout << "(1) Bootstrap" << std::endl;
+            std::cout << "(2) Create Configuration Resources" << std::endl;
+
+            cin >> g_Steps;
+            //
+            if (g_Steps == 0)
+                break;
+            else if (g_Steps == 1)
+            {
+                g_thingsmanager->doBootstrap(&onBootstrap);
+                isWaiting = 1;
+            }
+            else if (g_Steps == 2)
+            {
+                myConfigurationCollection = new ConfigurationCollection();
+                myConfigurationCollection->createResources(&entityHandlerForResource);
+
+                myDiagnosticsCollection = new DiagnosticsCollection();
+                myDiagnosticsCollection->createResources(&entityHandlerForResource);
+
+                myFactorySetCollection = new FactorySetCollection();
+                myFactorySetCollection->createResources(&entityHandlerForResource);
+                myDiagnosticsCollection->factoryReset = std::function < void()
+                        > (std::bind(&ConfigurationCollection::factoryReset,
+                                myConfigurationCollection));
+                isWaiting = 1;
+            }
+        }
+    }
+    catch (OCException e)
+    {
+        std::cout << "Exception in main: " << e.what();
+    }
+
+    // No explicit call to stop the platform.
+    // When OCPlatform destructor is invoked, internally we do platform cleanup
+}
+
diff --git a/service/things-manager/sampleapp/linux/configuration/makefile b/service/things-manager/sampleapp/linux/configuration/makefile
new file mode 100644 (file)
index 0000000..37824a9
--- /dev/null
@@ -0,0 +1,71 @@
+TGMROOT=../../../
+IOT_BASE=${TGMROOT}../../resource
+RST_NAME=.
+TARGET1=con-server
+TARGET2=con-client
+TARGET3=bootstrapserver
+
+OBJS = ConfigurationCollection.o DiagnosticsCollection.o FactorySetCollection.o con-server.o
+SRCS = $(OBJS:.o=.c)
+
+# C++ type Compile Flag define.
+CXX=g++
+CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
+
+CXX_INC        := -I../../ -I../../inc/ -I../../../sdk/inc/ -I../../../sdk/src/
+CXX_INC        += -I${IOT_BASE}/include/
+CXX_INC        += -I${IOT_BASE}/oc_logger/include
+CXX_INC        += -I${IOT_BASE}/csdk/stack/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocsocket/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocrandom/include
+CXX_INC        += -I${IOT_BASE}/csdk/logger/include
+CXX_INC        += -I${IOT_BASE}/dependencies/cereal/include
+
+CXX_LIB=-L""
+
+CXX_SRCPATH=${wildcard ../../src/*.cpp}
+CXX_SRCLIST=${notdir ${CXX_SRCPATH}}
+CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}}
+CXX_OBJLIST=${CXX_USESRCS:.cpp=.o}
+
+
+TGM = ../../
+SDK = ${TGMROOT}sdk
+TGM_INC = -I${TGMROOT}sdk/inc
+SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a
+
+LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a
+
+LD_LIB := $(IOT_BASE)/release/obj/liboc.a
+LD_LIB += $(IOT_BASE)/csdk/linux/release/liboctbstack.a
+LD_LIB += $(LIB_OC_LOGGER)
+
+
+# Force metatargets to build:
+.PHONY: all clean
+
+all: ${TARGET1} ${TARGET2} ${TARGET3}
+
+.cpp.o:
+       $(CXX) $(CXX_FLAGS) -c -o $@ $<  $(CXX_INC)  $(TGM_INC)
+
+$(TARGET1): $(OBJS)
+       $(CXX) $(CXX_FLAGS) -o $@ ${OBJS} $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+${TARGET2}: con-client.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET2} $<  $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+${TARGET3}: bootstrapserver.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET3} $<  $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+
+dep:
+       gccmakedep $(SRCS)
+
+clean:
+       rm -f -v *.o con-client
+       rm -f -v *.o con-server
+       rm -f -v *.o bootstrapserver
+
+#dep:
+#      gccmakedep $(SRCS)
diff --git a/service/things-manager/sampleapp/linux/groupaction/SConscript b/service/things-manager/sampleapp/linux/groupaction/SConscript
new file mode 100644 (file)
index 0000000..1ed0695
--- /dev/null
@@ -0,0 +1,35 @@
+##
+# linux sample app  build script
+##
+
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src'])
+linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
+linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread'])
+
+
+######################################################################
+#build sampleapp
+######################################################################
+groupserver = linux_sample_env.Program('groupserver', 'groupserver.cpp')
+lightserver = linux_sample_env.Program('lightserver', 'lightserver.cpp')
+bookmark = linux_sample_env.Program('bookmark', 'bookmark.cpp')
+Alias("GroupServerApp", groupserver)
+Alias("LightServerApp", lightserver)
+Alias("BookmarkApp", bookmark)
+env.AppendTarget('GroupServerApp')
+env.AppendTarget('LightServerApp')
+env.AppendTarget('BookmarkApp')
diff --git a/service/things-manager/sampleapp/linux/groupaction/bookmark.cpp b/service/things-manager/sampleapp/linux/groupaction/bookmark.cpp
new file mode 100644 (file)
index 0000000..6f67aef
--- /dev/null
@@ -0,0 +1,235 @@
+//******************************************************************
+//
+// 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 <functional>
+#include <pthread.h>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace std;
+
+namespace PH = std::placeholders;
+
+unsigned int startedThread;
+unsigned int gObservation;
+pthread_t threadId;
+
+void* ObserveHandler(void *param);
+
+class BookmarkResource
+{
+
+private:
+    OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
+    {
+        OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+        if (request)
+        {
+            // Get the request type and request flag
+            std::string requestType = request->getRequestType();
+            int requestFlag = request->getRequestHandlerFlag();
+
+            if (requestFlag & RequestHandlerFlag::InitFlag)
+            {
+                cout << "\t\trequestFlag : Init\n";
+
+                // entity handler to perform resource initialization operations
+            }
+            else if (requestFlag & RequestHandlerFlag::RequestFlag)
+            {
+                auto pResponse = std::make_shared< OC::OCResourceResponse >();
+                pResponse->setRequestHandle(request->getRequestHandle());
+                pResponse->setResourceHandle(request->getResourceHandle());
+
+                // If the request type is GET
+                if (requestType == "GET")
+                {
+                }
+                else if (requestType == "PUT")
+                {
+                    cout << "\t\t\trequestType : PUT\n";
+                }
+                else if (requestType == "POST")
+                {
+                    // POST request operations
+                }
+                else if (requestType == "DELETE")
+                {
+                    // DELETE request operations
+                }
+
+                pResponse->setErrorCode(200);
+                pResponse->setResponseResult(OC_EH_OK);
+                pResponse->setResourceRepresentation(getRepresentation());
+                if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                {
+                    ehResult = OC_EH_OK;
+                }
+            }
+
+            if (requestFlag & RequestHandlerFlag::ObserverFlag)
+            {
+                cout << "\t\trequestFlag : Observer\n";
+
+                if (!startedThread)
+                {
+                    pthread_create(&threadId, NULL, ObserveHandler, (void *) NULL);
+                    startedThread = 1;
+                    gObservation = 1;
+                }
+
+                ehResult = OC_EH_OK;
+            }
+        }
+        else
+        {
+            std::cout << "Request invalid" << std::endl;
+        }
+
+        return ehResult;
+    }
+
+public:
+    /// Constructor
+    BookmarkResource()
+    {
+        m_pressure = 0;
+
+        m_BookmarkUri = "/core/bookmark"; // URI of the resource
+        m_BookmarkType = "core.bookmark"; // resource type name. In this case, it is light
+
+        m_BookmarkInterface = DEFAULT_INTERFACE; // resource interface.
+        m_BookmarkHandle = 0;
+    }
+
+    /// This function internally calls registerResource API.
+    void createResources()
+    {
+        EntityHandler cb = std::bind(&BookmarkResource::entityHandler, this, PH::_1);
+
+        // This will internally create and register the resource.
+        OCStackResult result = OC::OCPlatform::registerResource(m_BookmarkHandle, m_BookmarkUri,
+                m_BookmarkType, m_BookmarkInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation (bookmark) was unsuccessful\n";
+        }
+        else
+        {
+            cout << "Resource URI : " << m_BookmarkUri << endl;
+            cout << "\tResource Type Name : " << m_BookmarkType << endl;
+            cout << "\tResource Interface : " << DEFAULT_INTERFACE << endl;
+            cout << "\tResource creation is successful with resource handle : " << m_BookmarkHandle
+                    << endl;
+        }
+    }
+
+    void setRepresentation(OCRepresentation& rep)
+    {
+        // AttributeMap attributeMap = rep.getAttributeMap();
+        // if(rep.getValue("level", m_pressure) == true)
+        {
+            std::cout << m_pressure << endl;
+        }
+    }
+
+    OCRepresentation getRepresentation()
+    {
+        OCRepresentation rep;
+
+        rep.setValue("level", (int) m_pressure);
+
+        return rep;
+    }
+
+public:
+    // Members of Bookmark
+    std::string m_BookmarkUri;
+    std::string m_BookmarkType;
+    std::string m_BookmarkInterface;
+    unsigned int m_pressure;
+    OCResourceHandle m_BookmarkHandle;
+};
+
+// Create the instance of the resource class (in this case instance of class 'BookmarkResource').
+BookmarkResource myBookmarkResource;
+
+void* ObserveHandler(void *param)
+{
+    while (startedThread)
+    {
+        sleep(1);
+
+        cout << "input a integer(0:opened, 5:close) : ";
+        cin >> myBookmarkResource.m_pressure;
+
+        if (myBookmarkResource.m_pressure == 0 || // When your book opened.
+                myBookmarkResource.m_pressure == 5) // When your book closed.
+        {
+            cout << "notifyObservers call!" << endl;
+
+            OCStackResult result = OCPlatform::notifyAllObservers(
+                    myBookmarkResource.m_BookmarkHandle);
+
+            if (OC_STACK_NO_OBSERVERS == result)
+            {
+                cout << "No More observers, stopping notifications" << endl;
+                gObservation = 0;
+                startedThread = 0;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+int main()
+{
+    // Create PlatformConfig object
+
+    OC::PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0",
+    // By setting to "0.0.0.0", it binds to all available interfaces
+            0,// Uses randomly available port
+            OC::QualityOfService::LowQos };
+
+    // Create a OCPlatform instance.
+    // Note: Platform creation is synchronous call.
+    try
+    {
+
+        // Invoke createResource function of class bookmark.
+        myBookmarkResource.createResources();
+
+        // Perform app tasks
+        while (true)
+        {
+            // some tasks
+        }
+    }
+    catch (OCException e)
+    {
+        std::cout << "Exception in main: " << e.what();
+    }
+}
diff --git a/service/things-manager/sampleapp/linux/groupaction/groupserver.cpp b/service/things-manager/sampleapp/linux/groupaction/groupserver.cpp
new file mode 100644 (file)
index 0000000..47177c7
--- /dev/null
@@ -0,0 +1,433 @@
+//******************************************************************
+//
+// 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 <OCPlatform.h>
+#include <OCApi.h>
+
+#include <functional>
+#include <pthread.h>
+#include <iostream>
+
+#include <ThingsManager.h>
+
+using namespace std;
+using namespace OC;
+using namespace OIC;
+namespace PH = std::placeholders;
+
+bool isReady = false;
+
+OCResourceHandle resourceHandle;
+std::vector< OCResourceHandle > resourceHandleVector;
+
+shared_ptr< OCResource > g_resource;
+vector< string > lights;
+
+ThingsManager *thingsMgr = new ThingsManager();
+
+void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode);
+
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
+
+void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep, const int& eCode,
+        const int& sequenceNumber);
+
+void allBulbOn();
+void allBulbOff();
+
+void foundResources(std::vector< std::shared_ptr< OC::OCResource > > listOfResource)
+{
+
+    for (auto rsrc = listOfResource.begin(); rsrc != listOfResource.end(); ++rsrc)
+    {
+        std::string resourceURI = (*rsrc)->uri();
+        std::string hostAddress = (*rsrc)->host();
+
+        if (resourceURI == "/a/light")
+        {
+
+            cout << "\tResource URI : " << resourceURI << endl;
+            cout << "\tResource Host : " << hostAddress << endl;
+
+            OCResourceHandle foundResourceHandle;
+            OCStackResult result = OCPlatform::registerResource(foundResourceHandle, (*rsrc));
+            cout << "\tresource registed!" << endl;
+            if (result == OC_STACK_OK)
+            {
+                OCPlatform::bindResource(resourceHandle, foundResourceHandle);
+                resourceHandleVector.push_back(foundResourceHandle);
+            }
+            else
+            {
+                cout << "\tresource Error!" << endl;
+            }
+
+            lights.push_back((hostAddress + resourceURI));
+        }
+    }
+
+    isReady = true;
+}
+
+void foundResource(std::shared_ptr< OCResource > resource)
+{
+    std::string resourceURI;
+    std::string hostAddress;
+
+    try
+    {
+        cout << "FOUND RESOURCE" << endl;
+
+        if (resource)
+        {
+            resourceURI = resource->uri();
+            hostAddress = resource->host();
+            if (resourceURI == "/core/a/collection")
+            {
+                g_resource = resource;
+
+                // g_resource->get("", DEFAULT_INTERFACE, QueryParamsMap(), onGet);
+
+                printf("\tHOST :: %s\n", resource->host().c_str());
+            }
+            else if (resourceURI == "/core/bookmark")
+            {
+                resource->observe(ObserveType::Observe, QueryParamsMap(), &onObserve);
+            }
+
+            // p_platform.bindResource(resourceHandle, foundResourceHandle);
+
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << "" << std::endl;
+    }
+}
+
+void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode)
+{
+    // std::vector<OCRepresentation> children = rep.getChildren();
+
+    // cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl;
+    // for( auto iter = children.begin(); iter != children.end();  ++iter )
+    // {
+    //     lights.push_back((*iter).getUri());
+    //     cout << "\tURI :: " << (*iter).getUri() << endl;
+    // }
+}
+
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    printf("\nonPut\n");
+}
+
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    printf("\nonPost\n");
+
+    if (rep.hasAttribute("ActionSet"))
+    {
+        std::string plainText;
+
+        if (rep.getValue("ActionSet", plainText))
+        {
+            ActionSet *actionset = thingsMgr->getActionSetfromString(plainText);
+            if (actionset != NULL)
+            {
+                cout << endl << "\tACTIONSET NAME :: " << actionset->actionsetName << endl;
+                for (auto actIter = actionset->listOfAction.begin();
+                        actIter != actionset->listOfAction.end(); ++actIter)
+                {
+                    cout << "\t\tTARGET :: " << (*actIter)->target << endl;
+
+                    for (auto capaIter = (*actIter)->listOfCapability.begin();
+                            capaIter != (*actIter)->listOfCapability.end(); ++capaIter)
+                    {
+                        cout << "\t\t\t" << (*capaIter)->capability << " :: " << (*capaIter)->status
+                                << endl;
+                    }
+                }
+            }
+            delete actionset;
+        }
+
+        // printf( "\tPlain Text :: %s\n", plainText.c_str() );
+    }
+    else if (rep.hasAttribute("DoAction"))
+    {
+        std::string plainText;
+        if (rep.getValue("DoAction", plainText))
+        {
+            cout << "\t" << plainText << endl;
+        }
+    }
+    else
+    {
+
+    }
+}
+
+void allBulbOff()
+{
+    OCRepresentation rep;
+
+    rep.setValue("DoAction", std::string("AllBulbOff"));
+
+    if (g_resource)
+    {
+        g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost);
+    }
+}
+
+void allBulbOn()
+{
+    OCRepresentation rep;
+
+    rep.setValue("DoAction", std::string("AllBulbOn"));
+
+    if (g_resource)
+    {
+        g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost);
+    }
+}
+
+void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep, const int& eCode,
+        const int& sequenceNumber)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        int level;
+
+        std::cout << "OBSERVE RESULT:" << std::endl;
+        std::cout << "\tSequenceNumber: " << sequenceNumber << endl;
+
+        if (rep.getValue("level", level))
+        {
+            if (level == 0)
+            {
+                allBulbOn();
+            }
+            else
+            {
+                allBulbOff();
+            }
+        }
+        std::cout << "\tlevel: " << level << std::endl;
+    }
+    else
+    {
+        std::cout << "onObserve Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+
+void createActionSet_AllBulbOff()
+{
+    string actionsetDesc;
+    ActionSet *allBulbOff = new ActionSet();
+    allBulbOff->actionsetName = "AllBulbOff";
+
+    for (auto iter = lights.begin(); iter != lights.end(); ++iter)
+    {
+        Action *action = new Action();
+        action->target = (*iter);
+
+        Capability *capa = new Capability();
+        capa->capability = "power";
+        capa->status = "off";
+
+        action->listOfCapability.push_back(capa);
+        allBulbOff->listOfAction.push_back(action);
+    }
+    // actionsetDesc = thingsMgr->getStringFromActionSet(allBulbOff);
+
+    // cout << "ActionSet :: " << actionsetDesc << endl;
+
+    // OCRepresentation rep;
+    // rep.setValue("ActionSet", actionsetDesc);
+
+    if (g_resource)
+    {
+        thingsMgr->addActionSet(g_resource, allBulbOff, onPut);
+        // g_resource->put("a.collection", GROUP_INTERFACE, rep,
+        //     QueryParamsMap(), &onPut);
+    }
+
+    delete allBulbOff;
+}
+
+void createActionSet_AllBulbOn()
+{
+    string actionsetDesc;
+    ActionSet *allBulbOff = new ActionSet();
+    allBulbOff->actionsetName = "AllBulbOn";
+
+    for (auto iter = lights.begin(); iter != lights.end(); ++iter)
+    {
+        Action *action = new Action();
+        action->target = (*iter);
+
+        Capability *capa = new Capability();
+        capa->capability = "power";
+        capa->status = "on";
+
+        action->listOfCapability.push_back(capa);
+        allBulbOff->listOfAction.push_back(action);
+    }
+    // actionsetDesc = thingsMgr->getStringFromActionSet(allBulbOff);
+
+    // cout << "ActionSet :: " << actionsetDesc << endl;
+
+    // OCRepresentation rep;
+    // rep.setValue("ActionSet", actionsetDesc);
+
+    if (g_resource)
+    {
+        thingsMgr->addActionSet(g_resource, allBulbOff, onPut);
+        // g_resource->put("a.collection", GROUP_INTERFACE, rep,
+        //     QueryParamsMap(), &onPut);
+    }
+
+    delete allBulbOff;
+}
+
+int main()
+{
+    PlatformConfig config
+    { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    try
+    {
+        string resourceURI = "/core/a/collection";
+        string resourceTypeName = "a.collection";
+        string resourceInterface = BATCH_INTERFACE;
+        OCPlatform::Configure(config);
+
+        // Find lights for group creation.
+        vector< string > types;
+        types.push_back("core.light");
+        thingsMgr->findCandidateResources(types, &foundResources, 5);
+
+        OCPlatform::registerResource(resourceHandle, resourceURI, resourceTypeName,
+                resourceInterface, NULL,
+                //&entityHandler, // entityHandler
+                OC_DISCOVERABLE);
+
+        cout << "registerResource is called." << endl;
+
+        OCPlatform::bindInterfaceToResource(resourceHandle, GROUP_INTERFACE);
+        OCPlatform::bindInterfaceToResource(resourceHandle, DEFAULT_INTERFACE);
+
+        bool isRun = true;
+
+        while (isRun)
+        {
+            while (isReady)
+            {
+                int n;
+
+                cout << endl;
+                cout << "1 :: CREATE ACTIONSET 2 :: EXECUTE ACTIONSET(ALLBULBON)"
+                        << "3 :: EXECUTE ACTIONSET(ALLBULBOFF)" << endl;
+                cout << "4 :: GET ACTIONSET 5 :: DELETE ACTIONSET 6 :: QUIT" << endl;
+                cout << "9 :: FIND GROUP 0 :: FIND BOOKMARK TO OBSERVE" << endl;
+
+                fflush(stdin);
+                cin >> n;
+
+                if (n == 9)
+                {
+                    OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=a.collection",
+                            &foundResource);
+                }
+                else if (n == 0)
+                {
+                    OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.bookmark",
+                            &foundResource);
+                }
+                else if (n == 1)
+                {
+
+                    // Craete Action Set
+                    // "AllBulbOff"
+                    //"movieTime*uri=coap://10.251.44.228:49858/a/light|power=10";
+                    createActionSet_AllBulbOff();
+                    createActionSet_AllBulbOn();
+
+                }
+                else if (n == 2)
+                {
+
+                    allBulbOn();
+                    // thingsMgr->executeActionSet(g_resource, "AllBulbOn", onPost);
+
+                }
+                else if (n == 3)
+                {
+
+                    allBulbOff();
+                    // thingsMgr->executeActionSet(g_resource, "AllBulbOff", onPost);
+
+                }
+                else if (n == 4)
+                {
+                    // OCRepresentation rep;
+
+                    // rep.setValue("GetActionSet", std::string("AllBulbOff"));
+
+                    // if(g_resource)
+                    // {
+                    //     g_resource->post("a.collection", GROUP_INTERFACE, rep,
+                    //         QueryParamsMap(), &onPost);
+                    // }
+
+                    thingsMgr->getActionSet(g_resource, "AllBulbOff", onPost);
+                }
+                else if (n == 5)
+                {
+                    // OCRepresentation rep;
+
+                    // rep.setValue("DelActionSet", std::string("AllBulbOff"));
+
+                    // if(g_resource)
+                    // {
+                    //     g_resource->put("a.collection", GROUP_INTERFACE, rep,
+                    //         QueryParamsMap(), &onPut);
+                    // }
+                    thingsMgr->deleteActionSet(g_resource, "AllBulbOff", onPut);
+                }
+                else if (n == 6)
+                {
+                    isRun = false;
+                    break;
+                }
+            }
+        }
+    }
+    catch (OCException& e)
+    {
+
+    }
+
+    return 0;
+}
diff --git a/service/things-manager/sampleapp/linux/groupaction/lightserver.cpp b/service/things-manager/sampleapp/linux/groupaction/lightserver.cpp
new file mode 100644 (file)
index 0000000..d73bf5e
--- /dev/null
@@ -0,0 +1,337 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample provides steps to define an interface for a resource
+/// (properties and methods) and host this resource on the server.
+///
+
+#include <functional>
+
+#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace std;
+namespace PH = std::placeholders;
+
+int gObservation = 0;
+void * ChangeLightRepresentation(void *param);
+void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest);
+
+// Specifies secure or non-secure
+// false: non-secure resource
+// true: secure resource
+bool isSecure = false;
+
+/// Specifies whether Entity handler is going to do slow response or not
+bool isSlowResponse = false;
+
+// Forward declaring the entityHandler
+
+/// This class represents a single resource named 'lightResource'. This resource has
+/// two simple properties named 'state' and 'power'
+
+class LightResource
+{
+
+public:
+    /// Access this property from a TB client
+    std::string m_power;
+    std::string m_lightUri;
+    OCResourceHandle m_resourceHandle;
+    OCRepresentation m_lightRep;
+
+public:
+    /// Constructor
+    LightResource() :
+            m_power(""), m_lightUri("/a/light"), m_resourceHandle(0)
+    {
+        // Initialize representation
+        m_lightRep.setUri(m_lightUri);
+
+        m_lightRep.setValue("power", m_power);
+    }
+
+    /* Note that this does not need to be a member function: for classes you do not have
+     access to, you can accomplish this with a free function: */
+
+    /// This function internally calls registerResource API.
+    void createResource()
+    {
+        std::string resourceURI = m_lightUri; //URI of the resource
+        std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
+        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+
+        EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1);
+
+        // This will internally create and register the resource.
+        OCStackResult result = OCPlatform::registerResource(m_resourceHandle, resourceURI,
+                resourceTypeName, resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation was unsuccessful\n";
+        }
+        else
+        {
+            cout << "Resource URI : " << resourceURI << endl;
+            cout << "\tResource Type Name : " << resourceTypeName << endl;
+            cout << "\tResource Interface : " << DEFAULT_INTERFACE << endl;
+            cout << "\tResource creation is successful with resource handle : " << m_resourceHandle
+                    << endl;
+        }
+    }
+
+    OCResourceHandle getHandle()
+    {
+        return m_resourceHandle;
+    }
+
+    // Puts representation.
+    // Gets values from the representation and
+    // updates the internal state
+    void put(OCRepresentation& rep)
+    {
+        try
+        {
+            if (rep.getValue("power", m_power))
+            {
+                cout << "\t\t\t\t" << "power: " << m_power << endl;
+            }
+            else
+            {
+                cout << "\t\t\t\t" << "power not found in the representation" << endl;
+            }
+        }
+        catch (exception& e)
+        {
+            cout << e.what() << endl;
+        }
+
+    }
+
+    // Post representation.
+    // Post can create new resource or simply act like put.
+    // Gets values from the representation and
+    // updates the internal state
+    OCRepresentation post(OCRepresentation& rep)
+    {
+        put(rep);
+        return get();
+    }
+
+    // gets the updated representation.
+    // Updates the representation with latest internal state before
+    // sending out.
+    OCRepresentation get()
+    {
+        m_lightRep.setValue("power", m_power);
+
+        return m_lightRep;
+    }
+
+    void addType(const std::string& type) const
+    {
+        OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+    }
+
+    void addInterface(const std::string& interface) const
+    {
+        OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+    }
+
+private:
+// This is just a sample implementation of entity handler.
+// Entity handler can be implemented in several ways by the manufacturer
+    OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
+    {
+        cout << "\tIn Server CPP entity handler:\n";
+        OCEntityHandlerResult ehResult = OC_EH_ERROR;
+        if (request)
+        {
+            // Get the request type and request flag
+            std::string requestType = request->getRequestType();
+            int requestFlag = request->getRequestHandlerFlag();
+
+            if (requestFlag & RequestHandlerFlag::InitFlag)
+            {
+                cout << "\t\trequestFlag : Init\n";
+
+                // entity handler to perform resource initialization operations
+            }
+            if (requestFlag & RequestHandlerFlag::RequestFlag)
+            {
+                cout << "\t\trequestFlag : Request\n";
+                auto pResponse = std::make_shared< OC::OCResourceResponse >();
+                pResponse->setRequestHandle(request->getRequestHandle());
+                pResponse->setResourceHandle(request->getResourceHandle());
+
+                // If the request type is GET
+                if (requestType == "GET")
+                {
+                    cout << "\t\t\trequestType : GET\n";
+                    if (isSlowResponse) // Slow response case
+                    {
+                        static int startedThread = 0;
+                        if (!startedThread)
+                        {
+                            std::thread t(handleSlowResponse, (void *) this, request);
+                            startedThread = 1;
+                            t.detach();
+                        }
+                        ehResult = OC_EH_SLOW;
+                    }
+                    else // normal response case.
+                    {
+                        pResponse->setErrorCode(200);
+                        pResponse->setResponseResult(OC_EH_OK);
+                        pResponse->setResourceRepresentation(get());
+                        if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                        {
+                            ehResult = OC_EH_OK;
+                        }
+                    }
+                }
+                else if (requestType == "PUT")
+                {
+                    cout << "\t\t\trequestType : PUT\n";
+                    OCRepresentation rep = request->getResourceRepresentation();
+
+                    // Do related operations related to PUT request
+                    // Update the lightResource
+                    put(rep);
+                    pResponse->setErrorCode(200);
+                    pResponse->setResponseResult(OC_EH_OK);
+                    pResponse->setResourceRepresentation(get());
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        ehResult = OC_EH_OK;
+                    }
+                }
+                else if (requestType == "POST")
+                {
+                    cout << "\t\t\trequestType : POST\n";
+
+                    OCRepresentation rep = request->getResourceRepresentation();
+
+                    // Do related operations related to POST request
+                    OCRepresentation rep_post = post(rep);
+                    pResponse->setResourceRepresentation(rep_post);
+                    pResponse->setErrorCode(200);
+                    if (rep_post.hasAttribute("createduri"))
+                    {
+                        pResponse->setResponseResult(OC_EH_RESOURCE_CREATED);
+                        pResponse->setNewResourceUri(
+                                rep_post.getValue< std::string >("createduri"));
+                    }
+
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        ehResult = OC_EH_OK;
+                    }
+                }
+                else if (requestType == "DELETE")
+                {
+                    // DELETE request operations
+                }
+            }
+        }
+        else
+        {
+            std::cout << "Request invalid" << std::endl;
+        }
+
+        return ehResult;
+    }
+};
+
+void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest)
+{
+    // This function handles slow response case
+    LightResource* lightPtr = (LightResource*) param;
+    // Induce a case for slow response by using sleep
+    std::cout << "SLOW response" << std::endl;
+    sleep(10);
+
+    auto pResponse = std::make_shared< OC::OCResourceResponse >();
+    pResponse->setRequestHandle(pRequest->getRequestHandle());
+    pResponse->setResourceHandle(pRequest->getResourceHandle());
+    pResponse->setResourceRepresentation(lightPtr->get());
+    pResponse->setErrorCode(200);
+    pResponse->setResponseResult(OC_EH_OK);
+
+    // Set the slow response flag back to false
+    isSlowResponse = false;
+    OCPlatform::sendResponse(pResponse);
+    return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0",
+    // By setting to "0.0.0.0", it binds to all available interfaces
+            0,// Uses randomly available port
+            OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+        // Create the instance of the resource class
+        // (in this case instance of class 'LightResource').
+        LightResource myLight;
+
+        // Invoke createResource function of class light.
+        myLight.createResource();
+
+        // 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)
+    {
+        //log(e.what());
+    }
+
+    // No explicit call to stop the platform.
+    // When OCPlatform::destructor is invoked, internally we do platform cleanup
+
+    return 0;
+}
diff --git a/service/things-manager/sampleapp/linux/groupaction/makefile b/service/things-manager/sampleapp/linux/groupaction/makefile
new file mode 100644 (file)
index 0000000..6604c3c
--- /dev/null
@@ -0,0 +1,70 @@
+
+TGMROOT=../../../
+IOT_BASE=${TGMROOT}../../resource
+RST_NAME=.
+
+
+
+# C++ type Compile Flag define.
+CXX=g++
+CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
+
+DEPEND_DIR:= ../../../../../resource/dependencies/
+CEREAL_DIR:= $(DEPEND_DIR)/cereal
+
+CXX_INC        := -I../../ -I../../inc/
+CXX_INC        += -I${IOT_BASE}/include/
+CXX_INC        += -I${IOT_BASE}/oc_logger/include
+CXX_INC        += -I${IOT_BASE}/csdk/stack/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocsocket/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocrandom/include
+CXX_INC        += -I${IOT_BASE}/csdk/logger/include
+CXX_INC        += -I$(CEREAL_DIR)/include
+CXX_INC        += -I../../../sdk/inc
+CXX_INC        += -I../../../sdk/src
+
+
+CXX_LIB=-L""
+
+CXX_SRCPATH=${wildcard ../../src/*.cpp}
+CXX_SRCLIST=${notdir ${CXX_SRCPATH}}
+CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}}
+CXX_OBJLIST=${CXX_USESRCS:.cpp=.o}
+
+
+TGM = ../../
+SDK = ${TGMROOT}sdk
+TGM_INC = -I${TGMROOT}sdk/inc
+SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a
+
+LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a
+
+LD_LIB := $(IOT_BASE)/release/obj/liboc.a
+LD_LIB += $(IOT_BASE)/csdk/linux/release/liboctbstack.a
+LD_LIB += $(LIB_OC_LOGGER)
+
+
+# Force metatargets to build:
+.PHONY: all clean
+
+all: bookmark lightserver groupserver
+
+#groupclient
+bookmark: ./bookmark.cpp
+       $(CXX) $(CXX_FLAGS) -o bookmark ./bookmark.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+lightserver: ./lightserver.cpp
+       $(CXX) $(CXX_FLAGS) -o lightserver ./lightserver.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+groupserver: ./groupserver.cpp
+       $(CXX) $(CXX_FLAGS) -o groupserver ./groupserver.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+# groupclient: ./groupclient.cpp
+#      $(CXX) $(CXX_FLAGS) -o groupclient ./groupclient.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+clean:
+       rm -f -v *.o ${TARGET}
+       rm -f groupserver
+       rm -f groupclient
+       rm -f lightserver
+       rm -f bookmark
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/SConscript b/service/things-manager/sampleapp/linux/groupsyncaction/SConscript
new file mode 100644 (file)
index 0000000..25d9b49
--- /dev/null
@@ -0,0 +1,38 @@
+##
+# linux sample app  build script
+##
+
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+linux_sample_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+linux_sample_env.AppendUnique(CPPPATH = ['include'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc'])
+linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src'])
+linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
+linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX'])
+linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread'])
+
+
+######################################################################
+#build sampleapp
+######################################################################
+group = linux_sample_env.Program('group', 'group.cpp')
+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("PhoneApp", phone)
+Alias("SpeakerApp", speaker)
+env.AppendTarget('GroupApp')
+env.AppendTarget('MusicplayerApp')
+env.AppendTarget('PhoneApp')
+env.AppendTarget('SpeakerApp')
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/group.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/group.cpp
new file mode 100644 (file)
index 0000000..d8b1082
--- /dev/null
@@ -0,0 +1,223 @@
+//******************************************************************
+//
+// 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>
+#include <cstdlib>
+#include <pthread.h>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+using namespace OC;
+using namespace OIC;
+
+static ThingsManager* gThingManager = NULL;
+
+static std::vector< OCResourceHandle > gResourceHandleList;
+
+static std::string collectionResourceType = "core.group";
+
+void onFindResource(std::shared_ptr< OCResource > resource)
+{
+    cout << "onFindResource" << endl;
+
+    if (resource)
+    {
+        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";
+        }
+        else
+        {
+            cout << "onFindResource : Joining group was unsuccessful\n";
+
+            OCPlatform::unregisterResource(resourceHandle);
+            return;
+        }
+
+        gResourceHandleList.push_back(resourceHandle);
+    }
+    else
+    {
+        cout << "onFindResource : There is no found resource." << endl;
+    }
+}
+
+int main(int argc, char* argv[])
+{
+
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both/*OC::ModeType::Server*/, "0.0.0.0", 0,
+            OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    gThingManager = new ThingsManager();
+
+    int selectedMenu;
+    OCStackResult result;
+
+    try
+    {
+        while (true)
+        {
+            // some operations
+            cout << "(1) CREATE GROUP " << endl;
+            cout << "(11) FIND MUSIC PLAYER & JOIN GROUP | (12) FIND SPEAKER & JOIN GROUP" << endl;
+            cout << "(21) LEAVE GROUP - MUSIC PLAYER  | (22) LEAVE GROUP - SPEAKER" << endl;
+            cout << "(31) DELETE GROUP " << endl;
+
+            std::cin >> selectedMenu;
+
+            if (selectedMenu == 1)
+            {
+                result = gThingManager->createGroup(collectionResourceType);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Group creation was successful\n";
+                }
+                else
+                {
+                    cout << "Group creation was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 11)
+            {
+                result = OCPlatform::findResource("",
+                        "coap://224.0.1.187/oc/core?rt=core.musicplayer", onFindResource);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Finding music player was successful\n";
+                }
+                else
+                {
+                    cout << "Finding music player was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 12)
+            {
+                result = OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.speaker",
+                        onFindResource);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Finding speaker was successful\n";
+                }
+                else
+                {
+                    cout << "Finding speaker was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 21)
+            {
+                std::vector< OCResourceHandle >::iterator It;
+                OCResourceHandle resourceHandle;
+                for (It = gResourceHandleList.begin(); It != gResourceHandleList.end(); ++It)
+                {
+                    resourceHandle = (*It);
+                    std::string mpType = "core.musicplayer";
+                    std::string type = OCGetResourceTypeName(resourceHandle, 0);
+                    if (0 == mpType.compare(type))
+                    {
+                        result = gThingManager->leaveGroup(collectionResourceType, resourceHandle);
+                        if (OC_STACK_OK == result)
+                        {
+                            cout << "Leaving group of music player was successful\n";
+                        }
+                        else
+                        {
+                            cout << "Leaving group of music player was unsuccessful\n";
+                        }
+                        break;
+                    }
+                }
+
+                gResourceHandleList.erase(It);
+                result = OCPlatform::unregisterResource(resourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Unregistering music player was successful\n";
+                }
+                else
+                {
+                    cout << "Unregistering music player was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 22)
+            {
+                std::vector< OCResourceHandle >::iterator It;
+                OCResourceHandle resourceHandle;
+                for (It = gResourceHandleList.begin(); It != gResourceHandleList.end(); ++It)
+                {
+                    resourceHandle = (*It);
+                    std::string mpType = "core.speaker";
+                    std::string type = OCGetResourceTypeName(resourceHandle, 0);
+                    if (0 == mpType.compare(type))
+                    {
+                        result = gThingManager->leaveGroup(collectionResourceType, resourceHandle);
+                        if (OC_STACK_OK == result)
+                        {
+                            cout << "Leaving group of speaker was successful\n";
+                        }
+                        else
+                        {
+                            cout << "Leaving group of speaker was unsuccessful\n";
+                        }
+                        break;
+                    }
+                }
+
+                gResourceHandleList.erase(It);
+                result = OCPlatform::unregisterResource(resourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Unregistering speaker was successful\n";
+                }
+                else
+                {
+                    cout << "Unregistering speaker was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 31)
+            {
+                gThingManager->deleteGroup(collectionResourceType);
+            }
+        }
+    }
+    catch (OCException& e)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/makefile b/service/things-manager/sampleapp/linux/groupsyncaction/makefile
new file mode 100644 (file)
index 0000000..0ee1e5c
--- /dev/null
@@ -0,0 +1,65 @@
+
+TGMROOT=../../../
+IOT_BASE=${TGMROOT}../../resource
+RST_NAME=.
+TARGET1=group
+TARGET2=phone
+TARGET3=musicplayer
+TARGET4=speaker
+BUILD:=release
+
+# C++ type Compile Flag define.
+CXX=g++
+CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
+
+CXX_INC        := -I../../ -I../../inc/ -I../../../sdk/inc/ -I../../../sdk/src/
+CXX_INC        += -I${IOT_BASE}/include/
+CXX_INC += -I${IOT_BASE}/oc_logger/include
+CXX_INC        += -I${IOT_BASE}/csdk/stack/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocsocket/include
+CXX_INC        += -I${IOT_BASE}/csdk/ocrandom/include
+CXX_INC        += -I${IOT_BASE}/csdk/logger/include
+CXX_INC        += -I${IOT_BASE}/dependencies/cereal/include
+
+CXX_LIB=-L""
+
+CXX_SRCPATH=${wildcard ../../src/*.cpp}
+CXX_SRCLIST=${notdir ${CXX_SRCPATH}}
+CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}}
+CXX_OBJLIST=${CXX_USESRCS:.cpp=.o}
+
+
+TGM = ../../
+SDK = ${TGMROOT}sdk
+TGM_INC = -I${TGMROOT}sdk/inc
+SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a
+
+LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a
+
+LD_LIB := $(IOT_BASE)/$(BUILD)/obj/liboc.a
+LD_LIB += $(IOT_BASE)/csdk/linux/$(BUILD)/liboctbstack.a
+LD_LIB += $(LIB_OC_LOGGER)
+
+
+# Force metatargets to build:
+.PHONY: all clean
+
+all: ${TARGET1} ${TARGET2} ${TARGET3} ${TARGET4}
+
+${TARGET1}: ./group.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET1} ./group.cpp   $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+${TARGET2}: ./phone.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET2} ./phone.cpp   $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+${TARGET3}: ./musicplayer.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET3} ./musicplayer.cpp   $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+${TARGET4}: ./speaker.cpp
+       $(CXX) $(CXX_FLAGS) -o ${TARGET4} ./speaker.cpp   $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
+
+clean:
+       rm -f -v *.o ${TARGET1}
+       rm -f -v *.o ${TARGET2}
+       rm -f -v *.o ${TARGET3}
+       rm -f -v *.o ${TARGET4}
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp
new file mode 100644 (file)
index 0000000..9a898a3
--- /dev/null
@@ -0,0 +1,163 @@
+//******************************************************************
+//
+// 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>
+#include <cstdlib>
+#include <pthread.h>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+using namespace OC;
+
+OCEntityHandlerResult mpEntityHandler(const std::shared_ptr< OCResourceRequest > request)
+{
+    cout << "mpEntityHandler:\n";
+
+    if (request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+        std::string action;
+
+        if (requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if (requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\trequestFlag : Request\n";
+
+            OCRepresentation rp = request->getResourceRepresentation();
+
+            // If the request type is GET
+            if (requestType == "GET")
+            {
+                cout << "\t\trequestType : GET\n";
+            }
+            else if (requestType == "PUT")
+            {
+                cout << "\t\trequestType : PUT\n";
+
+                action = rp.getValue< std::string >("play");
+                cout << "\t\t\tplay : " << action << endl;
+            }
+            else if (requestType == "POST")
+            {
+                cout << "\t\trequestType : POST\n";
+            }
+            else if (requestType == "DELETE")
+            {
+                cout << "\t\trequestType : DELETE\n";
+            }
+        }
+        else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        cout << "Request invalid" << endl;
+    }
+
+    return OC_EH_OK;
+}
+
+int main(int argc, char* argv[])
+{
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+
+    int selectedMenu;
+    OCStackResult result;
+    OCResourceHandle mpResourceHandle = NULL;
+
+    try
+    {
+        while (true)
+        {
+            // some operations
+            cout << "(1) CREATE MUSIC PLAYER | (2) DELETE MUSIC PLAYER" << endl;
+
+            std::cin >> selectedMenu;
+
+            if (selectedMenu == 1)
+            {
+                if (mpResourceHandle)
+                {
+                    cout << "Music player resource is registered already." << endl;
+                    continue;
+                }
+
+                std::string resourceURi = "/core/musicplayer";
+                std::string resourceTypeName = "core.musicplayer";
+                std::string resourceInterface = DEFAULT_INTERFACE;
+
+                result = OCPlatform::registerResource(mpResourceHandle, resourceURi,
+                        resourceTypeName, resourceInterface, mpEntityHandler,
+                        OC_DISCOVERABLE | OC_OBSERVABLE);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To register music player resource was successful\n";
+                }
+                else
+                {
+                    cout << "To register music player resource was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 2)
+            {
+                if (NULL == mpResourceHandle)
+                {
+                    cout
+                            << "Error! No resource to unregister. Register resource first!"
+                            << endl;
+                    continue;
+                }
+
+                result = OCPlatform::unregisterResource(mpResourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To unregister music player resource was successful\n";
+                }
+                else
+                {
+                    cout << "To unregister music player resource was unsuccessful\n";
+                }
+
+                mpResourceHandle = NULL;
+            }
+        }
+    }
+    catch (OCException& e)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp
new file mode 100644 (file)
index 0000000..57494d0
--- /dev/null
@@ -0,0 +1,478 @@
+//******************************************************************
+//
+// 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>
+#include <cstdlib>
+#include <pthread.h>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+using namespace OC;
+using namespace OIC;
+
+static ThingsManager* gThingManager = NULL;
+
+static OCResourceHandle gPhoneResourceHandle = NULL;
+
+static std::shared_ptr< OCResource > gFindGroup = NULL;
+
+static std::string collectionResourceType = "core.group";
+
+static ActionSet* gPlayStart;
+
+static ActionSet* gPlayStop;
+
+void onFindGroup(std::shared_ptr< OCResource > resource)
+{
+    if (resource)
+    {
+        if (NULL == gPhoneResourceHandle)
+        {
+            cout
+                    << "onFindGroup : Error! No resource to join group. Register resource first!"
+                    << endl;
+            return;
+        }
+
+        if (gFindGroup)
+        {
+            cout << "onFindGroup : Found group is already saved." << endl;
+        }
+        else
+        {
+            cout << "onFindGroup : Found group is saved now." << endl;
+            gFindGroup = resource;
+        }
+
+        gThingManager->joinGroup(gFindGroup, gPhoneResourceHandle);
+    }
+    else
+    {
+        cout << "onFindGroup : Resource is invalid. So a new Group Resource has to be created."
+                << endl;
+    }
+}
+
+void onAction(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        cout << "onAction" << endl;
+    }
+    else
+    {
+        cout << "onAction : error - " << eCode << endl;
+    }
+}
+
+void onGetChild(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        gPlayStart = new ActionSet();
+        gPlayStop = new ActionSet();
+
+        gPlayStart->actionsetName = "playstart";
+        gPlayStop->actionsetName = "playstop";
+
+        std::vector< OCRepresentation > childList = rep.getChildren();
+        OCRepresentation child;
+        std::string resourceURI;
+
+        QueryParamsMap query;
+        OCRepresentation rep;
+        std::string playStart;
+        std::string playStop;
+
+        std::vector< std::string > types;
+        std::string resType;
+
+        OCStackResult result;
+
+        for (unsigned int i = 0; i < childList.size(); ++i)
+        {
+//            cout << "\n\tchild resource - " << i + 1 << endl;
+
+            child = childList.at(i);
+            resourceURI = child.getUri();
+
+//            cout << "\t\tURI of the resource: " << resourceURI << endl;
+
+//            cout << "\t\tList of resource types: " << endl;
+
+            types = child.getResourceTypes();
+
+            for (unsigned int j = 0; j < types.size(); ++j)
+            {
+                resType = types.at(j);
+//                cout << "\t\t\t" << resType << endl;
+
+                if (std::string::npos != resType.find("musicplayer"))
+                {
+                    Capability *pStartCapa = new Capability;
+                    pStartCapa->capability = "play";
+                    pStartCapa->status = "on";
+
+                    Action* pPlayStart = new Action();
+                    pPlayStart->target = resourceURI;
+                    pPlayStart->listOfCapability.push_back(pStartCapa);
+
+                    gPlayStart->listOfAction.push_back(pPlayStart);
+
+                    Capability *pStopCapa = new Capability;
+                    pStopCapa->capability = "play";
+                    pStopCapa->status = "off";
+
+                    Action* pPlayStop = new Action();
+                    pPlayStop->target = resourceURI;
+                    pPlayStop->listOfCapability.push_back(pStopCapa);
+
+                    gPlayStop->listOfAction.push_back(pPlayStop);
+                }
+                else if (std::string::npos != resType.find("speaker"))
+                {
+                    Capability *pStartCapa = new Capability;
+                    pStartCapa->capability = "volume";
+                    pStartCapa->status = "50";
+
+                    Action* pPlayStart = new Action();
+                    pPlayStart->target = resourceURI;
+                    pPlayStart->listOfCapability.push_back(pStartCapa);
+
+                    gPlayStart->listOfAction.push_back(pPlayStart);
+
+                    Capability *pStopCapa = new Capability;
+                    pStopCapa->capability = "volume";
+                    pStopCapa->status = "0";
+
+                    Action* pPlayStop = new Action();
+                    pPlayStop->target = resourceURI;
+                    pPlayStop->listOfCapability.push_back(pStopCapa);
+
+                    gPlayStop->listOfAction.push_back(pPlayStop);
+                }
+            }
+        }
+
+//        std::string temp = gThingManager->getStringFromActionSet (gPlayStart);
+//        cout << "play start - " << temp << endl;
+
+//        temp  = gThingManager->getStringFromActionSet (gPlayStop);
+//        cout << "play stop - " << temp << endl;
+
+        if (0 == gPlayStart->listOfAction.empty())
+        {
+            result = gThingManager->addActionSet(gFindGroup, gPlayStart, onAction);
+            if (OC_STACK_OK == result)
+            {
+                cout << "addActionSet(gPlayStart) was successful\n";
+            }
+            else
+            {
+                cout << "addActionSet(gPlayStart) was unsuccessful. result = " << result << endl;
+            }
+        }
+
+        if (0 == gPlayStop->listOfAction.empty())
+        {
+            result = gThingManager->addActionSet(gFindGroup, gPlayStop, onAction);
+            if (OC_STACK_OK == result)
+            {
+                cout << "addActionSet(gPlayStop) was successful\n";
+            }
+            else
+            {
+                cout << "addActionSet(gPlayStop) was unsuccessful. result = " << result << endl;
+            }
+        }
+    }
+    else
+    {
+        cout << "onGetChild : error - " << eCode << endl;
+    }
+}
+
+int main(int argc, char* argv[])
+{
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+    gThingManager = new ThingsManager();
+
+    int selectedMenu;
+    OCStackResult result;
+
+    try
+    {
+        while (true)
+        {
+            // some operations
+            cout << "(1) CREATE PHONE" << endl;
+            cout
+                    << "(11) FIND & JOIN GROUP | (12) ADD GROUP ACTION | (13) PLAY START"
+                    << " | (14) PLAY STOP"<< endl;
+            cout << "(15) DELETE GROUP ACTION | (16) LEAVE GROUP" << endl;
+            cout << "(21) DELETE PHONE" << endl;
+
+            std::cin >> selectedMenu;
+
+            if (selectedMenu == 1)
+            {
+                if (gPhoneResourceHandle)
+                {
+                    cout << "Phone resource is registered already." << endl;
+                    continue;
+                }
+
+                std::string resourceURi = "/core/phone";
+                std::string resourceTypeName = "core.phone";
+                std::string resourceInterface = DEFAULT_INTERFACE;
+
+                result = OCPlatform::registerResource(gPhoneResourceHandle, resourceURi,
+                        resourceTypeName, resourceInterface, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To register phone resource was successful\n";
+                }
+                else
+                {
+                    cout << "To register phone resource was unsuccessful. result = " << result
+                            << endl;
+                }
+            }
+            else if (selectedMenu == 11)
+            {
+                std::vector< std::string > types;
+                types.clear();
+                types.push_back(collectionResourceType);
+
+                result = gThingManager->findGroup(types, &onFindGroup);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Finding group was successful\n";
+                }
+                else
+                {
+                    cout << "Finding group was unsuccessful. result = " << result << endl;
+                }
+            }
+            else if (selectedMenu == 12)
+            {
+                if (!gFindGroup)
+                {
+                    cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl;
+                    continue;
+                }
+
+                QueryParamsMap queryParamsMap;
+                result = gFindGroup->get("", DEFAULT_INTERFACE, queryParamsMap, onGetChild);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "gFindGroup->get was successful\n";
+                }
+                else
+                {
+                    cout << "gFindGroup->get was unsuccessful. result = " << result << endl;
+                }
+            }
+            else if (selectedMenu == 13)
+            {
+                if (!gFindGroup)
+                {
+                    cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl;
+                    continue;
+                }
+
+                if (!gPlayStart)
+                {
+                    cout << "gPlayStart is NULL. Please process step 12 first." << endl;
+                    continue;
+                }
+
+                result = gThingManager->executeActionSet(gFindGroup, "playstart", onAction);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "DoAction(playstart) was successful\n";
+                }
+                else
+                {
+                    cout << "DoAction(playstart) was unsuccessful. result = " << result << endl;
+                }
+            }
+            else if (selectedMenu == 14)
+            {
+                if (!gFindGroup)
+                {
+                    cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl;
+                    continue;
+                }
+
+                if (!gPlayStop)
+                {
+                    cout << "gPlayStop is NULL. Please process step 12 first." << endl;
+                    continue;
+                }
+
+                result = gThingManager->executeActionSet(gFindGroup, "playstop", onAction);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "DoAction(playstop) was successful\n";
+                }
+                else
+                {
+                    cout << "DoAction(playstop) was unsuccessful. result = " << result << endl;
+                }
+            }
+            else if (selectedMenu == 15)
+            {
+                if (!gFindGroup)
+                {
+                    cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl;
+                    continue;
+                }
+
+                if (!gPlayStart)
+                {
+                    cout << "gPlayStart is NULL. Please process step 12 first." << endl;
+                    continue;
+                }
+
+                if (!gPlayStop)
+                {
+                    cout << "gPlayStop is NULL. Please process step 12 first." << endl;
+                    continue;
+                }
+
+                result = gThingManager->deleteActionSet(gFindGroup, "playstart", onAction);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Delete Action(playstart) was successful\n";
+                }
+                else
+                {
+                    cout << "Delete Action(playstart) was unsuccessful. result = " << result
+                            << endl;
+                }
+
+                result = gThingManager->deleteActionSet(gFindGroup, "playstop", onAction);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Delete Action(playstop) was successful\n";
+                }
+                else
+                {
+                    cout << "Delete Action(playstop) was unsuccessful. result = " << result << endl;
+                }
+
+                Action* a;
+                Capability* c;
+
+                for (auto actionIter = gPlayStart->listOfAction.begin();
+                        actionIter != gPlayStart->listOfAction.end(); ++actionIter)
+                {
+                    a = (*actionIter);
+
+                    for (auto capaIter = a->listOfCapability.begin();
+                            capaIter != a->listOfCapability.end(); ++capaIter)
+                    {
+                        c = (*capaIter);
+                        delete c;
+                    }
+
+                    delete a;
+                }
+
+                delete gPlayStart;
+                gPlayStart = NULL;
+
+                for (auto actionIter = gPlayStop->listOfAction.begin();
+                        actionIter != gPlayStop->listOfAction.end(); ++actionIter)
+                {
+                    a = (*actionIter);
+
+                    for (auto capaIter = a->listOfCapability.begin();
+                            capaIter != a->listOfCapability.end(); ++capaIter)
+                    {
+                        c = (*capaIter);
+                        delete c;
+                    }
+
+                    delete a;
+                }
+
+                delete gPlayStop;
+                gPlayStop = NULL;
+            }
+            else if (selectedMenu == 16)
+            {
+                if (NULL == gPhoneResourceHandle)
+                {
+                    cout
+                            << "Error! No resource to leave group. Register resource first!"
+                            << endl;
+                    continue;
+                }
+
+                result = gThingManager->leaveGroup(collectionResourceType, gPhoneResourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "Leaving group was successful\n";
+                }
+                else
+                {
+                    cout << "Leaving group was unsuccessful. result = " << result << endl;
+                }
+            }
+            else if (selectedMenu == 21)
+            {
+                if (NULL == gPhoneResourceHandle)
+                {
+                    cout
+                            << "Error! No resource to unregister. Register resource first!"
+                            << endl;
+                    continue;
+                }
+
+                result = OCPlatform::unregisterResource(gPhoneResourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To unregister phone resource was successful\n";
+                }
+                else
+                {
+                    cout << "To unregister phone resource was unsuccessful. result = " << result
+                            << endl;
+                }
+                gPhoneResourceHandle = NULL;
+            }
+        }
+
+    }
+    catch (OCException& e)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp
new file mode 100644 (file)
index 0000000..41abb36
--- /dev/null
@@ -0,0 +1,165 @@
+//******************************************************************
+//
+// 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>
+#include <cstdlib>
+#include <pthread.h>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "ThingsManager.h"
+
+using namespace OC;
+
+OCEntityHandlerResult speakerEntityHandler(const std::shared_ptr< OCResourceRequest > request)
+{
+    cout << "speakerEntityHandler:\n";
+
+    if (request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+        std::string action;
+
+        if (requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if (requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\trequestFlag : Request\n";
+
+            OCRepresentation rp = request->getResourceRepresentation();
+
+            // If the request type is GET
+            if (requestType == "GET")
+            {
+                cout << "\t\trequestType : GET\n";
+            }
+            else if (requestType == "PUT")
+            {
+                cout << "\t\trequestType : PUT\n";
+
+                action = rp.getValue< std::string >("volume");
+                cout << "\t\t\tvolume : " << action << endl;
+            }
+            else if (requestType == "POST")
+            {
+                cout << "\t\trequestType : POST\n";
+            }
+            else if (requestType == "DELETE")
+            {
+                cout << "\t\trequestType : DELETE\n";
+            }
+        }
+        else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        cout << "Request invalid" << endl;
+    }
+
+    return OC_EH_OK;
+}
+
+int main(int argc, char* argv[])
+{
+
+    // Create PlatformConfig object
+    PlatformConfig cfg
+    { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    OCPlatform::Configure(cfg);
+
+    int selectedMenu;
+    OCStackResult result;
+    OCResourceHandle speakerResourceHandle = NULL;
+
+    try
+    {
+        while (true)
+        {
+            // some operations
+            cout << "(1) CREATE SPEAKER | (2) DELETE SPEAKER" << endl;
+
+            std::cin >> selectedMenu;
+
+            if (selectedMenu == 1)
+            {
+                if (speakerResourceHandle)
+                {
+                    cout << "Speaker resource is registered already." << endl;
+                    continue;
+                }
+
+                std::string resourceURi = "/core/speaker";
+                std::string resourceTypeName = "core.speaker";
+
+                std::string resourceInterface = DEFAULT_INTERFACE;
+
+                result = OCPlatform::registerResource(speakerResourceHandle, resourceURi,
+                        resourceTypeName, resourceInterface, speakerEntityHandler,
+                        OC_DISCOVERABLE | OC_OBSERVABLE);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To register speaker resource was successful\n";
+                }
+                else
+                {
+                    cout << "To register speaker resource was unsuccessful\n";
+                }
+            }
+            else if (selectedMenu == 2)
+            {
+                if (NULL == speakerResourceHandle)
+                {
+                    cout
+                            << "Error! No resource to unregister. Register resource first!"
+                            << endl;
+                    continue;
+                }
+
+                result = OCPlatform::unregisterResource(speakerResourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "To unregister speaker resource was successful\n";
+                }
+                else
+                {
+                    cout << "To unregister speaker resource was unsuccessful\n";
+                }
+
+                speakerResourceHandle = NULL;
+            }
+        }
+    }
+    catch (OCException& e)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/service/things-manager/sampleapp/linux/makefile b/service/things-manager/sampleapp/linux/makefile
new file mode 100644 (file)
index 0000000..092d768
--- /dev/null
@@ -0,0 +1,21 @@
+MAKE=make
+
+DIRLIST=configuration groupaction  groupsyncaction
+
+# Force metatargets to build:
+.PHONY: all clean
+
+all: build
+
+build:
+       @for subdir in ${DIRLIST} ; do \
+       ${MAKE} -C $${subdir} ; \
+       echo " " ; \
+       done
+       @echo " "
+
+clean:
+       @for subdir in ${DIRLIST} ; do \
+       ${MAKE} clean -C $${subdir} ; \
+       echo " " ; \
+       done
diff --git a/service/things-manager/sampleapp/linux/tgmclient/SConscript b/service/things-manager/sampleapp/linux/tgmclient/SConscript
deleted file mode 100644 (file)
index 2c347ff..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-##
-# linux sample app  build script
-##
-
-Import('env')
-
-# Add third party libraries
-lib_env = env.Clone()
-SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
-
-linux_sample_env = lib_env.Clone()
-######################################################################
-# Build flags
-######################################################################
-linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc'])
-linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
-linux_sample_env.AppendUnique(LIBS = ['oc', 'octbstack', 'coap', 'oc_logger', 'TGMSDKLibrary'])
-
-if env.get('TARGET_OS') not in ['windows', 'winrt']:
-       linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
-
-######################################################################
-# Source files and Targets
-######################################################################
-tgmclient = linux_sample_env.Program('tgmclient', 'tgmsdkclient.cpp')
-
-Alias("tgmclient_sample", tgmclient)
-env.AppendTarget('tgmclient_sample')
\ No newline at end of file
diff --git a/service/things-manager/sampleapp/linux/tgmclient/makefile b/service/things-manager/sampleapp/linux/tgmclient/makefile
deleted file mode 100644 (file)
index 7e2fe95..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-TGMROOT=../../../
-IOT_BASE=${TGMROOT}../../resource
-RST_NAME=.
-TARGET=tgmclient
-
-
-# C++ type Compile Flag define.
-CXX=g++
-CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
-
-CXX_INC        := -I../../ -I../../inc/ 
-CXX_INC        += -I${IOT_BASE}/include/ 
-CXX_INC += -I${IOT_BASE}/oc_logger/include
-CXX_INC        += -I${IOT_BASE}/csdk/stack/include 
-CXX_INC        += -I${IOT_BASE}/csdk/ocsocket/include 
-CXX_INC        += -I${IOT_BASE}/csdk/ocrandom/include 
-CXX_INC        += -I${IOT_BASE}/csdk/logger/include 
-
-CXX_LIB=-L""
-
-CXX_SRCPATH=${wildcard ../../src/*.cpp}
-CXX_SRCLIST=${notdir ${CXX_SRCPATH}}
-CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}}
-CXX_OBJLIST=${CXX_USESRCS:.cpp=.o}
-
-
-TGM = ../../
-SDK = ${TGMROOT}sdk
-TGM_INC = -I${TGMROOT}sdk/inc
-SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a
-
-LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a
-
-LD_LIB := $(IOT_BASE)/release/obj/liboc.a  
-LD_LIB += $(IOT_BASE)/csdk/linux/release/liboctbstack.a 
-LD_LIB += $(LIB_OC_LOGGER)
-
-
-# Force metatargets to build:
-.PHONY: all clean
-
-all: ${TARGET} 
-
-${TARGET}: ./tgmsdkclient.cpp
-       $(CXX) $(CXX_FLAGS) -o ${TARGET} ./tgmsdkclient.cpp   $(CXX_INC)  ${LD_LIB} $(TGM_INC) $(SDK_LIB)
-       
-clean:
-       rm -f -v *.o ${TARGET}
-       
diff --git a/service/things-manager/sampleapp/linux/tgmclient/tgmsdkclient.cpp b/service/things-manager/sampleapp/linux/tgmclient/tgmsdkclient.cpp
deleted file mode 100644 (file)
index b1405ab..0000000
+++ /dev/null
@@ -1,120 +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>
-#include <cstdlib>
-#include <pthread.h>
-#include "OCPlatform.h"
-#include "OCApi.h"
-#include "TGMClient.h"
-
-using namespace OC;
-
-void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
-{
-    if (eCode == OC_STACK_OK)
-    {
-        std::cout << "GET request was successful" << std::endl;
-        std::cout << "Resource URI: " << rep.getUri() << std::endl;
-
-        AttributeMap dataMap = rep.getAttributeMap();
-        for (auto it = dataMap.begin(); it != dataMap.end(); ++it)
-        {
-            std::cout << "\t KEY:" << it->first << "  //  VALUE:" << it->second << std::endl;
-        }
-
-    }
-    else
-    {
-        std::cout << "onGET Response error: " << eCode << std::endl;
-        std::exit(-1);
-    }
-}
-
-void onFoundCandidate(std::vector< std::shared_ptr< OCResource > > resources)
-{
-    std::cout << "\n\n  FOUND CANDIDATE  \n\n";
-    for (unsigned int i = 0; i < resources.size(); ++i)
-    {
-        QueryParamsMap test;
-        resources.at(i)->get(test, &onGet);
-    }
-}
-
-int main(int argc, char* argv[])
-{
-
-    // Create PlatformConfig object
-    PlatformConfig cfg
-    { OC::ServiceType::InProc, OC::ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos };
-
-    OCPlatform::Configure(cfg);
-    TGMClient *tgmclient = new TGMClient();
-
-    int selectedMenu;
-
-    try
-    {
-        std::vector < std::string > types;
-
-        while (true)
-        {
-            // some operations
-            std::cout << "ADD  | (1)TV | (2)LIGHT | (3)CURTAIN | (4)RESET |" << std::endl;
-            std::cout << "FIND | (5) ONCE | (6) 10sec |" << std::endl;
-
-            std::cin >> selectedMenu;
-
-            if (selectedMenu == 1)
-            {
-                types.push_back("core.tv");
-            }
-            else if (selectedMenu == 2)
-            {
-                types.push_back("core.light");
-            }
-            else if (selectedMenu == 3)
-            {
-                types.push_back("core.curtain");
-            }
-            else if (selectedMenu == 4)
-            {
-                types.clear();
-            }
-            else if (selectedMenu == 5)
-            {
-                tgmclient->findCandidateResources(types, &onFoundCandidate);
-            }
-            else if (selectedMenu == 6)
-            {
-                tgmclient->findCandidateResources(types, &onFoundCandidate, 10);
-            }
-
-        }
-
-    }
-    catch (OCException& e)
-    {
-        //log(e.what());
-    }
-
-    return 0;
-}
-
index 1cadc89..0e5ec03 100644 (file)
@@ -15,13 +15,14 @@ CXX=g++
 CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl
 
 
-CXX_INC        := -I../../ -I../../inc/ 
+CXX_INC        := -I../../ -I../../inc/ -I../../src/
 CXX_INC        += -I${IOT_BASE}/include/ 
 CXX_INC += -I${IOT_BASE}/oc_logger/include
 CXX_INC        += -I${IOT_BASE}/csdk/stack/include 
 CXX_INC        += -I${IOT_BASE}/csdk/ocsocket/include 
 CXX_INC        += -I${IOT_BASE}/csdk/ocrandom/include 
 CXX_INC        += -I${IOT_BASE}/csdk/logger/include 
+CXX_INC        += -I${IOT_BASE}/dependencies/cereal/include
 
 CXX_LIB=-L""
 
diff --git a/service/things-manager/sdk/inc/TGMClient.h b/service/things-manager/sdk/inc/TGMClient.h
deleted file mode 100644 (file)
index a087ee6..0000000
+++ /dev/null
@@ -1,85 +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   TGMClient.h
-
-/// @brief  This file contains the declaration of classes and its members related to TGMClient.
-
-#ifndef __OC_TGMCLIENT__
-#define __OC_TGMCLIENT__
-
-#include <string>
-#include <vector>
-#include <map>
-#include <cstdlib>
-#include "OCPlatform.h"
-#include "OCApi.h"
-
-using namespace OC;
-
-typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CandidateCallback;
-typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CollectionPresenceCallback;
-
-class TGMClient
-{
-public:
-    /**
-     * Constructor for TGMClient. Constructs a new TGMClient
-     */
-    TGMClient(void);
-
-    /**
-     * Virtual destructor
-     */
-    ~TGMClient(void);
-
-    /**
-     * API for candidate resources discovery.
-     * Callback only call when all resource types found.
-     *
-     * @param resourceTypes - required resource types(called "candidate")
-     * @param candidateCallback - callback. OCResource vector.
-     *
-     * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
-     *
-     * NOTE: OCStackResult is defined in ocstack.h.
-     */
-    OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
-            CandidateCallback callback, int waitsec = -1);
-
-    /**
-     * API for Collection member's state subscribe.
-     *
-     * NOTE: NOT IMPLEMENT YET
-     */
-    OCStackResult subscribeCollectionPresence(OCResourceHandle&, CollectionPresenceCallback)
-    {
-        return OC_STACK_NOTIMPL;
-    }
-
-private:
-
-    void onFoundResource(std::shared_ptr< OCResource > resource, int waitsec);
-    void findPreparedRequest(std::map< std::vector< std::string >, CandidateCallback > &request);
-    void lazyCallback(int second);
-
-};
-
-#endif  /* __OC_TGMCLIENT__*/
diff --git a/service/things-manager/sdk/inc/ThingsManager.h b/service/things-manager/sdk/inc/ThingsManager.h
new file mode 100644 (file)
index 0000000..de7c365
--- /dev/null
@@ -0,0 +1,408 @@
+//******************************************************************
+//
+// 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   ThingsManager.h
+///
+/// @brief  This file contains the declaration of  ThingsManager class
+///         and its members related to ThingsManager.
+
+#ifndef __OC_THINGSMANAGER__
+#define __OC_THINGSMANAGER__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "GroupManager.h"
+
+using namespace OC;
+
+namespace OIC
+{
+    /**
+     * @class  ThingsManager
+     * @brief  This class provides a set of functions regarding group management,
+     *          synchronization of group, configuration of things, and diagnostics about things.
+     *
+     */
+    class ThingsManager
+    {
+    public:
+        /**
+         * Constructor for ThingsManager
+         */
+        ThingsManager(void);
+
+        /**
+         * Virtual destructor for ThingsManager
+         */
+        ~ThingsManager(void);
+
+        /**
+         * API for discoverying candidate resources.
+         * Callback is called  when all resource types are found.
+         *
+         * @param resourceTypes - required resource types(called "candidate")
+         * @param candidateCallback - callback. Returns OCResource vector.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
+                std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback,
+                int waitsec = -1);
+
+        /**
+         * API for subscribing child's state.
+         *
+         * @param resource - collection resource for subscribing presence of all child resources.
+         * @param callback - callback funcion for result of child's presence.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource > resource,
+                std::function< void(std::string, OCStackResult) > callback);
+
+        /**
+         * API for register and bind resource to group.
+         *
+         * @param childHandle - child resource handle. It will be filled from resource param.
+         * @param resource - resource for register and bind to group. It has all data.
+         * @param collectionHandle - collection resource handle. It will be added child resource.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult bindResourceToGroup(OCResourceHandle& childHandle,
+                std::shared_ptr< OCResource > resource, OCResourceHandle& collectionHandle);
+
+        // Group Synchronization
+
+        /**
+         * API for finding a specific remote group when a resource tries to join a group.
+         * Callback is called when a group is found or not.
+         *
+         * @param collectionResourceTypes - resource types of a group to find and join
+         * @param callback - callback. It has OCResource param.
+         *                    If a group is found, OCResource has the group resource.
+         *                    Otherwise, OCResource is NULL.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult findGroup(std::vector< std::string > collectionResourceTypes,
+                FindCallback callback);
+
+        /**
+         * API for creating a new group.
+         *
+         * @param collectionResourceType - resource type of a group to create
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult createGroup(std::string collectionResourceType);
+
+        /**
+         * API for joining a group. This API is used when a resource that has a group tries
+         * to find a specific remote resource and makes it join a group
+         *
+         * @param collectionResourceType - resource type of a group to join.
+         * @param resourceHandle - resource handle to join a group.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult joinGroup(std::string collectionResourceType,
+                OCResourceHandle resourceHandle);
+
+        /**
+         * API for joining a group. This API is used when a resource that
+         * doesn't have a group tries to find and join a specific remote group.
+         *
+         * @param resource - group resource pointer to join.
+         *                   It can be the callback result of findGroup().
+         * @param resourceHandle - resource handle to join a group.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult joinGroup(const std::shared_ptr< OCResource > resource,
+                OCResourceHandle resourceHandle);
+
+        /**
+         * API for leaving a joined group.
+         *
+         * @param collectionResourceType - resource type of a group to leave.
+         * @param resourceHandle - resource handle to leave a group.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult leaveGroup(std::string collectionResourceType,
+                OCResourceHandle resourceHandle);
+
+        /**
+         * API for deleting a group.
+         *
+         * @param collectionResourceType - resource type of a group to delete.
+         *
+         * @return void
+         */
+        void deleteGroup(std::string collectionResourceType);
+
+        /**
+         * API for getting a list of joined groups.
+         *
+         * @param void
+         *
+         * @return std::map - return value of this API.
+         *                  It returns group resource type and group resource handle as a map type.
+         */
+        std::map< std::string, OCResourceHandle > getGroupList(void);
+
+        // Things Configuration
+
+        /**
+         * API for updating configuration value of multiple things of a target group
+         * or a single thing.
+         * Callback is called when a response arrives.
+         * Before using the below function, a developer should acquire a resource pointer of
+         * (collection) resource that he wants to send a request by calling findResource() function
+         * provided in OCPlatform. And he should also notice a "Configuration Name" term which
+         * represents a nickname of a target attribute of a resource that he wants to update.
+         * The base motivation to introduce the term is to avoid a usage of URI to access a resource
+         * from a developer. Thus, a developer should know which configuration names are supported
+         * by Things Configuration class and what the configuration name means.
+         * To get a list of supported configuration names,
+         * use getListOfSupportedConfigurationUnits()
+         * function, which provides the list in JSON format.
+         *
+         * @param resource - resource pointer representing the target group or the single thing.
+         * @param configurations - ConfigurationUnit: a nickname of attribute of target resource
+         *                         (e.g., installedlocation, currency, (IP)address)
+         *                         Value : a value to be updated
+         * @param callback - callback for updateConfigurations.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource,
+                std::map< std::string, std::string > configurations,
+                std::function<
+                        void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                const int eCode) > callback);
+
+        /**
+         * API for getting configuration value of multiple things of a target group
+         * or a single thing.
+         * Callback is called when a response arrives.
+         *
+         * @param resource - resource pointer representing the target group or the single thing.
+         * @param configurations - ConfigurationUnit: a nickname of attribute of target resource.
+         * @param callback - callback for getConfigurations.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult getConfigurations(std::shared_ptr< OCResource > resource,
+                std::vector< std::string > configurations,
+                std::function<
+                        void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                const int eCode) > callback);
+
+        /**
+         * API for showing the list of supported configuration units (configurable parameters)
+         * Callback is called when a response arrives.
+         *
+         * @param void
+         * @return std::string - return value of this API.
+         *                       It returns the list in JSON format
+         */
+        std::string getListOfSupportedConfigurationUnits();
+
+        /**
+         * API for boostrapping system configuration parameters from a bootstrap server.
+         * Callback call when a response from the bootstrap server arrives.
+         *
+         * @param callback - callback for doBootstrap.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult doBootstrap(
+                std::function<
+                        void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                const int eCode) > callback);
+
+        // Things Diagnostics
+
+        /**
+         * API to let thing(device) reboot.
+         * The target thing could be a group of multiple things or a single thing.
+         * Callback is called when a response arrives.
+         *
+         * @param resource - resource pointer representing the target group
+         * @param callback - callback for reboot.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult reboot(std::shared_ptr< OCResource > resource,
+                std::function<
+                        void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                const int eCode) > callback);
+
+        /**
+         * API for factory reset on thing(device).
+         * The target thing could be a group of multiple things or a single thing.
+         * Callback is called when a response arrives.
+         *
+         * @param resource - resource pointer representing the target group
+         * @param callback - callback for factoryReset.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult factoryReset(std::shared_ptr< OCResource > resource,
+                std::function<
+                        void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                const int eCode) > callback);
+
+        // Group Action.
+
+        /**
+         * API for extracting Action Set string from the Action Set class instance
+         *
+         * @param newActionSet - pointer of Action Set
+         *
+         * @return std::string - return value of this API.
+         *                                          It returns Action Set String.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        std::string getStringFromActionSet(const ActionSet *newActionSet);
+
+        /**
+         * API for extrracting Action Set class instance from Action Set String.
+         *
+         * @param desc - description of Action set
+         *
+         * @return ActionSet* - return value of this API.
+         *                      It returns pointer of ActionSet.
+         */
+        ActionSet* getActionSetfromString(std::string desc);
+
+        /**
+         * API for adding an Action Set.
+         * Callback is called when the response of PUT operation arrives.
+         *
+         * @param resource - resource pointer of the group resource
+         * @param newActionSet - pointer of Action Set
+         * @param callback - callback for PUT operation.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult addActionSet(std::shared_ptr< OCResource > resource,
+                const ActionSet* newActionSet, PutCallback cb);
+
+        /**
+         * API for executing the Action Set.
+         * Callback is called when the response of  POST operation arrives.
+         *
+         * @param resource - resource pointer of the group resource
+         * @param actionsetName - Action Set name for executing the Action set
+         * @param callback - callback for POST operation.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult executeActionSet(std::shared_ptr< OCResource > resource,
+                std::string actionsetName, PostCallback cb);
+
+        /**
+         * API for reading the Action Set.
+         * Callback is called when the response of  GET operation arrives.
+         *
+         * @param resource - resource pointer of the group resource
+         * @param actionsetName - Action Set name for reading the Action set
+         * @param callback - callback for GET operation.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult getActionSet(std::shared_ptr< OCResource > resource,
+                std::string actionsetName, GetCallback cb);
+
+        /**
+         * API for removing the Action Set.
+         * Callback is called when the response of  POST operation arrives.
+         *
+         * @param resource - resource pointer of the group resource
+         * @param actionsetName - Action Set name for removing the Action set
+         * @param callback - callback for POST operation.
+         *
+         * @return OCStackResult - return value of this API.
+         *                         It returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource,
+                std::string actionsetName, PostCallback);
+
+    };
+}
+#endif  /* __OC_THINGSMANAGER__*/
diff --git a/service/things-manager/sdk/src/GroupManager.cpp b/service/things-manager/sdk/src/GroupManager.cpp
new file mode 100644 (file)
index 0000000..aed8734
--- /dev/null
@@ -0,0 +1,572 @@
+//******************************************************************
+//
+// 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    GroupManager.cpp
+///  @brief
+
+#include "GroupManager.h"
+#include <algorithm>
+#include <thread>
+#include <unistd.h>
+
+#include <string.h>
+
+#define PLAIN_DELIMITER "\""
+#define ACTION_DELIMITER "*"
+#define DESC_DELIMITER "|"
+#define ATTR_DELIMITER "="
+
+using namespace OC;
+
+namespace OIC
+{
+std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
+std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
+std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
+std::vector< std::string > allFoundResourceTypes;
+
+template< typename T >
+bool IsSubset(std::vector< T > full, std::vector< T > sub)
+{
+    std::sort(full.begin(), full.end());
+    std::sort(sub.begin(), sub.end());
+    return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
+}
+std::vector< std::string > &str_split(const std::string &s, char delim,
+        std::vector< std::string > &elems)
+{
+    std::stringstream ss(s);
+    std::string item;
+    while (std::getline(ss, item, delim))
+    {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+std::vector< std::string > str_split(const std::string &s, char delim)
+{
+    std::vector< std::string > elems;
+    str_split(s, delim, elems);
+    return elems;
+}
+
+void GroupManager::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
+{
+
+    std::string resourceURI;
+    std::string hostAddress;
+    try
+    {
+        // 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;
+
+            hostAddress.append(resourceURI);
+
+            for (auto &resourceTypes : resource->getResourceTypes())
+            {
+                std::cout << "\t\t" << resourceTypes << std::endl;
+
+                if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
+                        resourceTypes) == allFoundResourceTypes.end())
+                {
+                    allFoundResourceTypes.push_back(resourceTypes);
+                }
+
+                rtForResourceList[resourceTypes][hostAddress] = 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;
+            }
+
+            if (waitsec == -1)
+            {
+                findPreparedRequest(candidateRequest);
+            }
+        }
+        else
+        {
+            // Resource is invalid
+            std::cout << "Resource is invalid" << std::endl;
+        }
+
+    }
+    catch (std::exception& e)
+    {
+        //log(e.what());
+    }
+}
+
+GroupManager::GroupManager(void)
+{
+    ;
+}
+
+/**
+ * Virtual destructor
+ */
+GroupManager::~GroupManager(void)
+{
+    candidateRequest.clear();
+    candidateRequestForTimer.clear();
+    rtForResourceList.clear();
+    allFoundResourceTypes.clear();
+}
+
+void GroupManager::findPreparedRequest(
+        std::map< std::vector< std::string >, CandidateCallback > &request)
+{
+    std::vector< std::shared_ptr< OCResource > > resources;
+
+    for (auto it = request.begin(); it != request.end();)
+    {
+
+        if (IsSubset(allFoundResourceTypes, it->first))
+        {
+            //std::cout << "IS SUBSET !!! \n";
+
+            for (unsigned int i = 0; i < it->first.size(); ++i)
+            {
+
+                for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
+                        secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
+                {
+                    resources.push_back(secondIt->second);
+                }
+            }
+
+            it->second(resources);
+
+            //TODO : decide policy - callback only once
+            request.erase(it++);
+        }
+        else
+        {
+            ++it;
+        }
+
+    }
+
+}
+
+void GroupManager::lazyCallback(int second)
+{
+    sleep(second);
+    findPreparedRequest(candidateRequestForTimer);
+
+}
+
+OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes,
+        CandidateCallback callback, int waitsec)
+{
+    if (resourceTypes.size() < 1)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    std::sort(resourceTypes.begin(), resourceTypes.end());
+    resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
+            resourceTypes.end());
+
+    if (waitsec != -1)
+    {
+        candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
+    }
+    else
+    {
+        candidateRequest.insert(std::make_pair(resourceTypes, callback));
+    }
+
+    for (unsigned int i = 0; i < resourceTypes.size(); ++i)
+    {
+        std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
+        std::string query = "coap://224.0.1.187/oc/core?rt=";
+        query.append(resourceTypes.at(i));
+        OCPlatform::findResource("", query.c_str(),
+                std::function < void(std::shared_ptr < OCResource > resource)
+                        > (std::bind(&GroupManager::onFoundResource, this, std::placeholders::_1,
+                                waitsec)));
+    }
+
+    if (waitsec != -1)
+    {
+        std::thread exec(
+                std::function< void(int second) >(
+                        std::bind(&GroupManager::lazyCallback, this, std::placeholders::_1)),
+                waitsec);
+        exec.detach();
+    }
+
+    return OC_STACK_OK;
+}
+
+/*
+ Presence Check
+ */
+
+std::map< std::string, CollectionPresenceCallback > presenceCallbacks;
+
+// Callback to presence
+void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce,
+        const std::string& hostAddress, std::string host, std::string uri)
+{
+    std::cout << "uri : " << uri << std::endl;
+    std::cout << "host : " << host << std::endl;
+    std::cout << "result : " << result << std::endl;
+    switch (result)
+    {
+        case OC_STACK_OK:
+            std::cout << "Nonce# " << nonce << std::endl;
+            break;
+        case OC_STACK_PRESENCE_STOPPED:
+            std::cout << "Presence Stopped\n";
+            break;
+        case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+            std::cout << "Presence do not handle\n";
+            break;
+        case OC_STACK_PRESENCE_TIMEOUT:
+            std::cout << "Presence TIMEOUT\n";
+            break;
+        default:
+            std::cout << "Error\n";
+            break;
+    }
+
+    if (presenceCallbacks.find(uri) != presenceCallbacks.end())
+    {
+        (presenceCallbacks.find(uri)->second)(uri, result);
+    }
+}
+
+void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep,
+        CollectionPresenceCallback callback)
+{
+    std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+    /* //bug not found
+     if(rep.hasAttribute("name"))
+     {
+     std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl;
+     }
+     */
+    std::vector< OCRepresentation > children = rep.getChildren();
+
+    for (auto oit = children.begin(); oit != children.end(); ++oit)
+    {
+        std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+        std::vector< std::string > hostAddressVector = str_split(oit->getUri(), '/');
+        std::string hostAddress = "";
+        for (unsigned int i = 0; i < hostAddressVector.size(); ++i)
+        {
+            if (i < 3)
+            {
+                hostAddress.append(hostAddressVector.at(i));
+                if (i != 2)
+                {
+                    hostAddress.append("/");
+                }
+            }
+        }
+
+        std::vector< std::string > resourceTypes = oit->getResourceTypes();
+        for (unsigned int i = 0; i < resourceTypes.size(); ++i)
+        {
+            std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl;
+        }
+
+        std::string resourceType = "core.";
+        resourceType.append(str_split(oit->getUri(), '/').at(4));
+        std::cout << "\t\tconvertRT : " << resourceType << std::endl;
+        std::cout << "\t\thost : " << hostAddress << std::endl;
+        OCPlatform::OCPresenceHandle presenceHandle;
+        OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
+                resourceType,
+                std::function<
+                        void(OCStackResult result, const unsigned int nonce,
+                                const std::string& hostAddress) >(
+                        std::bind(&GroupManager::collectionPresenceHandler, this,
+                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                                hostAddress, oit->getUri())));
+
+        if (result == OC_STACK_OK)
+        {
+            std::cout << "\t\tOK!" << std::endl;
+            presenceCallbacks.insert(std::make_pair(oit->getUri(), callback));
+        }
+        else
+        {
+            callback("", OC_STACK_ERROR);
+        }
+
+    }
+}
+
+void GroupManager::onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+        const int eCode, CollectionPresenceCallback callback)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        std::cout << "GET request was successful" << std::endl;
+        std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+        checkCollectionRepresentation(rep, callback);
+
+    }
+    else
+    {
+        std::cout << "onGET Response error: " << eCode << std::endl;
+        callback("", OC_STACK_ERROR);
+        std::exit(-1);
+    }
+}
+
+OCStackResult GroupManager::subscribeCollectionPresence(
+        std::shared_ptr< OCResource > collectionResource, CollectionPresenceCallback callback)
+{
+    OCStackResult result = OC_STACK_OK;
+    //callback("core.room",OC_STACK_OK);
+
+    QueryParamsMap queryParam;
+
+    //parameter 1 = resourceType
+    collectionResource->get("", DEFAULT_INTERFACE, queryParam,
+            std::function<
+                    void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                            const int eCode) >(
+                    std::bind(&GroupManager::onGetForPresence, this, std::placeholders::_1,
+                            std::placeholders::_2, std::placeholders::_3, callback)));
+
+    return result;
+}
+
+/*
+ Group Action
+ */
+
+std::string GroupManager::getStringFromActionSet(const ActionSet *newActionSet)
+{
+    std::string message = "";
+
+    message = newActionSet->actionsetName;
+    message.append("*");
+    for (auto iterAction = newActionSet->listOfAction.begin();
+            iterAction != newActionSet->listOfAction.end(); iterAction++)
+    {
+        message.append("uri=");
+        message.append((*iterAction)->target);
+        message.append("|");
+
+        for (auto iterCapa = (*iterAction)->listOfCapability.begin();
+                iterCapa != (*iterAction)->listOfCapability.end(); iterCapa++)
+        {
+            message.append((*iterCapa)->capability);
+            message.append("=");
+            message.append((*iterCapa)->status);
+
+            if (iterCapa + 1 != (*iterAction)->listOfCapability.end())
+                message.append("|");
+        }
+
+        if (iterAction + 1 != newActionSet->listOfAction.end())
+        {
+            message.append("*");
+        }
+    }
+
+    return message;
+}
+
+ActionSet* GroupManager::getActionSetfromString(std::string desc)
+{
+
+    char *token = NULL;
+    char *plainText = NULL;
+    char *plainPtr = NULL;
+
+    ActionSet *actionset = new ActionSet();
+    plainText = new char[(desc.length() + 1)];
+    strcpy(plainText, desc.c_str());
+
+    token = strtok_r(plainText, ACTION_DELIMITER, &plainPtr);
+
+    if (token != NULL)
+    {
+        actionset->actionsetName = std::string(token);
+        token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
+    }
+    else
+    {
+        delete actionset;
+        delete[] plainText;
+        return NULL;
+    }
+
+    while (token)
+    {
+        char *descPtr = NULL;
+        char *desc = new char[(strlen(token) + 1)];
+
+        if (desc != NULL)
+        {
+            Action *action = NULL;
+            strcpy(desc, token);
+            token = strtok_r(desc, DESC_DELIMITER, &descPtr);
+
+            // cout << "desc :: " << token << endl;
+            while (token != NULL)
+            {
+                char *attrPtr = NULL;
+                char *attr = new char[(strlen(token) + 1)];
+
+                strcpy(attr, token);
+
+                // cout << "attr :: " << attr << endl;
+
+                token = strtok_r(attr, ATTR_DELIMITER, &attrPtr);
+                while (token != NULL)
+                {
+                    if (strcmp(token, "uri") == 0)
+                    {
+                        token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
+                        action = new Action();
+
+                        if (action != NULL)
+                        {
+                            action->target = std::string(token);
+                        }
+                        else
+                        {
+                            delete actionset;
+                            delete[] attr;
+                            delete desc;
+                            delete[] plainText;
+                            return NULL;
+                        }
+                    }
+                    else
+                    {
+                        Capability *capa = new Capability();
+                        capa->capability = std::string(token);
+                        token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
+                        capa->status = std::string(token);
+
+                        if (action != NULL)
+                        {
+                            action->listOfCapability.push_back(capa);
+                        }
+                        else
+                        {
+                            delete capa;
+                            delete actionset;
+                            delete[] attr;
+                            delete[] plainText;
+                            delete desc;
+                            return NULL;
+                        }
+                    }
+
+                    token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr);
+                }
+
+                delete[] attr;
+                token = strtok_r(NULL, DESC_DELIMITER, &descPtr);
+            }
+
+            actionset->listOfAction.push_back(action);
+            //delete action;
+        }
+        else
+        {
+            delete actionset;
+            delete[] plainText;
+            return NULL;
+        }
+
+        delete[] desc;
+
+        token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr);
+    }
+
+    delete plainText;
+    return actionset;
+}
+
+OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource,
+        const ActionSet* newActionSet, PutCallback cb)
+{
+    // BUILD message of ActionSet which it is included delimiter.
+    std::string message = getStringFromActionSet(newActionSet);
+    OCRepresentation rep;
+
+    rep.setValue("ActionSet", message);
+
+    return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+            QueryParamsMap(), cb);
+}
+
+OCStackResult GroupManager::executeActionSet(std::shared_ptr< OCResource > resource,
+        std::string actionsetName, PostCallback cb)
+{
+    OCRepresentation rep;
+
+    rep.setValue("DoAction", actionsetName);
+    return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+            QueryParamsMap(), cb);
+}
+
+OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource,
+        std::string actionsetName, PostCallback cb)
+{
+    OCRepresentation rep;
+
+    rep.setValue("GetActionSet", actionsetName);
+
+    return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+            QueryParamsMap(), cb);
+}
+
+OCStackResult GroupManager::deleteActionSet(std::shared_ptr< OCResource > resource,
+        std::string actionsetName, PutCallback cb)
+{
+    OCRepresentation rep;
+
+    rep.setValue("DelActionSet", actionsetName);
+
+    return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep,
+            QueryParamsMap(), cb);
+}
+}
diff --git a/service/things-manager/sdk/src/GroupManager.h b/service/things-manager/sdk/src/GroupManager.h
new file mode 100644 (file)
index 0000000..d0dad45
--- /dev/null
@@ -0,0 +1,151 @@
+//******************************************************************
+//
+// 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   GroupManager.h
+
+/// @brief  This file contains the declaration of classes and its members related to GroupManager
+
+#ifndef __OC_GROUPMANAGER__
+#define __OC_GROUPMANAGER__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+namespace OIC
+{
+typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CandidateCallback;
+typedef std::function< void(std::string, OCStackResult) > CollectionPresenceCallback;
+
+typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > GetCallback;
+typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > PostCallback;
+typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > PutCallback;
+
+class Capability
+{
+public:
+    std::string capability;
+    std::string status;
+};
+
+class Action
+{
+public:
+    Action() :
+            target("")
+    {
+    }
+    ~Action()
+    {
+        listOfCapability.clear();
+    }
+    std::string target;
+
+    std::vector< Capability* > listOfCapability;
+};
+
+class ActionSet
+{
+public:
+    ActionSet() :
+            actionsetName("")
+    {
+    }
+    ~ActionSet()
+    {
+        listOfAction.clear();
+    }
+    std::string actionsetName;
+
+    std::vector< Action* > listOfAction;
+};
+
+class GroupManager
+{
+public:
+    /**
+     * Constructor for GroupManager. Constructs a new GroupManager
+     */
+    GroupManager(void);
+
+    /**
+     * Virtual destructor
+     */
+    ~GroupManager(void);
+
+    /**
+     * API for candidate resources discovery.
+     * Callback only call when all resource types found.
+     *
+     * @param resourceTypes - required resource types(called "candidate")
+     * @param candidateCallback - callback. OCResource vector.
+     *
+     * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+     *
+     * NOTE: OCStackResult is defined in ocstack.h.
+     */
+    OCStackResult findCandidateResources(std::vector< std::string > resourceTypes,
+            CandidateCallback callback, int waitsec = -1);
+
+    /**
+     * API for Collection member's state subscribe.
+     *
+     * NOTE: NOT IMPLEMENT YET
+     */
+    OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource > resource,
+            CollectionPresenceCallback);
+
+private:
+
+    void onFoundResource(std::shared_ptr< OCResource > resource, int waitsec);
+    void findPreparedRequest(std::map< std::vector< std::string >, CandidateCallback > &request);
+    void lazyCallback(int second);
+
+    void onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode, CollectionPresenceCallback callback);
+    void checkCollectionRepresentation(const OCRepresentation& rep,
+            CollectionPresenceCallback callback);
+    void collectionPresenceHandler(OCStackResult result, const unsigned int nonce,
+            const std::string& hostAddress, std::string host, std::string uri);
+
+    /**
+     *   API for Collection(Group) action.
+     */
+
+public:
+    std::string getStringFromActionSet(const ActionSet *newActionSet);
+    ActionSet* getActionSetfromString(std::string desc);
+
+    OCStackResult addActionSet(std::shared_ptr< OCResource > resource,
+            const ActionSet* newActionSet, PutCallback cb);
+    OCStackResult executeActionSet(std::shared_ptr< OCResource > resource,
+            std::string actionsetName, PostCallback cb);
+    OCStackResult getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName,
+            PostCallback cb);
+    OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName,
+            PostCallback);
+};
+}
+#endif  /* __OC_GROUPMANAGER__*/
diff --git a/service/things-manager/sdk/src/GroupSynchronization.cpp b/service/things-manager/sdk/src/GroupSynchronization.cpp
new file mode 100644 (file)
index 0000000..dd2c96c
--- /dev/null
@@ -0,0 +1,1277 @@
+//******************************************************************
+//
+// 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    GroupSynchronization.cpp
+/// @brief
+
+#include "GroupSynchronization.h"
+
+using namespace OC;
+
+namespace OIC
+{
+
+GroupSynchronization* GroupSynchronization::groupSyncnstance = NULL;
+
+GroupSynchronization* GroupSynchronization::getInstance()
+{
+    if (groupSyncnstance == NULL)
+    {
+        groupSyncnstance = new GroupSynchronization();
+    }
+    return groupSyncnstance;
+}
+
+void GroupSynchronization::deleteInstance()
+{
+    if (groupSyncnstance)
+    {
+        delete groupSyncnstance;
+        groupSyncnstance = NULL;
+    }
+}
+
+OCStackResult GroupSynchronization::findGroup(
+        std::vector< std::string > collectionResourceTypes, FindCallback callback)
+{
+    cout << "GroupSynchronization::findGroup" << endl;
+
+    foundGroupResourceList.clear();
+
+    findCallback = callback;
+
+    for (unsigned int i = 0; i < collectionResourceTypes.size(); ++i)
+    {
+        std::string query = "coap://224.0.1.187/oc/core?rt=";
+        query.append(collectionResourceTypes.at(i));
+        cout << "GroupSynchronization::findGroup - " << query << endl;
+
+        OCPlatform::findResource("", query,
+                std::bind(&GroupSynchronization::onFindGroup, this, std::placeholders::_1));
+    }
+
+    // thread to check if GroupSynchronization::onFoundGroup is called or not.
+    std::thread t(std::bind(&GroupSynchronization::checkFindGroup, this));
+    t.detach();
+
+    return OC_STACK_OK;
+}
+
+OCStackResult GroupSynchronization::createGroup(std::string collectionResourceType)
+{
+    foundGroupResourceList.clear();
+
+    OCResourceHandle collectionResHandle = NULL;
+    OCResourceHandle groupSyncResHandle = NULL;
+
+    if (0 != collectionResourceType.length())
+    {
+        cout << "GroupSynchronization::createGroup - The created group is added." << endl;
+
+        OCStackResult result;
+
+        // creating master collection resource
+        std::string collectionUri = "/" + collectionResourceType;
+        int i;
+        while ((i = collectionUri.find(".")) != std::string::npos)
+        {
+            collectionUri.replace(i, 1, "/");
+        }
+        cout << "GroupSynchronization::createGroup : collection uri - " << collectionUri
+                << ", type - " << collectionResourceType << endl;
+
+        std::string resourceInterface = DEFAULT_INTERFACE;
+
+        result = OCPlatform::registerResource(collectionResHandle, collectionUri,
+                collectionResourceType, resourceInterface, NULL,
+                OC_DISCOVERABLE | OC_OBSERVABLE);
+        if (result != OC_STACK_OK)
+        {
+            cout << "To register resource (" << collectionUri << ") was unsuccessful. result - "
+                    << result << endl;
+            goto Error;
+        }
+
+        OCPlatform::bindInterfaceToResource(collectionResHandle, GROUP_INTERFACE);
+        if (result != OC_STACK_OK)
+        {
+            cout << "To bind Interface (collection) was unsuccessful. result - " << result
+                    << endl;
+        }
+
+        collectionResourceHandleList[collectionResourceType] = collectionResHandle;
+
+        // creating master group sync resource
+        std::string groupSyncUri = collectionUri + "/groupsync";
+        std::string groupSyncResType = collectionResourceType + ".groupsync";
+
+//        cout << "GroupSynchronization::createGroup : groupSync uri - " << groupSyncUri
+//                << ", type - " << collectionResourceType << endl;
+
+        result = OCPlatform::registerResource(groupSyncResHandle, groupSyncUri,
+                groupSyncResType, resourceInterface,
+                std::bind(&GroupSynchronization::groupEntityHandler, this,
+                        std::placeholders::_1), OC_DISCOVERABLE | OC_OBSERVABLE);
+        if (result != OC_STACK_OK)
+        {
+            cout << "To register resource (groupsync) was unsuccessful. result - " << result
+                    << endl;
+            goto Error;
+        }
+
+        groupSyncResourceHandleList[collectionResourceType] = groupSyncResHandle;
+
+        return OC_STACK_OK;
+    }
+    else
+    {
+        cout << "GroupSynchronization::createGroup : Error! Input params are wrong." << endl;
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    Error:
+
+    if (collectionResHandle)
+    {
+        OCPlatform::unregisterResource(collectionResHandle);
+        auto iterator = collectionResourceHandleList.find(collectionResourceType);
+        if (iterator != collectionResourceHandleList.end())
+        {
+            collectionResourceHandleList.erase(iterator);
+        }
+    }
+
+    if (groupSyncResHandle)
+    {
+        OCPlatform::unregisterResource(groupSyncResHandle);
+        auto iterator = groupSyncResourceHandleList.find(collectionResourceType);
+        if (iterator != groupSyncResourceHandleList.end())
+        {
+            groupSyncResourceHandleList.erase(iterator);
+        }
+    }
+
+    return OC_STACK_NO_RESOURCE;
+}
+
+OCStackResult GroupSynchronization::joinGroup(std::string collectionResourceType,
+        OCResourceHandle resourceHandle)
+{
+    if ((0 != collectionResourceType.length()) && (resourceHandle))
+    {
+        auto resIt = collectionResourceHandleList.find(collectionResourceType);
+        if (resIt == groupSyncResourceHandleList.end())
+        {
+            cout << "GroupSynchronization::joinGroup : error! There is no collection to join"
+                    << endl;
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCResourceHandle collectionResHandle = resIt->second;
+
+        OCStackResult result = OCPlatform::bindResource(collectionResHandle, resourceHandle);
+        if (result != OC_STACK_OK)
+        {
+            cout << "GroupSynchronization::joinGroup : To bind resource was unsuccessful."
+                    << "result - " << result << endl;
+            return OC_STACK_ERROR;
+        }
+        cout << "GroupSynchronization::joinGroup : "
+                << "To bind collectionResHandle and resourceHandle" << endl;
+
+        std::vector< OCResourceHandle > childHandleList;
+
+        auto childIt = childResourceHandleList.find(collectionResHandle);
+        if (childIt != childResourceHandleList.end())
+        {
+            childHandleList = childIt->second;
+        }
+
+        childHandleList.push_back(resourceHandle);
+        childResourceHandleList[collectionResHandle] = childHandleList;
+
+        deviceResourceHandleList.push_back(resourceHandle);
+
+        debugGroupSync();
+    }
+    else
+    {
+        cout << "GroupSynchronization::joinGroup : Error! input params are wrong." << endl;
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    return OC_STACK_OK;
+}
+
+OCStackResult GroupSynchronization::joinGroup(const std::shared_ptr< OCResource > resource,
+        OCResourceHandle resourceHandle)
+{
+    if ((resource) && (resourceHandle))
+    {
+        cout << "GroupSynchronization::joinGroup" << endl;
+
+        // making representation to join group
+        std::string method = "joinGroup";
+        std::vector< std::string > type = resource->getResourceTypes();
+        std::string resourceType;
+        resourceType.append(OCGetResourceTypeName(resourceHandle, 0));
+
+        OCRepresentation rep;
+        rep.setValue("method", method);
+        rep.setValue("collectionResourceType", type[0]);
+        rep.setValue("resourceType", resourceType);
+
+        cout << "\tmethod - " << method << endl;
+        cout << "\tcollectionResourceType - " << type[0] << endl;
+        cout << "\tresourceType - " << resourceType << endl;
+
+        // creating group sync resource with the received collection resource.
+        // entity handler of group sync is used to join group.
+        std::string host = resource->host();
+        std::string uri = resource->uri() + "/groupsync";
+
+        std::vector< std::string > resourceTypes;
+        std::string temp;
+        for (unsigned int i = 0; i < type.size(); ++i)
+        {
+            temp = type[0] + ".groupsync";
+            resourceTypes.push_back(temp);
+        }
+
+        std::vector< std::string > resourceInterface;
+        resourceInterface.push_back(DEFAULT_INTERFACE);
+
+        OCResource::Ptr groupSyncResource = OCPlatform::constructResourceObject(host, uri, 1,
+                resourceTypes, resourceInterface);
+        groupSyncResourceList[type[0]] = groupSyncResource;
+
+        cout << "GroupSynchronization::joinGroup : creating groupSyncResource." << endl;
+
+        // Create QueryParameters Map and add query params (if any)
+        QueryParamsMap queryParamsMap;
+
+        // request to join group to the remote group sync resource
+        OCStackResult result = groupSyncResource->put(rep, queryParamsMap,
+                std::bind(&GroupSynchronization::onJoinGroup, this, std::placeholders::_1,
+                        std::placeholders::_2, std::placeholders::_3));
+        if (OC_STACK_OK == result)
+        {
+            cout << "GroupSynchronization::joinGroup : groupSyncResource->put was successful."
+                    << endl;
+        }
+        else
+        {
+            cout << "GroupSynchronization::joinGroup : "
+                    << "groupSyncResource->put was unsuccessful. result - " << result << endl;
+        }
+
+        // saving the remote collection resource.
+        // It is used in onJoinGroup() and onGetJoinedRemoteChild().
+        remoteCollectionResource = resource;
+
+        // saving the resource handle to join. It is used in onGetJoinedRemoteChild()
+        deviceResourceHandle = resourceHandle;
+
+        return OC_STACK_OK;
+    }
+    else
+    {
+        cout << "GroupSynchronization::joinGroup : Error! Input params are wrong." << endl;
+        return OC_STACK_INVALID_PARAM;
+    }
+}
+
+OCStackResult GroupSynchronization::leaveGroup(std::string collectionResourceType,
+        OCResourceHandle resourceHandle)
+{
+    if ((0 != collectionResourceType.length()) && (resourceHandle))
+    {
+        cout << "GroupSynchronization::leaveGroup : collectionResourceType - "
+                << collectionResourceType << endl;
+
+        OCResourceHandle collectionResHandle;
+
+        auto handleIt = groupSyncResourceHandleList.find(collectionResourceType);
+
+        // if groupSyncResourceHandleList has resourceType,
+        // this app created collection resource handle.
+        if (handleIt != groupSyncResourceHandleList.end())
+        {
+            handleIt = collectionResourceHandleList.find(collectionResourceType);
+            if (handleIt == collectionResourceHandleList.end())
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "Error! There is no collection resource handle to leave." << endl;
+                return OC_STACK_INVALID_PARAM;
+            }
+
+            collectionResHandle = handleIt->second;
+//            cout << "GroupSynchronization::leaveGroup : collection handle uri - "
+//                    << OCGetResourceUri(collectionResHandle) << endl;
+
+            OCStackResult result = OCPlatform::unbindResource(collectionResHandle,
+                    resourceHandle);
+            if (OC_STACK_OK == result)
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "To unbind resource was successful." << endl;
+            }
+            else
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "To unbind resource was unsuccessful. result - " << result << endl;
+            }
+
+            auto It = std::find(deviceResourceHandleList.begin(),
+                    deviceResourceHandleList.end(), resourceHandle);
+            if (It == deviceResourceHandleList.end()) // there is no resource handle to find
+            {
+                result = OCPlatform::unregisterResource(resourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "GroupSynchronization::leaveGroup : "
+                            << "To unregister resource was successful." << endl;
+                }
+                else
+                {
+                    cout << "GroupSynchronization::leaveGroup : "
+                            << "To unregister resource was unsuccessful. result - " << result
+                            << endl;
+                }
+            }
+            else
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "This resource cannot be unregistered." << endl;
+                deviceResourceHandleList.erase(It);
+            }
+
+            auto handleListIt = childResourceHandleList.find(collectionResHandle);
+            if (handleListIt == childResourceHandleList.end())
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "Error! There is no child resource list to delete." << endl;
+                return OC_STACK_INVALID_PARAM;
+            }
+
+            std::vector< OCResourceHandle > childList = handleListIt->second;
+            auto childIt = std::find(childList.begin(), childList.end(), resourceHandle);
+            if (childIt != childList.end())
+            {
+                cout << "GroupSynchronization::groupEntityHandler : "
+                        << "Found! The resource to leave is found." << endl;
+                childList.erase(childIt);
+            }
+
+            childResourceHandleList[collectionResHandle] = childList;
+
+            debugGroupSync();
+        }
+        else // requesting to unbind this resourceHandle to the remote collection resource
+        {
+            auto resourceIt = groupSyncResourceList.find(collectionResourceType);
+
+            if (resourceIt == groupSyncResourceList.end())
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "Error! There is no collectin resource type to leave." << endl;
+                return OC_STACK_INVALID_PARAM;
+            }
+
+            std::shared_ptr< OCResource > resource = resourceIt->second;
+//            cout << "GroupSynchronization::leaveGroup : group sync resource uri - "
+//                    << resource->uri() << endl;
+
+            handleIt = collectionResourceHandleList.find(collectionResourceType);
+            if (handleIt == collectionResourceHandleList.end())
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "Error! There is no collection resource handle to leave." << endl;
+                return OC_STACK_INVALID_PARAM;
+            }
+
+            collectionResHandle = handleIt->second;
+
+            // making representation to leave group
+            std::string method = "leaveGroup";
+            std::string type = OCGetResourceTypeName(collectionResHandle, 0);
+            std::string resourceType;
+            resourceType.append(OCGetResourceTypeName(resourceHandle, 0));
+
+            OCRepresentation rep;
+            rep.setValue("method", method);
+            rep.setValue("collectionResourceType", type);
+            rep.setValue("resourceType", resourceType);
+
+            cout << "\tmethod - " << method << endl;
+            cout << "\tcollectionResourceType - " << type << endl;
+            cout << "\tresourceType - " << resourceType << endl;
+
+            QueryParamsMap queryParamsMap;
+
+            // request to leave group to the remote group sync resource
+            OCStackResult result = resource->put(rep, queryParamsMap,
+                    std::bind(&GroupSynchronization::onLeaveGroup, this, std::placeholders::_1,
+                            std::placeholders::_2, std::placeholders::_3));
+            if (OC_STACK_OK == result)
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "groupSyncResource->put was successful." << endl;
+            }
+            else
+            {
+                cout << "GroupSynchronization::leaveGroup : "
+                        << "groupSyncResource->put was unsuccessful. result - " << result
+                        << endl;
+            }
+
+            // deleting all remote resources. These are copied in onGetJoinedRemoteChild()
+            deleteGroup(collectionResourceType);
+        }
+    }
+    else
+    {
+        cout << "GroupSynchronization::leaveGroup : Error! Input params are wrong." << endl;
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    return OC_STACK_OK;
+}
+
+void GroupSynchronization::deleteGroup(std::string collectionResourceType)
+{
+    if (0 != collectionResourceType.length())
+    {
+        cout << "GroupSynchronization::deleteGroup" << endl;
+
+        OCStackResult result;
+
+        auto handleIt = collectionResourceHandleList.find(collectionResourceType);
+        if (handleIt == collectionResourceHandleList.end())
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << "Error! There is no collection resource handle to delete." << endl;
+            return;
+        }
+        OCResourceHandle collectionResHandle = handleIt->second;
+
+        collectionResourceHandleList.erase(handleIt);
+
+        auto handleListIt = childResourceHandleList.find(collectionResHandle);
+        if (handleListIt == childResourceHandleList.end())
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << "Error! There is no child resource list to delete." << endl;
+            return;
+        }
+        std::vector< OCResourceHandle > childList = handleListIt->second;
+
+        childResourceHandleList.erase(handleListIt);
+
+        result = OCPlatform::unbindResources(collectionResHandle, childList);
+        if (OC_STACK_OK == result)
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << "To unbind resources was successful." << endl;
+        }
+        else
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << "To unbind resources was unsuccessful. result - " << result << endl;
+        }
+
+        result = OCPlatform::unregisterResource(collectionResHandle);
+        if (result != OC_STACK_OK)
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << "To unregister collection resource handle was successful." << endl;
+        }
+        else
+        {
+            cout << "GroupSynchronization::deleteGroup : "
+                    << " To unregister collection resource handle was unsuccessful. result - "
+                    << result << endl;
+        }
+
+        OCResourceHandle resourceHandle;
+        std::vector< OCResourceHandle >::iterator It;
+
+        for (unsigned int i = 0; i < childList.size(); i++)
+        {
+            resourceHandle = childList.at(i);
+
+            It = std::find(deviceResourceHandleList.begin(), deviceResourceHandleList.end(),
+                    resourceHandle);
+            if (It != deviceResourceHandleList.end()) // find !!
+            {
+                deviceResourceHandleList.erase(It);
+            }
+            else
+            {
+                result = OCPlatform::unregisterResource(resourceHandle);
+                if (OC_STACK_OK == result)
+                {
+                    cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1
+                            << ") was successful." << endl;
+                }
+                else
+                {
+                    cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1
+                            << ") was unsuccessful. result - " << result << endl;
+                }
+            }
+        }
+
+        handleIt = groupSyncResourceHandleList.find(collectionResourceType);
+
+        // if groupSyncResourceHandleList has resourceType,
+        // group sync of this app created collection resource.
+        if (handleIt != groupSyncResourceHandleList.end())
+        {
+            resourceHandle = handleIt->second; // group sync resource handle
+            result = OCPlatform::unregisterResource(resourceHandle);
+            if (OC_STACK_OK == result)
+            {
+                cout << "GroupSynchronization::deleteGroup : "
+                        << "To unregister group sync resource handle was successful." << endl;
+            }
+            else
+            {
+                cout << "GroupSynchronization::deleteGroup : "
+                        << "To unregister group sync resource handle was unsuccessful. "
+                        << "result - " << result << endl;
+            }
+
+            groupSyncResourceHandleList.erase(handleIt);
+        }
+
+        auto resourceIt = groupSyncResourceList.find(collectionResourceType);
+        if (resourceIt != groupSyncResourceList.end())
+        {
+            groupSyncResourceList.erase(resourceIt);
+        }
+
+        debugGroupSync();
+    }
+    else
+    {
+        cout << "GroupSynchronization::deleteGroup : Error! Input params are wrong." << endl;
+    }
+}
+
+std::map< std::string, OCResourceHandle > GroupSynchronization::getGroupList()
+{
+    return collectionResourceHandleList;
+}
+
+OCEntityHandlerResult GroupSynchronization::groupEntityHandler(
+        const std::shared_ptr< OCResourceRequest > request)
+{
+    cout << "GroupSynchronization::groupEntityHandler\n";
+
+    if (request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if (requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if (requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if (requestType == "GET")
+            {
+                cout << "\t\trequestType : GET\n";
+            }
+            else if (requestType == "PUT")
+            {
+                cout << "\t\trequestType : PUT\n";
+
+                //get method name, group resource type and resource type to join group
+                OCRepresentation rp = request->getResourceRepresentation();
+                std::string methodType = rp.getValue< std::string >("method");
+                std::string collectionResourceType = rp.getValue< std::string >(
+                        "collectionResourceType");
+                std::string resourceType = rp.getValue< std::string >("resourceType");
+
+                cout << "\t\t\tmethod : " << methodType << endl;
+                cout << "\t\t\tcollection resourceType : " << collectionResourceType << endl;
+                cout << "\t\t\tresourceType : " << resourceType << endl;
+
+                auto handleIt = collectionResourceHandleList.find(collectionResourceType);
+                if (handleIt == collectionResourceHandleList.end())
+                {
+                    cout << "GroupSynchronization::groupEntityHandler : "
+                            << "Error! There is no collection resource handle to delete."
+                            << endl;
+                    return OC_EH_ERROR;
+                }
+                collectionResourceHandle = handleIt->second;
+                // in case of join group it is used in onFindResource()
+
+                if (methodType == "joinGroup")
+                {
+                    std::string resourceName = "coap://224.0.1.187/oc/core?rt=";
+                    resourceName += resourceType;
+                    cout << "\t\t\tresourceName : " << resourceName << endl;
+
+                    resourceRequest = request;
+
+                    OCPlatform::findResource("", resourceName,
+                            std::bind(&GroupSynchronization::onFindResource, this,
+                                    std::placeholders::_1));
+                }
+                else if (methodType == "leaveGroup")
+                {
+                    auto it = childResourceHandleList.find(collectionResourceHandle);
+                    if (it == childResourceHandleList.end())
+                    {
+                        cout << "GroupSynchronization::groupEntityHandler : "
+                                << "Error! There is no child resource list." << endl;
+                        return OC_EH_ERROR;
+                    }
+
+                    std::vector< OCResourceHandle > childList = it->second;
+                    OCResourceHandle resourceHandle;
+                    for (auto childIt = childList.begin(); childIt != childList.end();)
+                    {
+                        resourceHandle = (*childIt);
+                        char* type = (char*) OCGetResourceTypeName(resourceHandle, 0);
+
+                        if (0 == resourceType.compare(type))
+                        {
+                            cout << "GroupSynchronization::groupEntityHandler : "
+                                    << "Found! The resource to leave is found. - " << type
+                                    << endl;
+
+                            childIt = childList.erase(childIt++);
+
+                            OCStackResult result = OCPlatform::unbindResource(
+                                    collectionResourceHandle, resourceHandle);
+                            if (OC_STACK_OK == result)
+                            {
+                                cout << "GroupSynchronization::groupEntityHandler : "
+                                        << "To unbind resource was successful." << endl;
+                            }
+                            else
+                            {
+                                cout << "GroupSynchronization::groupEntityHandler : "
+                                        << "To unbind resource was unsuccessful. result - "
+                                        << result << endl;
+                            }
+
+                            result = OCPlatform::unregisterResource(resourceHandle);
+                            if (OC_STACK_OK == result)
+                            {
+                                cout << "GroupSynchronization::groupEntityHandler : "
+                                        << "To unregister resource was successful." << endl;
+                            }
+                            else
+                            {
+                                cout << "GroupSynchronization::groupEntityHandler : "
+                                        << "To unregister resource was unsuccessful. result - "
+                                        << result << endl;
+                            }
+
+//                            break;
+                        }
+                        else
+                        {
+                            ++childIt;
+                        }
+
+                    }
+
+                    childResourceHandleList[collectionResourceHandle] = childList;
+
+                    debugGroupSync();
+
+                    auto pResponse = std::make_shared< OC::OCResourceResponse >();
+                    pResponse->setRequestHandle(request->getRequestHandle());
+                    pResponse->setResourceHandle(request->getResourceHandle());
+                    pResponse->setErrorCode(200);
+                    pResponse->setResponseResult(OC_EH_OK);
+
+                    OCRepresentation rep = request->getResourceRepresentation();
+                    pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        cout << "GroupSynchronization::groupEntityHandler : "
+                                << "sendResponse is successful." << endl;
+                    }
+                }
+
+                if (methodType != "") //TODO: Check groupmethodtype NULL
+                {
+                }
+            }
+            else if (requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if (requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if (requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+
+    return OC_EH_OK;
+}
+
+void GroupSynchronization::onFindGroup(std::shared_ptr< OCResource > resource)
+{
+    cout << "GroupSynchronization::onFindGroup" << endl;
+
+    try
+    {
+        if (resource)
+        {
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////////debugging
+            std::string resourceURI;
+            std::string hostAddress;
+
+            // Get the resource URI
+            resourceURI = resource->uri();
+            cout << "\tURI of the resource: " << resourceURI << endl;
+
+            // Get the resource host address
+            hostAddress = resource->host();
+            cout << "\tHost address of the resource: " << hostAddress << endl;
+
+            hostAddress.append(resourceURI);
+
+            // Get the resource types
+            cout << "\tList of resource types: " << endl;
+
+            for (auto &resourceTypes : resource->getResourceTypes())
+            {
+                cout << "\t\t" << resourceTypes << endl;
+            }
+
+            // Get the resource interfaces
+            cout << "\tList of resource interfaces: " << endl;
+            for (auto &resourceInterfaces : resource->getResourceInterfaces())
+            {
+                cout << "\t\t" << resourceInterfaces << endl;
+            }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+            if (false == IsSameGroup(resource))
+            {
+                saveGroup(resource);
+                findCallback(resource);
+            }
+        }
+        else
+        {
+            // Resource is invalid
+            cout << "Resource is invalid" << endl;
+            findCallback(NULL);
+        }
+
+    }
+    catch (std::exception& e)
+    {
+        //log(e.what());
+    }
+}
+
+void GroupSynchronization::checkFindGroup(void)
+{
+    cout << "GroupSynchronization::checkFindGroup" << endl;
+
+    for (int i = 0; i < 15; i++)
+    {
+        std::chrono::milliseconds workTime(300);
+        std::this_thread::sleep_for(workTime);
+
+        std::lock_guard < std::mutex > guard(foundGroupMutex);
+
+        if (false == foundGroupResourceList.empty())
+        {
+            cout << "GroupSynchronization::checkFoundGroup : " << "Some group is received."
+                    << endl;
+            return;
+        }
+    }
+
+    cout << "GroupSynchronization::checkFoundGroup : "
+            << "It is failed to find resource within 3s." << endl;
+
+    onFindGroup(NULL);
+    return;
+}
+
+bool GroupSynchronization::IsSameGroup(std::shared_ptr< OCResource > resource)
+{
+    std::lock_guard < std::mutex > guard(foundGroupMutex);
+
+    if (true == foundGroupResourceList.empty())
+    {
+        cout << "GroupSynchronization::IsSameGroup : There is no found group." << endl;
+        return false;
+    }
+
+    std::string foundHostAddress, savedHostAddress;
+    foundHostAddress = resource->host();
+//    foundHostAddress.append (resource->uri());
+
+    for (unsigned int i = 0; i < foundGroupResourceList.size(); ++i)
+    {
+        savedHostAddress = (foundGroupResourceList.at(i))->host();
+//        savedHostAddress.append ((foundGroupResourceList.at(i))->uri());
+//        cout << "GroupSynchronization::IsSameGroup : foundHostAddress - " << foundHostAddress
+//                << ", savedHostAddress - " << savedHostAddress << endl;
+
+        if (0 == foundHostAddress.compare(savedHostAddress.c_str()))
+        {
+            cout << "GroupSynchronization::IsSameGroup : Found! The same group is found."
+                    << endl;
+            return true;
+        }
+    }
+
+    cout << "GroupSynchronization::IsSameGroup :  There is no same group." << endl;
+    return false;
+}
+
+void GroupSynchronization::saveGroup(std::shared_ptr< OCResource > resource)
+{
+    cout << "GroupSynchronization::saveGroup" << endl;
+
+    std::lock_guard < std::mutex > guard(foundGroupMutex);
+
+    foundGroupResourceList.push_back(resource);
+}
+
+void GroupSynchronization::onJoinGroup(const HeaderOptions& headerOptions,
+        const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        cout << "GroupSynchronization::onJoinGroup : " << endl;
+
+        if (remoteCollectionResource)
+        {
+            std::string resourceInterface = DEFAULT_INTERFACE;
+            QueryParamsMap queryParamsMap;
+
+            OCStackResult result = remoteCollectionResource->get("", resourceInterface,
+                    queryParamsMap,
+                    std::bind(&GroupSynchronization::onGetJoinedRemoteChild, this,
+                            std::placeholders::_1, std::placeholders::_2,
+                            std::placeholders::_3));
+            if (OC_STACK_OK == result)
+            {
+                cout << "GroupSynchronization::onJoinGroup : "
+                        << "remoteCollectionResource->get was successful." << endl;
+            }
+            else
+            {
+                cout << "GroupSynchronization::onJoinGroup : "
+                        << "remoteCollectionResource->get was unsuccessful. result - " << result
+                        << endl;
+            }
+        }
+    }
+    else
+    {
+        cout << "GroupSynchronization::onJoinGroup : error - " << eCode << endl;
+    }
+}
+
+void GroupSynchronization::onFindResource(std::shared_ptr< OCResource > resource)
+{
+    cout << "GroupSynchronization::onFindResource" << endl;
+
+    if (resource)
+    {
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////// debugging
+        std::string resourceURI;
+        std::string hostAddress;
+
+        // Get the resource URI
+        resourceURI = resource->uri();
+        cout << "\tURI of the resource: " << resourceURI << endl;
+
+        // Get the resource host address
+        hostAddress = resource->host();
+        cout << "\tHost address of the resource: " << hostAddress << endl;
+
+        hostAddress.append(resourceURI);
+
+        // Get the resource types
+        cout << "\tList of resource types: " << endl;
+
+        for (auto &resourceTypes : resource->getResourceTypes())
+        {
+            cout << "\t\t" << resourceTypes << endl;
+        }
+
+        // Get the resource interfaces
+        cout << "\tList of resource interfaces: " << endl;
+        for (auto &resourceInterfaces : resource->getResourceInterfaces())
+        {
+            cout << "\t\t" << resourceInterfaces << endl;
+        }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+        OCResourceHandle resourceHandle;
+        OCStackResult result = OCPlatform::registerResource(resourceHandle, resource);
+        if (result != OC_STACK_OK)
+        {
+            cout << "GroupSynchronization::"
+                    << "onFindResource - Resource to join creation was unsuccessful. result - "
+                    << result << endl;
+            return;
+        }
+//        cout << "GroupSynchronization::onFindResource : creating resourceHandle. resource type - "
+//                << OCGetResourceTypeName(resourceHandle, 0) << endl;
+
+        result = OCPlatform::bindResource(collectionResourceHandle, resourceHandle);
+        if (result != OC_STACK_OK)
+        {
+            cout << "GroupSynchronization::onFindResource : "
+                    << "To bind resource was unsuccessful. result - " << result << endl;
+            return;
+        }
+        cout << "GroupSynchronization::onFindResource : "
+                << "To bind joinGroupHandle and resourceHandle was successful." << endl;
+
+        auto it = childResourceHandleList.find(collectionResourceHandle);
+        std::vector< OCResourceHandle > childHandleList;
+        if (it != childResourceHandleList.end())
+        {
+            childHandleList = it->second;
+        }
+
+        childHandleList.push_back(resourceHandle);
+        childResourceHandleList[collectionResourceHandle] = childHandleList;
+
+        auto pResponse = std::make_shared< OC::OCResourceResponse >();
+        pResponse->setRequestHandle(resourceRequest->getRequestHandle());
+        pResponse->setResourceHandle(resourceRequest->getResourceHandle());
+        pResponse->setErrorCode(200);
+        pResponse->setResponseResult(OC_EH_OK);
+
+        OCRepresentation rep = resourceRequest->getResourceRepresentation();
+        pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+        if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+        {
+            cout << "GroupSynchronization::onFindResource : sendResponse is successful."
+                    << endl;
+        }
+    }
+    else
+    {
+        cout << "GroupSynchronization::onFindResource : "
+                << "Resource is invalid. So a new Group Resource has to be created." << endl;
+    }
+
+    debugGroupSync();
+}
+
+void GroupSynchronization::onGetJoinedRemoteChild(const HeaderOptions& headerOptions,
+        const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        cout << "GroupSynchronization::onGetJoinedRemoteChild" << endl;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+////////// debugging
+        std::string resourceURI;
+
+        // Get the resource URI
+        resourceURI = rep.getUri();
+        cout << "\tURI of the resource: " << resourceURI << endl;
+
+        // Get the resource types
+        cout << "\tList of resource types: " << endl;
+
+        for (auto &resourceTypes : rep.getResourceTypes())
+        {
+            cout << "\t\t" << resourceTypes << endl;
+        }
+
+        // Get the resource interfaces
+        cout << "\tList of resource interfaces: " << endl;
+        for (auto &resourceInterfaces : rep.getResourceInterfaces())
+        {
+            cout << "\t\t" << resourceInterfaces << endl;
+        }
+
+        std::vector< OCRepresentation > childList = rep.getChildren();
+        OCRepresentation child;
+        for (unsigned int i = 0; i < childList.size(); ++i)
+        {
+            cout << "\n\tchild resource - " << i + 1 << endl;
+
+            child = childList.at(i);
+            resourceURI = child.getUri();
+            cout << "\t\tURI of the resource: " << resourceURI << endl;
+
+            cout << "\t\tList of resource types: " << endl;
+            for (auto &types : child.getResourceTypes())
+            {
+                cout << "\t\t\t" << types << endl;
+            }
+
+            cout << "\tList of resource interfaces: " << endl;
+            for (auto &interfaces : child.getResourceInterfaces())
+            {
+                cout << "\t\t\t" << interfaces << endl;
+            }
+        }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+        // creating remote collection resource handle
+        OCResourceHandle remoteCollectionResourceHandle;
+        resourceURI = remoteCollectionResource->uri();
+        std::vector< std::string > types = remoteCollectionResource->getResourceTypes();
+        std::vector< std::string > interfaces =
+                remoteCollectionResource->getResourceInterfaces();
+
+        OCStackResult result = OCPlatform::registerResource(remoteCollectionResourceHandle,
+                resourceURI, types[0], interfaces[0], NULL, OC_OBSERVABLE);
+        if (result != OC_STACK_OK)
+        {
+            cout << "GroupSynchronization::onGetJoinedRemoteChild - "
+                    << "To register remoteCollectionResourceHandle"
+                    << " was unsuccessful. result - " << result << endl;
+            return;
+        }
+        cout << "GroupSynchronization::onGetJoinedRemoteChild : "
+                "To register remoteCollectionResourceHandle was successful." << endl;
+
+        // binding remote collection resource handle and resource handle to join
+        collectionResourceHandleList[types[0]] = remoteCollectionResourceHandle;
+
+        result = OCPlatform::bindResource(remoteCollectionResourceHandle, deviceResourceHandle);
+        if (OC_STACK_OK == result)
+        {
+            cout << "GroupSynchronization::onGetJoinedRemoteChild : "
+                    << "binding remoteCollectionResourceHandle and deviceResourceHandle"
+                    << endl;
+        }
+        else
+        {
+            cout << "GroupSynchronization::onGetJoinedRemoteChild - "
+                    << "To bind remoteCollectionResourceHandle and deviceResourceHandle "
+                    << "was unsuccessful. result - " << result << endl;
+        }
+
+        std::vector< OCResourceHandle > childHandleList;
+        childHandleList.push_back(deviceResourceHandle);
+        deviceResourceHandleList.push_back(deviceResourceHandle);
+
+        // binding copied remote collection resource handle and copied remote resource
+        OCResourceHandle resourceHandle;
+        for (unsigned int i = 0; i < childList.size(); ++i)
+        {
+            cout << "\tremote resource - " << i + 1 << endl;
+
+            child = childList.at(i);
+            resourceURI = child.getUri();
+            types = child.getResourceTypes();
+            interfaces = child.getResourceInterfaces();
+
+            if (0 == types[0].compare(OCGetResourceTypeName(deviceResourceHandle, 0)))
+            {
+                cout << "GroupSynchronization::onGetJoinedRemoteChild : " << types[0]
+                        << " is bind already." << endl;
+                continue;
+            }
+
+            result = OCPlatform::registerResource(resourceHandle, resourceURI, types[0],
+                    interfaces[0], NULL, OC_OBSERVABLE);
+            if (OC_STACK_OK == result)
+            {
+                result = OCPlatform::bindResource(remoteCollectionResourceHandle,
+                        resourceHandle);
+                if (result != OC_STACK_OK)
+                {
+                    cout << "GroupSynchronization::onGetJoinedRemoteChild - "
+                            << "binding remoteCollectionResourceHandle and resourceHandle "
+                            << "was unsuccessful. result - " << result << endl;
+                    OCPlatform::unregisterResource(resourceHandle);
+                }
+
+                childHandleList.push_back(resourceHandle);
+                cout << "GroupSynchronization::onGetJoinedRemoteChild : "
+                        << "binding remoteCollectionResourceHandle and resourceHandle" << endl;
+            }
+            else
+            {
+                cout << "GroupSynchronization::onGetJoinedRemoteChild - "
+                        << "To register remoteCollectionResourceHandle was unsuccessful."
+                        << " result - " << result << endl;
+            }
+        }
+
+        childResourceHandleList[remoteCollectionResourceHandle] = childHandleList;
+        // this handle list is used to leave group
+    }
+    else
+    {
+        cout << "GroupSynchronization::onGetJoinedRemoteChild : error - " << eCode << endl;
+    }
+
+    debugGroupSync();
+}
+
+void GroupSynchronization::onLeaveGroup(const HeaderOptions& headerOptions,
+        const OCRepresentation& rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK)
+    {
+        cout << "GroupSynchronization::onLeaveGroup" << endl;
+    }
+    else
+    {
+        cout << "GroupSynchronization::onLeaveGroup : error - " << eCode << endl;
+    }
+    debugGroupSync();
+}
+
+void GroupSynchronization::debugGroupSync(void)
+{
+    cout << "GroupSynchronization::debugGroupSync" << endl;
+
+    unsigned int i;
+    std::map< std::string, OCResourceHandle >::iterator handleIt;
+    std::map< OCResourceHandle, std::vector< OCResourceHandle > >::iterator childIt;
+    std::string type;
+    OCResourceHandle resourceHandle;
+    std::vector< OCResourceHandle > handleList;
+    std::shared_ptr< OCResource > resource;
+
+    cout << "Resource Handle Created by App" << endl;
+    for (i = 0; i < deviceResourceHandleList.size(); i++)
+    {
+        resourceHandle = deviceResourceHandleList.at(i);
+
+        cout << i + 1 << ". details" << endl;
+        cout << "  uri - " << OCGetResourceUri(resourceHandle) << endl;
+        cout << "  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
+        cout << "  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
+                << endl << endl;
+    }
+
+    cout << "\nGroup Sync Resource Handle List. The number is "
+            << groupSyncResourceHandleList.size() << endl;
+    i = 1;
+    for (handleIt = groupSyncResourceHandleList.begin();
+            handleIt != groupSyncResourceHandleList.end(); ++handleIt)
+    {
+        type = handleIt->first;
+        cout << "\t" << i << ". group sync resource type - " << type << endl;
+        cout << "\t  details" << endl;
+
+        resourceHandle = handleIt->second;
+        cout << "\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
+        cout << "\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
+        cout << "\t  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
+                << endl << endl;
+        ;
+        i++;
+    }
+
+    cout << "Copied Remote Group Sync Resource List. The number is "
+            << groupSyncResourceList.size() << endl;
+    std::vector< std::string > list;
+    i = 1;
+    for (auto resourceIt = groupSyncResourceList.begin();
+            resourceIt != groupSyncResourceList.end(); ++resourceIt)
+    {
+        type = resourceIt->first;
+        cout << "\t" << i << ". group sync resource type - " << type << endl;
+        cout << "\t details" << endl;
+
+        resource = resourceIt->second;
+        cout << "\t  host - " << resource->host() << endl;
+        cout << "\t  uri - " << resource->uri() << endl;
+        list = resource->getResourceTypes();
+        cout << "\t  resource type - " << list[0] << endl;
+        list = resource->getResourceInterfaces();
+        cout << "\t  resource interface - " << list[0] << endl << endl;
+        i++;
+    }
+
+//    cout << "The number of collection Resource Handle is " << collectionResourceHandleList.size()
+//            << endl;
+//    cout << "The number of child resource handle list is " << childResourceHandleList.size()
+//            << endl;
+
+    cout << "Collection Resource Handle List" << endl;
+    i = 1;
+    for (handleIt = collectionResourceHandleList.begin();
+            handleIt != collectionResourceHandleList.end(); ++handleIt)
+    {
+        type = handleIt->first;
+        cout << "\t" << i << ". collection resource type - " << type << endl;
+        cout << "\t  details" << endl;
+
+        resourceHandle = handleIt->second;
+        cout << "\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
+        cout << "\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
+        cout << "\t  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
+                << endl << endl;
+
+        childIt = childResourceHandleList.find(resourceHandle);
+        if (childIt != childResourceHandleList.end())
+        {
+            handleList = childIt->second;
+            for (unsigned int j = 0; j < handleList.size(); j++)
+            {
+
+                cout << "\t\t" << j + 1 << ". child resource details" << endl;
+
+                resourceHandle = handleList.at(j);
+                cout << "\t\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
+                cout << "\t\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0)
+                        << endl;
+                cout << "\t\t  resource interface - "
+                        << OCGetResourceInterfaceName(resourceHandle, 0) << endl << endl;
+            }
+        }
+
+        i++;
+    }
+}
+}
diff --git a/service/things-manager/sdk/src/GroupSynchronization.h b/service/things-manager/sdk/src/GroupSynchronization.h
new file mode 100644 (file)
index 0000000..da5f153
--- /dev/null
@@ -0,0 +1,138 @@
+//******************************************************************
+//
+// 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   GroupSynchronization.h
+
+/// @brief  This file contains the declaration of classes and
+///its members related to GroupSynchronization.
+
+#ifndef __OC_GROUPSYNCHRONIZATION__
+#define __OC_GROUPSYNCHRONIZATION__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+namespace OIC
+{
+class GroupSynchronization
+{
+private:
+
+    std::map< std::string, OCResourceHandle > collectionResourceHandleList;
+    // collection resource handle list
+    std::map< OCResourceHandle, std::vector< OCResourceHandle > > childResourceHandleList;
+
+    std::map< std::string, OCResourceHandle > groupSyncResourceHandleList;
+    // group sync resource handle list
+    std::map< std::string, std::shared_ptr< OCResource > > groupSyncResourceList;
+    // remote group sync resource list
+
+    std::vector< OCResourceHandle > deviceResourceHandleList; // these cannot be removed.
+    OCResourceHandle deviceResourceHandle;
+
+    OCResourceHandle collectionResourceHandle; // collection handle
+    std::shared_ptr< OCResource > remoteCollectionResource;
+
+    FindCallback findCallback;
+
+    std::vector< std::shared_ptr< OCResource > > foundGroupResourceList;
+
+    std::mutex foundGroupMutex;
+//    std::mutex groupSyncMutex;
+
+    std::shared_ptr< OCResourceRequest > resourceRequest; // this is used for slow response
+
+    static GroupSynchronization* groupSyncnstance;
+
+    GroupSynchronization()
+    {
+        collectionResourceHandleList.clear();
+        childResourceHandleList.clear();
+        groupSyncResourceHandleList.clear();
+        groupSyncResourceList.clear();
+        deviceResourceHandleList.clear();
+
+        deviceResourceHandle = NULL;
+        collectionResourceHandle = NULL;
+        remoteCollectionResource = NULL;
+        findCallback = NULL;
+    }
+    ;
+
+    ~GroupSynchronization()
+    {
+        std::map< std::string, OCResourceHandle >::iterator handleIt;
+        for (handleIt = collectionResourceHandleList.begin();
+                handleIt != collectionResourceHandleList.end(); ++handleIt)
+        {
+            deleteGroup(handleIt->first);
+        }
+    }
+    ;
+
+public:
+
+    static GroupSynchronization* getInstance();
+    void deleteInstance();
+
+    OCStackResult findGroup(std::vector< std::string > collectionResourceTypes,
+            FindCallback callback);
+    OCStackResult createGroup(std::string collectionResourceType);
+    OCStackResult joinGroup(std::string collectionResourceTyps,
+            OCResourceHandle resourceHandle);
+    OCStackResult joinGroup(const std::shared_ptr< OCResource > resource,
+            OCResourceHandle resourceHandle);
+    OCStackResult leaveGroup(std::string collectionResourceType,
+            OCResourceHandle resourceHandle);
+    void deleteGroup(std::string collectionResourceType);
+
+    std::map< std::string, OCResourceHandle > getGroupList();
+
+private:
+
+    OCEntityHandlerResult groupEntityHandler(
+            const std::shared_ptr< OCResourceRequest > request);
+
+    void onFindGroup(std::shared_ptr< OCResource > resource);
+    void onJoinGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode);
+    void onFindResource(std::shared_ptr< OCResource > resource);
+    void onGetJoinedRemoteChild(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode);
+    void onLeaveGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode);
+//    void onSubscribePresence (OCStackResult result,
+//        const unsigned int nonce/*, std::string resourceType, std::string host*/);
+
+    void checkFindGroup(void);
+    bool IsSameGroup(std::shared_ptr< OCResource > resource);
+    void saveGroup(std::shared_ptr< OCResource > resource);
+
+    void debugGroupSync(void);
+
+};
+}
+#endif    // __OC_GROUPSYNCHRONIZATION__
diff --git a/service/things-manager/sdk/src/TGMClient.cpp b/service/things-manager/sdk/src/TGMClient.cpp
deleted file mode 100644 (file)
index 7534a00..0000000
+++ /dev/null
@@ -1,205 +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    TGMClient.cpp
-///  @brief   
-
-#include "TGMClient.h"
-#include <algorithm>
-#include <thread>
-
-using namespace OC;
-
-std::map< std::vector< std::string >, CandidateCallback > candidateRequest;
-std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer;
-std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList;
-std::vector< std::string > allFoundResourceTypes;
-
-template< typename T >
-bool IsSubset(std::vector< T > full, std::vector< T > sub)
-{
-    std::sort(full.begin(), full.end());
-    std::sort(sub.begin(), sub.end());
-    return std::includes(full.begin(), full.end(), sub.begin(), sub.end());
-}
-
-void TGMClient::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec)
-{
-
-    std::string resourceURI;
-    std::string hostAddress;
-    try
-    {
-        // 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;
-
-            hostAddress.append(resourceURI);
-
-            for (auto &resourceTypes : resource->getResourceTypes())
-            {
-                std::cout << "\t\t" << resourceTypes << std::endl;
-
-                if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(),
-                        resourceTypes) == allFoundResourceTypes.end())
-                {
-                    allFoundResourceTypes.push_back(resourceTypes);
-                }
-
-                rtForResourceList[resourceTypes][hostAddress] = 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;
-            }
-
-            if (waitsec == -1)
-            {
-                findPreparedRequest(candidateRequest);
-            }
-        }
-        else
-        {
-            // Resource is invalid
-            std::cout << "Resource is invalid" << std::endl;
-        }
-
-    }
-    catch (std::exception& e)
-    {
-        //log(e.what());
-    }
-}
-
-TGMClient::TGMClient(void)
-{
-    ;
-}
-
-/**
- * Virtual destructor
- */
-TGMClient::~TGMClient(void)
-{
-    candidateRequest.clear();
-    candidateRequestForTimer.clear();
-    rtForResourceList.clear();
-    allFoundResourceTypes.clear();
-}
-
-void TGMClient::findPreparedRequest(
-        std::map< std::vector< std::string >, CandidateCallback > &request)
-{
-    std::vector < std::shared_ptr < OCResource >> resources;
-
-    for (auto it = request.begin(); it != request.end();)
-    {
-
-        if (IsSubset(allFoundResourceTypes, it->first))
-        {
-            //std::cout << "IS SUBSET !!! \n";
-
-            for (unsigned int i = 0; i < it->first.size(); ++i)
-            {
-
-                for (auto secondIt = rtForResourceList[it->first.at(i)].begin();
-                        secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt)
-                {
-                    resources.push_back(secondIt->second);
-                }
-            }
-
-            it->second(resources);
-
-            //TODO : decide policy - callback only once 
-            request.erase(it++);
-        }
-        else
-        {
-            ++it;
-        }
-
-    }
-
-}
-
-void TGMClient::lazyCallback(int second)
-{
-    sleep(second);
-    findPreparedRequest(candidateRequestForTimer);
-
-}
-OCStackResult TGMClient::findCandidateResources(std::vector< std::string > resourceTypes,
-        CandidateCallback callback, int waitsec)
-{
-    if (resourceTypes.size() < 1)
-    {
-        return OC_STACK_ERROR;
-    }
-
-    std::sort(resourceTypes.begin(), resourceTypes.end());
-    resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()),
-            resourceTypes.end());
-
-    if (waitsec != -1)
-    {
-        candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback));
-    }
-    else
-    {
-        candidateRequest.insert(std::make_pair(resourceTypes, callback));
-    }
-
-    for (unsigned int i = 0; i < resourceTypes.size(); ++i)
-    {
-        std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl;
-        std::string query = "coap://224.0.1.187/oc/core?rt=";
-        query.append(resourceTypes.at(i));
-        OCPlatform::findResource("", query.c_str(),
-                std::function < void(std::shared_ptr < OCResource > resource)
-                        > (std::bind(&TGMClient::onFoundResource, this, std::placeholders::_1,
-                                waitsec)));
-    }
-
-    if (waitsec != -1)
-    {
-        std::thread exec(
-                std::function< void(int second) >(
-                        std::bind(&TGMClient::lazyCallback, this, std::placeholders::_1)), waitsec);
-        exec.detach();
-    }
-
-    return OC_STACK_OK;
-}
diff --git a/service/things-manager/sdk/src/ThingsConfiguration.cpp b/service/things-manager/sdk/src/ThingsConfiguration.cpp
new file mode 100644 (file)
index 0000000..a0f57a2
--- /dev/null
@@ -0,0 +1,609 @@
+//******************************************************************
+//
+// 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    ThingsConfiguration.cpp
+/// @brief
+
+#include <OCApi.h>
+#include <OCPlatform.h>
+#include <cstdlib>
+#include <algorithm>
+#include "ThingsConfiguration.h"
+
+using namespace OC;
+
+namespace OIC
+{
+    const int SUCCESS_RESPONSE = 0;
+    int cnt = 0;
+
+    std::map< std::string, ConfigurationRequestEntry > configurationRequestTable;
+
+    ThingsConfiguration* ThingsConfiguration::thingsConfigurationInstance = NULL;
+
+    ConfigurationCallback g_bootstrapCallback;
+
+    ThingsConfiguration* ThingsConfiguration::getInstance()
+    {
+        if (thingsConfigurationInstance == NULL)
+        {
+            thingsConfigurationInstance = new ThingsConfiguration();
+        }
+        return thingsConfigurationInstance;
+    }
+
+    void ThingsConfiguration::deleteInstance()
+    {
+        if (thingsConfigurationInstance)
+        {
+            delete thingsConfigurationInstance;
+            thingsConfigurationInstance = NULL;
+        }
+    }
+
+    std::string ThingsConfiguration::getAttributeByConfigurationName(ConfigurationName name)
+    {
+        for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++)
+        {
+            if ((*it).m_name == name)
+                return (*it).m_attribute;
+        }
+
+        return "";
+    }
+
+    std::string ThingsConfiguration::getUriByConfigurationName(ConfigurationName name)
+    {
+        for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++)
+        {
+            if ((*it).m_name == name)
+                return (*it).m_uri;
+        }
+
+        return "";
+    }
+
+    std::string ThingsConfiguration::getUpdateVal(std::string conf)
+    {
+        std::map< std::string, ConfigurationRequestEntry >::iterator it =
+                configurationRequestTable.find(conf);
+
+        if (it == configurationRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_updateVal;
+
+    }
+    std::shared_ptr< OCResource > ThingsConfiguration::getResource(std::string conf)
+    {
+        std::map< std::string, ConfigurationRequestEntry >::iterator it =
+                configurationRequestTable.find(conf);
+
+        if (it == configurationRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_resource;
+    }
+
+    ConfigurationCallback ThingsConfiguration::getCallback(std::string conf)
+    {
+        std::map< std::string, ConfigurationRequestEntry >::iterator it =
+                configurationRequestTable.find(conf);
+
+        if (it == configurationRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_callback;
+    }
+
+    std::string ThingsConfiguration::getListOfSupportedConfigurationUnits()
+    {
+        std::string res;
+
+        res = "{\"Configuration Units\":[";
+
+        auto it = ConfigurationUnitTable.begin();
+        while (1)
+        {
+            res = res + (*it).getJSON();
+            it++;
+
+            if (it == ConfigurationUnitTable.end())
+                break;
+            else
+                res += ",";
+        }
+
+        res += "]}";
+
+        return res;
+    }
+
+    std::string ThingsConfiguration::getHostFromURI(std::string oldUri)
+    {
+        size_t f;
+        std::string newUri;
+
+        if ((f = oldUri.find("/factoryset/oic/")) != string::npos)
+            newUri = oldUri.replace(f, oldUri.size(), "");
+        else if ((f = oldUri.find("/oic/")) != string::npos)
+            newUri = oldUri.replace(f, oldUri.size(), "");
+
+        return newUri;
+    }
+
+    void ThingsConfiguration::onDeleteActionSet(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string conf)
+    {
+        std::shared_ptr < OCResource > resource = getResource(conf);
+
+        std::cout << __func__ << std::endl;
+
+        if (resource)
+        {
+            QueryParamsMap query;
+
+            // After deletion of the left action set, find target child resource's URIs by sending
+            // GET message. Note that, this resource is surely a collection resource which has child
+            // resources.
+            resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsConfiguration::onGetChildInfoForUpdate, this,
+                                    std::placeholders::_1, std::placeholders::_2,
+                                    std::placeholders::_3, conf)));
+
+        }
+
+    }
+
+    void ThingsConfiguration::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "GET request was successful" << std::endl;
+
+            std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+            std::vector < OCRepresentation > children = rep.getChildren();
+            for (auto oit = children.begin(); oit != children.end(); ++oit)
+            {
+                std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+            }
+
+            // Get information by using configuration name(conf)
+            std::shared_ptr < OCResource > resource = getResource(conf);
+            std::string actionstring = conf;
+            std::string uri = getUriByConfigurationName(conf);
+            std::string attr = getAttributeByConfigurationName(conf);
+
+            if (uri == "")
+                return;
+
+            if (resource)
+            {
+                // In this nest, we create a new action set of which name is the configuration name.
+                // Required information consists of a host address, URI, attribute key, and
+                // attribute value.
+                ActionSet *newActionSet = new ActionSet();
+                newActionSet->actionsetName = conf;
+
+                for (auto oit = children.begin(); oit != children.end(); ++oit)
+                {
+                    Action *newAction = new Action();
+
+                    // oit->getUri() includes a host address as well as URI.
+                    // We should split these to each other and only use the host address to create
+                    // a child resource's URI. Note that the collection resource and its child
+                    // resource are located in same host.
+                    newAction->target = getHostFromURI(oit->getUri()) + uri;
+
+                    Capability *newCapability = new Capability();
+                    newCapability->capability = attr;
+                    newCapability->status = getUpdateVal(conf);
+
+                    newAction->listOfCapability.push_back(newCapability);
+                    newActionSet->listOfAction.push_back(newAction);
+                }
+
+                // Request to create a new action set by using the above actionSet
+                g_groupmanager->addActionSet(resource, newActionSet,
+                        std::function<
+                                void(const HeaderOptions& headerOptions,
+                                        const OCRepresentation& rep, const int eCode) >(
+                                std::bind(&ThingsConfiguration::onCreateActionSet, this,
+                                        std::placeholders::_1, std::placeholders::_2,
+                                        std::placeholders::_3, conf)));
+
+                free(newActionSet);
+            }
+
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsConfiguration::onGetChildInfoForGet(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "GET request was successful" << std::endl;
+            std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+            std::shared_ptr< OCResource > resource, tempResource;
+            std::vector < std::shared_ptr< OCResource > > p_resources;
+            std::vector < std::string > m_if;
+            std::string uri = getUriByConfigurationName(conf);
+
+            if (uri == "")
+                return;
+
+            if (uri == "/oic/con" || uri == "/factoryset" || uri == "/factoryset/oic/con")
+                m_if.push_back(BATCH_INTERFACE);
+            else
+                m_if.push_back(DEFAULT_INTERFACE);
+
+            std::vector < OCRepresentation > children = rep.getChildren();
+            for (auto oit = children.begin(); oit != children.end(); ++oit)
+            {
+                std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+
+                // Using a host address and child URIs, we can dynamically create resource objects.
+                // Note that the child resources have not found before, we have no resource objects.
+                // For this reason, we create the resource objects.
+
+                std::string host = getHostFromURI(oit->getUri());
+                tempResource = OCPlatform::constructResourceObject(host, uri, true,
+                        oit->getResourceTypes(), m_if);
+
+                p_resources.push_back(tempResource);
+            }
+
+            // Send GET messages to the child resources in turn.
+            for (unsigned int i = 0; i < p_resources.size(); ++i)
+            {
+                resource = p_resources.at(i);
+                if (resource)
+                {
+                    try
+                    {
+                        if (isSimpleResource(resource))
+                        {
+                            QueryParamsMap test;
+                            resource->get(test, getCallback(conf));
+                        }
+                        else
+                        {
+                            QueryParamsMap test;
+                            resource->get(resource->getResourceTypes().at(0), BATCH_INTERFACE, test,
+                                    getCallback(conf));
+                        }
+                    }
+                    catch (OCException& e)
+                    {
+                        std::cout << e.reason() << std::endl;
+                    }
+
+                }
+            }
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsConfiguration::onCreateActionSet(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            std::shared_ptr < OCResource > resource = getResource(conf);
+            if (resource)
+            {
+                // Now, it is time to execute the action set.
+                g_groupmanager->executeActionSet(resource, conf,
+                        std::function<
+                                void(const HeaderOptions& headerOptions,
+                                        const OCRepresentation& rep, const int eCode) >(
+                                std::bind(&ThingsConfiguration::onExecuteForGroupAction, this,
+                                        std::placeholders::_1, std::placeholders::_2,
+                                        std::placeholders::_3, conf)));
+            }
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsConfiguration::onExecuteForGroupAction(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            getCallback(conf)(headerOptions, rep, eCode);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    bool ThingsConfiguration::isSimpleResource(std::shared_ptr< OCResource > resource)
+    {
+
+        for (unsigned int i = 0; i < resource->getResourceTypes().size(); ++i)
+        {
+            if (resource->getResourceTypes().at(i).find(".resourceset", 0) != std::string::npos)
+                return false;
+        }
+
+        return true;
+    }
+
+    bool ThingsConfiguration::hasBatchInterface(std::shared_ptr< OCResource > resource)
+    {
+        for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i)
+        {
+            if (resource->getResourceInterfaces().at(i) == BATCH_INTERFACE)
+                return true;
+        }
+
+        return false;
+    }
+
+    void ThingsConfiguration::onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "Get request was successful" << std::endl;
+
+            getCallback(conf)(headerOptions, rep, eCode);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsConfiguration::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode, std::string conf)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            // Callback
+            getCallback(conf)(headerOptions, rep, eCode);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    OCStackResult ThingsConfiguration::updateConfigurations(std::shared_ptr< OCResource > resource,
+            std::map< ConfigurationName, ConfigurationValue > configurations,
+            ConfigurationCallback callback)
+    {
+        // For M2, # of configurations is 1
+        // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...)
+        if (configurations.size() == 0)
+        {
+            std::cout << "# of request configuration is 0" << std::endl;
+            return OC_STACK_ERROR;
+        }
+
+        if (!resource)
+        {
+            std::cout << "resource is NULL\n";
+            return OC_STACK_ERROR;
+        }
+
+        std::map< ConfigurationName, ConfigurationValue >::iterator it = configurations.begin();
+        std::string conf = it->first; // configuration name
+        std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case
+
+        // Check the request queue if a previous request is still left. If so, remove it.
+        std::map< std::string, ConfigurationRequestEntry >::iterator iter =
+                configurationRequestTable.find(conf);
+        if (iter != configurationRequestTable.end())
+            configurationRequestTable.erase(iter);
+
+        // Create new request entry stored in the queue
+        ConfigurationRequestEntry newCallback(conf, callback, resource, it->second);
+        configurationRequestTable.insert(std::make_pair(conf, newCallback));
+
+        OCRepresentation rep;
+        QueryParamsMap query;
+        if (isSimpleResource(resource))
+        {
+            // This resource does not need to use a group manager. Just send a PUT message
+            rep.setValue(getAttributeByConfigurationName(conf), getUpdateVal(conf));
+            return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3, conf)));
+        }
+        else
+        {
+            // This resource is a collection resource which uses group manager functionalities.
+            // First, delete an existing action set of which name is same as a current action set
+            // name. As of now, the name is determined by "Configuration Name" which a user just
+            // specifies.
+            return g_groupmanager->deleteActionSet(resource, conf,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsConfiguration::onDeleteActionSet, this,
+                                    std::placeholders::_1, std::placeholders::_2,
+                                    std::placeholders::_3, conf)));
+        }
+    }
+
+    OCStackResult ThingsConfiguration::getConfigurations(std::shared_ptr< OCResource > resource,
+            std::vector< ConfigurationName > configurations, ConfigurationCallback callback)
+    {
+        // For M2, # of configurations is 1
+        // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...)
+        if (configurations.size() == 0)
+        {
+            std::cout << "# of request configuration is 0" << std::endl;
+            return OC_STACK_ERROR;
+        }
+        if (!resource)
+        {
+            std::cout << "resource is NULL\n";
+            return OC_STACK_ERROR;
+        }
+
+        std::vector< ConfigurationName >::iterator it = configurations.begin();
+        std::string conf = (*it); // configuration name
+        std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case
+
+        // Check the request queue if a previous request is still left. If so, remove it.
+        std::map< std::string, ConfigurationRequestEntry >::iterator iter =
+                configurationRequestTable.find(conf);
+        if (iter != configurationRequestTable.end())
+            configurationRequestTable.erase(iter);
+
+        // Create new request entry stored in the queue
+        ConfigurationRequestEntry newCallback(conf, callback, resource, conf);
+        configurationRequestTable.insert(std::make_pair(conf, newCallback));
+
+        QueryParamsMap query;
+        OCRepresentation rep;
+
+        if (isSimpleResource(resource))
+        {
+            // This resource is a simple resource. Just send a PUT message
+            std::string m_if = DEFAULT_INTERFACE;
+
+            if (hasBatchInterface(resource))
+                m_if = BATCH_INTERFACE;
+
+            return resource->get(resource->getResourceTypes().at(0), m_if, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3, conf)));
+        }
+        else
+        {
+            // This resource is a collection resource. On the contrary of a update, it does not use
+            // group manager functionality. It just acquires child resource's URI and send GET
+            // massages to the child resources in turn.
+            // First, request the child resources's URI.
+            return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsConfiguration::onGetChildInfoForGet, this,
+                                    std::placeholders::_1, std::placeholders::_2,
+                                    std::placeholders::_3, conf)));
+        }
+
+    }
+
+// callback handler on GET request
+    void ThingsConfiguration::onGetBootstrapInformation(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            g_bootstrapCallback(headerOptions, rep, eCode);
+        }
+
+        else
+        {
+            std::cout << "onGET Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsConfiguration::onFoundBootstrapServer(
+            std::vector< std::shared_ptr< OCResource > > resources)
+    {
+        std::string resourceURI;
+        std::string hostAddress;
+
+        try
+        {
+            // Do some operations with resource object.
+            for (unsigned int i = 0; i < resources.size(); ++i)
+            {
+                std::shared_ptr < OCResource > resource = resources.at(i);
+
+                if (resource)
+                { // Request configuration resources
+
+                    std::cout << "Getting bootstrap server representation on: " << DEFAULT_INTERFACE
+                            << std::endl;
+
+                    resource->get("bootstrap", DEFAULT_INTERFACE, QueryParamsMap(),
+                            &onGetBootstrapInformation);
+
+                }
+                else
+                {
+                    // Resource is invalid
+                    std::cout << "Resource is invalid" << std::endl;
+                }
+            }
+
+        }
+        catch (std::exception& e)
+        {
+            //log(e.what());
+        }
+    }
+
+    OCStackResult ThingsConfiguration::doBootstrap(ConfigurationCallback callback)
+    {
+        g_bootstrapCallback = callback;
+
+        // Find bootstrap server.
+        std::vector < std::string > type;
+        type.push_back("bootstrap");
+
+        std::cout << "Finding Bootstrap Server resource... " << std::endl;
+        return g_groupmanager->findCandidateResources(type, &onFoundBootstrapServer);
+    }
+}
diff --git a/service/things-manager/sdk/src/ThingsConfiguration.h b/service/things-manager/sdk/src/ThingsConfiguration.h
new file mode 100644 (file)
index 0000000..79e2579
--- /dev/null
@@ -0,0 +1,546 @@
+//******************************************************************
+//
+// 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   ThingsConfiguration.h
+
+/// @brief  This file contains the declaration of classes and its members related to
+///         ThingsConfiguration.
+
+#ifndef __OC_THINGSCONFIGURATION__
+#define __OC_THINGSCONFIGURATION__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "GroupManager.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+namespace OIC
+{
+/// Declearation of Configuation Callback funtion type
+    typedef std::function<
+            void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+            > ConfigurationCallback;
+
+    typedef std::string ConfigurationName;
+    typedef std::string ConfigurationValue;
+
+    /**
+     * @brief
+     * The following class is used as a item stacking in request queue. The class stores a request
+     * and referential information (e.g., a configuration name, a target resource object, a callback
+     * function passed from the applications, and a update value). When the function for updating/
+     * getting configuration value is called from applications, this class instance is created and
+     * stored in the request queue. The queue is maintained in a std::map structure so if desiring
+     * to find a specific request, you can find it by querying a configuration name.
+     */
+    class ConfigurationRequestEntry
+    {
+    public:
+        ConfigurationRequestEntry(std::string ID, ConfigurationCallback callback,
+                std::shared_ptr< OCResource > resource, std::string updateVal):
+                m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal)
+        {
+        }
+        ;
+
+        // Configuration Name (used in key value in std::map structure)
+        // e.g., time, network, security, and so on
+        std::string m_ID;
+        // Reference callback pointer
+        ConfigurationCallback m_callback;
+        // Reference resource object
+        std::shared_ptr< OCResource > m_resource;
+        // Update value only used for configuration update
+        std::string m_updateVal;
+    };
+
+    /**
+     * @brief
+     * The following class is used to store providing configuration name and its relevant
+     * information. The relevant information includes a brief description, uri, and attribute key.
+     * Note that a developer only specifies a configuration name, not URI nor attribute key, to
+     * update/get a value to a remote. Thus, using configuration name, we convert it to more
+     * specific information (i.e. uri and attribute key) to send a request. This class is reponsible
+     * to storing these information.
+     */
+    class ConfigurationUnitInfo
+    {
+    public:
+
+        std::string m_name;
+        std::string m_description;
+        std::string m_uri;
+        std::string m_attribute;
+
+        ConfigurationUnitInfo(std::string name, std::string description, std::string uri,
+                std::string attribute) :
+                m_name(name), m_description(description), m_uri(uri), m_attribute(attribute)
+        {
+        }
+        ;
+
+        // If a developer wants to know a list of configuration names, gives it in JSON format.
+        std::string getJSON()
+        {
+            std::string res;
+
+            res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}";
+
+            return res;
+        }
+    };
+
+#define NUMCONFUNIT 6
+    typedef std::string ConfigurationName;
+    typedef std::string ConfigurationValue;
+
+    class ThingsConfiguration
+    {
+    public:
+        /**
+         * Constructor for ThingsConfiguration. Constructs a new ThingsConfiguration
+         */
+        ThingsConfiguration(void)
+        {
+            ConfigurationUnitInfo unit[] =
+            {
+            { "configuration", "Configuration Collection's value and its child resource's value",
+                    "/oic/con", "value" },
+            { "region", "the current region in which the device is located geographically",
+                    "/oic/con/0/region", "value" },
+            { "timelink", "link of time collection.", "/oic/con/0/time", "link" },
+            { "ipaddress", "IP Address", "/oic/con/network/0/IPAddress", "value" },
+            { "securitymode",
+                    "Resource for security information (credentials, access control list etc.)",
+                    "/oic/con/security/0/mode", "value" },
+                    { "getfactoryset", "get all default configuration value", "/factoryset/oic/con",
+                            "value" } };
+
+            for (int i = 0; i < NUMCONFUNIT; i++)
+                ConfigurationUnitTable.push_back(unit[i]);
+        }
+        ;
+
+        /**
+         * Virtual destructor
+         */
+        ~ThingsConfiguration(void)
+        {
+        }
+        ;
+
+        static ThingsConfiguration *thingsConfigurationInstance;
+        static ThingsConfiguration* getInstance();
+        void deleteInstance();
+
+        void setGroupManager(GroupManager *groupmanager)
+        {
+            g_groupmanager = groupmanager;
+        }
+        ;
+
+        /**
+         * API for updating configuration value of multiple things of a target group or a single
+         * thing.
+         * Callback is called when a response arrives.
+         * Before using the below function, a developer should acquire a resource pointer of
+         * (collection) resource that he want to send a request by calling findResource() function
+         * provided in OCPlatform. And he should also notice a "Configuration Name" term which
+         * represents a nickname of a target attribute of a resource that he wants to update.
+         * The base motivation to introduce the term is to avoid a usage of URI to access a resource
+         * from a developer. Thus, a developer should know which configuration names are supported
+         * by Things Configuration class and what the configuration name means.
+         * To get a list of supported configuration names, use getListOfSupportedConfigurationUnits(
+         * ) function, which provides the list in JSON format.
+         * NOTICE: A series of callback functions is called from updateConfigurations() function:
+         * (1) For a collection resource
+         * updateConfiguration()->onDeleteActionSet()->onGetChildInfoForUpdate()->onCreateActionSet(
+         * )->...(CoAP msg. is transmitted)->OnExecuteForGroupAction()->callback function in APP.
+         * (2) For a simple resource
+         * updateConfiguration()->...(CoAP msg. is transmitted)->OnPut()->callback function in APP.
+         *
+         * @param resource - resource pointer representing the target group or the single thing.
+         * @param configurations - ConfigurationUnit: a nickname of attribute of target resource
+         *                         (e.g., installedlocation, currency, (IP)address)
+         *                         Value : a value to be updated
+         * @param callback - callback.
+         *
+         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource,
+                std::map< ConfigurationName, ConfigurationValue > configurations,
+                ConfigurationCallback callback);
+
+        /**
+         * API for getting configuration value of multiple things of a target group or a single
+         * thing.
+         * Callback is called when a response arrives.
+         * NOTICE: A series of callback functions is called from getConfigurations() function:
+         * (1) For a collection resource
+         * getConfigurations()->onGetChildInfoForGet()->...(CoAP msg. is transmitted)
+         * ->callback function in APP.
+         * (2) For a simple resource
+         * getConfigurations()->...(CoAP msg. is transmitted)->onGet()->callback function in APP.
+         *
+         * @param resource - resource pointer representing the target group or the single thing.
+         * @param configurations - ConfigurationUnit: a nickname of attribute of target resource.
+         * @param callback - callback.
+         *
+         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult getConfigurations(std::shared_ptr< OCResource > resource,
+                std::vector< ConfigurationName > configurations, ConfigurationCallback callback);
+
+        /**
+         * API to show a list of supported configuration units (configurable parameters)
+         * Callback call when a response arrives.
+         *
+         * @return the list in JSON format
+         */
+        std::string getListOfSupportedConfigurationUnits();
+
+        /**
+         * API for bootstrapping functionality. Find a bootstrap server and get configuration
+         * information from the bootstrap server. With the information, make a configuration
+         * resource.
+         *
+         * @param callback - callback.
+         *
+         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult doBootstrap(ConfigurationCallback callback);
+
+    private:
+
+        GroupManager *g_groupmanager;
+
+        std::vector< ConfigurationUnitInfo > ConfigurationUnitTable;
+
+        void onExecuteForGroupAction(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+        void onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+        void onGetChildInfoForGet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                const int eCode, std::string conf);
+        void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                const int eCode, std::string conf);
+        void onGetActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                const int eCode, std::string conf);
+        void onDeleteActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                const int eCode, std::string conf);
+        void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+                std::string conf);
+        void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+                std::string conf);
+        static void onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource > > resources);
+        static void onGetBootstrapInformation(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode);
+        // Copyright 2014 Samsung Electronics All Rights Reserved.
+
+        /// @file   ThingsConfiguration.h
+
+        /// @brief  This file contains the declaration of classes and its members related to
+        ///         ThingsConfiguration.
+
+#ifndef __OC_THINGSCONFIGURATION__
+#define __OC_THINGSCONFIGURATION__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "GroupManager.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+        using namespace OC;
+
+/// Declearation of Configuation Callback funtion type
+        typedef std::function<
+        void(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode) > ConfigurationCallback;
+
+        typedef std::string ConfigurationName;
+        typedef std::string ConfigurationValue;
+
+        /**
+         * @brief
+         * The following class is used as a item stacking in request queue. The class stores a
+         * request and referential information (e.g., a configuration name, a target resource
+         * object, a callback function passed from the applications, and a update value). When the
+         * function for updating/getting configuration value is called from applications, this class
+         * instance is created and stored in the request queue. The queue is maintained in
+         * a std::map structure so if desiring to find a specific request, you can find it
+         * by querying a configuration name.
+         */
+        class ConfigurationRequestEntry
+        {
+        public:
+            ConfigurationRequestEntry(std::string ID, ConfigurationCallback callback,
+                    std::shared_ptr< OCResource > resource, std::string updateVal) :
+            m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal)
+            {
+            }
+            ;
+
+            // Configuration Name (used in key value in std::map structure)
+            // e.g., time, network, security, and so on
+            std::string m_ID;
+            // Reference callback pointer
+            ConfigurationCallback m_callback;
+            // Reference resource object
+            std::shared_ptr< OCResource > m_resource;
+            // Update value only used for configuration update
+            std::string m_updateVal;
+        };
+
+        /**
+         * @brief
+         * The following class is used to store providing configuration name and its relevant
+         * information. The relevant information includes a brief description, uri, and attribute
+         * key. Note that a developer only specifies a configuration name, not URI nor attribute
+         * key, to update/get a value to a remote. Thus, using configuration name, we convert it to
+         * more specific information (i.e. uri and attribute key) to send a request. This class is
+         * reponsible to storing these information.
+         */
+        class ConfigurationUnitInfo
+        {
+        public:
+
+            std::string m_name;
+            std::string m_description;
+            std::string m_uri;
+            std::string m_attribute;
+
+            ConfigurationUnitInfo(std::string name, std::string description, std::string uri,
+                    std::string attribute) :
+            m_name(name), m_description(description), m_uri(uri), m_attribute(attribute)
+            {
+            }
+            ;
+
+            // If a developer wants to know a list of configuration names, gives it in JSON format.
+            std::string getJSON()
+            {
+                std::string res;
+
+                res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}";
+
+                return res;
+            }
+        };
+
+#define NUMCONFUNIT 6
+        typedef std::string ConfigurationName;
+        typedef std::string ConfigurationValue;
+
+        class ThingsConfiguration
+        {
+        public:
+            /**
+             * Constructor for ThingsConfiguration. Constructs a new ThingsConfiguration
+             */
+            ThingsConfiguration(void)
+            {
+                ConfigurationUnitInfo unit[] =
+                {
+                    {   "configuration", "Configuration value and its child resource's value",
+                            "/oic/con", "value"},
+                    {   "region", "the current region in which the Thing is located geographically",
+                        "/oic/con/0/region", "value"},
+                    {   "timelink", "link of time collection.", "/oic/con/0/time", "link"},
+                    {   "ipaddress", "IP Address", "/oic/con/network/0/IPAddress", "value"},
+                    {   "securitymode",
+                        "Resource for security information (credentials, access control list etc.)",
+                        "/oic/con/security/0/mode", "value"},
+                    {   "getfactoryset", "get all default configuration value",
+                        "/factoryset/oic/con", "value"}};
+
+                for (int i = 0; i < NUMCONFUNIT; i++)
+                ConfigurationUnitTable.push_back(unit[i]);
+            }
+            ;
+
+            /**
+             * Virtual destructor
+             */
+            ~ThingsConfiguration(void)
+            {
+            }
+            ;
+
+            static ThingsConfiguration *thingsConfigurationInstance;
+            static ThingsConfiguration* getInstance();
+            void deleteInstance();
+
+            void setGroupManager(GroupManager *groupmanager)
+            {
+                g_groupmanager = groupmanager;
+            }
+            ;
+
+            /**
+             * API for updating configuration value of multiple things of a target group or a single
+             * thing.
+             * Callback is called when a response arrives.
+             * Before using the below function, a developer should acquire a resource pointer of
+             * (collection) resource that he want to send a request by calling findResource()
+             * function provided in OCPlatform. And he should also notice a "Configuration Name"
+             * term which represents a nickname of a target attribute of a resource that he wants to
+             * update.
+             * The base motivation to introduce the term is to avoid a usage of URI to access
+             * a resource from a developer. Thus, a developer should know which configuration names
+             * are supported by Things Configuration class and what the configuration name means.
+             * To get a list of supported configuration names, use getListOfSupportedConfigurationU-
+             * nits() function, which provides the list in JSON format.
+             * NOTICE: A series of callback functions is called from updateConfigurations() function
+             * (1) For a collection resource
+             * updateConfiguration()->onDeleteActionSet()->onGetChildInfoForUpdate()->onCreateActio-
+             * nSet()->...(CoAP msg. is transmitted)->OnExecuteForGroupAction()->callback function
+             * in APP.
+             * (2) For a simple resource
+             * updateConfiguration()->...(CoAP msg. is transmitted)->OnPut()->callback function in
+             * APP.
+             *
+             * @param resource - resource pointer representing the target group or the single thing.
+             * @param configurations - ConfigurationUnit: a nickname of attribute of target resource
+             *                         (e.g., installedlocation, currency, (IP)address)
+             *                         Value : a value to be updated
+             * @param callback - callback.
+             *
+             * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+             *
+             * NOTE: OCStackResult is defined in ocstack.h.
+             */
+            OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource,
+                    std::map< ConfigurationName, ConfigurationValue > configurations,
+                    ConfigurationCallback callback);
+
+            /**
+             * API for getting configuration value of multiple things of a target group or a single
+             * thing.
+             * Callback is called when a response arrives.
+             * NOTICE: A series of callback functions is called from getConfigurations() function:
+             * (1) For a collection resource
+             * getConfigurations()->onGetChildInfoForGet()->...(CoAP msg. is transmitted)
+             * ->callback function in APP.
+             * (2) For a simple resource
+             * getConfigurations()->...(CoAP msg. is transmitted)->onGet()->callback function in APP
+             *
+             * @param resource - resource pointer representing the target group or the single thing.
+             * @param configurations - ConfigurationUnit: a nickname of attribute of target resource
+             * @param callback - callback.
+             *
+             * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+             *
+             * NOTE: OCStackResult is defined in ocstack.h.
+             */
+            OCStackResult getConfigurations(std::shared_ptr< OCResource > resource,
+                    std::vector< ConfigurationName > configurations, ConfigurationCallback callback);
+
+            /**
+             * API to show a list of supported configuration units (configurable parameters)
+             * Callback call when a response arrives.
+             *
+             * @return the list in JSON format
+             */
+            std::string getListOfSupportedConfigurationUnits();
+
+            /**
+             * API for bootstrapping functionality. Find a bootstrap server and get configuration
+             * information from the bootstrap server. With the information, make a configuration
+             * resource.
+             *
+             * @param callback - callback.
+             *
+             * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+             *
+             * NOTE: OCStackResult is defined in ocstack.h.
+             */
+            OCStackResult doBootstrap(ConfigurationCallback callback);
+
+        private:
+
+            GroupManager *g_groupmanager;
+
+            std::vector< ConfigurationUnitInfo > ConfigurationUnitTable;
+
+            void onExecuteForGroupAction(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onGetChildInfoForGet(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onCreateActionSet(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onGetActionSet(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onDeleteActionSet(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onGet(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            void onPut(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+            static void onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource >
+                > resources);
+            static void onGetBootstrapInformation(const HeaderOptions& headerOptions,
+                    const OCRepresentation& rep, const int eCode);
+
+            std::shared_ptr< OCResource > getResource(std::string conf);
+            ConfigurationCallback getCallback(std::string conf);
+            std::string getUpdateVal(std::string conf);
+            std::string getAttributeByConfigurationName(ConfigurationName name);
+            std::string getUriByConfigurationName(ConfigurationName name);
+
+            std::string getHostFromURI(std::string oldUri);
+
+            bool isSimpleResource(std::shared_ptr< OCResource > resource);
+            bool hasBatchInterface(std::shared_ptr< OCResource > resource);
+
+        };
+
+#endif  /* __OC_THINGSCONFIGURATION__*/
+
+        std::shared_ptr< OCResource > getResource(std::string conf);
+        ConfigurationCallback getCallback(std::string conf);
+        std::string getUpdateVal(std::string conf);
+        std::string getAttributeByConfigurationName(ConfigurationName name);
+        std::string getUriByConfigurationName(ConfigurationName name);
+
+        std::string getHostFromURI(std::string oldUri);
+
+        bool isSimpleResource(std::shared_ptr< OCResource > resource);
+        bool hasBatchInterface(std::shared_ptr< OCResource > resource);
+
+    };
+}
+#endif  /* __OC_THINGSCONFIGURATION__*/
+
diff --git a/service/things-manager/sdk/src/ThingsDiagnostics.cpp b/service/things-manager/sdk/src/ThingsDiagnostics.cpp
new file mode 100644 (file)
index 0000000..7eccc62
--- /dev/null
@@ -0,0 +1,395 @@
+//******************************************************************
+//
+// 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    ThingsDiagnostics.cpp
+///  @brief
+
+#include <OCApi.h>
+#include <OCPlatform.h>
+#include <cstdlib>
+
+#include "ThingsDiagnostics.h"
+
+using namespace OC;
+
+namespace OIC
+{
+    const int SUCCESS_RESPONSE = 0;
+
+    std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable;
+
+    ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL;
+
+    ThingsDiagnostics* ThingsDiagnostics::getInstance()
+    {
+        if (thingsDiagnosticsInstance == NULL)
+        {
+            thingsDiagnosticsInstance = new ThingsDiagnostics();
+        }
+        return thingsDiagnosticsInstance;
+    }
+
+    void ThingsDiagnostics::deleteInstance()
+    {
+        if (thingsDiagnosticsInstance)
+        {
+            delete thingsDiagnosticsInstance;
+            thingsDiagnosticsInstance = NULL;
+        }
+    }
+
+    std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name)
+    {
+        for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
+        {
+            if ((*it).m_name == name)
+                return (*it).m_attribute;
+        }
+
+        return "";
+    }
+
+    std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name)
+    {
+        for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++)
+        {
+            if ((*it).m_name == name)
+                return (*it).m_uri;
+        }
+
+        return "";
+    }
+
+    std::string ThingsDiagnostics::getUpdateVal(std::string diag)
+    {
+        std::map< std::string, DiagnosticsRequestEntry >::iterator it =
+                diagnosticsRequestTable.find(diag);
+
+        if (it == diagnosticsRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_updateVal;
+
+    }
+    std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag)
+    {
+        std::map< std::string, DiagnosticsRequestEntry >::iterator it =
+                diagnosticsRequestTable.find(diag);
+
+        if (it == diagnosticsRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_resource;
+    }
+
+    DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag)
+    {
+        std::map< std::string, DiagnosticsRequestEntry >::iterator it =
+                diagnosticsRequestTable.find(diag);
+
+        if (it == diagnosticsRequestTable.end())
+            return NULL;
+        else
+            return it->second.m_callback;
+    }
+
+    std::string ThingsDiagnostics::getHostFromURI(std::string oldUri)
+    {
+        size_t f;
+        std::string newUri;
+
+        if ((f = oldUri.find("/factoryset/oic/")) != string::npos)
+            newUri = oldUri.replace(f, oldUri.size(), "");
+        else if ((f = oldUri.find("/oic/")) != string::npos)
+            newUri = oldUri.replace(f, oldUri.size(), "");
+
+        return newUri;
+    }
+
+    std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits()
+    {
+        std::string res;
+
+        res = "{\"Diagnostics Units\":[";
+
+        auto it = DiagnosticsUnitTable.begin();
+        while (1)
+        {
+            res = res + (*it).getJSON();
+            it++;
+
+            if (it == DiagnosticsUnitTable.end())
+                break;
+            else
+                res += ",";
+        }
+
+        res += "]}";
+
+        return res;
+    }
+
+    void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string diag)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "GET request was successful" << std::endl;
+
+            std::cout << "\tResource URI: " << rep.getUri() << std::endl;
+
+            std::vector < OCRepresentation > children = rep.getChildren();
+            for (auto oit = children.begin(); oit != children.end(); ++oit)
+            {
+                std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
+            }
+
+            // Get information by using diagnostics name(diag)
+            std::shared_ptr < OCResource > resource = getResource(diag);
+            std::string actionstring = diag;
+            std::string uri = getUriByDiagnosticsName(diag);
+            std::string attr = getAttributeByDiagnosticsName(diag);
+
+            if (uri == "")
+                return;
+
+            if (resource)
+            {
+                // In this nest, we create a new action set of which name is the dignostics name.
+                // Required information consists of a host address, URI, attribute key, and
+                // attribute value.
+                ActionSet *newActionSet = new ActionSet();
+                newActionSet->actionsetName = diag;
+
+                for (auto oit = children.begin(); oit != children.end(); ++oit)
+                {
+                    Action *newAction = new Action();
+
+                    // oit->getUri() includes a host address as well as URI.
+                    // We should split these to each other and only use the host address to create
+                    // a child resource's URI. Note that the collection resource and its child
+                    // resource are located in same host.
+                    newAction->target = getHostFromURI(oit->getUri()) + uri;
+
+                    Capability *newCapability = new Capability();
+                    newCapability->capability = attr;
+                    newCapability->status = getUpdateVal(diag);
+
+                    newAction->listOfCapability.push_back(newCapability);
+                    newActionSet->listOfAction.push_back(newAction);
+                }
+
+                // Request to create a new action set by using the above actionSet
+                g_groupmanager->addActionSet(resource, newActionSet,
+                        std::function<
+                                void(const HeaderOptions& headerOptions,
+                                        const OCRepresentation& rep, const int eCode) >(
+                                std::bind(&ThingsDiagnostics::onCreateActionSet, this,
+                                        std::placeholders::_1, std::placeholders::_2,
+                                        std::placeholders::_3, diag)));
+
+                free(newActionSet);
+
+            }
+
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string diag)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            std::shared_ptr < OCResource > resource = getResource(diag);
+            if (resource)
+            {
+                // Now, it is time to execute the action set.
+                g_groupmanager->executeActionSet(resource, diag,
+                        std::function<
+                                void(const HeaderOptions& headerOptions,
+                                        const OCRepresentation& rep, const int eCode) >(
+                                std::bind(&ThingsDiagnostics::onExecuteForGroupAction, this,
+                                        std::placeholders::_1, std::placeholders::_2,
+                                        std::placeholders::_3, diag)));
+            }
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions,
+            const OCRepresentation& rep, const int eCode, std::string diag)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            getCallback(diag)(headerOptions, rep, eCode);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+            const int eCode, std::string diag)
+    {
+        if (eCode == SUCCESS_RESPONSE)
+        {
+            std::cout << "PUT request was successful" << std::endl;
+
+            getCallback(diag)(headerOptions, rep, eCode);
+        }
+        else
+        {
+            std::cout << "onPut Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+
+    bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource)
+    {
+        for (unsigned int i = 0; i < resource->getResourceTypes().size(); ++i)
+        {
+            if (resource->getResourceTypes().at(0).find(".resourceset", 0) != std::string::npos)
+                return false;
+        }
+
+        return true;
+    }
+
+    OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource,
+            DiagnosticsCallback callback)
+    {
+        if (!resource)
+        {
+            std::cout << "resource is NULL\n";
+            return OC_STACK_ERROR;
+        }
+
+        std::string diag = "reboot";
+
+        // Check the request queue if a previous request is still left. If so, remove it.
+        std::map< std::string, DiagnosticsRequestEntry >::iterator iter =
+                diagnosticsRequestTable.find(diag);
+        if (iter != diagnosticsRequestTable.end())
+            diagnosticsRequestTable.erase(iter);
+
+        // Create new request entry stored in the queue
+        DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
+        diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
+
+        QueryParamsMap query;
+        OCRepresentation rep;
+
+        if (isSimpleResource(resource))
+        {
+            // This resource is a simple resource. Just send a PUT message
+            OCRepresentation rep;
+            rep.setValue < std::string > (diag, "true");
+
+            return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3, diag)));
+        }
+        else
+        {
+            // This resource is a collection resource. It just acquires child resource's URI and
+            // send GET massages to the child resources in turn.
+            // First, request the child resources's URI.
+            // TODO: Add a deletion of actionset
+            return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
+                                    std::placeholders::_1, std::placeholders::_2,
+                                    std::placeholders::_3, diag)));
+        }
+    }
+
+    OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource,
+            DiagnosticsCallback callback)
+    {
+        if (!resource)
+        {
+            std::cout << "resource is NULL\n";
+            return OC_STACK_ERROR;
+        }
+
+        std::string diag = "factoryreset";
+
+        // Check the request queue if a previous request is still left. If so, remove it.
+        std::map< std::string, DiagnosticsRequestEntry >::iterator iter =
+                diagnosticsRequestTable.find(diag);
+        if (iter != diagnosticsRequestTable.end())
+            diagnosticsRequestTable.erase(iter);
+
+        // Create new request entry stored in the queue
+        DiagnosticsRequestEntry newCallback(diag, callback, resource, "true");
+        diagnosticsRequestTable.insert(std::make_pair(diag, newCallback));
+
+        QueryParamsMap query;
+        OCRepresentation rep;
+
+        if (isSimpleResource(resource))
+        {
+            // This resource is a simple resource. Just send a PUT message
+            OCRepresentation rep;
+            rep.setValue < std::string > ("value", "true");
+
+            return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3, diag)));
+        }
+        else
+        {
+            // This resource is a collection resource. It just acquires child resource's URI and
+            // send GET massages to the child resources in turn.
+            // First, request the child resources's URI.
+            // TODO: Add a deletion of actionset
+            return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query,
+                    std::function<
+                            void(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                                    const int eCode) >(
+                            std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this,
+                                    std::placeholders::_1, std::placeholders::_2,
+                                    std::placeholders::_3, diag)));
+        }
+    }
+}
diff --git a/service/things-manager/sdk/src/ThingsDiagnostics.h b/service/things-manager/sdk/src/ThingsDiagnostics.h
new file mode 100644 (file)
index 0000000..dda9362
--- /dev/null
@@ -0,0 +1,223 @@
+//******************************************************************
+//
+// 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   ThingsDiagnostics.h
+
+/// @brief  This file contains the declaration of classes and its members related to
+///         ThingsDiagnostics.
+
+#ifndef __OC_THINGSDIAGNOSTICS__
+#define __OC_THINGSDIAGNOSTICS__
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdlib>
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "GroupManager.h"
+
+using namespace OC;
+namespace OIC
+{
+
+    /// Declearation of Diagnostics Callback funtion type
+    typedef std::function<
+            void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+            > DiagnosticsCallback;
+
+    /**
+     *  @brief
+     *  The following class is used as a item stacking in request queue. The class stores a request
+     *  and referential information (e.g., a diagnostics name, a target resource object, a callback
+     *  function passed from the applications, and a update value). When the function for updating/
+     *  getting diagnostics value is called from applications, this class instance is created and
+     *  stored in the request queue. The queue is maintained in a std::map structure so if desiring
+     *  to find a specific request, you can find it by querying a diagnostics name.
+     */
+    class DiagnosticsRequestEntry
+    {
+    public:
+        DiagnosticsRequestEntry(std::string ID, DiagnosticsCallback callback,
+                std::shared_ptr< OCResource > resource, std::string updateVal) :
+                m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal)
+        {
+        }
+        ;
+
+        // Diagnostics Name (used in key value in std::map structure)
+        // e.g., reboot and factoryset
+        std::string m_ID;
+
+        // Reference callback pointer
+        DiagnosticsCallback m_callback;
+
+        // Reference resource object
+        std::shared_ptr< OCResource > m_resource;
+
+        // Update value only used for diagnostics update (always "true")
+        std::string m_updateVal;
+    };
+
+    /**
+     *  @brief
+     *  The following class is used to store providing diagnostics name and its relevant information
+     *  The relevant information includes a brief description, uri, and attribute key.
+     *  Note that a developer only specifies a diagnostics name, not URI nor attribute key, to
+     *  update a value to a remote. Thus, using diagnostics name, we convert it to more specific
+     *  information (i.e. uri and attribute key) to send a request. This class is reponsible to
+     *  storing these information.
+     */
+    class DiagnosticsUnitInfo
+    {
+    public:
+        DiagnosticsUnitInfo(std::string name, std::string description, std::string uri,
+                std::string attribute) :
+                m_name(name), m_description(description), m_uri(uri), m_attribute(attribute)
+        {
+        }
+        ;
+
+        std::string m_name;
+        std::string m_description;
+        std::string m_uri;
+        std::string m_attribute;
+
+        // If a developer wants to know a list of diagnostics names, gives it in JSON format.
+        std::string getJSON()
+        {
+            std::string res;
+
+            res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}";
+
+            return res;
+        }
+    };
+
+#define NUMDIAGUNIT 3
+    typedef std::string DiagnosticsName;
+    typedef std::string DiagnosticsValue;
+
+    class ThingsDiagnostics
+    {
+    public:
+        /**
+         * Constructor for ThingsDiagnostics. Constructs a new ThingsDiagnostics
+         */
+        ThingsDiagnostics(void)
+        {
+            DiagnosticsUnitInfo unit[] =
+                    {
+                    { "reboot", "reboot", "/oic/diag/0/reboot", "value" },
+                            { "value",
+                                    "Collecting any device statistics",
+                                    "/oic/diag/0/startCollection", "value" },
+                            { "factoryreset", "restore all configuration values to default values",
+                                    "/oic/diag/0/factoryReset", "value" } };
+
+            for (int i = 0; i < NUMDIAGUNIT; i++)
+                DiagnosticsUnitTable.push_back(unit[i]);
+        }
+        ;
+
+        /**
+         * Virtual destructor
+         */
+        ~ThingsDiagnostics(void)
+        {
+        }
+        ;
+
+        static ThingsDiagnostics *thingsDiagnosticsInstance;
+        static ThingsDiagnostics* getInstance();
+        void deleteInstance();
+
+        void setGroupManager(GroupManager *groupmanager)
+        {
+            g_groupmanager = groupmanager;
+        }
+        ;
+
+        /**
+         * API to make things reboot
+         * Callback call when a response arrives.
+         *
+         * @param resource - resource pointer representing the target group
+         * @param callback - callback.
+         *
+         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+        OCStackResult reboot(std::shared_ptr< OCResource > resource, DiagnosticsCallback callback);
+
+        /**
+         * API for factory reset on device
+         * Callback call when a response arrives.
+         *
+         * @param resource - resource pointer representing the target group
+         * @param callback - callback.
+         *
+         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
+         *
+         * NOTE: OCStackResult is defined in ocstack.h.
+         */
+
+        OCStackResult factoryReset(std::shared_ptr< OCResource > resource,
+                DiagnosticsCallback callback);
+
+        /**
+         * API to show a list of supported diagnostics units
+         * Callback call when a response arrives.
+         *
+         * @return the list in JSON format
+         */
+        std::string getListOfSupportedDiagnosticsUnits();
+
+    private:
+
+        GroupManager *g_groupmanager;
+
+        std::vector< DiagnosticsUnitInfo > DiagnosticsUnitTable;
+
+        void onExecuteForGroupAction(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+        void onGetChildInfoForUpdate(const HeaderOptions& headerOptions,
+                const OCRepresentation& rep, const int eCode, std::string conf);
+        void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep,
+                const int eCode, std::string conf);
+        void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+                std::string conf);
+        void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode,
+                std::string conf);
+
+        std::shared_ptr< OCResource > getResource(std::string conf);
+        DiagnosticsCallback getCallback(std::string conf);
+        std::string getUpdateVal(std::string conf);
+        std::string getAttributeByDiagnosticsName(DiagnosticsName name);
+        std::string getUriByDiagnosticsName(DiagnosticsName name);
+
+        std::string getHostFromURI(std::string oldUri);
+
+        bool isSimpleResource(std::shared_ptr< OCResource > resource);
+
+    };
+}
+#endif  /* __OC_THINGSCONFIGURATION__*/
diff --git a/service/things-manager/sdk/src/ThingsManager.cpp b/service/things-manager/sdk/src/ThingsManager.cpp
new file mode 100644 (file)
index 0000000..a65b987
--- /dev/null
@@ -0,0 +1,188 @@
+//******************************************************************
+//
+// 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    ThingsManager.cpp
+
+#include "ThingsManager.h"
+#include "GroupManager.h"
+#include "GroupSynchronization.h"
+#include "ThingsConfiguration.h"
+#include "ThingsDiagnostics.h"
+#include <algorithm>
+#include <thread>
+
+using namespace OC;
+namespace OIC
+{
+
+    GroupManager *g_groupManager;
+    GroupSynchronization *g_groupSync = NULL;
+    ThingsConfiguration *g_thingsConf = NULL;
+    ThingsDiagnostics *g_thingsDiag = NULL;
+
+    ThingsManager::ThingsManager(void)
+    {
+        g_groupManager = new GroupManager();
+        g_groupSync = GroupSynchronization::getInstance();
+        g_thingsConf = ThingsConfiguration::getInstance();
+        g_thingsDiag = ThingsDiagnostics::getInstance();
+        g_thingsConf->setGroupManager(g_groupManager);
+        g_thingsDiag->setGroupManager(g_groupManager);
+    }
+
+    /**
+     * Virtual destructor
+     */
+    ThingsManager::~ThingsManager(void)
+    {
+        delete g_groupManager;
+        g_groupSync->deleteInstance();
+        g_thingsConf->deleteInstance();
+        g_thingsDiag->deleteInstance();
+    }
+
+    OCStackResult ThingsManager::findCandidateResources(std::vector< std::string > resourceTypes,
+            std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback,
+            int waitsec)
+    {
+        OCStackResult result = g_groupManager->findCandidateResources(resourceTypes, callback,
+                waitsec);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::subscribeCollectionPresence(std::shared_ptr< OCResource > resource,
+            std::function< void(std::string, OCStackResult) > callback)
+    {
+        OCStackResult result = g_groupManager->subscribeCollectionPresence(resource, callback);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::findGroup(std::vector< std::string > collectionResourceTypes,
+            FindCallback callback)
+    {
+        OCStackResult result = g_groupSync->findGroup(collectionResourceTypes, callback);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::createGroup(std::string collectionResourceType)
+    {
+        OCStackResult result = g_groupSync->createGroup(collectionResourceType);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::joinGroup(std::string collectionResourceType,
+            OCResourceHandle resourceHandle)
+    {
+        OCStackResult result = g_groupSync->joinGroup(collectionResourceType, resourceHandle);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::joinGroup(const std::shared_ptr< OCResource > resource,
+            OCResourceHandle resourceHandle)
+    {
+        OCStackResult result = g_groupSync->joinGroup(resource, resourceHandle);
+
+        return result;
+    }
+
+    OCStackResult ThingsManager::leaveGroup(std::string collectionResourceType,
+            OCResourceHandle resourceHandle)
+    {
+        OCStackResult result = g_groupSync->leaveGroup(collectionResourceType, resourceHandle);
+
+        return result;
+    }
+
+    void ThingsManager::deleteGroup(std::string collectionResourceType)
+    {
+        g_groupSync->deleteGroup(collectionResourceType);
+    }
+
+    std::map< std::string, OCResourceHandle > ThingsManager::getGroupList()
+    {
+        return g_groupSync->getGroupList();
+    }
+
+    OCStackResult ThingsManager::updateConfigurations(std::shared_ptr< OCResource > resource,
+            std::map< ConfigurationName, ConfigurationValue > configurations,
+            ConfigurationCallback callback)
+    {
+        return g_thingsConf->updateConfigurations(resource, configurations, callback);
+    }
+    OCStackResult ThingsManager::getConfigurations(std::shared_ptr< OCResource > resource,
+            std::vector< ConfigurationName > configurations, ConfigurationCallback callback)
+    {
+        return g_thingsConf->getConfigurations(resource, configurations, callback);
+    }
+    std::string ThingsManager::getListOfSupportedConfigurationUnits()
+    {
+        return g_thingsConf->getListOfSupportedConfigurationUnits();
+    }
+
+    OCStackResult ThingsManager::doBootstrap(ConfigurationCallback callback)
+    {
+        return g_thingsConf->doBootstrap(callback);
+    }
+
+    OCStackResult ThingsManager::reboot(std::shared_ptr< OCResource > resource,
+            ConfigurationCallback callback)
+    {
+        return g_thingsDiag->reboot(resource, callback);
+    }
+    OCStackResult ThingsManager::factoryReset(std::shared_ptr< OCResource > resource,
+            ConfigurationCallback callback)
+    {
+        return g_thingsDiag->factoryReset(resource, callback);
+    }
+
+    std::string ThingsManager::getStringFromActionSet(const ActionSet *newActionSet)
+    {
+        return g_groupManager->getStringFromActionSet(newActionSet);
+    }
+    ActionSet* ThingsManager::getActionSetfromString(std::string desc)
+    {
+        return g_groupManager->getActionSetfromString(desc);
+    }
+    OCStackResult ThingsManager::addActionSet(std::shared_ptr< OCResource > resource,
+            const ActionSet* newActionSet, PutCallback cb)
+    {
+        return g_groupManager->addActionSet(resource, newActionSet, cb);
+    }
+    OCStackResult ThingsManager::executeActionSet(std::shared_ptr< OCResource > resource,
+            std::string actionsetName, PostCallback cb)
+    {
+        return g_groupManager->executeActionSet(resource, actionsetName, cb);
+    }
+    OCStackResult ThingsManager::getActionSet(std::shared_ptr< OCResource > resource,
+            std::string actionsetName, GetCallback cb)
+    {
+        return g_groupManager->getActionSet(resource, actionsetName, cb);
+    }
+    OCStackResult ThingsManager::deleteActionSet(std::shared_ptr< OCResource > resource,
+            std::string actionsetName, PostCallback cb)
+    {
+        return g_groupManager->deleteActionSet(resource, actionsetName, cb);
+    }
+}
index 718e296..ac543d2 100644 (file)
@@ -17,7 +17,7 @@ resource_path = src_dir + '/resource'
 ######################################################################
 # Check dependent packages (Linux only)
 ######################################################################
-if target_os == 'linux':
+if target_os in ['linux', 'tizen']:
        if not env.GetOption('help'):
                if not target_arch == platform.machine():
                        print '''