Merge "Merge branch 'group-manager'"
authorUze Choi <uzchoi@samsung.com>
Mon, 7 Mar 2016 05:49:37 +0000 (05:49 +0000)
committerGerrit Code Review <gerrit@172.30.200.205>
Mon, 7 Mar 2016 05:49:38 +0000 (05:49 +0000)
51 files changed:
resource/docs/Doxyfile
service/SConscript
service/scene-manager/README.txt [new file with mode: 0755]
service/scene-manager/SConscript [new file with mode: 0755]
service/scene-manager/include/RemoteScene.h [new file with mode: 0644]
service/scene-manager/include/RemoteSceneAction.h [new file with mode: 0644]
service/scene-manager/include/RemoteSceneCollection.h [new file with mode: 0644]
service/scene-manager/include/RemoteSceneList.h [new file with mode: 0644]
service/scene-manager/include/Scene.h [new file with mode: 0755]
service/scene-manager/include/SceneAction.h [new file with mode: 0755]
service/scene-manager/include/SceneCollection.h [new file with mode: 0755]
service/scene-manager/include/SceneList.h [new file with mode: 0755]
service/scene-manager/sampleapp/SConscript [new file with mode: 0755]
service/scene-manager/sampleapp/linux/SConscript [new file with mode: 0755]
service/scene-manager/sampleapp/linux/fanserver.cpp [new file with mode: 0755]
service/scene-manager/sampleapp/linux/lightserver.cpp [new file with mode: 0755]
service/scene-manager/sampleapp/linux/sceneclient.cpp [new file with mode: 0755]
service/scene-manager/sampleapp/linux/sceneserver.cpp [new file with mode: 0755]
service/scene-manager/src/RemoteScene.cpp [new file with mode: 0644]
service/scene-manager/src/RemoteSceneAction.cpp [new file with mode: 0644]
service/scene-manager/src/RemoteSceneCollection.cpp [new file with mode: 0644]
service/scene-manager/src/RemoteSceneList.cpp [new file with mode: 0644]
service/scene-manager/src/RemoteSceneUtils.h [new file with mode: 0644]
service/scene-manager/src/Scene.cpp [new file with mode: 0755]
service/scene-manager/src/SceneAction.cpp [new file with mode: 0755]
service/scene-manager/src/SceneCollection.cpp [new file with mode: 0755]
service/scene-manager/src/SceneCollectionResource.cpp [new file with mode: 0644]
service/scene-manager/src/SceneCollectionResource.h [new file with mode: 0644]
service/scene-manager/src/SceneCollectionResourceRequestor.cpp [new file with mode: 0644]
service/scene-manager/src/SceneCollectionResourceRequestor.h [new file with mode: 0644]
service/scene-manager/src/SceneCommons.h [new file with mode: 0644]
service/scene-manager/src/SceneList.cpp [new file with mode: 0755]
service/scene-manager/src/SceneListResource.cpp [new file with mode: 0644]
service/scene-manager/src/SceneListResource.h [new file with mode: 0644]
service/scene-manager/src/SceneListResourceRequestor.cpp [new file with mode: 0644]
service/scene-manager/src/SceneListResourceRequestor.h [new file with mode: 0644]
service/scene-manager/src/SceneMemberResource.cpp [new file with mode: 0644]
service/scene-manager/src/SceneMemberResource.h [new file with mode: 0644]
service/scene-manager/src/SceneMemberResourceRequestor.cpp [new file with mode: 0644]
service/scene-manager/src/SceneMemberResourceRequestor.h [new file with mode: 0644]
service/scene-manager/src/SceneUtils.cpp [new file with mode: 0644]
service/scene-manager/unittests/RemoteSceneActionTest.cpp [new file with mode: 0644]
service/scene-manager/unittests/RemoteSceneCollectionTest.cpp [new file with mode: 0644]
service/scene-manager/unittests/RemoteSceneListTest.cpp [new file with mode: 0644]
service/scene-manager/unittests/RemoteSceneTest.cpp [new file with mode: 0644]
service/scene-manager/unittests/SConscript [new file with mode: 0755]
service/scene-manager/unittests/SceneActionTest.cpp [new file with mode: 0755]
service/scene-manager/unittests/SceneCollectionTest.cpp [new file with mode: 0755]
service/scene-manager/unittests/SceneListTest.cpp [new file with mode: 0755]
service/scene-manager/unittests/SceneTest.cpp [new file with mode: 0755]
tools/tizen/.gbs.conf

index 6857776..363635a 100644 (file)
@@ -678,7 +678,9 @@ INPUT                  = . \
                          ../../service/things-manager/sdk/inc/ThingsMaintenance.h \
                          ../../service/easy-setup/sdk/common \
                          ../../service/easy-setup/sdk/enrollee/api \
-                         ../../service/resource-directory/include
+                        ../../service/resource-directory/include \
+                        ../../service/scene-manager/include \
+                        
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
index 2e6e25f..da5062e 100755 (executable)
@@ -36,9 +36,13 @@ if target_os not in ['arduino','darwin', 'ios']:
     # Build resource-encapsulation project
     SConscript('resource-encapsulation/SConscript')
 
-    # Build resource-container project    
+    # Build resource-container project
     SConscript('resource-container/SConscript')
 
+    # Build scene-manager project
+    if target_os in ['linux']:
+        SConscript('scene-manager/SConscript')
+
     # Build simulator module
     if target_os in ['linux'] and env.get('SIMULATOR', False):
         SConscript('simulator/SConscript')
diff --git a/service/scene-manager/README.txt b/service/scene-manager/README.txt
new file mode 100755 (executable)
index 0000000..7c21ad4
--- /dev/null
@@ -0,0 +1 @@
+initial file
diff --git a/service/scene-manager/SConscript b/service/scene-manager/SConscript
new file mode 100755 (executable)
index 0000000..9348578
--- /dev/null
@@ -0,0 +1,108 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# NotificationManager build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+    env.AppendUnique(CCFLAGS = ['-Os'])
+    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+scenemanager_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+scenemanager_env.AppendUnique(CPPPATH = ['./include'])
+scenemanager_env.AppendUnique(CPPPATH = ['./src'])
+scenemanager_env.AppendUnique(CPPPATH = ['../../resource/csdk/connectivity/api'])
+scenemanager_env.AppendUnique(CPPPATH = ['../resource-encapsulation/include'])
+scenemanager_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/common/primitiveResource/include'])
+scenemanager_env.AppendUnique(CPPPATH = ['../resource-encapsulation/src/common/expiryTimer/include'])
+
+
+scenemanager_env.PrependUnique(LIBS = [
+    'rcs_client',
+    'rcs_server',
+    'rcs_common',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'libcoap'
+    ])
+
+if target_os not in ['windows', 'winrt']:
+    scenemanager_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os not in ['darwin', 'ios', 'windows', 'winrt']:
+    scenemanager_env.AppendUnique(LINKFLAGS = ['-Wl,--no-undefined'])
+
+if target_os == 'linux':
+    scenemanager_env.AppendUnique(LIBS = ['pthread'])
+    
+
+if target_os == 'android':
+    scenemanager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    scenemanager_env.AppendUnique(LIBS = ['gnustl_shared','log'])
+
+if not env.get('RELEASE'):
+    scenemanager_env.PrependUnique(LIBS = ['gcov'])
+    scenemanager_env.AppendUnique(CXXFLAGS = ['--coverage'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+SCENE_SRC_DIR = './src/' 
+scenemanager_src = Glob(SCENE_SRC_DIR + '*.cpp')
+
+if target_os in ['tizen','android'] :
+    scenemanagersdk = scenemanager_env.SharedLibrary('scene_manager', scenemanager_src)
+else :
+    scenemanagersdk = scenemanager_env.StaticLibrary('scene_manager', scenemanager_src)
+
+scenemanager_env.InstallTarget(scenemanagersdk, 'libscene_manager')
+scenemanager_env.UserInstallTargetLib(scenemanagersdk, 'libscene_manager')
+scenemanager_env.UserInstallTargetHeader('include/SceneList.h', 'service/scene-manager', 'SceneList.h')
+scenemanager_env.UserInstallTargetHeader('include/SceneCollection.h', 'service/scene-manager', 'SceneCollection.h')
+scenemanager_env.UserInstallTargetHeader('include/Scene.h', 'service/scene-manager', 'Scene.h')
+scenemanager_env.UserInstallTargetHeader('include/SceneAction.h', 'service/scene-manager', 'SceneAction.h')
+scenemanager_env.UserInstallTargetHeader('include/RemoteSceneList.h', 'service/scene-manager', 'RemoteSceneList.h')
+scenemanager_env.UserInstallTargetHeader('include/RemoteSceneCollection.h', 'service/scene-manager', 'RemoteSceneCollection.h')
+scenemanager_env.UserInstallTargetHeader('include/RemoteScene.h', 'service/scene-manager', 'RemoteScene.h')
+scenemanager_env.UserInstallTargetHeader('include/RemoteSceneAction.h', 'service/scene-manager', 'RemoteSceneAction.h')
+
+# Go to build Unit test
+if target_os == 'linux':
+    SConscript('unittests/SConscript')
+
+# Go to build sample apps
+SConscript('sampleapp/SConscript')
diff --git a/service/scene-manager/include/RemoteScene.h b/service/scene-manager/include/RemoteScene.h
new file mode 100644 (file)
index 0000000..32aa8c1
--- /dev/null
@@ -0,0 +1,190 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_REMOTE_SCENE_H_
+#define SM_REMOTE_SCENE_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <mutex>
+
+#include "RemoteSceneAction.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SceneCollectionResourceRequestor;
+        class SceneMemberResourceRequestor;
+
+        /*
+        * @class RemoteScene
+        *
+        * @brief RemoteScene class is an interface class to send a request to a Scene provided by
+        * SceneCollection resource on remote side. This class provides APIs for adding new
+        * SceneAction to the Scene and creating a new SceneAction instance, retrieving all
+        * SceneAction instances created before. And it also provides an API to execute a Scene
+        * on remote side.
+        */
+        class RemoteScene
+        {
+            public:
+                typedef std::shared_ptr< RemoteScene > Ptr;
+
+                /**
+                * Callback definition to be invoked a the response of addNewSceneAction is
+                * received.
+                *
+                * @param action created RemoteSceneAction instance pointer
+                * @param eCode the error code received
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see addNewSceneAction
+                */
+                typedef std::function< void(RemoteSceneAction::Ptr action, int eCode) >
+                    AddNewSceneActionCallback;
+
+                /**
+                * Callback definition to be invoked when a response of execute is
+                * received.
+                *
+                * @param sceneName name of the scene which is executed
+                * @param eCode the error code received
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see execute
+                */
+                typedef std::function< void(const std::string &sceneName, int eCode) >
+                    RemoteSceneExecuteCallback;
+
+            public:
+                ~RemoteScene() = default;
+
+                /**
+                * Requests to add new SceneAction to the Scene on remote side and
+                * creates RemoteSceneAction instance corresponding to the created SceneAction.
+                *
+                * @param targetResource A pointer of discovered resource
+                * @param attrs AttributeS to set when the Scene executed
+                * @param cb A callback to receive created RemoteSceneAction instance
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid.
+                *
+                * @note RemoteSceneAction instance is only produced by RemoteScene class
+                *
+                * @see RCSResourceAttributes
+                */
+                void addNewSceneAction(RCSRemoteResourceObject::Ptr targetResource,
+                    const RCSResourceAttributes &attrs, AddNewSceneActionCallback cb);
+
+                /**
+                * Requests to add new SceneAction to the Scene on remote side and
+                * creates RemoteSceneAction instance corresponding to the created SceneAction.
+                *
+                * @param targetResource A pointer of discovered resource
+                * @param key A key of an attribute
+                * @param value A value to be mapped against the key
+                * @param cb A callback to receive created RemoteSceneAction instance
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid.
+                *
+                * @note RemoteSceneAction instance is only produced by RemoteScene class
+                *
+                * @see RCSResourceAttributes::Value
+                */
+                void addNewSceneAction(RCSRemoteResourceObject::Ptr targetResource,
+                                       const std::string &key,
+                                       const RCSResourceAttributes::Value &value,
+                                       AddNewSceneActionCallback cb);
+
+                /**
+                * Gets all RemoteSceneAction instances included in the Scene.
+                *
+                * @return A vector of shared pointer of RemoteSceneAction instances
+                */
+                std::vector< RemoteSceneAction::Ptr > getRemoteSceneActions() const;
+
+                /**
+                * Gets RemoteSceneAction instance by using a certain discovered resource.
+                *
+                * @param targetResource A pointer of discovered resource
+                *
+                * @return A shared pointer of RemoteSceneAction instance
+                *
+                * @throws RCSInvalidParameterException If targetResource is invalid
+                */
+                RemoteSceneAction::Ptr getRemoteSceneAction(
+                    const RCSRemoteResourceObject::Ptr targetResource) const;
+
+                /**
+                * Gets a name attribute of the Scene.
+                *
+                * @return A name of the Scene
+                */
+                std::string getName() const;
+
+                /**
+                * Requests to execute the Scene on remote side.
+                *
+                * @param cb A callback to receive result of Scene execution
+                *
+                * @throws RCSInvalidParameterException If callback is null
+                */
+                void execute(RemoteSceneExecuteCallback cb);
+
+            private:
+                RemoteScene(
+                    const std::string &name, std::shared_ptr< SceneCollectionResourceRequestor >);
+
+                RemoteSceneAction::Ptr createRemoteSceneAction(
+                    const std::string &,  const RCSResourceAttributes &);
+
+                void addExistingRemoteSceneAction(const std::string &, const std::string &,
+                    RCSRemoteResourceObject::Ptr, const std::string &key,
+                    const RCSResourceAttributes::Value &);
+
+                void onSceneActionAdded(
+                    int, RCSRemoteResourceObject::Ptr,
+                    const RCSResourceAttributes &, const AddNewSceneActionCallback &);
+
+                void onSceneExecuted(const std::string &name, int,
+                                    const RemoteSceneExecuteCallback &);
+
+            private:
+                std::string m_name;
+                mutable std::mutex m_sceneActionLock;
+                std::unordered_map < std::string, RemoteSceneAction::Ptr >
+                    m_remoteSceneActions;
+
+                std::shared_ptr< SceneCollectionResourceRequestor > m_requestor;
+
+                friend class RemoteSceneCollection;
+        };
+
+    }
+}
+
+#endif /* SM_REMOTE_SCENE_H_ */
\ No newline at end of file
diff --git a/service/scene-manager/include/RemoteSceneAction.h b/service/scene-manager/include/RemoteSceneAction.h
new file mode 100644 (file)
index 0000000..993943d
--- /dev/null
@@ -0,0 +1,133 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_REMOTE_SCENEACTION_H_
+#define SM_REMOTE_SCENEACTION_H_
+
+#include <memory>
+#include <string>
+#include <mutex>
+
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneMemberResourceRequestor;
+
+        /*
+        * @class RemoteSceneAction
+        *
+        * @brief RemoteSceneAction class indicates a unit of actions when a scene is executed.
+        * RemoteSceneAction instance is initialized with 3 essential parameters:
+        * a target resource, target attribute key, and its target value.
+        * And this class also provides APIs to update a target attribute information if one wants.
+        * Note that, adding a new RemoteSceneAction is done by sending a CoAP request to update a
+        * SceneMember resource's attribute.
+        */
+        class RemoteSceneAction
+        {
+            public:
+                typedef std::shared_ptr< RemoteSceneAction > Ptr;
+
+                /**
+                * Callback definition to be invoked when a response of resetExecutionParameter is
+                * received.
+                *
+                * @param eCode the error code received on a remote-side scene resource server
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see resetExecutionParameter
+                */
+                typedef std::function< void(int eCode) > ResetExecutionParameterCallback;
+
+            public:
+                ~RemoteSceneAction() = default;
+
+                /**
+                * Requests to reset the RemoteSceneAction parameters like
+                * a target attribute key and its value.
+                *
+                * @param key key of attribute
+                * @param value value to be mapped against the key
+                * @param cb A callback to receive the response
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid.
+                *
+                * @see RCSResourceAttributes::Value
+                */
+                void resetExecutionParameter(const std::string &key,
+                    const RCSResourceAttributes::Value &value, ResetExecutionParameterCallback cb);
+
+                /**
+                * Requests to reset the RemoteSceneAction parameters like
+                * a target attribute key and its value.
+                *
+                * @param attr Attributes to set
+                * @param cb A callback to receive the response
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid.
+                *
+                * @see RCSResourceAttributes
+                */
+                void resetExecutionParameter(
+                    const RCSResourceAttributes &attr, ResetExecutionParameterCallback cb);
+
+                /**
+                * Returns an execution parameter of the SceneAction.
+                *
+                * @return RCSResourceAttributes
+                */
+                RCSResourceAttributes getExecutionParameter() const;
+
+                /**
+                * Returns a target remote resource object of the RemoteSceneAction instance
+                *
+                * @return pointer of RCSRemoteResourceObject
+                */
+                RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+            private:
+                RemoteSceneAction(std::shared_ptr< SceneMemberResourceRequestor >,
+                                  const std::string &sceneName, const RCSResourceAttributes &);
+                RemoteSceneAction(std::shared_ptr< SceneMemberResourceRequestor >,
+                                  const std::string &sceneName,
+                                  const std::string &key, const RCSResourceAttributes::Value &);
+
+                void onExecutionParameterSet(int, const RCSResourceAttributes &,
+                    const ResetExecutionParameterCallback &);
+
+            private:
+                std::string m_sceneName;
+                mutable std::mutex m_attributeLock;
+                RCSResourceAttributes m_attributes;
+                std::shared_ptr< SceneMemberResourceRequestor > m_requestor;
+
+                friend class RemoteScene;
+        };
+
+    }
+}
+
+#endif /* SM_REMOTE_SCENEACTION_H_ */
\ No newline at end of file
diff --git a/service/scene-manager/include/RemoteSceneCollection.h b/service/scene-manager/include/RemoteSceneCollection.h
new file mode 100644 (file)
index 0000000..d7b0e2f
--- /dev/null
@@ -0,0 +1,173 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_REMOTE_SCENECOLLECTION_H_
+#define SM_REMOTE_SCENECOLLECTION_H_
+
+#include <memory>
+#include <functional>
+#include <string>
+#include <unordered_map>
+#include <mutex>
+
+#include "RemoteScene.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneCollectionResourceRequestor;
+
+        /**
+        * @class RemoteSceneCollection
+        *
+        * @brief RemoteSceneCollection class is an interface class to send a request to
+        * SceneCollection resource on remote side. This class provides APIs for adding new Scene
+        * to the SceneCollection resource and creating a new RemoteSceneCollection instance
+        * corresponding to the created SceneCollection resource. This class also supports
+        * retrieving all Scene instances created before. Besides, it provides APIs for retrieving
+        * and updating attribute values of the SceneCollection resource like name attribute.
+        */
+        class RemoteSceneCollection
+        {
+            public:
+                typedef std::shared_ptr< RemoteSceneCollection > Ptr;
+
+                /**
+                * Callback definition to be invoked when a response of addNewScene is
+                * received.
+                *
+                * @param scene created RemoteScene instance pointer
+                * @param eCode the error code received from the SceneCollection on remote
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see addNewScene
+                */
+                typedef std::function< void(RemoteScene::Ptr scene, int eCode) >
+                    AddNewSceneCallback;
+
+                /**
+                * Callback definition to be invoked when a response of setName is
+                * received.
+                *
+                * @param eCode the error code received from the SceneCollection on remote
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see setName
+                */
+                typedef std::function< void(int eCode) > SetNameCallback;
+
+            public:
+                ~RemoteSceneCollection() = default;
+
+                /**
+                * Requests to add new Scene to the SceneCollection resource on remote side
+                * and creates RemoteScene instance corresponding to the created Scene.
+                *
+                * @param name A name of Scene to add
+                * @param cb A callback to receive created RemoteScene instance
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid
+                *
+                * @note RemoteScene instance is only produced by RemoteSceneCollection class.
+                * @note Name of Scene must be unique in one SceneCollection
+                */
+                void addNewScene(const std::string &name, AddNewSceneCallback cb);
+
+                /**
+                * Gets all RemoteScene instances from RemoteSceneCollection instance.
+                *
+                * @return A unordered_map of shared pointers of RemoteScene instances
+                */
+                std::unordered_map< std::string, RemoteScene::Ptr > getRemoteScenes() const;
+
+                /**
+                * Gets RemoteScene instance with a specific Scene name.
+                *
+                * @param sceneName name of the Scene to get
+                *
+                * @return A shared pointer of RemoteScene instance
+                *
+                * @throws RCSInvalidParameterException If sceneName is invalid
+                */
+                RemoteScene::Ptr getRemoteScene(const std::string &sceneName) const;
+
+                /**
+                * Request to set a name attribute of the SceneCollection resource on remote side.
+                *
+                * @param name A name of the SceneCollection
+                * @param cb A callback to receive the response
+                *
+                * @throws RCSInvalidParameterException If callback is null
+                */
+                void setName(const std::string &name, SetNameCallback cb);
+
+                /**
+                * Gets a name attribute of the SceneCollection resource
+                *
+                * @return A name of the SceneCollection
+                */
+                std::string getName() const;
+
+                /**
+                * Gets an id attribute of the SceneCollection resource.
+                *
+                * @return an id of the SceneCollection resource
+                */
+                std::string getId() const;
+
+            private:
+                RemoteSceneCollection(
+                    std::shared_ptr< SceneCollectionResourceRequestor >,
+                    const std::string &id, const std::string &name);
+
+                void addExistingRemoteScenes(const std::vector< std::string > &);
+
+                void initializeRemoteScenes(const std::vector< RCSResourceAttributes > &,
+                                                     const std::string &);
+
+                RemoteScene::Ptr createRemoteScene(const std::string &);
+
+                void onSceneAddedRemoved(int, const std::string &name, int,
+                                         const AddNewSceneCallback &);
+
+                void onNameSet(int, const std::string &, const SetNameCallback &);
+
+            private:
+                std::string m_id;
+                std::string m_name;
+                mutable std::mutex m_nameLock;
+                mutable std::mutex m_sceneLock;
+                std::unordered_map< std::string, RemoteScene::Ptr > m_remoteScenes;
+                std::shared_ptr< SceneCollectionResourceRequestor > m_requestor;
+
+                friend class RemoteSceneList;
+        };
+
+    }
+}
+
+#endif /* SM_REMOTE_SCENECOLLECTION_H_ */
\ No newline at end of file
diff --git a/service/scene-manager/include/RemoteSceneList.h b/service/scene-manager/include/RemoteSceneList.h
new file mode 100644 (file)
index 0000000..183c144
--- /dev/null
@@ -0,0 +1,194 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_REMOTE_SCENELIST_H_
+#define SM_REMOTE_SCENELIST_H_
+
+#include <memory>
+#include <vector>
+#include <functional>
+#include <mutex>
+
+#include "RemoteSceneCollection.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SceneListResourceRequestor;
+
+        /**
+        * @class RemoteSceneList
+        *
+        * @brief RemoteSceneList class is an interface class to send a request to
+        * SceneList resource on remote side. This class provides APIs for adding
+        * new SceneCollection resource to the SceneList resource and
+        * creating a RemoteSceneCollection instance corresponding to the
+        * created SceneCollection resource. This class also supports retrieving the existing
+        * instances as well as setting/getting a name attribute of the SceneList resource.
+        */
+        class RemoteSceneList
+        {
+            public:
+                typedef std::unique_ptr< RemoteSceneList > Ptr;
+
+                /**
+                * Callback definition to be invoked when a response of createInstance is
+                * received.
+                *
+                * @param list Created RemoteSceneList instance pointer
+                * @param eCode The error code received from the SceneList on remote side
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see createInstance
+                */
+                typedef std::function< void(RemoteSceneList::Ptr list, int eCode) >
+                    CreateInstanceCallback;
+
+                /**
+                * Callback definition to be invoked when a response of addNewSceneCollection is
+                * received.
+                *
+                * @param collection Created RemoteSceneCollection instance pointer
+                * @param eCode The error code received from the SceneList on remote
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see addNewSceneCollection
+                */
+                typedef std::function< void(RemoteSceneCollection::Ptr collection, int eCode) >
+                    AddNewSceneCollectionCallback;
+
+                /**
+                * Callback definition to be invoked when a response of setName is
+                * received.
+                *
+                * @param eCode the error code received from the SceneList on remote
+                *
+                * @note Error code '200' stands for success, '400' for bad request,
+                * and '500' for internal error.
+                *
+                * @see setName
+                */
+                typedef std::function< void(int eCode) > SetNameCallback;
+
+            public:
+                ~RemoteSceneList() = default;
+
+                /**
+                * Creates RemoteSceneList instance with provided RCSRemoteResourceObject of
+                * discovered SceneList resource on remote side.
+                *
+                * To create RemoteSceneList instance, discovery of SceneList resource
+                * which has 'oic.wk.scenelist' as resource type is required,
+                * and the found resource should be provided as parameter.
+                * After that, one can acceess existing SceneCollections, Scenes, and SceneActions
+                * instances that are already produced at the SceneList resource.
+                * Created RemoteSceneList will be delivered to CreateInstanceCallback.
+                *
+                * @param sceneListResource RCSRemoteResourceObject pointer of SceneList
+                * @param cb A callback to receive the response
+                *
+                * @throws RCSInvalidParameterException If parameter is invalid.
+                *
+                * @see RCSRemoteResourceObject
+                */
+                static void createInstance(
+                    RCSRemoteResourceObject::Ptr sceneListResource, CreateInstanceCallback cb);
+
+                /**
+                * Requests to add new SceneCollection resource to the SceneList resource on remote
+                * side and creates RemoteSceneCollection instance corresponding to the created
+                * SceneCollection resource.
+                *
+                * @param cb A callback to receive created RemoteSceneCollection instance
+                *
+                * @throws RCSInvalidParameterException If callback is null.
+                *
+                * @note RemoteSceneCollection instance is only produced by RemoteSceneList class.
+                */
+                void addNewSceneCollection(AddNewSceneCollectionCallback cb);
+
+                /**
+                * Gets all RemoteSceneCollection instances stored in the RemoteSceneList instance.
+                *
+                * @return A vector of shared pointers of RemoteSceneCollection instances
+                */
+                std::vector< RemoteSceneCollection::Ptr > getRemoteSceneCollections() const;
+
+                /**
+                * Request to set a name attribute of the SceneList resource on remote side.
+                *
+                * @param name A name of the SceneList
+                * @param cb A callback to receive the response
+                *
+                * @throws RCSInvalidParameterException If callback is null.
+                */
+                void setName(const std::string &name, SetNameCallback cb);
+
+                /**
+                * Gets a name attribute of the SceneList resource.
+                *
+                * @return A name of the SceneList resource
+                */
+                std::string getName() const;
+
+            private:
+                RemoteSceneList(std::shared_ptr< SceneListResourceRequestor >);
+
+                static void onInstanceCreated(const RCSRepresentation &, int, const std::string &,
+                    std::shared_ptr< SceneListResourceRequestor >, const CreateInstanceCallback &);
+
+                static RemoteSceneList::Ptr buildSceneList(
+                    std::shared_ptr< SceneListResourceRequestor >, const RCSResourceAttributes &);
+
+                RemoteSceneCollection::Ptr createRemoteSceneCollection(
+                    const std::string &link, const std::string &id, const std::string &name);
+
+                std::shared_ptr< SceneListResourceRequestor > getListResourceRequestor() const;
+
+                std::vector<std::pair<RCSResourceAttributes, std::vector<RCSResourceAttributes>>>
+                    parseSceneListFromAttributes(const RCSResourceAttributes &);
+
+                std::vector<RCSResourceAttributes> getChildrenAttributes(
+                    const RCSResourceAttributes &) const;
+
+                void onSceneCollectionCreated(
+                    const std::string &link, const std::string &id, const std::string &name,
+                    int, const AddNewSceneCollectionCallback &);
+
+                void onNameSet(int, const std::string &, const SetNameCallback &);
+
+            private:
+                std::string m_name;
+                std::vector< RemoteSceneCollection::Ptr > m_remoteSceneCollections;
+                mutable std::mutex m_nameLock;
+                mutable std::mutex m_collectionLock;
+                std::shared_ptr< SceneListResourceRequestor > m_requestor;
+        };
+
+    }
+}
+
+#endif /* SM_REMOTE_SCENELIST_H_ */
\ No newline at end of file
diff --git a/service/scene-manager/include/Scene.h b/service/scene-manager/include/Scene.h
new file mode 100755 (executable)
index 0000000..abc7397
--- /dev/null
@@ -0,0 +1,160 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENE_H_
+#define SM_SCENE_H_
+
+#include "SceneAction.h"
+
+#include <vector>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneCollectionResource;
+
+        /**
+         * @class Scene
+         *
+         * @brief Scene class is an interface class to manage scenes provided by SceneCollection
+         * resource. This class provide APIs for creating a new SceneAction instance, retrieving all
+         * SceneAction instances created before. And it provides an API to execute a scene.
+         *
+         */
+        class Scene
+        {
+        public:
+
+            /**
+             * @class InvalidAddMemberRequestException
+             *
+             * @brief If request of adding member is invalid, throw InvalidMemberRequestException.
+             * Adding member is invalid that scene member resource is already registered.
+             */
+            class InvalidAddMemberRequestException: public RCSException
+            {
+            public:
+                InvalidAddMemberRequestException(std::string&& what) :
+                    RCSException{ std::move(what) } {}
+            };
+
+            typedef std::shared_ptr< Scene > Ptr;
+
+            /**
+             * Typedef for callback of execute APIs
+             *
+             * @see execute
+             */
+            typedef std::function< void(int) >  ExecuteCallback;
+
+        private:
+            Scene(const Scene&) = default;
+            Scene(const std::string&, std::shared_ptr<SceneCollectionResource>);
+            friend class SceneCollection;
+
+        public:
+
+            /**
+             * Adds new SceneAction instance to the Scene instance
+             *
+             * @param pRCSRemoteResourceObject        A pointer of discovered resource
+             * @param key                               A key of attributes
+             * @param value                             A value to be mapped against the key
+             *
+             * @return A shared pointer of SceneAction instance
+             *
+             * @throws RCSInvalidParameterException if pRCSRemoteResourceObject is nullptr
+             * @throws InvalidAddMemberRequestException
+             *         if scene member resource is already registered
+             *
+             * @note SceneAction instance is only produced by Scene class
+             *
+             * @see RCSResourceAttributes
+             */
+            SceneAction::Ptr addNewSceneAction(
+                    const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject,
+                    std::string key, RCSResourceAttributes::Value value);
+
+            /**
+             * Adds new SceneAction instance to the Scene instance
+             *
+             * @param pRCSRemoteResourceObject        A pointer of discovered resource
+             * @param attr                              A attribute set of key and value
+             *
+             * @return A shared pointer of SceneAction instance
+             *
+             * @throws RCSInvalidParameterException if pRCSRemoteResourceObject is nullptr
+             * @throws InvalidAddMemberRequestException if SceneMember is already registered
+             *
+             * @note SceneAction instance is only produced by Scene class
+             *
+             * @see RCSResourceAttributes
+             */
+            SceneAction::Ptr addNewSceneAction(
+                    const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject,
+                    RCSResourceAttributes attr);
+
+            /**
+             * Gets SceneAction using discovered resource
+             *
+             * @param pRCSRemoteResourceObject        A pointer of discovered resource
+             *
+             * @return A shared pointer of SceneAction
+             *
+             * @throws RCSInvalidParameterException
+             * if pRCSRemoteResourceObject is unknown resource
+             */
+            SceneAction::Ptr getSceneAction(
+                    const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject) const;
+
+            /**
+             * Gets all SceneActions include current Scene
+             *
+             * @return A vector of shared pointer of SceneAction instance
+             *
+             */
+            std::vector<SceneAction::Ptr> getSceneActions() const ;
+
+            /**
+             * Gets Scene's name provided SceneCollection resource
+             *
+             * @return Scene's name
+             */
+            std::string getName() const;
+
+            /**
+             * Requests executing Scene to SceneCollection resource
+             *
+             * @param cb                        A callback to execute Scene
+             */
+            void execute(ExecuteCallback cb);
+
+        private:
+            std::string m_name;
+            std::shared_ptr< SceneCollectionResource > m_sceneCollectionResource;
+
+        };
+    } /* namespace Service */
+} /* namespace OIC */
+
+#endif /* SM_SCENE_H_ */
+
diff --git a/service/scene-manager/include/SceneAction.h b/service/scene-manager/include/SceneAction.h
new file mode 100755 (executable)
index 0000000..8c2fd45
--- /dev/null
@@ -0,0 +1,102 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENEACTION_H_
+#define SM_SCENEACTION_H_
+
+#include "RCSRemoteResourceObject.h"
+#include "RCSResourceAttributes.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneMemberResource;
+
+        /**
+         * @class SceneAction
+         *
+         * @brief SceneAction class indicates a unit of actions when a scene is executed.
+         * SceneAction instance is initialized with 3 essential parameters: a target resource,
+         * target attribute key, and its target value. And this class also provide APIs to update
+         * a target attribute information if one wants
+         *
+         */
+        class SceneAction
+        {
+        public:
+            typedef std::shared_ptr< SceneAction > Ptr;
+
+        private:
+            SceneAction(const std::shared_ptr< SceneMemberResource >,
+                    const std::string&, const RCSResourceAttributes&);
+            SceneAction(const std::shared_ptr< SceneMemberResource >,
+                    const std::string&, const std::string&,
+                    const RCSResourceAttributes::Value&);
+            friend class Scene;
+
+        public:
+            /**
+             * Sets the SceneAction parameters like a target attribute key and its value
+             * It replaces existing execution parameter
+             *
+             * @param key                   A key of attributes
+             * @param value                 A value to be mapped against the key
+             *
+             * @see RCSResourceAttributes
+             */
+            void resetExecutionParameter(const std::string& key, RCSResourceAttributes::Value value);
+
+            /**
+             * Sets the SceneAction parameters like a target attribute key and its value
+             * It replaces existing execution parameter
+             *
+             * @param attr                  Attributes to set
+             *
+             * @see RCSResourceAttributes
+             */
+            void resetExecutionParameter(const RCSResourceAttributes& attr);
+
+            /**
+             * Gets execution parameter of the SceneAction instance
+             *
+             * @return attributes of SceneMember resource
+             *
+             * @see RCSResourceAttributes
+             */
+            RCSResourceAttributes getExecutionParameter() const;
+
+            /**
+             * Gets remote resource object
+             *
+             * @return RCSRemoteResourceObject
+             */
+            RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+        private:
+            RCSRemoteResourceObject::Ptr m_pRemoteResourceObject;
+            std::string m_sceneName;
+            std::shared_ptr< SceneMemberResource > m_sceneMemberResource;
+        };
+    } /* namespace Service */
+} /* namespace OIC */
+
+#endif /* SM_SCENEACTION_H_ */
diff --git a/service/scene-manager/include/SceneCollection.h b/service/scene-manager/include/SceneCollection.h
new file mode 100755 (executable)
index 0000000..0d13e75
--- /dev/null
@@ -0,0 +1,114 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENECOLLECTION_H_
+#define SM_SCENECOLLECTION_H_
+
+#include "Scene.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneCollectionResource;
+
+        /**
+         * @class SceneCollection
+         *
+         * @brief SceneCollection class is an interface class to manage SceneCollection resource.
+         * This class provides APIs to create a new Scene instance and retrieve all Scene instances
+         * created before. Besides, it provide APIs for retrieving and updating attribute values
+         * like name attribute
+         *
+         */
+        class SceneCollection
+        {
+        public:
+            typedef std::shared_ptr< SceneCollection > Ptr;
+
+        private:
+            SceneCollection(const std::shared_ptr< SceneCollectionResource >&);
+            friend class SceneList;
+
+        public:
+
+            /**
+             * Adds new Scene instance to SceneCollection resource
+             *
+             * @param sceneName              A scene's name
+             *
+             * @return A shared pointer of Scene instance
+             *
+             * @note Scene instance is only produced by SceneCollection class
+             * @note Scene's name must unique in one SceneCollection resource
+             */
+            Scene::Ptr addNewScene(const std::string& sceneName);
+
+            /**
+             * Gets all Scene instances from SceneCollection resource
+             *
+             * @return A unordered_map of shared pointers of Scene instances with a Scene's name
+             */
+            std::unordered_map< std::string, Scene::Ptr > getScenes() const;
+
+            /**
+             * Gets a Scene instance with a specific Scene's name.
+             *
+             * @param sceneName             A Scene's name
+             *
+             * @return A shared pointer of Scene instance
+             *
+             * @throws RCSInvalidParameterException
+             * if Scene's name does not exist in SceneCollection resource
+             */
+            Scene::Ptr getScene(const std::string& sceneName) const;
+
+            /**
+             * Sets a name attribute of SceneCollection resource
+             *
+             * @param name               A SceneCollection resource's name
+             */
+            void setName(const std::string& name);
+
+            /**
+             * Gets a name attribute from SceneCollection resource.
+             *
+             * @return A SceneCollection resource's name
+             */
+            std::string getName() const;
+
+            /**
+             * Gets a Id attribute of SceneCollection resource.
+             *
+             * @return A SceneCollection resource's Id
+             *
+             */
+            std::string getId() const;
+
+        private:
+            std::shared_ptr< SceneCollectionResource > m_sceneCollectionResource;
+
+        };
+    } /* namespace Service */
+} /* namespace OIC */
+
+#endif /* SM_SCENECOLLECTION_H_ */
+
diff --git a/service/scene-manager/include/SceneList.h b/service/scene-manager/include/SceneList.h
new file mode 100755 (executable)
index 0000000..89d3334
--- /dev/null
@@ -0,0 +1,92 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENELIST_H_
+#define SM_SCENELIST_H_
+
+#include "SceneCollection.h"
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        /**
+         * @class SceneList
+         *
+         * @brief SceneList class is an interface class to manage SceneList resource. This class
+         * provides APIs for creating a new SceneCollection instance and retrieving the existing
+         * instances as well as for setting/getting a name attribute of SceneList resource.
+         *
+         */
+        class SceneList
+        {
+        private:
+            SceneList() = default;
+            ~SceneList() = default;
+
+        public:
+            /**
+             * Gets static instance of SceneList
+             *
+             * @return SceneList instance
+             *
+             */
+            static SceneList* getInstance();
+
+            /**
+             * Adds new SceneCollection instance
+             *
+             * @return A shared pointer of SceneCollection instance
+             *
+             * @note SceneCollection instance is only produced by SceneList class
+             */
+            SceneCollection::Ptr addNewSceneCollection();
+
+            /**
+             * Gets all SceneCollection instances stored in SceneList resource
+             *
+             * @return A vector of shared pointers of SceneCollection instances
+             *
+             * @note SceneCollection instance that addNewSceneCollection returns is not same
+             * instance that getSceneCollections returns
+             */
+            std::vector<SceneCollection::Ptr> getSceneCollections() const;
+
+            /**
+             * Sets a name attribute of SceneList resource
+             *
+             * @param sceneListName               A SceneList resource's name
+             */
+            void setName(const std::string& sceneListName);
+
+            /**
+             * Gets a name attribute of SceneList resource
+             *
+             * @return A SceneList resource's name
+             */
+            std::string getName() const;
+        };
+    } /* namespace Service */
+} /* namespace OIC */
+
+#endif /* SM_SCENELIST_H_ */
diff --git a/service/scene-manager/sampleapp/SConscript b/service/scene-manager/sampleapp/SConscript
new file mode 100755 (executable)
index 0000000..d59dc6d
--- /dev/null
@@ -0,0 +1,10 @@
+##
+# Examples build script
+##
+Import('env')
+
+target_os = env.get('TARGET_OS')
+if target_os == 'linux':
+       SConscript('linux/SConscript')
+elif target_os == 'arduino':
+       SConscript('arduino/SConscript')
\ No newline at end of file
diff --git a/service/scene-manager/sampleapp/linux/SConscript b/service/scene-manager/sampleapp/linux/SConscript
new file mode 100755 (executable)
index 0000000..6946510
--- /dev/null
@@ -0,0 +1,48 @@
+##
+# GroupManager build script
+##
+
+Import('env')
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+scenemanager_sample_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+scenemanager_sample_env.AppendUnique(CPPPATH = ['../../include', '../../src'])
+scenemanager_sample_env.AppendUnique(CPPPATH = ['../../../resource-encapsulation/include'])
+scenemanager_sample_env.AppendUnique(CPPPATH = ['../../../../extlibs/cjson'])
+scenemanager_sample_env.AppendUnique(CPPPATH = ['../../../../resource/csdk/connectivity/api'])
+scenemanager_sample_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+scenemanager_sample_env.AppendUnique(LIBS = [
+    'scene_manager',
+    'rcs_client',
+    'rcs_server',
+    'rcs_common',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    'pthread'
+    ])
+
+if env.get('SECURED') == '1':
+    scenemanager_sample_env.AppendUnique(LIBS = ['tinydtls'])
+
+if 'rt' in scenemanager_sample_env.get('LIBS'):
+    scenemanager_sample_env.Append(LIBS = ['rt'])
+
+if not env.get('RELEASE'):
+    scenemanager_sample_env.PrependUnique(LIBS = ['gcov'])
+    scenemanager_sample_env.AppendUnique(CXXFLAGS = ['--coverage'])
+####################################################################
+# Source files and Targets
+######################################################################
+sceneserver = scenemanager_sample_env.Program('sceneserver', 'sceneserver.cpp')
+sceneclient = scenemanager_sample_env.Program('sceneclient', 'sceneclient.cpp')
+fanserver = scenemanager_sample_env.Program('fanserver', 'fanserver.cpp')
+lightserver = scenemanager_sample_env.Program('lightserver', 'lightserver.cpp')
\ No newline at end of file
diff --git a/service/scene-manager/sampleapp/linux/fanserver.cpp b/service/scene-manager/sampleapp/linux/fanserver.cpp
new file mode 100755 (executable)
index 0000000..4f6a3c7
--- /dev/null
@@ -0,0 +1,331 @@
+//******************************************************************
+//
+// 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 FanResource
+{
+
+public:
+    /// Access this property from a TB client
+    std::string m_speed;
+    std::string m_fanUri;
+    OCResourceHandle m_resourceHandle;
+    OCRepresentation m_fanRep;
+
+public:
+    /// Constructor
+    FanResource() :
+            m_speed("10"), m_fanUri("/a/fan"), m_resourceHandle(0)
+    {
+        // Initialize representation
+        m_fanRep.setUri(m_fanUri);
+
+        m_fanRep.setValue("speed", m_speed);
+    }
+
+    /* 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_fanUri; //URI of the resource
+        std::string resourceTypeName = "core.fan"; //resource type name. In this case, it is light
+        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+
+        EntityHandler cb = std::bind(&FanResource::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("speed", m_speed))
+            {
+                cout << "\t\t\t\t" << "speed: " << m_speed << endl;
+            }
+            else
+            {
+                cout << "\t\t\t\t" << "speed 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_fanRep.setValue("speed", m_speed);
+
+        return m_fanRep;
+    }
+
+    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::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
+    FanResource* fanPtr = (FanResource*) 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(fanPtr->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()
+{
+    // 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').
+        FanResource myFan;
+
+        // Invoke createResource function of class light.
+        myFan.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/scene-manager/sampleapp/linux/lightserver.cpp b/service/scene-manager/sampleapp/linux/lightserver.cpp
new file mode 100755 (executable)
index 0000000..45ae0f0
--- /dev/null
@@ -0,0 +1,331 @@
+//******************************************************************
+//
+// 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::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()
+{
+    // 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/scene-manager/sampleapp/linux/sceneclient.cpp b/service/scene-manager/sampleapp/linux/sceneclient.cpp
new file mode 100755 (executable)
index 0000000..48837f1
--- /dev/null
@@ -0,0 +1,574 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#include "OCPlatform.h"
+#include "RCSDiscoveryManager.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSAddress.h"
+#include "RemoteSceneList.h"
+
+using namespace OC;
+using namespace OIC::Service;
+
+constexpr int CREATE_REMOTE_SCENE_LIST = 1;
+
+constexpr int CREATE_REMOTE_SCENE_COLLECTION = 1;
+constexpr int SHOW_REMOTE_SCENE_COLLECTION = 2;
+
+constexpr int CREATE_REMOTE_SCENE = 1;
+constexpr int CREATE_REMOTE_SCENE_ACTION = 1;
+
+constexpr int EXECUTE_REMOTE_SCENE = 1;
+
+constexpr int SCENE_RESULT_OK = 200;
+
+constexpr int numCreatedSceneAction = 2;
+static int numRecvSceneActionCreationResp = 0;
+
+typedef std::function< void() > Run;
+Run g_currentRun;
+
+const std::string scene_name = "Night mode";
+const std::string relativetUri = OC_RSRVD_WELL_KNOWN_URI;
+const std::vector<std::string> resourceTypes{ "oic.wk.scenelist", "core.light", "core.fan" };
+
+std::mutex g_mtx;
+std::mutex g_discoverymtx;
+std::condition_variable g_cond;
+
+std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> g_discoveryTask;
+
+RCSRemoteResourceObject::Ptr g_foundListResource;
+RCSRemoteResourceObject::Ptr g_foundLightResource;
+RCSRemoteResourceObject::Ptr g_foundFanResource;
+
+RemoteSceneList::Ptr g_sceneList;
+RemoteSceneCollection::Ptr g_sceneCollection;
+RemoteScene::Ptr g_scene;
+
+void displaySceneList();
+void runCreateRemoteSceneList();
+void runRemoteSceneCollection();
+void runCreateRemoteScene();
+void runCreateRemoteSceneAction();
+void runExecuteCreatedRemoteScene();
+void runExecuteExistingRemoteScene();
+
+// Scene Manager Remote API sample ---
+void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int eCode)
+{
+    std::cout << __func__ << " - error code : " << eCode << std::endl;
+
+    if (eCode == SCENE_RESULT_OK)
+    {
+        g_sceneList = std::move(remoteSceneList);
+        g_currentRun = runRemoteSceneCollection;
+    }
+    else
+    {
+        std::cout << "Create Remote scene list failed." << std::endl;
+        g_currentRun = runCreateRemoteSceneList;
+    }
+    g_currentRun();
+}
+
+void onRemoteSceneCollectionCreated(RemoteSceneCollection::Ptr remoteSceneCol, int eCode)
+{
+    std::cout << __func__ << " - error code : " << eCode << std::endl;
+
+    if (eCode == SCENE_RESULT_OK)
+    {
+        g_sceneCollection = remoteSceneCol;
+        g_currentRun = runCreateRemoteScene;
+    }
+    else
+    {
+        std::cout << "Create Remote scene collection failed." << std::endl;
+        g_currentRun = runRemoteSceneCollection;
+    }
+
+    g_currentRun();
+}
+
+void onRemoteSceneCreated(RemoteScene::Ptr remoteScene, int eCode)
+{
+    std::cout << __func__ << " - error code : " << eCode << std::endl;
+
+    if (eCode == SCENE_RESULT_OK)
+    {
+        g_scene = remoteScene;
+
+        g_currentRun = runCreateRemoteSceneAction;
+    }
+    else
+    {
+        std::cout << "Create Remote scene failed." << std::endl;
+        g_currentRun = runCreateRemoteScene;
+    }
+
+    g_currentRun();
+}
+
+void onRemoteSceneActionCreated(RemoteSceneAction::Ptr, int eCode)
+{
+    std::cout << __func__ << " - error code : " << eCode << std::endl;
+
+    if (eCode == SCENE_RESULT_OK)
+    {
+        g_currentRun = runExecuteCreatedRemoteScene;
+    }
+    else
+    {
+        std::cout << "Create Remote scene action failed." << std::endl;
+        g_currentRun = runCreateRemoteSceneAction;
+    }
+
+    numRecvSceneActionCreationResp++;
+
+    if(numCreatedSceneAction == numRecvSceneActionCreationResp)
+        g_currentRun();
+}
+
+void onRemoteSceneExecuted(const std::string &sceneName, int eCode)
+{
+    std::cout << __func__ << " - scene name : " << sceneName
+              <<  ", error code : " << eCode << std::endl;
+
+    if (eCode != SCENE_RESULT_OK)
+    {
+        std::cout << "Execute scene failed." << std::endl;
+    }
+
+    g_currentRun();
+}
+
+// --- Scene Manager Remote API sample
+
+void createRemoteSceneList()
+{
+    if (g_foundListResource)
+    {
+        RemoteSceneList::createInstance(g_foundListResource, onRemoteSceneListCreated);
+    }
+    else
+    {
+        std::cout << "Scene List Resource is not discovered." << std::endl;
+        g_currentRun();
+    }
+}
+
+void createRemoteSceneCollection()
+{
+    if (!g_sceneList) return;
+
+    g_sceneList->addNewSceneCollection(onRemoteSceneCollectionCreated);
+}
+
+void showRemoteSceneCollection()
+{
+    if (!g_sceneList) return;
+
+    if (g_sceneList->getRemoteSceneCollections().size() == 0) return;
+
+    g_sceneCollection = g_sceneList->getRemoteSceneCollections().at(0);
+
+    if( g_sceneCollection->getRemoteScenes().size() == 0) return;
+
+    g_scene = g_sceneCollection->getRemoteScenes().begin()->second;
+}
+
+void createRemoteScene()
+{
+    if (!g_sceneCollection) return;
+
+    g_sceneCollection->addNewScene(scene_name, onRemoteSceneCreated);
+}
+
+void createRemoteSceneAction(
+    RemoteScene::Ptr scene, RCSRemoteResourceObject::Ptr member,
+    const std::string &key, const std::string &value)
+{
+    if (scene && member)
+    {
+        g_scene->addNewSceneAction(member, key, RCSResourceAttributes::Value(value),
+            onRemoteSceneActionCreated);
+    }
+}
+
+void createRemoteSceneActions()
+{
+    createRemoteSceneAction(g_scene, g_foundLightResource, "power", "on");
+    createRemoteSceneAction(g_scene, g_foundFanResource, "speed", "50");
+}
+
+void executeScene()
+{
+    displaySceneList();
+
+    if (g_scene)
+    {
+        g_scene->execute(onRemoteSceneExecuted);
+        std::cout << "\n\t'" << g_scene->getName() << "' is executed!\n" << std::endl;
+    }
+}
+
+// --- Scene Manager Remote API sample
+
+void configurePlatform()
+{
+    PlatformConfig config
+    {
+        OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos
+    };
+    OCPlatform::Configure(config);
+}
+
+int processUserInput(int min, int max)
+{
+    assert(min <= max);
+
+    int input;
+
+    std::cin >> input;
+
+    if (!std::cin.fail())
+    {
+        if (input == max + 1)  exit(0);
+        if (min <= input && input <= max) return input;
+    }
+
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
+}
+
+void displaySceneList()
+{
+    if (!g_sceneList) return;
+
+    std::cout << "\t" << g_sceneList->getName() << "(SceneList)" << std::endl;
+
+    if (!g_sceneCollection) return;
+
+    std::cout << "\t\t   |_ _ _ " << g_sceneCollection->getId() << " (SceneCollection)" << std::endl;
+
+    for( const auto &it_scene : g_sceneCollection->getRemoteScenes() )
+    {
+        std::cout << "\t\t\t   |_ _ _ " << it_scene.first << " (Scene)" << std::endl;
+
+        auto sceneActionList = it_scene.second->getRemoteSceneActions();
+        for (const auto &it : sceneActionList)
+        {
+            auto attr = it->getExecutionParameter();
+            for (const auto &att : attr)
+            {
+                std::cout << "\t\t\t      \t\t|_ _ _ ";
+                std::cout << it->getRemoteResourceObject()->getUri() << " : ";
+                std::cout << att.key() << " - " << att.value().toString() << std::endl;
+            }
+        }
+    }
+}
+
+void displayClear(Run runFunc)
+{
+    auto ret = std::system("/usr/bin/clear");
+    if(ret == -1)
+    {
+        std::cout << "clear error!" << std::endl;
+    }
+    g_currentRun = runFunc;
+}
+
+void displayCreateRemoteSceneListMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_REMOTE_SCENE_LIST  << ". Create a RemoteSceneList \n";
+    std::cout << CREATE_REMOTE_SCENE_LIST + 1  << ". Quit                 \n";
+    std::cout << "========================================================\n";
+}
+
+void displayRemoteSceneCollectionMenu()
+{
+    std::cout << "========================================================               \n";
+    std::cout << CREATE_REMOTE_SCENE_COLLECTION  << ". Create a RemoteSceneCollection    \n";
+    std::cout << SHOW_REMOTE_SCENE_COLLECTION  << ". Show existing RemoteSceneCollection \n";
+    std::cout << SHOW_REMOTE_SCENE_COLLECTION + 1  << ". Quit                            \n";
+    std::cout << "========================================================               \n";
+}
+
+void displayRemoteSceneCreationMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_REMOTE_SCENE  << ". Create a RemoteScene          \n";
+    std::cout << CREATE_REMOTE_SCENE + 1  << ". Quit                      \n";
+    std::cout << "========================================================\n";
+}
+
+void displayRemoteSceneActionCreationMenu()
+{
+    std::cout << "========================================================   \n";
+    std::cout << CREATE_REMOTE_SCENE_ACTION  << ". Create RemoteSceneActions \n";
+    std::cout << CREATE_REMOTE_SCENE_ACTION + 1  << ". Quit                  \n";
+    std::cout << "========================================================   \n";
+}
+
+void displayExecuteCreatedRemoteSceneCreationMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << EXECUTE_REMOTE_SCENE  << ". Execute RemoteScene          \n";
+    std::cout << EXECUTE_REMOTE_SCENE + 1  << ". Quit                     \n";
+    std::cout << "========================================================\n";
+}
+
+void displayExecuteExistingRemoteSceneCreationMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << EXECUTE_REMOTE_SCENE  << ". Execute a first RemoteScene  \n";
+    std::cout << EXECUTE_REMOTE_SCENE + 1  << ". Quit                     \n";
+    std::cout << "========================================================\n";
+}
+
+void runExecuteExistingRemoteScene()
+{
+    displaySceneList();
+
+    displayExecuteExistingRemoteSceneCreationMenu();
+
+    try
+    {
+        int command = processUserInput(EXECUTE_REMOTE_SCENE, EXECUTE_REMOTE_SCENE);
+        switch(command)
+        {
+            case EXECUTE_REMOTE_SCENE:
+                executeScene();
+                displayClear(runExecuteExistingRemoteScene);
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void runExecuteCreatedRemoteScene()
+{
+    displaySceneList();
+
+    displayExecuteCreatedRemoteSceneCreationMenu();
+
+    try
+    {
+        int command = processUserInput(EXECUTE_REMOTE_SCENE, EXECUTE_REMOTE_SCENE);
+        switch(command)
+        {
+            case EXECUTE_REMOTE_SCENE:
+                executeScene();
+                displayClear(runExecuteCreatedRemoteScene);
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void runCreateRemoteSceneAction()
+{
+    displaySceneList();
+
+    displayRemoteSceneActionCreationMenu();
+
+    try
+    {
+        int command = processUserInput(CREATE_REMOTE_SCENE_ACTION, CREATE_REMOTE_SCENE_ACTION);
+        switch(command)
+        {
+            case CREATE_REMOTE_SCENE_ACTION:
+                createRemoteSceneActions();
+                displayClear(runExecuteCreatedRemoteScene);
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void runCreateRemoteScene()
+{
+    displaySceneList();
+
+    displayRemoteSceneCreationMenu();
+
+    try
+    {
+        int command = processUserInput(CREATE_REMOTE_SCENE, CREATE_REMOTE_SCENE);
+        switch(command)
+        {
+            case CREATE_REMOTE_SCENE:
+                createRemoteScene();
+                displayClear(runCreateRemoteSceneAction);
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void runRemoteSceneCollection()
+{
+    displaySceneList();
+
+    displayRemoteSceneCollectionMenu();
+
+    try
+    {
+        int command = processUserInput(CREATE_REMOTE_SCENE_COLLECTION, SHOW_REMOTE_SCENE_COLLECTION);
+        switch(command)
+        {
+            case CREATE_REMOTE_SCENE_COLLECTION:
+                createRemoteSceneCollection();
+                displayClear(runCreateRemoteScene);
+                break;
+            case SHOW_REMOTE_SCENE_COLLECTION:
+                showRemoteSceneCollection();
+                displayClear(runExecuteExistingRemoteScene);
+                g_currentRun();
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void runCreateRemoteSceneList()
+{
+    displayCreateRemoteSceneListMenu();
+
+    try
+    {
+        int command = processUserInput(CREATE_REMOTE_SCENE_LIST, CREATE_REMOTE_SCENE_LIST);
+        switch(command)
+        {
+            case CREATE_REMOTE_SCENE_LIST:
+                createRemoteSceneList();
+                displayClear(runRemoteSceneCollection);
+                break;
+        }
+    } catch (std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        g_currentRun();
+    }
+}
+
+void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
+{
+    std::lock_guard< std::mutex > lock(g_discoverymtx);
+    std::cout << "onResourceDiscovered callback" << std::endl;
+
+    std::string resourceURI = foundResource->getUri();
+    std::string hostAddress = foundResource->getAddress();
+    std::vector< std::string > vecRTs = foundResource->getTypes();
+
+    std::cout << "\t\tResource URI : " << resourceURI << std::endl;
+    std::cout << "\t\tResource Host : " << hostAddress << std::endl;
+
+    // if the found resource is a scene list resource
+    if (std::find(vecRTs.begin(), vecRTs.end(), "oic.wk.scenelist") != vecRTs.end())
+        g_foundListResource = foundResource;
+
+    // if the found resource is a light resource
+    else if (std::find(vecRTs.begin(), vecRTs.end(), "core.light") != vecRTs.end())
+    {
+        g_foundLightResource = foundResource;
+    }
+
+    // if the found resource is a fan resource
+    else if (std::find(vecRTs.begin(), vecRTs.end(), "core.fan") != vecRTs.end())
+    {
+        g_foundFanResource = foundResource;
+    }
+
+    if (g_foundListResource && g_foundLightResource && g_foundFanResource)
+    {
+        g_discoveryTask->cancel();
+        return;
+    }
+
+    g_cond.notify_all();
+}
+
+void discoverResource()
+{
+    std::cout << "Wait 4 seconds until discovered." << std::endl;
+
+    try
+    {
+        g_discoveryTask
+            = RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
+                    relativetUri, resourceTypes, &onResourceDiscovered);
+    }
+    catch (const RCSPlatformException &e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+    std::unique_lock<std::mutex> lck(g_mtx);
+
+    g_cond.wait_for(lck, std::chrono::seconds(4));
+    return;
+}
+
+int main()
+{
+    configurePlatform();
+
+    try
+    {
+        discoverResource();
+
+        g_currentRun = runCreateRemoteSceneList;
+        g_currentRun();
+    }
+    catch(std::exception &e)
+    {
+        std::cout << e.what() << std::endl;
+        return 0;
+    }
+
+    while (true) { }
+
+    std::cout << "Stopping the scene client" << std::endl;
+
+    return 0;
+}
diff --git a/service/scene-manager/sampleapp/linux/sceneserver.cpp b/service/scene-manager/sampleapp/linux/sceneserver.cpp
new file mode 100755 (executable)
index 0000000..a865d11
--- /dev/null
@@ -0,0 +1,436 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <iostream>
+#include <vector>
+
+#include "OCPlatform.h"
+#include "RCSDiscoveryManager.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSResourceAttributes.h"
+#include "RCSResourceObject.h"
+#include "RCSAddress.h"
+#include "SceneList.h"
+
+using namespace OC;
+using namespace OIC::Service;
+
+constexpr int CREATE_SCENE_LIST = 1;
+constexpr int CREATE_SCENE_COLLECTION = 1;
+constexpr int CREATE_SCENE = 1;
+constexpr int CREATE_SCENE_ACTION = 1;
+
+constexpr int EXECUTE_SCENE_1 = 1;
+constexpr int EXECUTE_SCENE_2 = 2;
+
+typedef void (*DisplayControlMenuFunc)();
+typedef std::function<void()> Run;
+
+std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
+Run g_currentRun;
+
+struct CloseApp {};
+
+const std::vector<std::string> resourceTypes{"core.light", "core.fan"};
+const std::string relativetUri = OC_RSRVD_WELL_KNOWN_URI;
+
+std::mutex mtx;
+std::condition_variable cond;
+
+RCSRemoteResourceObject::Ptr g_selectedResource;
+std::shared_ptr<RCSRemoteResourceObject> g_discoveredResources;
+
+std::vector<RCSRemoteResourceObject::Ptr> g_foundResourceList;
+std::vector<RCSResourceObject::Ptr> g_memberResourceList;
+
+SceneCollection::Ptr g_sceneColObj;
+Scene::Ptr g_scene;
+Scene::Ptr g_scene_2;
+SceneAction::Ptr g_sceneAction;
+
+typedef std::function<void(std::shared_ptr<RCSRemoteResourceObject>)> DiscoveryCallback;
+typedef std::function<void (int)> ExecuteCallback;
+
+void onExecute(int /*Code*/)
+{
+    std::cout << __func__ << std::endl;
+}
+
+void configurePlatform()
+{
+    PlatformConfig config
+    {
+        OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos
+    };
+    OCPlatform::Configure(config);
+}
+
+int processUserInput(int min, int max)
+{
+    assert(min <= max);
+
+    int input;
+
+    std::cin >> input;
+
+    if (!std::cin.fail())
+    {
+        if(input == max + 1) throw CloseApp();
+        if(min <= input && input <= max) return input;
+    }
+
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
+}
+
+void displayCreateSceneListMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_SCENE_LIST  << ". Create a SceneList                       \n";
+    std::cout << CREATE_SCENE_LIST + 1  << ". Quit                       \n";
+    std::cout << "========================================================\n";
+}
+
+void displayCreateSceneCollectionMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_SCENE_COLLECTION  << ". Create a SceneCollection                       \n";
+    std::cout << CREATE_SCENE_COLLECTION + 1  << ". Quit                       \n";
+    std::cout << "========================================================\n";
+}
+
+void displayCreateSceneMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_SCENE  << ". Create a Scene                       \n";
+    std::cout << CREATE_SCENE + 1  << ". Quit                       \n";
+    std::cout << "========================================================\n";
+}
+
+void displayCreateSceneActionMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << CREATE_SCENE_ACTION  << ". Create a SceneAction                       \n";
+    std::cout << CREATE_SCENE_ACTION + 1  << ". Quit                       \n";
+    std::cout << "========================================================\n";
+}
+
+void displayExecuteSceneMenu()
+{
+    std::cout << "========================================================\n";
+    std::cout << EXECUTE_SCENE_1  << ". Execute Scene1                       \n";
+    std::cout << EXECUTE_SCENE_2  << ". Execute Scene2                       \n";
+    std::cout << EXECUTE_SCENE_2 + 1  << ". Quit                       \n";
+    std::cout << "========================================================\n";
+}
+
+void displaySceneList()
+{
+    std::cout << "\t" << SceneList::getInstance()->getName();
+    std::cout << "(SceneList)" << std::endl;
+}
+
+void displaySceneCollection()
+{
+    std::cout << "\t\t   |_ _ _ " << g_sceneColObj->getName();
+    std::cout << "(SceneCollection)" << std::endl;
+}
+
+void displayScene()
+{
+    std::cout << "\t\t\t      |_ _ _ " << g_scene->getName();
+    std::cout << "(Scene)" << std::endl;
+    std::cout << "\t\t\t      |_ _ _ " << g_scene_2->getName();
+    std::cout << "(Scene)" << std::endl;
+}
+
+void displayClear(Run runFunc)
+{
+    std::cout << "\nPress Enter to Continue....." << std::endl;
+    std::cin.ignore();
+    if(std::cin.get() == '\n')
+    {
+        auto ret = std::system("/usr/bin/clear");
+        if(ret == -1)
+        {
+            std::cout << "clear error!" << std::endl;
+        }
+        g_currentRun = runFunc;
+    }
+}
+
+void displaySceneAction()
+{
+    std::cout << "\t\t\t      |_ _ _ " << g_scene->getName();
+    std::cout << "(Scene)" << std::endl;
+    auto sceneActionList = g_scene->getSceneActions();
+    for(const auto &it : sceneActionList)
+    {
+        auto attr = it->getExecutionParameter();
+        for(const auto &att : attr)
+        {
+            std::cout << "\t\t\t      |\t\t|_ _ _ ";
+            std::cout << it->getRemoteResourceObject()->getUri() << ":";
+            std::cout << att.key() << " - "  << att.value().toString() << std::endl;
+        }
+    }
+
+    std::cout << "\t\t\t      |_ _ _ " << g_scene_2->getName();
+    std::cout << "(Scene)" << std::endl;
+
+    sceneActionList = g_scene_2->getSceneActions();
+    for(const auto &it : sceneActionList)
+    {
+        auto attr = it->getExecutionParameter();
+        for(const auto &att : attr)
+        {
+            std::cout << "\t\t\t       \t\t|_ _ _ ";
+            std::cout << it->getRemoteResourceObject()->getUri() << ":";
+            std::cout << att.key() << " - "  << att.value().toString() << std::endl;
+        }
+    }
+}
+
+void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
+{
+    std::cout << "onResourceDiscovered callback" << std::endl;
+
+    std::string resourceURI = foundResource->getUri();
+    std::string hostAddress = foundResource->getAddress();
+
+    std::cout << "\t\tResource URI : " << resourceURI << std::endl;
+    std::cout << "\t\tResource Host : " << hostAddress << std::endl;
+
+    g_foundResourceList.push_back(foundResource);
+
+    cond.notify_all();
+}
+
+bool discoverResource()
+{
+    std::cout << "Wait 2 seconds until discovered." << std::endl;
+
+    try
+    {
+        discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByTypes(
+                RCSAddress::multicast(), relativetUri, resourceTypes, &onResourceDiscovered);
+    }
+    catch(const RCSPlatformException& e)
+    {
+         std::cout << e.what() << std::endl;
+    }
+    catch(const RCSException& e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+    std::unique_lock<std::mutex> lck(mtx);
+
+    cond.wait_for(lck, std::chrono::seconds(4));
+    return g_discoveredResources != nullptr;
+}
+
+void createSceneList()
+{
+    SceneList::getInstance()->setName("Home");
+    displaySceneList();
+}
+
+void createSceneCollection()
+{
+    g_sceneColObj = SceneList::getInstance()->addNewSceneCollection();
+    g_sceneColObj->setName("Living Room");
+    displaySceneList();
+    displaySceneCollection();
+}
+
+void createScene()
+{
+    try
+    {
+        g_scene = g_sceneColObj->addNewScene("Going Out");
+        g_scene_2 = g_sceneColObj->addNewScene("TV mode");
+    }
+    catch(const RCSException& e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+
+    displaySceneList();
+    displaySceneCollection();
+    displayScene();
+}
+
+void createSceneAction()
+{
+    try
+    {
+        g_scene->addNewSceneAction(g_foundResourceList.at(0), "power", "off");
+        g_scene->addNewSceneAction(g_foundResourceList.at(1), "speed", "0");
+
+        g_scene_2->addNewSceneAction(g_foundResourceList.at(0), "power", "on");
+        g_scene_2->addNewSceneAction(g_foundResourceList.at(1), "speed", "20");
+    }
+    catch(const RCSException& e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+
+    displaySceneList();
+    displaySceneCollection();
+    displaySceneAction();
+}
+
+void executeScene(int sceneNum)
+{
+    displaySceneList();
+    displaySceneCollection();
+    displaySceneAction();
+
+    switch(sceneNum)
+    {
+        case 1:
+            try
+            {
+                g_scene->execute(onExecute);
+                std::cout << "\t'" << g_scene->getName() << "' is executed!" << std::endl;
+            }
+            catch(const RCSException& e)
+            {
+                std::cout << e.what() <<std::endl;
+            }
+            break;
+        case 2:
+            try
+            {
+                g_scene_2->execute(onExecute);
+                std::cout << "\t'" << g_scene_2->getName() << "' is executed!" << std::endl;
+            }
+            catch(const RCSException& e)
+            {
+                std::cout << e.what() <<std::endl;
+            }
+            break;
+    }
+}
+
+void runExecuteScene()
+{
+    displayExecuteSceneMenu();
+
+    int command = processUserInput(EXECUTE_SCENE_1, EXECUTE_SCENE_2);
+    switch(command)
+    {
+        case EXECUTE_SCENE_1:
+            executeScene(1);
+            break;
+        case EXECUTE_SCENE_2:
+            executeScene(2);
+            break;
+    }
+    displayClear(runExecuteScene);
+}
+
+void runCreateSceneAction()
+{
+    displayCreateSceneActionMenu();
+
+    int command = processUserInput(CREATE_SCENE_ACTION, CREATE_SCENE_ACTION);
+    switch(command)
+    {
+        case CREATE_SCENE_ACTION:
+            createSceneAction();
+            displayClear(runExecuteScene);
+            break;
+    }
+}
+
+void runCreateScene()
+{
+    displayCreateSceneMenu();
+
+    int command = processUserInput(CREATE_SCENE, CREATE_SCENE);
+    switch(command)
+    {
+        case CREATE_SCENE:
+            createScene();
+            displayClear(runCreateSceneAction);
+            break;
+    }
+}
+
+void runCreateSceneCollection()
+{
+    displayCreateSceneCollectionMenu();
+
+    int command = processUserInput(CREATE_SCENE_COLLECTION, CREATE_SCENE_COLLECTION);
+    switch(command)
+    {
+        case CREATE_SCENE_COLLECTION:
+            createSceneCollection();
+            displayClear(runCreateScene);
+            break;
+    }
+}
+
+void runCreateSceneList()
+{
+    displayCreateSceneListMenu();
+
+    int command = processUserInput(CREATE_SCENE_LIST, CREATE_SCENE_LIST);
+    switch(command)
+    {
+        case CREATE_SCENE_LIST:
+            discoveryTask->cancel();
+            createSceneList();
+            displayClear(runCreateSceneCollection);
+            break;
+    }
+}
+
+int main()
+{
+    configurePlatform();
+
+    discoverResource();
+
+    g_currentRun = runCreateSceneList;
+
+    while (true)
+    {
+        try
+        {
+            g_currentRun();
+        }
+        catch (const std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+        catch (const CloseApp&)
+        {
+            break;
+        }
+    }
+
+    std::cout << "Stopping the client" << std::endl;
+
+    return 0;
+}
diff --git a/service/scene-manager/src/RemoteScene.cpp b/service/scene-manager/src/RemoteScene.cpp
new file mode 100644 (file)
index 0000000..5956d8b
--- /dev/null
@@ -0,0 +1,195 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "RemoteScene.h"
+
+#include <utility>
+#include <cassert>
+
+#include "SceneCommons.h"
+#include "SceneCollectionResourceRequestor.h"
+#include "SceneMemberResourceRequestor.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RemoteScene::RemoteScene(
+            const std::string &name, std::shared_ptr< SceneCollectionResourceRequestor > requestor)
+            : m_name{ name }, m_requestor{ requestor }
+        {
+            assert(requestor);
+        }
+
+        void RemoteScene::addNewSceneAction(
+            RCSRemoteResourceObject::Ptr targetResource, const RCSResourceAttributes &attrs,
+            AddNewSceneActionCallback clientCB)
+        {
+            if (targetResource == nullptr)
+            {
+                throw RCSInvalidParameterException("RCSRemoteResoureObject value is null");
+            }
+
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "addNewSceneAction : Callback is NULL" };
+            }
+
+            SceneCollectionResourceRequestor::InternalAddMemberCallback internalCB
+                = std::bind(&RemoteScene::onSceneActionAdded, this,
+                std::placeholders::_1, targetResource, attrs, std::move(clientCB));
+
+            m_requestor->requestAddSceneMember(
+                targetResource, m_name, attrs, internalCB);
+        }
+
+        void RemoteScene::addNewSceneAction(
+            RCSRemoteResourceObject::Ptr targetResource,
+            const std::string &key, const RCSResourceAttributes::Value &value,
+            AddNewSceneActionCallback clientCB)
+        {
+            RCSResourceAttributes attrs;
+            attrs[key] = RCSResourceAttributes::Value(value);
+
+            addNewSceneAction(targetResource, attrs, clientCB);
+        }
+
+        std::vector< RemoteSceneAction::Ptr > RemoteScene::getRemoteSceneActions() const
+        {
+            std::lock_guard< std::mutex > actionlock(m_sceneActionLock);
+            std::vector< RemoteSceneAction::Ptr > sceneActionList;
+
+            for (auto itrMap : m_remoteSceneActions)
+            {
+                sceneActionList.push_back(itrMap.second);
+            }
+
+            return sceneActionList;
+        }
+
+        RemoteSceneAction::Ptr RemoteScene::getRemoteSceneAction(
+            const RCSRemoteResourceObject::Ptr targetResource) const
+        {
+            if (targetResource == nullptr)
+            {
+                throw RCSInvalidParameterException("RCSRemoteResoureObject value is null");
+            }
+
+            std::lock_guard< std::mutex > actionlock(m_sceneActionLock);
+            auto itr = m_remoteSceneActions.find(
+                targetResource->getAddress() + targetResource->getUri());
+
+            if (itr == m_remoteSceneActions.end())
+            {
+                throw RCSInvalidParameterException("Invalid RCSRemoteResoureObject");
+            }
+
+            return itr->second;
+        }
+
+        std::string RemoteScene::getName() const
+        {
+            return m_name;
+        }
+
+        void RemoteScene::execute(RemoteSceneExecuteCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "execute : Callback is NULL" };
+            }
+
+            SceneCollectionResourceRequestor::InternalSceneRequestCallback internalCB
+                = std::bind(&RemoteScene::onSceneExecuted, this, std::placeholders::_2,
+                            std::placeholders::_3, std::move(clientCB));
+
+            m_requestor->requestSceneExecution(m_name, internalCB);
+        }
+
+        RemoteSceneAction::Ptr RemoteScene::createRemoteSceneAction(
+            const std::string &targetHref, const RCSResourceAttributes &attrs)
+        {
+            SceneMemberResourceRequestor::Ptr memRequestor
+                = m_requestor->getSceneMemberResourceRequestor(targetHref);
+
+            if (memRequestor == nullptr)
+            {
+                return nullptr;
+            }
+
+            RemoteSceneAction::Ptr newAction(new RemoteSceneAction(memRequestor, m_name, attrs));
+
+            {
+                std::lock_guard< std::mutex > actionlock(m_sceneActionLock);
+                m_remoteSceneActions.insert(
+                    std::make_pair(targetHref, newAction));
+            }
+
+            return newAction;
+        }
+
+        void RemoteScene::addExistingRemoteSceneAction(
+            const std::string &href, const std::string &id, RCSRemoteResourceObject::Ptr target,
+            const std::string &key, const RCSResourceAttributes::Value &value)
+        {
+            std::string targetHref = target->getAddress() + target->getUri();
+
+            SceneMemberResourceRequestor::Ptr foundMemberRequestor
+                = m_requestor->getSceneMemberResourceRequestor(targetHref);
+
+            if (foundMemberRequestor == nullptr)
+                m_requestor->createSceneMemberResourceRequestor(href, id, target);
+
+            RCSResourceAttributes attrs;
+            attrs[key] = RCSResourceAttributes::Value(value);
+
+            createRemoteSceneAction(targetHref, attrs);
+        }
+
+        void RemoteScene::onSceneActionAdded(
+            int eCode, RCSRemoteResourceObject::Ptr target, const RCSResourceAttributes &attrs,
+            const AddNewSceneActionCallback &clientCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            RemoteSceneAction::Ptr newAction = nullptr;
+
+            if (eCode == SCENE_RESPONSE_SUCCESS)
+            {
+                std::string targetLink = target->getAddress() + target->getUri();
+
+                newAction = createRemoteSceneAction(targetLink, attrs);
+
+                if (newAction)
+                    result = SCENE_RESPONSE_SUCCESS;
+            }
+
+            clientCB(newAction, result);
+        }
+
+        void RemoteScene::onSceneExecuted(const std::string &sceneName, const int eCode,
+            const RemoteSceneExecuteCallback &clientCB)
+        {
+            clientCB(sceneName, eCode);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/service/scene-manager/src/RemoteSceneAction.cpp b/service/scene-manager/src/RemoteSceneAction.cpp
new file mode 100644 (file)
index 0000000..314ad16
--- /dev/null
@@ -0,0 +1,101 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "RemoteSceneAction.h"
+
+#include <cassert>
+
+#include "SceneCommons.h"
+#include "SceneMemberResourceRequestor.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RemoteSceneAction::RemoteSceneAction(
+            SceneMemberResourceRequestor::Ptr requestor,
+            const std::string &sceneName, const RCSResourceAttributes &attrs)
+                : m_sceneName{ sceneName }, m_attributes{ attrs }, m_requestor{ requestor }
+        {
+            assert(requestor);
+        }
+
+        RemoteSceneAction::RemoteSceneAction(
+            SceneMemberResourceRequestor::Ptr requestor, const std::string &sceneName,
+            const std::string &key, const RCSResourceAttributes::Value &value)
+                : m_sceneName{ sceneName }, m_requestor{ requestor }
+        {
+            assert(requestor);
+            m_attributes[key] = value;
+        }
+
+        void RemoteSceneAction::resetExecutionParameter(const std::string &key,
+                                       const RCSResourceAttributes::Value &value,
+                                       ResetExecutionParameterCallback clientCB)
+        {
+            RCSResourceAttributes attr;
+            attr[key] = RCSResourceAttributes::Value(value);
+
+            resetExecutionParameter(attr, std::move(clientCB));
+        }
+
+        void RemoteSceneAction::resetExecutionParameter(const RCSResourceAttributes &attr,
+            ResetExecutionParameterCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "resetExecutionParameter : Callback is NULL" };
+            }
+
+            SceneMemberResourceRequestor::InternalAddSceneActionCallback internalCB
+                = std::bind(&RemoteSceneAction::onExecutionParameterSet, this,
+                std::placeholders::_1, attr, std::move(clientCB));
+
+            m_requestor->requestSceneActionCreation(
+                m_sceneName, attr, internalCB);
+        }
+
+        RCSResourceAttributes RemoteSceneAction::getExecutionParameter() const
+        {
+            std::lock_guard< std::mutex > lock(m_attributeLock);
+            return m_attributes;
+        }
+
+        RCSRemoteResourceObject::Ptr RemoteSceneAction::getRemoteResourceObject() const
+        {
+            return m_requestor->getRemoteResourceObject();
+        }
+
+        void RemoteSceneAction::onExecutionParameterSet(int eCode, const RCSResourceAttributes &attr,
+            const ResetExecutionParameterCallback &clientCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            if (eCode == SCENE_RESPONSE_SUCCESS)
+            {
+                std::lock_guard< std::mutex > lock(m_attributeLock);
+                m_attributes = attr;
+                result = SCENE_RESPONSE_SUCCESS;
+            }
+
+            clientCB(result);
+        }
+    }
+}
diff --git a/service/scene-manager/src/RemoteSceneCollection.cpp b/service/scene-manager/src/RemoteSceneCollection.cpp
new file mode 100644 (file)
index 0000000..f0ffd05
--- /dev/null
@@ -0,0 +1,212 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "RemoteSceneCollection.h"
+
+#include <cassert>
+
+#include "SceneCommons.h"
+#include "RemoteSceneUtils.h"
+#include "SceneCollectionResourceRequestor.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RemoteSceneCollection::RemoteSceneCollection(
+            std::shared_ptr< SceneCollectionResourceRequestor > requestor,
+            const std::string &id, const std::string &name)
+            : m_id{ id }, m_name{ name }, m_requestor{ requestor }
+        {
+            assert(requestor);
+        }
+
+        void RemoteSceneCollection::addNewScene
+        (const std::string &name, AddNewSceneCallback clientCB)
+        {
+            if (name.empty())
+            {
+                throw RCSInvalidParameterException("Scene name is an empty string");
+            }
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "addNewScene : Callback is NULL" };
+            }
+
+            SceneCollectionResourceRequestor::InternalSceneRequestCallback internalCB
+                = std::bind(&RemoteSceneCollection::onSceneAddedRemoved, this,
+                            std::placeholders::_1, std::placeholders::_2,
+                            std::placeholders::_3, std::move(clientCB));
+
+            m_requestor->requestSceneCreation(name, internalCB);
+        }
+
+        std::unordered_map< std::string, RemoteScene::Ptr >
+            RemoteSceneCollection::getRemoteScenes() const
+        {
+            std::lock_guard< std::mutex > scenelock(m_sceneLock);
+            return m_remoteScenes;
+        }
+
+        RemoteScene::Ptr RemoteSceneCollection::getRemoteScene(const std::string &sceneName) const
+        {
+            std::lock_guard< std::mutex > scenelock(m_sceneLock);
+            auto itr = m_remoteScenes.find(sceneName);
+
+            if (itr == m_remoteScenes.end())
+            {
+                throw RCSInvalidParameterException("Invalid scene name");
+            }
+
+            return  itr->second;
+        }
+
+        void RemoteSceneCollection::setName(const std::string &name, SetNameCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "setName : Callback is NULL" };
+            }
+
+            SceneCollectionResourceRequestor::InternalSetNameCallback internalCB
+                = std::bind(&RemoteSceneCollection::onNameSet, this,
+                            std::placeholders::_1, name, std::move(clientCB));
+
+            m_requestor->requestSetName(name, internalCB);
+        }
+
+        std::string RemoteSceneCollection::getName() const
+        {
+            std::lock_guard< std::mutex > lock(m_nameLock);
+            return m_name;
+        }
+
+        std::string RemoteSceneCollection::getId() const
+        {
+            return m_id;
+        }
+
+        void RemoteSceneCollection::addExistingRemoteScenes(const std::vector< std::string > &scenes)
+        {
+            for (const auto &scenename : scenes)
+            {
+                createRemoteScene(scenename);
+            }
+        }
+
+        void RemoteSceneCollection::initializeRemoteScenes(
+            const std::vector< RCSResourceAttributes > &MemberReps, const std::string &host)
+        {
+            try
+            {
+                for (const auto &attrs : MemberReps)
+                {
+                    for (const auto &mappingInfo :
+                            attrs.at(SCENE_KEY_SCENEMAPPINGS).get
+                                <std::vector< RCSResourceAttributes > >())
+                    {
+                        std::string sceneName
+                            = mappingInfo.at(SCENE_KEY_SCENE).get< std::string >();
+
+                        auto remoteScene = m_remoteScenes.find(sceneName);
+                        if (remoteScene == m_remoteScenes.end()) continue;
+
+                        RemoteScene::Ptr pRemoteScene = m_remoteScenes.at(sceneName);
+
+                        RCSResourceAttributes targetLinkAttrs
+                            = attrs.at(SCENE_KEY_PAYLOAD_LINK).get< RCSResourceAttributes >();
+
+                        RCSRemoteResourceObject::Ptr targetResource
+                            = SceneUtils::createRCSResourceObject(
+                            targetLinkAttrs.at(SCENE_KEY_HREF).get< std::string >(),
+                            SCENE_CONNECTIVITY,
+                            targetLinkAttrs.at(SCENE_KEY_RT).get< std::vector< std::string > >(),
+                            targetLinkAttrs.at(SCENE_KEY_IF).get< std::vector< std::string > >());
+
+                        std::string mappingInfoKey
+                            = mappingInfo.at(SCENE_KEY_MEMBERPROPERTY).get< std::string >();
+                        RCSResourceAttributes::Value mappingInfoValue
+                            = mappingInfo.at(SCENE_KEY_MEMBERVALUE);
+
+                        pRemoteScene->addExistingRemoteSceneAction(
+                            host + attrs.at(SCENE_KEY_URI).get< std::string >(),
+                            attrs.at(SCENE_KEY_ID).get< std::string >(), targetResource,
+                            mappingInfoKey, mappingInfoValue);
+                    }
+                }
+            }
+            catch (const std::exception &e)
+            {
+                SCENE_CLIENT_PRINT_LOG(e.what());
+            }
+        }
+
+        RemoteScene::Ptr RemoteSceneCollection::createRemoteScene(const std::string &name)
+        {
+            std::lock_guard< std::mutex > scenelock(m_sceneLock);
+            RemoteScene::Ptr pNewRemoteScene(new RemoteScene(name, m_requestor));
+
+            m_remoteScenes[name] = pNewRemoteScene;
+
+            return pNewRemoteScene;
+        }
+
+        void RemoteSceneCollection::onSceneAddedRemoved(int reqType,
+            const std::string &name, int eCode,
+            const AddNewSceneCallback &addCB)
+        {
+            switch (reqType)
+            {
+                case SceneCollectionResourceRequestor::REQUEST_TYPE::ADD_SCENE:
+                {
+                    if (eCode == SCENE_RESPONSE_SUCCESS)
+                    {
+                        addCB(createRemoteScene(name), SCENE_RESPONSE_SUCCESS);
+                    }
+                    else
+                    {
+                        addCB(nullptr, SCENE_CLIENT_BADREQUEST);
+                    }
+                }
+                    break;
+
+                case SceneCollectionResourceRequestor::REQUEST_TYPE::REMOVE_SCENE:
+                    break;
+            }
+        }
+
+        void RemoteSceneCollection::onNameSet(int eCode, const std::string &name,
+                                              const SetNameCallback &clientCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            if (eCode == SCENE_RESPONSE_SUCCESS)
+            {
+                std::lock_guard< std::mutex > lock(m_nameLock);
+                m_name = name;
+                result = SCENE_RESPONSE_SUCCESS;
+            }
+
+            clientCB(result);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/service/scene-manager/src/RemoteSceneList.cpp b/service/scene-manager/src/RemoteSceneList.cpp
new file mode 100644 (file)
index 0000000..8a7a9e7
--- /dev/null
@@ -0,0 +1,279 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "RemoteSceneList.h"
+
+#include <map>
+#include <algorithm>
+
+#include "SceneCommons.h"
+#include "RemoteSceneUtils.h"
+#include "SceneListResourceRequestor.h"
+#include "SceneCollectionResourceRequestor.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        RemoteSceneList::RemoteSceneList(SceneListResourceRequestor::Ptr requestor)
+            : m_requestor{ requestor }
+        {
+
+        }
+
+        void RemoteSceneList::createInstance(RCSRemoteResourceObject::Ptr sceneListResource,
+                                             CreateInstanceCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "createInstance : Callback is NULL" };
+            }
+
+            if (sceneListResource == nullptr)
+            {
+                throw RCSInvalidParameterException("Scene List resource object is null");
+            }
+
+            std::vector< std::string > rts = sceneListResource->getTypes();
+            auto it = std::find(rts.begin(), rts.end(), SCENE_LIST_RT);
+            if (it == rts.end())
+            {
+                throw RCSInvalidParameterException(
+                    "Remote resource object is not a Scene List Resource");
+            }
+
+            SceneListResourceRequestor::Ptr pRequestor =
+                std::make_shared< SceneListResourceRequestor >(sceneListResource);
+
+            std::string requestIf = OC::DEFAULT_INTERFACE;
+            pRequestor->requestGet(requestIf, std::bind(
+                &RemoteSceneList::onInstanceCreated,
+                std::placeholders::_2, std::placeholders::_3, requestIf,
+                pRequestor, std::move(clientCB)));
+        }
+
+        void RemoteSceneList::addNewSceneCollection(AddNewSceneCollectionCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "addNewSceneCollection : Callback is NULL" };
+            }
+
+            SceneListResourceRequestor::InternalCreateSceneCollectionCallback internalCB
+                = std::bind(&RemoteSceneList::onSceneCollectionCreated, this,
+                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                std::placeholders::_4, std::move(clientCB));
+
+            m_requestor->requestSceneCollectionCreation("", internalCB);
+        }
+
+        std::vector< RemoteSceneCollection::Ptr >
+            RemoteSceneList::getRemoteSceneCollections() const
+        {
+            std::lock_guard< std::mutex > collectionlock(m_collectionLock);
+            return m_remoteSceneCollections;
+        }
+
+        void RemoteSceneList::setName(const std::string &name, SetNameCallback clientCB)
+        {
+            if (!clientCB)
+            {
+                throw RCSInvalidParameterException{ "setName : Callback is NULL" };
+            }
+
+            SceneListResourceRequestor::InternalSetNameCallback internalCB
+                = std::bind(&RemoteSceneList::onNameSet, this,
+                std::placeholders::_1, name, std::move(clientCB));
+
+            m_requestor->requestSetName(name, internalCB);
+        }
+
+        std::string RemoteSceneList::getName() const
+        {
+            std::lock_guard< std::mutex > lock(m_nameLock);
+            return m_name;
+        }
+
+        void RemoteSceneList::onInstanceCreated(
+            const RCSRepresentation &rep, int eCode, const std::string &If,
+            SceneListResourceRequestor::Ptr requestor, const CreateInstanceCallback &cb)
+        {
+            if (eCode == OC_STACK_OK)
+            {
+                if (If == OC::DEFAULT_INTERFACE)
+                {
+                    auto retPtr = buildSceneList(requestor, rep.getAttributes());
+                    cb(std::move(retPtr), SCENE_RESPONSE_SUCCESS);
+                }
+                else if (If == OC::BATCH_INTERFACE)
+                {
+                    // TODO build remote scene list instance with batch interface.
+                }
+                else
+                {
+                    // TODO error handle.
+                }
+            }
+        }
+
+        RemoteSceneList::Ptr RemoteSceneList::buildSceneList(
+            SceneListResourceRequestor::Ptr requestor, const RCSResourceAttributes &attrs)
+        {
+            RemoteSceneList::Ptr newList(new RemoteSceneList(requestor));
+            auto collections = newList->parseSceneListFromAttributes(attrs);
+
+            try
+            {
+                newList->m_name = attrs.at(SCENE_KEY_NAME).get< std::string >();
+
+                for (const auto &itr : collections)
+                {
+                    auto collection = itr.first;
+                    auto host = newList->getListResourceRequestor()
+                                    ->getRemoteResourceObject()->getAddress();
+
+                    RemoteSceneCollection::Ptr newCollection
+                        = newList->createRemoteSceneCollection(
+                                    host + collection.at(SCENE_KEY_URI).get< std::string >(),
+                                    collection.at(SCENE_KEY_ID).get< std::string >(),
+                                    collection.at(SCENE_KEY_NAME).get< std::string >());
+
+                    newCollection->addExistingRemoteScenes(
+                        collection.at(SCENE_KEY_SCENEVALUES).get< std::vector< std::string > >());
+
+                    newCollection->initializeRemoteScenes(itr.second, host);
+                }
+            }
+            catch (const std::exception &e)
+            {
+                SCENE_CLIENT_PRINT_LOG(e.what());
+            }
+
+            return std::move(newList);
+        }
+
+        RemoteSceneCollection::Ptr RemoteSceneList::createRemoteSceneCollection(
+            const std::string &link, const std::string &id, const std::string &name)
+        {
+            try
+            {
+                std::vector< std::string > vecRT{ SCENE_COLLECTION_RT };
+                std::vector< std::string > vecIF{ SCENE_CLIENT_REQ_IF };
+
+                RCSRemoteResourceObject::Ptr pResource
+                    = SceneUtils::createRCSResourceObject(link, SCENE_CONNECTIVITY, vecRT, vecIF);
+
+                SceneCollectionResourceRequestor::Ptr pRequestor(
+                    new SceneCollectionResourceRequestor(pResource));
+
+                RemoteSceneCollection::Ptr newCollection(
+                    new RemoteSceneCollection(pRequestor, id, name));
+
+                {
+                    std::lock_guard< std::mutex > collectionlock(m_collectionLock);
+                    m_remoteSceneCollections.push_back(newCollection);
+                }
+
+                return newCollection;
+            }
+            catch (const std::exception &e)
+            {
+                SCENE_CLIENT_PRINT_LOG(e.what());
+                return nullptr;
+            }
+        }
+
+        SceneListResourceRequestor::Ptr RemoteSceneList::getListResourceRequestor() const
+        {
+            return m_requestor;
+        }
+
+        std::vector<std::pair<RCSResourceAttributes, std::vector<RCSResourceAttributes>>>
+            RemoteSceneList::parseSceneListFromAttributes(const RCSResourceAttributes & listAttrs)
+        {
+            std::vector<std::pair<RCSResourceAttributes, std::vector<RCSResourceAttributes>>>
+                retParsed;
+
+            auto collectionsResourceAttrs = getChildrenAttributes(listAttrs);
+
+            for (unsigned int i = 0; i < collectionsResourceAttrs.size(); ++i)
+            {
+                retParsed.push_back(
+                    std::make_pair(
+                        collectionsResourceAttrs[i],
+                        getChildrenAttributes(collectionsResourceAttrs[i])));
+            }
+
+            return retParsed;
+        }
+
+        std::vector<RCSResourceAttributes> RemoteSceneList::getChildrenAttributes(
+            const RCSResourceAttributes & attrs) const
+        {
+            const std::string SCENE_CHILD = "child";
+
+            std::vector<RCSResourceAttributes> retChildren = {};
+
+            if (attrs.contains(SCENE_CHILD))
+            {
+                retChildren
+                    = attrs.at(SCENE_CHILD).get<std::vector<RCSResourceAttributes>>();
+            }
+
+            return retChildren;
+        }
+
+        void RemoteSceneList::onSceneCollectionCreated(
+            const std::string &link, const std::string &id, const std::string &name, int eCode,
+            const AddNewSceneCollectionCallback &clientCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            RemoteSceneCollection::Ptr newCollection = nullptr;
+
+            if (eCode == SCENE_RESPONSE_SUCCESS)
+            {
+                newCollection =
+                    createRemoteSceneCollection(link, id, name);
+
+                if (newCollection)
+                    result = SCENE_RESPONSE_SUCCESS;
+            }
+
+            clientCB(newCollection, result);
+        }
+
+        void RemoteSceneList::onNameSet(int eCode, const std::string &name,
+            const SetNameCallback &clientCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            if (eCode == SCENE_RESPONSE_SUCCESS)
+            {
+                std::lock_guard< std::mutex > lock(m_nameLock);
+                m_name = name;
+                result = SCENE_RESPONSE_SUCCESS;
+            }
+
+            clientCB(result);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/service/scene-manager/src/RemoteSceneUtils.h b/service/scene-manager/src/RemoteSceneUtils.h
new file mode 100644 (file)
index 0000000..b85e696
--- /dev/null
@@ -0,0 +1,41 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef REMOTE_SCENE_UTILS_H
+#define REMOTE_SCENE_UTILS_H
+
+#include <cassert>
+
+#include "logger.h"
+
+#define SCENE_CLIENT_PRINT_LOG(strError) \
+        OIC_LOG_V(ERROR, "[SCENE_CLIENT]", "%s:%d %s", __PRETTY_FUNCTION__, __LINE__, strError);
+
+#define SCENE_CLIENT_ASSERT_NOT_NULL(Val) \
+        { \
+            if (!(Val)) \
+            { \
+                SCENE_CLIENT_PRINT_LOG("NULL value"); \
+                assert(Val); \
+                return; \
+            } \
+        }
+
+#endif // REMOTE_SCENE_UTILS_H
\ No newline at end of file
diff --git a/service/scene-manager/src/Scene.cpp b/service/scene-manager/src/Scene.cpp
new file mode 100755 (executable)
index 0000000..f407a01
--- /dev/null
@@ -0,0 +1,153 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "Scene.h"
+
+#include "SceneCollectionResource.h"
+
+#include <algorithm>
+
+namespace OIC
+{
+    namespace Service
+    {
+        Scene::Scene(const std::string& sceneName,
+                SceneCollectionResource::Ptr sceneCollectionResource) :
+                m_name(sceneName), m_sceneCollectionResource(sceneCollectionResource) {}
+
+        SceneAction::Ptr Scene::addNewSceneAction(
+               const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject,
+               std::string key, RCSResourceAttributes::Value value)
+        {
+            RCSResourceAttributes resAttr;
+            resAttr[key] = value;
+            return addNewSceneAction(pRCSRemoteResourceObject, std::move(resAttr));
+        }
+
+        SceneAction::Ptr Scene::addNewSceneAction(
+                const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject,
+                RCSResourceAttributes attr)
+        {
+            if(pRCSRemoteResourceObject == nullptr)
+            {
+                throw RCSInvalidParameterException("pRCSRemoteResourceObject is empty!");
+            }
+
+            SceneMemberResource::Ptr sceneMemberResObj;
+            sceneMemberResObj = SceneMemberResource::createSceneMemberResource(
+                    pRCSRemoteResourceObject);
+            try
+            {
+                m_sceneCollectionResource->addSceneMember(sceneMemberResObj);
+            }
+            catch(std::exception& e)
+            {
+                auto sceneMemberRes = m_sceneCollectionResource->findSceneMembers(m_name);
+
+                auto it = std::find_if(sceneMemberRes.begin(), sceneMemberRes.end(),
+                        [&pRCSRemoteResourceObject](const SceneMemberResource::Ptr& member)
+                        {
+                            return member->getRemoteResourceObject() == pRCSRemoteResourceObject;
+                        }
+                );
+
+                if(it != sceneMemberRes.end())
+                {
+                    throw InvalidAddMemberRequestException(
+                            "It is already registered member. Please set Execution Parameter!");
+                }
+
+                auto sceneMembers = m_sceneCollectionResource->getSceneMembers();
+                auto memberRes = std::find_if(sceneMembers.begin(), sceneMembers.end(),
+                        [&pRCSRemoteResourceObject](const SceneMemberResource::Ptr& member)
+                        {
+                            return member->getRemoteResourceObject() == pRCSRemoteResourceObject;
+                        }
+                );
+                return SceneAction::Ptr(new SceneAction((*memberRes), m_name, attr));
+            }
+
+            return SceneAction::Ptr(new SceneAction(sceneMemberResObj, m_name, attr));
+        }
+
+        SceneAction::Ptr Scene::getSceneAction(
+                const RCSRemoteResourceObject::Ptr& pRCSRemoteResourceObject) const
+        {
+            auto sceneMemberRes = m_sceneCollectionResource->findSceneMembers(m_name);
+
+            auto it = std::find_if(sceneMemberRes.begin(), sceneMemberRes.end(),
+                    [&pRCSRemoteResourceObject](const SceneMemberResource::Ptr& member)
+                    {
+                        return member->getRemoteResourceObject() == pRCSRemoteResourceObject;
+                    }
+            );
+
+            if(it == sceneMemberRes.end())
+            {
+                throw RCSInvalidParameterException("Unknown Remote Resource!");
+            }
+
+            RCSResourceAttributes actionParam;
+            for(const auto &info : (*it)->findMappingInfos(m_name))
+            {
+                actionParam[info.key] = info.value;
+            }
+
+            return SceneAction::Ptr(new SceneAction((*it), m_name, actionParam));
+        }
+
+        std::vector<SceneAction::Ptr> Scene::getSceneActions() const
+        {
+            std::vector<SceneAction::Ptr> actions;
+            auto sceneMemberRes = m_sceneCollectionResource->findSceneMembers(m_name);
+
+            std::for_each(sceneMemberRes.begin(), sceneMemberRes.end(),
+                [&actions, &m_name](const SceneMemberResource::Ptr& member)
+                {
+                    RCSResourceAttributes actionParam;
+
+                    for(const auto &it : member->findMappingInfos(m_name))
+                    {
+                        actionParam[it.key] = it.value;
+                    }
+                    actions.push_back(SceneAction::Ptr(
+                            new SceneAction(member, m_name, actionParam)));
+                }
+            );
+
+            return actions;
+         }
+
+        std::string Scene::getName() const
+        {
+            return m_name;
+        }
+
+        void Scene::execute(ExecuteCallback cb)
+        {
+            if(cb == nullptr)
+            {
+                throw RCSInvalidParameterException("Callback is empty!");
+            }
+
+            m_sceneCollectionResource->execute(m_name, std::move(cb));
+        }
+    } /* namespace Service */
+} /* namespace OIC */
diff --git a/service/scene-manager/src/SceneAction.cpp b/service/scene-manager/src/SceneAction.cpp
new file mode 100755 (executable)
index 0000000..79e5f00
--- /dev/null
@@ -0,0 +1,89 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneAction.h"
+
+#include "SceneMemberResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        SceneAction::SceneAction(const SceneMemberResource::Ptr SceneMemberResource,
+                const std::string& sceneName, const RCSResourceAttributes& attr) :
+                m_pRemoteResourceObject(SceneMemberResource->getRemoteResourceObject()),
+                m_sceneName(sceneName),
+                m_sceneMemberResource(SceneMemberResource)
+        {
+            for (const auto& it : attr)
+            {
+                m_sceneMemberResource->addMappingInfo(
+                        SceneMemberResource::MappingInfo(m_sceneName, it.key(), it.value()));
+            }
+        }
+
+        SceneAction::SceneAction(const SceneMemberResource::Ptr SceneMemberResource,
+                const std::string& sceneName, const std::string& key,
+                const RCSResourceAttributes::Value& value) :
+                m_pRemoteResourceObject(SceneMemberResource->getRemoteResourceObject()),
+                m_sceneName(sceneName), m_sceneMemberResource(SceneMemberResource)
+        {
+            m_sceneMemberResource->addMappingInfo(
+                                SceneMemberResource::MappingInfo(m_sceneName, key, value));
+        }
+
+        void SceneAction::resetExecutionParameter(const std::string& key,
+                RCSResourceAttributes::Value value)
+        {
+            RCSResourceAttributes attr;
+            attr[key] = value;
+            resetExecutionParameter(attr);
+        }
+
+        void SceneAction::resetExecutionParameter(const RCSResourceAttributes& attr)
+        {
+            for(const auto& it : attr)
+            {
+                m_sceneMemberResource->addMappingInfo(
+                        SceneMemberResource::MappingInfo(m_sceneName, it.key(), it.value()));
+            }
+        }
+
+        RCSResourceAttributes SceneAction::getExecutionParameter() const
+        {
+            RCSResourceAttributes attr;
+            for(const auto& it : m_sceneMemberResource->getMappingInfos())
+            {
+                if(it.sceneName == m_sceneName)
+                {
+                    attr[it.key] = RCSResourceAttributes::Value(it.value);
+                }
+            }
+            return attr;
+        }
+
+        RCSRemoteResourceObject::Ptr SceneAction::getRemoteResourceObject() const
+        {
+            return m_pRemoteResourceObject;
+        }
+
+    } /* namespace Service */
+} /* namespace OIC */
+
diff --git a/service/scene-manager/src/SceneCollection.cpp b/service/scene-manager/src/SceneCollection.cpp
new file mode 100755 (executable)
index 0000000..c72d26b
--- /dev/null
@@ -0,0 +1,84 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneCollection.h"
+
+#include "SceneCollectionResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        SceneCollection::SceneCollection(
+                const SceneCollectionResource::Ptr& sceneCollectionResource) :
+                m_sceneCollectionResource(sceneCollectionResource) {}
+
+        Scene::Ptr SceneCollection::addNewScene(const std::string& sceneName)
+        {
+            if(sceneName.empty())
+            {
+                throw RCSInvalidParameterException("Scene name is an empty string");
+            }
+
+            m_sceneCollectionResource->addScene(sceneName);
+            return Scene::Ptr(new Scene(sceneName, m_sceneCollectionResource));
+        }
+
+        std::unordered_map< std::string, Scene::Ptr > SceneCollection::getScenes() const
+        {
+            std::unordered_map< std::string, Scene::Ptr > scenes;
+
+            for(const auto &it : m_sceneCollectionResource->getSceneValues())
+            {
+                Scene::Ptr scenePtr(new Scene(it, m_sceneCollectionResource));
+                scenes.insert(std::pair< std::string, Scene::Ptr >(it, scenePtr));
+            }
+            return scenes;
+        }
+
+        Scene::Ptr SceneCollection::getScene(const std::string& sceneName) const
+        {
+            auto sceneValues = m_sceneCollectionResource->getSceneValues();
+            auto it = std::find(sceneValues.begin(), sceneValues.end(), sceneName);
+            if(it != sceneValues.end())
+            {
+                throw RCSInvalidParameterException("Scene Name is Invalid!");
+            }
+            return Scene::Ptr(new Scene(sceneName, m_sceneCollectionResource));
+        }
+
+        void SceneCollection::setName(const std::string& name)
+        {
+            m_sceneCollectionResource->setName(name);
+        }
+
+        std::string SceneCollection::getName() const
+        {
+            return m_sceneCollectionResource->getName();
+        }
+
+        std::string SceneCollection::getId() const
+        {
+            return m_sceneCollectionResource->getId();
+        }
+
+    } /* namespace Service */
+} /* namespace OIC */
+
diff --git a/service/scene-manager/src/SceneCollectionResource.cpp b/service/scene-manager/src/SceneCollectionResource.cpp
new file mode 100644 (file)
index 0000000..7585d61
--- /dev/null
@@ -0,0 +1,467 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneCollectionResource.h"
+
+#include <atomic>
+#include "OCApi.h"
+#include "RCSRequest.h"
+#include "RCSSeparateResponse.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        namespace
+        {
+            std::atomic_int g_numOfSceneCollection(0);
+        }
+
+        SceneCollectionResource::SceneCollectionResource()
+        : m_uri(PREFIX_SCENE_COLLECTION_URI + "/" + std::to_string(g_numOfSceneCollection++)),
+          m_address(), m_sceneCollectionResourceObject(), m_requestHandler()
+        {
+            m_sceneCollectionResourceObject = createResourceObject();
+        }
+
+        SceneCollectionResource::Ptr SceneCollectionResource::create()
+        {
+            SceneCollectionResource::Ptr sceneCollectionResource(new SceneCollectionResource());
+
+            sceneCollectionResource->setDefaultAttributes();
+
+            sceneCollectionResource->initSetRequestHandler();
+
+            sceneCollectionResource->m_address = SceneUtils::getNetAddress();
+
+            return sceneCollectionResource;
+        }
+
+        SceneCollectionResource::Ptr SceneCollectionResource::create(
+                const RCSResourceAttributes & inputAttr)
+        {
+            auto sceneCollectionResource = SceneCollectionResource::create();
+            if (inputAttr.contains(SCENE_KEY_NAME))
+            {
+                sceneCollectionResource->setName(inputAttr.at(SCENE_KEY_NAME).get<std::string>());
+            }
+
+            if (inputAttr.contains(SCENE_KEY_SCENEVALUES))
+            {
+                auto sceneValues = inputAttr.at(SCENE_KEY_SCENEVALUES).
+                        get<std::vector<std::string>>();
+                sceneCollectionResource->getRCSResourceObject()->setAttribute(
+                        SCENE_KEY_SCENEVALUES, sceneValues);
+            }
+
+            if (inputAttr.contains(SCENE_KEY_LAST_SCENE))
+            {
+                auto sceneValues = inputAttr.at(SCENE_KEY_LAST_SCENE).get<std::string>();
+                sceneCollectionResource->getRCSResourceObject()->setAttribute(
+                        SCENE_KEY_LAST_SCENE, sceneValues);
+            }
+
+            return sceneCollectionResource;
+        }
+
+        RCSResourceObject::Ptr SceneCollectionResource::createResourceObject()
+        {
+            return RCSResourceObject::Builder(
+                        m_uri, SCENE_COLLECTION_RT, OC_RSRVD_INTERFACE_DEFAULT).
+                        addInterface(OC::BATCH_INTERFACE).
+                        setDiscoverable(true).setObservable(false).build();
+        }
+
+        void SceneCollectionResource::setDefaultAttributes()
+        {
+            m_sceneCollectionResourceObject->setAttribute(SCENE_KEY_LAST_SCENE, std::string());
+            m_sceneCollectionResourceObject->setAttribute(SCENE_KEY_NAME, std::string());
+            m_sceneCollectionResourceObject->setAttribute(
+                    SCENE_KEY_ID, SceneUtils::OICGenerateUUIDStr());
+            m_sceneCollectionResourceObject->setAttribute(SCENE_KEY_RTS, SCENE_MEMBER_RT);
+            m_sceneCollectionResourceObject->setAttribute(
+                    SCENE_KEY_SCENEVALUES, std::vector<std::string>());
+            m_sceneCollectionResourceObject->setAttribute(SCENE_KEY_URI, m_uri);
+        }
+
+        void SceneCollectionResource::initSetRequestHandler()
+        {
+            m_requestHandler.m_owner
+                = std::weak_ptr<SceneCollectionResource>(shared_from_this());
+
+            m_sceneCollectionResourceObject->setSetRequestHandler(std::bind(
+                    &SceneCollectionResource::SceneCollectionRequestHandler::onSetRequest,
+                    m_requestHandler, std::placeholders::_1, std::placeholders::_2));
+        }
+
+        void SceneCollectionResource::addScene(const std::string & newScene)
+        {
+            addScene(std::string(newScene));
+        }
+
+        void SceneCollectionResource::addScene(std::string && newScene)
+        {
+            auto sceneValues = m_sceneCollectionResourceObject->getAttributeValue(
+                    SCENE_KEY_SCENEVALUES).get< std::vector< std::string > >();
+
+            auto foundScene
+                = std::find(sceneValues.begin(), sceneValues.end(), newScene);
+            if (foundScene == sceneValues.end())
+            {
+                sceneValues.push_back(std::move(newScene));
+
+                m_sceneCollectionResourceObject->setAttribute(SCENE_KEY_SCENEVALUES, sceneValues);
+            }
+            else
+            {
+                throw std::exception();
+            }
+        }
+
+        void SceneCollectionResource::addSceneMember(
+                SceneMemberResource::Ptr newMember)
+        {
+            std::lock_guard<std::mutex> memberlock(m_sceneMemberLock);
+
+            auto foundmember = std::find_if(m_sceneMembers.begin(), m_sceneMembers.end(),
+                    [& newMember](const SceneMemberResource::Ptr & ptr) -> bool
+                    {
+                        return ptr->getTargetUri() == newMember->getTargetUri();
+                    });
+
+            if (foundmember != m_sceneMembers.end())
+            {
+                throw std::exception();
+            }
+
+            m_sceneMembers.push_back(newMember);
+            m_sceneCollectionResourceObject->bindResource(newMember->getRCSResourceObject());
+        }
+
+        void SceneCollectionResource::execute(std::string && sceneName)
+        {
+            execute(std::move(sceneName), nullptr);
+        }
+
+        void SceneCollectionResource::execute(const std::string & sceneName)
+        {
+            execute(std::string(sceneName));
+        }
+
+        void SceneCollectionResource::execute(
+                const std::string & sceneName, SceneExecuteCallback executeCB)
+        {
+            execute(std::string(sceneName), std::move(executeCB));
+        }
+
+        void SceneCollectionResource::execute(
+                std::string && sceneName, SceneExecuteCallback executeCB)
+        {
+            auto sceneValues = m_sceneCollectionResourceObject->getAttributeValue(
+                    SCENE_KEY_SCENEVALUES).get< std::vector< std::string > >();
+
+            auto foundSceneValue
+                = std::find(sceneValues.begin(), sceneValues.end(), sceneName);
+            if (foundSceneValue == sceneValues.end() && executeCB && !m_sceneMembers.size())
+            {
+                std::thread(std::move(executeCB), SCENE_CLIENT_BADREQUEST).detach();
+                return;
+            }
+
+            m_sceneCollectionResourceObject->setAttribute(
+                    SCENE_KEY_LAST_SCENE, std::move(sceneName));
+
+            {
+                std::lock_guard<std::mutex> memberlock(m_sceneMemberLock);
+                auto executeHandler
+                    = SceneExecuteResponseHandler::createExecuteHandler(
+                            shared_from_this(), std::move(executeCB));
+                for (auto & it : m_sceneMembers)
+                {
+                    it->execute(sceneName, std::bind(
+                            &SceneExecuteResponseHandler::onResponse, executeHandler,
+                            std::placeholders::_1, std::placeholders::_2));
+                }
+            }
+        }
+
+        std::string SceneCollectionResource::getId() const
+        {
+            return m_sceneCollectionResourceObject->getAttributeValue(
+                    SCENE_KEY_ID).get<std::string>();
+        }
+
+        std::string SceneCollectionResource::getUri() const
+        {
+            return m_uri;
+        }
+
+        std::string SceneCollectionResource::getAddress() const
+        {
+            return m_address;
+        }
+
+        std::vector<std::string> SceneCollectionResource::getSceneValues() const
+        {
+            return m_sceneCollectionResourceObject->getAttributeValue(
+                    SCENE_KEY_SCENEVALUES).get<std::vector<std::string>>();
+        }
+
+        std::vector<SceneMemberResource::Ptr> SceneCollectionResource::getSceneMembers() const
+        {
+            std::lock_guard<std::mutex> memberlock(m_sceneMemberLock);
+            return m_sceneMembers;
+        }
+
+        std::vector<SceneMemberResource::Ptr> SceneCollectionResource::findSceneMembers(
+                const std::string & sceneName) const
+        {
+            std::lock_guard<std::mutex> memberlock(m_sceneMemberLock);
+            std::vector<SceneMemberResource::Ptr> retMembers;
+            std::for_each(m_sceneMembers.begin(), m_sceneMembers.end(),
+                    [& retMembers, & sceneName](SceneMemberResource::Ptr pMember)
+                    {
+                        if(pMember->hasSceneValue(sceneName))
+                        {
+                            retMembers.push_back(pMember);
+                        }
+                    });
+            return retMembers;
+        }
+
+        RCSResourceObject::Ptr SceneCollectionResource::getRCSResourceObject() const
+        {
+            return m_sceneCollectionResourceObject;
+        }
+
+        void SceneCollectionResource::setName(std::string && sceneCollectionName)
+        {
+            m_sceneCollectionResourceObject->setAttribute(
+                    SCENE_KEY_NAME, std::move(sceneCollectionName));
+        }
+
+        void SceneCollectionResource::setName(const std::string & sceneCollectionName)
+        {
+            setName(std::string(sceneCollectionName));
+        }
+
+        std::string SceneCollectionResource::getName() const
+        {
+            return m_sceneCollectionResourceObject->getAttributeValue(
+                    SCENE_KEY_NAME).get<std::string>();
+        }
+
+        RCSSetResponse SceneCollectionResource::SceneCollectionRequestHandler::
+        onSetRequest(const RCSRequest & request, RCSResourceAttributes & attributes)
+        {
+            if (request.getInterface() == LINK_BATCH)
+            {
+                return createSceneMemberRequest(request, attributes);
+            }
+
+            if (attributes.contains(SCENE_KEY_SCENEVALUES))
+            {
+                return addSceneRequest(request, attributes);
+            }
+
+            if (attributes.contains(SCENE_KEY_LAST_SCENE))
+            {
+                return executeSceneRequest(request, attributes);
+            }
+
+            if (attributes.contains(SCENE_KEY_NAME))
+            {
+                return setSceneCollectionName(request, attributes);
+            }
+
+            return RCSSetResponse::create(attributes, (int)SCENE_CLIENT_BADREQUEST).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse SceneCollectionResource::SceneCollectionRequestHandler::
+        addSceneRequest(const RCSRequest & /*request*/, RCSResourceAttributes & attributes)
+        {
+            SceneCollectionResource::Ptr ptr = m_owner.lock();
+            if (ptr == nullptr)
+            {
+                return RCSSetResponse::create(attributes, SCENE_CLIENT_BADREQUEST).
+                        setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+            }
+
+            auto values = attributes.at(SCENE_KEY_SCENEVALUES).get<std::vector<std::string>>();
+
+            auto sizeofValues = values.size();
+            unsigned int sameSize = 0;
+            std::for_each(values.begin(), values.end(),
+                    [& ptr, & sameSize](const std::string & value)
+                    {
+                        try
+                        {
+                            ptr->addScene(value);
+                        } catch (...)
+                        {
+                            sameSize++;
+                        }
+                    });
+
+            int eCode = SCENE_RESPONSE_SUCCESS;
+            if (sameSize == sizeofValues)
+            {
+                eCode = SCENE_CLIENT_BADREQUEST;
+            }
+
+            return RCSSetResponse::create(attributes, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse SceneCollectionResource::SceneCollectionRequestHandler::
+        executeSceneRequest(const RCSRequest & request, RCSResourceAttributes & attributes)
+        {
+            SceneCollectionResource::Ptr ptr = m_owner.lock();
+            if (ptr == nullptr)
+            {
+                return RCSSetResponse::create(attributes, SCENE_CLIENT_BADREQUEST).
+                        setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+            }
+
+            auto requestKey = attributes.at(SCENE_KEY_LAST_SCENE).get<std::string>();
+
+            RCSRequest req(request.getResourceObject().lock(), request.getOCRequest());
+
+            ptr->execute(std::string(requestKey),
+                    [& req](int /*eCode*/)
+                    {
+                        // TODO need to set error code.
+                        // and need to set specific attr' but this attr not to be apply to RCSResourceObject.
+                        RCSSeparateResponse(req).set();
+                    });
+
+            return RCSSetResponse::separate();
+        }
+
+        RCSSetResponse SceneCollectionResource::SceneCollectionRequestHandler::
+        createSceneMemberRequest(const RCSRequest & /*request*/, RCSResourceAttributes & attributes)
+        {
+            int eCode = SCENE_CLIENT_BADREQUEST;
+            SceneCollectionResource::Ptr ptr = m_owner.lock();
+            if (!ptr)
+            {
+                return RCSSetResponse::create(attributes, eCode).
+                        setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+            }
+
+            RCSResourceAttributes responseAtt(attributes);
+            if (attributes.contains(SCENE_KEY_PAYLOAD_LINK))
+            {
+                auto linkAtt = attributes.at(SCENE_KEY_PAYLOAD_LINK).get<RCSResourceAttributes>();
+                if (linkAtt.contains(SCENE_KEY_HREF) &&
+                        linkAtt.contains(SCENE_KEY_RT) && linkAtt.contains(SCENE_KEY_IF))
+                {
+                    auto memberObj = SceneMemberResource::createSceneMemberResource(linkAtt);
+                    try
+                    {
+                        ptr->addSceneMember(memberObj);
+                    }
+                    catch (...)
+                    {
+                        return RCSSetResponse::create(responseAtt, eCode).
+                                setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+                    }
+                    eCode = SCENE_RESPONSE_SUCCESS;
+
+                    if (attributes.contains(SCENE_KEY_SCENEMAPPINGS))
+                    {
+                        addMemberInfoFromRemote(memberObj, attributes.at(
+                                SCENE_KEY_SCENEMAPPINGS).get<std::vector<RCSResourceAttributes>>());
+                    }
+                    responseAtt[SCENE_KEY_ID] = RCSResourceAttributes::Value(memberObj->getId());
+                    responseAtt[SCENE_KEY_CREATEDLINK]
+                                = RCSResourceAttributes::Value(memberObj->getFullUri());
+                }
+            }
+
+            return RCSSetResponse::create(responseAtt, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse
+        SceneCollectionResource::SceneCollectionRequestHandler::setSceneCollectionName(
+                const RCSRequest & /*request*/, RCSResourceAttributes & attr)
+        {
+            int eCode = SCENE_CLIENT_BADREQUEST;
+            SceneCollectionResource::Ptr ptr = m_owner.lock();
+            if (ptr != nullptr)
+            {
+                eCode = SCENE_RESPONSE_SUCCESS;
+                ptr->setName(attr.at(SCENE_KEY_NAME).get<std::string>());
+            }
+
+            return RCSSetResponse::create(attr, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        void SceneCollectionResource::SceneCollectionRequestHandler::addMemberInfoFromRemote(
+                SceneMemberResource::Ptr memberObj, std::vector<RCSResourceAttributes> mInfo)
+        {
+            std::for_each(mInfo.begin(), mInfo.end(),
+                    [& memberObj](const RCSResourceAttributes & att)
+                    {
+                        memberObj->addMappingInfo(SceneMemberResource::MappingInfo::create(att));
+                    });
+        }
+
+        void SceneCollectionResource::SceneExecuteResponseHandler::
+        onResponse(const RCSResourceAttributes & /*attributes*/, int errorCode)
+        {
+            m_responseMembers++;
+            if (errorCode != SCENE_RESPONSE_SUCCESS && m_errorCode != errorCode)
+            {
+                m_errorCode = errorCode;
+            }
+            if (m_responseMembers == m_numOfMembers)
+            {
+                m_cb(m_errorCode);
+            }
+        }
+
+        SceneCollectionResource::SceneExecuteResponseHandler::Ptr
+        SceneCollectionResource::SceneExecuteResponseHandler::createExecuteHandler(
+                const SceneCollectionResource::Ptr ptr, SceneExecuteCallback executeCB)
+        {
+            auto executeHandler = std::make_shared<SceneExecuteResponseHandler>();
+
+            executeHandler->m_numOfMembers = ptr->m_sceneMembers.size();
+            executeHandler->m_responseMembers = 0;
+
+            executeHandler->m_cb =
+                    [executeCB](int eCode)
+                    {
+                        std::thread(std::move(executeCB), eCode).detach();
+                    };
+
+            executeHandler->m_owner
+                = std::weak_ptr<SceneCollectionResource>(ptr);
+            executeHandler->m_errorCode  = SCENE_RESPONSE_SUCCESS;
+
+            return executeHandler;
+        }
+
+    }
+}
diff --git a/service/scene-manager/src/SceneCollectionResource.h b/service/scene-manager/src/SceneCollectionResource.h
new file mode 100644 (file)
index 0000000..f625df6
--- /dev/null
@@ -0,0 +1,147 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SCENE_COLLECTION_RESOURCE_OBJECT_H
+#define SCENE_COLLECTION_RESOURCE_OBJECT_H
+
+#include <list>
+
+#include "RCSResourceObject.h"
+#include "SceneCommons.h"
+#include "SceneMemberResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SceneCollectionResource
+                : public std::enable_shared_from_this<SceneCollectionResource>
+        {
+        public:
+            typedef std::shared_ptr< SceneCollectionResource > Ptr;
+            typedef std::function< void(int) > SceneExecuteCallback;
+
+            ~SceneCollectionResource() = default;
+
+            static SceneCollectionResource::Ptr create();
+            static SceneCollectionResource::Ptr create(const RCSResourceAttributes &);
+
+            void addScene(std::string &&);
+            void addScene(const std::string &);
+
+            void addSceneMember(SceneMemberResource::Ptr);
+
+            void execute(std::string &&);
+            void execute(const std::string &);
+            void execute(std::string &&, SceneExecuteCallback);
+            void execute(const std::string &, SceneExecuteCallback);
+
+            void setName(std::string &&);
+            void setName(const std::string &);
+
+            std::vector<std::string> getSceneValues() const;
+
+            std::string getName() const;
+
+            std::string getId() const;
+            std::string getUri() const;
+            std::string getAddress() const;
+
+            std::vector<SceneMemberResource::Ptr> getSceneMembers() const;
+
+            std::vector<SceneMemberResource::Ptr> findSceneMembers(
+                    const std::string & sceneName) const;
+
+            RCSResourceObject::Ptr getRCSResourceObject() const;
+
+        private:
+            class SceneExecuteResponseHandler
+            {
+            public:
+                typedef std::shared_ptr<SceneExecuteResponseHandler> Ptr;
+
+                SceneExecuteResponseHandler()
+                : m_numOfMembers(0), m_responseMembers(0), m_errorCode(0) { }
+                ~SceneExecuteResponseHandler() = default;
+
+                int m_numOfMembers;
+                int m_responseMembers;
+                int m_errorCode;
+                std::weak_ptr<SceneCollectionResource> m_owner;
+                SceneExecuteCallback m_cb;
+
+                static SceneExecuteResponseHandler::Ptr createExecuteHandler(
+                        const SceneCollectionResource::Ptr, SceneExecuteCallback);
+                void onResponse(const RCSResourceAttributes &, int);
+            };
+
+            class SceneCollectionRequestHandler
+            {
+            public:
+                SceneCollectionRequestHandler() = default;
+                ~SceneCollectionRequestHandler() = default;
+
+                std::weak_ptr<SceneCollectionResource> m_owner;
+
+                RCSSetResponse onSetRequest(
+                        const RCSRequest &, RCSResourceAttributes &);
+
+            private:
+                RCSSetResponse addSceneRequest(
+                        const RCSRequest &, RCSResourceAttributes &);
+                RCSSetResponse executeSceneRequest(
+                        const RCSRequest &, RCSResourceAttributes &);
+                RCSSetResponse createSceneMemberRequest(
+                        const RCSRequest &, RCSResourceAttributes &);
+                RCSSetResponse setSceneCollectionName(
+                        const RCSRequest &, RCSResourceAttributes &);
+
+                void addMemberInfoFromRemote(SceneMemberResource::Ptr,
+                        std::vector<RCSResourceAttributes>);
+            };
+
+            std::string m_uri;
+            std::string m_address;
+
+            RCSResourceObject::Ptr m_sceneCollectionResourceObject;
+            mutable std::mutex m_sceneMemberLock;
+            std::vector<SceneMemberResource::Ptr> m_sceneMembers;
+
+            SceneCollectionRequestHandler m_requestHandler;
+
+            SceneCollectionResource();
+
+            SceneCollectionResource(const SceneCollectionResource &) = delete;
+            SceneCollectionResource & operator = (
+                    const SceneCollectionResource &) = delete;
+
+            SceneCollectionResource(SceneCollectionResource &&) = delete;
+            SceneCollectionResource & operator = (
+                    SceneCollectionResource &&) = delete;
+
+            RCSResourceObject::Ptr createResourceObject();
+            void setDefaultAttributes();
+            void initSetRequestHandler();
+        };
+    }
+}
+
+#endif // SCENE_COLLECTION_RESOURCE_OBJECT_H
+
diff --git a/service/scene-manager/src/SceneCollectionResourceRequestor.cpp b/service/scene-manager/src/SceneCollectionResourceRequestor.cpp
new file mode 100644 (file)
index 0000000..f36d3bc
--- /dev/null
@@ -0,0 +1,341 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneCollectionResourceRequestor.h"
+#include "RemoteSceneUtils.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        SceneCollectionResourceRequestor::SceneCollectionResourceRequestor(
+            RCSRemoteResourceObject::Ptr collectionResource)
+                : m_sceneCollectionResource{ collectionResource }
+        {
+            SCENE_CLIENT_ASSERT_NOT_NULL(collectionResource);
+        }
+
+        void SceneCollectionResourceRequestor::requestSceneCreation(
+            const std::string &name, InternalSceneRequestCallback createSceneCB)
+        {
+            RCSResourceAttributes attributesToSet;
+            std::vector< std::string > scenenames{ name };
+            
+            attributesToSet[SCENE_KEY_SCENEVALUES] = scenenames;
+
+            RCSRemoteResourceObject::RemoteAttributesSetCallback setRequestCB
+                = std::bind(&SceneCollectionResourceRequestor::onSetResponseForScene,
+                            std::placeholders::_1, std::placeholders::_2,
+                            name, std::move(createSceneCB), ADD_SCENE,
+                            SceneCollectionResourceRequestor::wPtr(shared_from_this()));
+
+            m_sceneCollectionResource->setRemoteAttributes(
+                std::move(attributesToSet), std::move(setRequestCB));
+        }
+
+        void SceneCollectionResourceRequestor::requestSceneRemoval
+        (const std::string &/* name */, InternalSceneRequestCallback)
+        {
+
+        }
+
+        void SceneCollectionResourceRequestor::requestSceneExecution
+        (const std::string &name, InternalSceneRequestCallback executeSceneCB)
+        {
+            RCSResourceAttributes attributesToSet;
+            attributesToSet[SCENE_KEY_LAST_SCENE] = name;
+
+            RCSRemoteResourceObject::RemoteAttributesSetCallback setRequestCB
+                = std::bind(&SceneCollectionResourceRequestor::onSetResponseForScene,
+                            std::placeholders::_1, std::placeholders::_2,
+                            name, std::move(executeSceneCB), EXECUTE_SCENE,
+                            SceneCollectionResourceRequestor::wPtr(shared_from_this()));
+
+            m_sceneCollectionResource->setRemoteAttributes(
+                std::move(attributesToSet), std::move(setRequestCB));
+        }
+
+        void SceneCollectionResourceRequestor::requestAddSceneMember(
+            RCSRemoteResourceObject::Ptr targetResource, const std::string &sceneName,
+            const RCSResourceAttributes &attr, InternalAddMemberCallback addMemberCB)
+        {
+            SCENE_CLIENT_ASSERT_NOT_NULL(targetResource);
+
+            RCSResourceAttributes attributesToSet, linkAttrs;
+
+            linkAttrs[SCENE_KEY_HREF] = targetResource->getAddress() + targetResource->getUri();
+            linkAttrs[SCENE_KEY_IF] = targetResource->getInterfaces();
+            linkAttrs[SCENE_KEY_RT] = targetResource->getTypes();
+
+            attributesToSet[SCENE_KEY_PAYLOAD_LINK] = linkAttrs;
+
+            if (!attr.empty())
+            {
+                std::vector< RCSResourceAttributes > vecSceneMappings;
+                for (const auto &itr : attr)
+                {
+                    RCSResourceAttributes sceneMappingAttrs;
+                    sceneMappingAttrs[SCENE_KEY_SCENE] = sceneName;
+                    sceneMappingAttrs[SCENE_KEY_MEMBERPROPERTY] = itr.key();
+                    sceneMappingAttrs[SCENE_KEY_MEMBERVALUE] = itr.value();
+
+                    vecSceneMappings.push_back(sceneMappingAttrs);
+                }
+
+                attributesToSet[SCENE_KEY_SCENEMAPPINGS] = vecSceneMappings;
+            }
+
+            RCSRemoteResourceObject::SetCallback setRequestCB
+                = std::bind(&SceneCollectionResourceRequestor::onSceneMemberAdded,
+                            std::placeholders::_2, std::placeholders::_3,
+                            targetResource,
+                            std::move(addMemberCB),
+                            SceneCollectionResourceRequestor::wPtr(shared_from_this()));
+
+            RCSQueryParams queryParams;
+            queryParams.setResourceInterface(LINK_BATCH);
+
+            m_sceneCollectionResource->set(queryParams, std::move(attributesToSet),
+                                              std::move(setRequestCB));
+        }
+
+        void SceneCollectionResourceRequestor::requestSetName
+        (const std::string &name, InternalSetNameCallback internalCB)
+        {
+            RCSResourceAttributes attrs;
+            attrs[SCENE_KEY_NAME] = name;
+
+            RCSRemoteResourceObject::SetCallback setRequestCB
+                = std::bind(&SceneCollectionResourceRequestor::onNameSet,
+                std::placeholders::_2, std::placeholders::_3, name, std::move(internalCB),
+                SceneCollectionResourceRequestor::wPtr(shared_from_this()));
+
+            RCSQueryParams queryParams;
+            queryParams.setResourceInterface(SCENE_CLIENT_REQ_IF);
+
+            m_sceneCollectionResource->set(queryParams, std::move(attrs), std::move(setRequestCB));
+        }
+
+        void SceneCollectionResourceRequestor::requestGet(
+            const std::string &ifType, RCSRemoteResourceObject::GetCallback cb)
+        {
+            RCSQueryParams params;
+            params.setResourceInterface(ifType);
+
+            m_sceneCollectionResource->get(params, cb);
+        }
+
+        RCSRemoteResourceObject::Ptr 
+            SceneCollectionResourceRequestor::getRemoteResourceObject() const
+        {
+            return m_sceneCollectionResource;
+        }
+
+        SceneMemberResourceRequestor::Ptr
+        SceneCollectionResourceRequestor::createSceneMemberResourceRequestor(
+            const std::string &memHref, const std::string &id, RCSRemoteResourceObject::Ptr target)
+        {
+            try
+            {
+                std::vector< std::string > vecRT{ SCENE_MEMBER_RT };
+                std::vector< std::string > vecIF{ SCENE_CLIENT_REQ_IF };
+
+                RCSRemoteResourceObject::Ptr pResource
+                    = SceneUtils::createRCSResourceObject(
+                        memHref, SCENE_CONNECTIVITY, vecRT, vecIF);
+
+                SceneMemberResourceRequestor::Ptr pMemRequestor =
+                    std::make_shared< SceneMemberResourceRequestor >(pResource, id);
+
+                pMemRequestor->setRemoteResourceObject(target);
+                
+                {
+                    std::lock_guard< std::mutex > memberlock(m_memberRequestorLock);
+                    m_memberRequestors[target->getAddress() + target->getUri()] = pMemRequestor;
+                }
+
+                return pMemRequestor;
+            }
+            catch (const std::exception &e)
+            {
+                SCENE_CLIENT_PRINT_LOG(e.what());
+                return nullptr;
+            }
+        }
+
+        SceneMemberResourceRequestor::Ptr
+        SceneCollectionResourceRequestor::getSceneMemberResourceRequestor(
+            const std::string &targetHref) const
+        {
+            std::lock_guard< std::mutex > memberlock(m_memberRequestorLock);
+
+            return m_memberRequestors.find(targetHref) != m_memberRequestors.end() ?
+                m_memberRequestors.at(targetHref) : nullptr;
+        }
+
+        void SceneCollectionResourceRequestor::onSetResponseForScene(
+            const RCSResourceAttributes &attrs, int eCode,
+            const std::string &name, const InternalSceneRequestCallback &cb,
+            REQUEST_TYPE reqType, SceneCollectionResourceRequestor::wPtr ptr)
+        {
+            SceneCollectionResourceRequestor::Ptr collectionPtr = ptr.lock();
+
+            if (collectionPtr)
+            {
+                collectionPtr->onSetResponseForScene_impl(
+                    std::move(attrs), eCode, name, std::move(cb), reqType);
+            }
+        }
+
+        void SceneCollectionResourceRequestor::onSetResponseForScene_impl(
+            const RCSResourceAttributes &attrs, int eCode, const std::string &name,
+            const InternalSceneRequestCallback &internalCB, REQUEST_TYPE reqType)
+        {
+            // TODO error code
+            int resultCode = SCENE_CLIENT_BADREQUEST;
+
+            if (eCode == OC_STACK_OK)
+            {
+                try
+                {
+                    switch (reqType)
+                    {
+                        case ADD_SCENE:
+                            {
+                                auto scenes
+                                    = attrs.at(SCENE_KEY_SCENEVALUES).
+                                        get< std::vector< std::string > >();
+
+                                if ((std::find(scenes.begin(), scenes.end(), name))
+                                    != scenes.end())
+                                {
+                                    resultCode = SCENE_RESPONSE_SUCCESS;
+                                }
+                            }
+                            break;
+
+                        case REMOVE_SCENE:
+                            break;
+
+                        case EXECUTE_SCENE:
+                            {
+                                auto lastScene
+                                    = attrs.at(SCENE_KEY_LAST_SCENE).get< std::string >();
+
+                                if (lastScene.compare(name) == 0)
+                                {
+                                    resultCode = SCENE_RESPONSE_SUCCESS;
+                                }
+                            }
+                            break;
+                    }
+                }
+                catch (const std::exception &e)
+                {
+                    SCENE_CLIENT_PRINT_LOG(e.what());
+                    resultCode = SCENE_SERVER_INTERNALSERVERERROR;
+                }
+            }
+
+            internalCB(reqType, name, resultCode);
+        }
+
+        void SceneCollectionResourceRequestor::onSceneMemberAdded(
+            const RCSRepresentation &rep, int eCode,
+            RCSRemoteResourceObject::Ptr target, const InternalAddMemberCallback &internalCB,
+            SceneCollectionResourceRequestor::wPtr ptr)
+        {
+            SceneCollectionResourceRequestor::Ptr collection = ptr.lock();
+
+            if (collection)
+            {
+                collection->onSceneMemberAdded_impl(
+                    std::move(rep), eCode, target, std::move(internalCB));
+            }
+        }
+
+        void SceneCollectionResourceRequestor::onSceneMemberAdded_impl(
+            const RCSRepresentation &rep, int eCode,
+            RCSRemoteResourceObject::Ptr target, const InternalAddMemberCallback &internalCB)
+        {
+            // TODO error code
+            int result = SCENE_CLIENT_BADREQUEST;
+            SceneMemberResourceRequestor::Ptr memRequestor = nullptr;
+
+            if (eCode == OC_STACK_OK)
+            {
+                try
+                {
+                    RCSResourceAttributes receivedAttrs = rep.getAttributes();
+
+                    memRequestor
+                        = createSceneMemberResourceRequestor(
+                              receivedAttrs.at(SCENE_KEY_CREATEDLINK).get< std::string >(),
+                              receivedAttrs.at(SCENE_KEY_ID).get< std::string >(), target);
+
+                    if (memRequestor)
+                    {
+                        memRequestor->setRemoteResourceObject(target);
+                        result = SCENE_RESPONSE_SUCCESS;
+                    }
+                }
+                catch (const std::exception &e)
+                {
+                    SCENE_CLIENT_PRINT_LOG(e.what());
+                    result = SCENE_SERVER_INTERNALSERVERERROR;
+                }
+            }
+
+            internalCB(result);
+        }
+
+        void SceneCollectionResourceRequestor::onNameSet(const RCSRepresentation &rep, int eCode,
+            const std::string &name, const InternalSetNameCallback &internalCB,
+            SceneCollectionResourceRequestor::wPtr ptr)
+        {
+            SceneCollectionResourceRequestor::Ptr collectionPtr = ptr.lock();
+
+            if (collectionPtr)
+            {
+                collectionPtr->onNameSet_impl(std::move(rep), eCode, name, std::move(internalCB));
+            }
+        }
+
+        void SceneCollectionResourceRequestor::onNameSet_impl(
+            const RCSRepresentation &rep, int eCode, const std::string &name,
+            const InternalSetNameCallback &internalCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            if (eCode == OC_STACK_OK)
+            {
+                if (rep.getAttributes().at(SCENE_KEY_NAME).get< std::string >() == name)
+                {
+                    result = SCENE_RESPONSE_SUCCESS;
+                }
+
+            }
+
+            internalCB(result);
+        }
+
+    }
+}
diff --git a/service/scene-manager/src/SceneCollectionResourceRequestor.h b/service/scene-manager/src/SceneCollectionResourceRequestor.h
new file mode 100644 (file)
index 0000000..1975f80
--- /dev/null
@@ -0,0 +1,120 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENECOLLECTION_RESOURCE_REQUESTOR_H_
+#define SM_SCENECOLLECTION_RESOURCE_REQUESTOR_H_
+
+#include <map>
+#include <mutex>
+
+#include "SceneCommons.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSRepresentation.h"
+#include "SceneMemberResourceRequestor.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneCollectionResourceRequestor
+            : public std::enable_shared_from_this< SceneCollectionResourceRequestor >
+        {
+            public:
+                typedef std::shared_ptr< SceneCollectionResourceRequestor > Ptr;
+                typedef std::weak_ptr< SceneCollectionResourceRequestor > wPtr;
+
+                enum REQUEST_TYPE
+                {
+                    ADD_SCENE, REMOVE_SCENE, EXECUTE_SCENE
+                };
+
+                typedef std::function< 
+                    void(REQUEST_TYPE, const std::string &name, int eCode) >
+                        InternalSceneRequestCallback;
+
+                typedef std::function < void(int eCode) > InternalAddMemberCallback;
+
+                typedef std::function < void(int eCode) > InternalSetNameCallback;
+
+            public:
+                SceneCollectionResourceRequestor(RCSRemoteResourceObject::Ptr collectionResource);
+                ~SceneCollectionResourceRequestor() = default;
+
+                void requestSceneCreation(const std::string &name, InternalSceneRequestCallback);
+                void requestSceneRemoval(const std::string &name, InternalSceneRequestCallback);
+
+                void requestSceneExecution(const std::string &name, InternalSceneRequestCallback);
+
+                void requestAddSceneMember(RCSRemoteResourceObject::Ptr targetResource,
+                                           const std::string &sceneName,
+                                           const RCSResourceAttributes &attr,
+                                           InternalAddMemberCallback);
+
+                void requestSetName(const std::string &, InternalSetNameCallback);
+
+                void requestGet(const std::string &, RCSRemoteResourceObject::GetCallback);
+
+                RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+                SceneMemberResourceRequestor::Ptr createSceneMemberResourceRequestor(
+                    const std::string &memHref, const std::string &id,
+                    RCSRemoteResourceObject::Ptr target);
+
+                SceneMemberResourceRequestor::Ptr getSceneMemberResourceRequestor(
+                    const std::string &targetHref) const;
+
+            private:
+                static void onSetResponseForScene(
+                    const RCSResourceAttributes &attrs, int eCode,
+                    const std::string &name, const InternalSceneRequestCallback &,
+                    REQUEST_TYPE, SceneCollectionResourceRequestor::wPtr);
+
+                void onSetResponseForScene_impl(
+                    const RCSResourceAttributes &attrs, int eCode,
+                    const std::string &name, const InternalSceneRequestCallback &,
+                    REQUEST_TYPE);
+
+                static void onSceneMemberAdded(
+                    const RCSRepresentation &, int eCode,
+                    RCSRemoteResourceObject::Ptr, const InternalAddMemberCallback &,
+                    SceneCollectionResourceRequestor::wPtr);
+
+                void onSceneMemberAdded_impl(
+                    const RCSRepresentation &, int eCode,
+                    RCSRemoteResourceObject::Ptr, const InternalAddMemberCallback &);
+
+                static void onNameSet(const RCSRepresentation &, int eCode, const std::string &,
+                    const InternalSetNameCallback &, SceneCollectionResourceRequestor::wPtr);
+
+                void onNameSet_impl(const RCSRepresentation &, int eCode, const std::string &,
+                    const InternalSetNameCallback &);
+
+            private:
+                RCSRemoteResourceObject::Ptr m_sceneCollectionResource;
+                mutable std::mutex m_memberRequestorLock;
+                std::map< std::string, SceneMemberResourceRequestor::Ptr > m_memberRequestors;
+        };
+        
+    }
+}
+
+#endif /* SM_SCENECOLLECTION_RESOURCE_REQUESTOR_H_ */
+
diff --git a/service/scene-manager/src/SceneCommons.h b/service/scene-manager/src/SceneCommons.h
new file mode 100644 (file)
index 0000000..f1c8962
--- /dev/null
@@ -0,0 +1,128 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the declaration of SceneUtils class and constant variables.
+ */
+
+#ifndef SCENE_COMMONS_H
+#define SCENE_COMMONS_H
+
+#include <string>
+#include <vector>
+
+#include "OCApi.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        const std::string SCENE_LIST_DEFAULT_NAME = "list of scene Collections";
+
+        const std::string SCENE_KEY_LAST_SCENE = "lastScene";
+        const std::string SCENE_KEY_SCENEVALUES = "sceneValues";
+        const std::string SCENE_KEY_NAME = "n";
+        const std::string SCENE_KEY_ID = "id";
+        const std::string SCENE_KEY_RTS = "rts";
+        const std::string SCENE_KEY_RT = "rt";
+        const std::string SCENE_KEY_IF = "if";
+        const std::string SCENE_KEY_PAYLOAD_LINK = "link";
+        const std::string SCENE_KEY_SCENEMAPPINGS = "sceneMappings";
+        const std::string SCENE_KEY_HREF = "href";
+        const std::string SCENE_KEY_SCENE = "scene";
+        const std::string SCENE_KEY_MEMBERPROPERTY = "memberProperty";
+        const std::string SCENE_KEY_MEMBERVALUE = "memberValue";
+        const std::string SCENE_KEY_CREATEDLINK = "createdlink";
+
+        const std::string SCENE_KEY_URI = "uri";
+        const std::string SCENE_KEY_CHILD = "child";
+
+        const std::string SCENE_LIST_RT = "oic.wk.scenelist";
+        const std::string SCENE_MEMBER_RT = "oic.r.scenemember";
+        const std::string SCENE_COLLECTION_RT = "oic.wk.scenecollection";
+
+        const std::string COAP_TAG = "coap://";
+        const std::string SCENE_LIST_URI = "/SceneListResURI";
+        const std::string PREFIX_SCENE_COLLECTION_URI = "/a/sceneCollection";
+        const std::string PREFIX_SCENE_MEMBER_URI = "/a/sceneMember";
+
+        const std::string LINK_BATCH = "oic.if.lb";
+
+        const OCConnectivityType SCENE_CONNECTIVITY = CT_ADAPTER_IP;
+        const std::string SCENE_CLIENT_REQ_IF = OC::DEFAULT_INTERFACE;
+        const std::string SCENE_CLIENT_CREATE_REQ_IF = OC::BATCH_INTERFACE;
+
+        const int SCENE_RESPONSE_SUCCESS = 200;
+        const int SCENE_CLIENT_BADREQUEST = 400;
+        const int SCENE_SERVER_INTERNALSERVERERROR = 500;
+
+        class SceneUtils
+        {
+        public:
+            /**
+             * Returns UUID for Scene collection resource and members ID.
+             *
+             * @throw RCSException
+             */
+            static std::string OICGenerateUUIDStr();
+
+            /**
+             * Returns host resource's address and uri from coap address.
+             *
+             * @param address uri of host resource (e.g. coap://192.168.0.2:12345/a/light)
+             * @param[out] host host resource's address (e.g. 192.168.0.2:12345)
+             * @param[out] uri host resource's uri (e.g. /a/light)
+             *
+             * @throw RCSInvalidParameterException
+             */
+            static void getHostUriString(
+                    const std::string address, std::string *host, std::string *uri);
+
+            /**
+             * Returns information of my own network address.
+             *
+             * This functionality use the CA interface for getting network information.
+             * But It has design issue. So, It will should change to other interface.
+             *
+             * @throw RCSException
+             */
+            static std::string getNetAddress();
+
+            /**
+            * Returns RCSRemoteResourceObject pointer created with provided resource information.
+            *
+            * @param address uri of resource (e.g. coap://192.168.0.2:12345/a/light)
+            * @param ct OCConnectivityType type of connectivity indicating the interface
+            * @param vecRT a vector of resource types implemented by the resource
+            * @param vecIF a vector of interfaces that the resource supports/implements
+            *
+            * @throw RCSException
+            */
+            static RCSRemoteResourceObject::Ptr createRCSResourceObject(
+                const std::string &address, const OCConnectivityType ct,
+                const std::vector< std::string > &vecRT, const std::vector< std::string > &vecIF);
+        };
+    }
+}
+
+#endif // SCENE_COMMONS_H
diff --git a/service/scene-manager/src/SceneList.cpp b/service/scene-manager/src/SceneList.cpp
new file mode 100755 (executable)
index 0000000..ec1d096
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneList.h"
+
+#include "SceneListResource.h"
+#include "SceneCollectionResource.h"
+
+#include "RCSRequest.h"
+#include "PrimitiveResource.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        SceneList * SceneList::getInstance()
+        {
+            static SceneList instance;
+            return &instance;
+        }
+
+        SceneCollection::Ptr SceneList::addNewSceneCollection()
+        {
+            auto sceneCollectionResObj =
+                    SceneCollectionResource::create();
+            SceneListResource::getInstance()->addSceneCollectionResource(sceneCollectionResObj);
+
+            return SceneCollection::Ptr(new SceneCollection(sceneCollectionResObj));
+        }
+
+        std::vector< SceneCollection::Ptr > SceneList::getSceneCollections() const
+        {
+            std::vector<SceneCollection::Ptr> sceneCollections;
+            for(const auto& it : SceneListResource::getInstance()->getSceneCollections())
+            {
+                SceneCollection::Ptr sceneCollectionPtr(new SceneCollection(it));
+                sceneCollections.push_back(sceneCollectionPtr);
+            }
+            return sceneCollections;
+        }
+
+        void SceneList::setName(const std::string& sceneListName)
+        {
+            SceneListResource::getInstance()->setName(sceneListName);
+        }
+
+        std::string SceneList::getName() const
+        {
+            return SceneListResource::getInstance()->getName();
+        }
+    } /* namespace Service */
+} /* namespace OIC */
+
diff --git a/service/scene-manager/src/SceneListResource.cpp b/service/scene-manager/src/SceneListResource.cpp
new file mode 100644 (file)
index 0000000..ef1585a
--- /dev/null
@@ -0,0 +1,196 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneListResource.h"
+
+#include "RCSRequest.h"
+#include "OCApi.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        SceneListResource::SceneListResource()
+        : m_sceneListObj(createResourceObject())
+        {
+            m_sceneListObj->setAttribute(SCENE_KEY_NAME, SCENE_LIST_DEFAULT_NAME);
+            m_sceneListObj->setAttribute(SCENE_KEY_RTS, SCENE_LIST_RT);
+
+            m_sceneListObj->setSetRequestHandler(&SceneListRequestHandler::onSetRequest);
+            m_sceneListObj->setGetRequestHandler(&SceneListRequestHandler::onGetRequest);
+        }
+
+        SceneListResource * SceneListResource::getInstance()
+        {
+            static SceneListResource instance;
+            return & instance;
+        }
+
+        RCSResourceObject::Ptr SceneListResource::createResourceObject()
+        {
+            return RCSResourceObject::Builder(
+                    SCENE_LIST_URI, SCENE_LIST_RT, OC_RSRVD_INTERFACE_DEFAULT).
+                            addInterface(OC::BATCH_INTERFACE).
+                            setDiscoverable(true).setObservable(false).build();
+        }
+
+        void SceneListResource::addSceneCollectionResource(
+                SceneCollectionResource::Ptr newObject)
+        {
+            std::lock_guard<std::mutex> collectionlock(m_sceneCollectionLock);
+            m_sceneCollections.push_back(newObject);
+            m_sceneListObj->bindResource(newObject->getRCSResourceObject());
+        }
+
+        std::string SceneListResource::getName() const
+        {
+            return m_sceneListObj->getAttributeValue(SCENE_KEY_NAME).get<std::string>();
+        }
+
+        void SceneListResource::setName(std::string && newName)
+        {
+            m_sceneListObj->setAttribute(SCENE_KEY_NAME, std::move(newName));
+        }
+
+        void SceneListResource::setName(const std::string & newName)
+        {
+            setName(std::string(newName));
+        }
+
+        std::vector<SceneCollectionResource::Ptr> SceneListResource::getSceneCollections() const
+        {
+            std::lock_guard<std::mutex> collectionlock(m_sceneCollectionLock);
+            return m_sceneCollections;
+        }
+
+        RCSResourceObject::Ptr SceneListResource::getResourceObject() const
+        {
+            return m_sceneListObj;
+        }
+
+        std::vector<RCSResourceAttributes> SceneListResource::getChildrenAttributes() const
+        {
+            std::vector<RCSResourceAttributes> childrenAttrs;
+
+            auto sceneCollections = getSceneCollections();
+
+            std::for_each(sceneCollections.begin(), sceneCollections.end(),
+                    [& childrenAttrs](const SceneCollectionResource::Ptr & pCollection)
+                    {
+                        RCSResourceAttributes collectionAttr;
+                        {
+                            RCSResourceObject::LockGuard guard(
+                                    pCollection->getRCSResourceObject());
+                            collectionAttr = pCollection->getRCSResourceObject()->getAttributes();
+                        }
+
+                        auto sceneMembers = pCollection->getSceneMembers();
+                        std::vector<RCSResourceAttributes> membersAttrs;
+
+                        std::for_each(sceneMembers.begin(), sceneMembers.end(),
+                                [& membersAttrs](const SceneMemberResource::Ptr & pMember)
+                                {
+                                    RCSResourceObject::LockGuard guard(pMember->getRCSResourceObject());
+                                    membersAttrs.push_back(pMember->getRCSResourceObject()->getAttributes());
+                                });
+
+                        if (membersAttrs.size())
+                        {
+                            collectionAttr[SCENE_KEY_CHILD] = membersAttrs;
+                        }
+
+                        childrenAttrs.push_back(collectionAttr);
+                    });
+
+            return childrenAttrs;
+        }
+
+        RCSSetResponse SceneListResource::SceneListRequestHandler::onSetRequest(
+                const RCSRequest & request, RCSResourceAttributes & attributes)
+        {
+            RCSResourceAttributes responseAttr;
+            int eCode = SCENE_CLIENT_BADREQUEST;
+
+            if(request.getInterface() == LINK_BATCH)
+            {
+                auto newObject
+                    = SceneCollectionResource::create(attributes);
+
+                SceneListResource::getInstance()->addSceneCollectionResource(newObject);
+
+                auto responseAtt = attributes;
+                responseAtt[SCENE_KEY_NAME] = RCSResourceAttributes::Value(newObject->getName());
+                responseAtt[SCENE_KEY_ID] = RCSResourceAttributes::Value(newObject->getId());
+
+                auto uri = COAP_TAG + newObject->getAddress() + newObject->getUri();
+                responseAtt[SCENE_KEY_PAYLOAD_LINK]
+                            = RCSResourceAttributes::Value(uri);
+
+                responseAttr = responseAtt;
+                eCode = SCENE_RESPONSE_SUCCESS;
+            }
+
+            else if (attributes.contains(SCENE_KEY_NAME))
+            {
+                SceneListResource::getInstance()->setName(
+                        attributes.at(SCENE_KEY_NAME).get<std::string>());
+
+                responseAttr = attributes;
+                eCode = SCENE_RESPONSE_SUCCESS;
+            }
+            else
+            {
+                responseAttr = attributes;
+                eCode = SCENE_CLIENT_BADREQUEST;
+            }
+
+            return RCSSetResponse::create(responseAttr, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSGetResponse SceneListResource::SceneListRequestHandler::onGetRequest(
+                const RCSRequest & request, RCSResourceAttributes & /*attributes*/)
+        {
+
+            if(request.getInterface() != OC::DEFAULT_INTERFACE)
+            {
+                return RCSGetResponse::defaultAction();
+            }
+
+            auto childrenAttrs = SceneListResource::getInstance()->getChildrenAttributes();
+
+            RCSResourceAttributes retAttr;
+
+            {
+                RCSResourceObject::LockGuard lock(
+                        SceneListResource::getInstance()->getResourceObject());
+                retAttr = SceneListResource::getInstance()->getResourceObject()->getAttributes();
+            }
+
+            if (childrenAttrs.size())
+            {
+                retAttr[SCENE_KEY_CHILD] = childrenAttrs;
+            }
+
+            return RCSGetResponse::create(retAttr);
+        }
+
+    }
+}
diff --git a/service/scene-manager/src/SceneListResource.h b/service/scene-manager/src/SceneListResource.h
new file mode 100644 (file)
index 0000000..d9e0d03
--- /dev/null
@@ -0,0 +1,110 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the declaration of classes and its members related to SceneListResrouceObject
+ */
+
+#ifndef SCENE_LIST_RESOURCE_OBJECT_H
+#define SCENE_LIST_RESOURCE_OBJECT_H
+
+#include <string>
+
+#include "RCSResourceObject.h"
+#include "SceneCollectionResource.h"
+#include "SceneCommons.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SceneListResource
+        {
+        public:
+            /**
+             * Returns Scene List Resource object as single instance.
+             */
+            static SceneListResource * getInstance();
+
+            /**
+             * Add Scene Collection resource object to Scene List Resource.
+             *
+             * @param collectionObj created Scene Collection Resource Object by constructor of SceneCollectionResourceObject class
+             */
+            void addSceneCollectionResource(SceneCollectionResource::Ptr collectionObj);
+
+            /**
+             * Returns Scene List name.
+             */
+            std::string getName() const;
+
+            /**
+             * Sets Scene List name.
+             *
+             * @param name name to set
+             */
+            void setName(std::string && name);
+
+            /**
+             * @overload
+             */
+            void setName(const std::string &);
+
+            /**
+             * Returns all of Scene Collection Resource object.
+             */
+            std::vector<SceneCollectionResource::Ptr> getSceneCollections() const;
+
+            std::vector<RCSResourceAttributes> getChildrenAttributes() const;
+
+            RCSResourceObject::Ptr getResourceObject() const;
+
+        private:
+            class SceneListRequestHandler
+            {
+            public:
+                SceneListRequestHandler() = default;
+                ~SceneListRequestHandler() = default;
+
+                static RCSSetResponse onSetRequest(const RCSRequest &, RCSResourceAttributes &);
+                static RCSGetResponse onGetRequest(const RCSRequest &, RCSResourceAttributes &);
+            };
+
+            RCSResourceObject::Ptr m_sceneListObj;
+            mutable std::mutex m_sceneCollectionLock;
+            std::vector<SceneCollectionResource::Ptr> m_sceneCollections;
+
+            SceneListResource();
+            ~SceneListResource() = default;
+
+            SceneListResource(const SceneListResource &) = delete;
+            SceneListResource & operator = (const SceneListResource &) = delete;
+
+            SceneListResource(SceneListResource &&) = delete;
+            SceneListResource & operator = (SceneListResource &&) = delete;
+
+            RCSResourceObject::Ptr createResourceObject();
+        };
+    }
+}
+
+#endif // SCENE_LIST_RESOURCE_OBJECT_H
diff --git a/service/scene-manager/src/SceneListResourceRequestor.cpp b/service/scene-manager/src/SceneListResourceRequestor.cpp
new file mode 100644 (file)
index 0000000..2776afa
--- /dev/null
@@ -0,0 +1,159 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneListResourceRequestor.h"
+#include "RemoteSceneUtils.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        SceneListResourceRequestor::SceneListResourceRequestor(
+            RCSRemoteResourceObject::Ptr listResource)
+                : m_sceneListResource{ listResource }
+        {
+            SCENE_CLIENT_ASSERT_NOT_NULL(listResource);
+        }
+
+        void SceneListResourceRequestor::requestSceneCollectionCreation(
+            const std::string &name, InternalCreateSceneCollectionCallback internalCB)
+        {
+            RCSResourceAttributes attrs;
+            attrs[SCENE_KEY_NAME] = name;
+
+            RCSRemoteResourceObject::SetCallback setRequestCB
+                = std::bind(&SceneListResourceRequestor::onSceneCollectionCreated,
+                            std::placeholders::_2, std::placeholders::_3,
+                            name, std::move(internalCB),
+                            SceneListResourceRequestor::wPtr(shared_from_this()));
+
+            RCSQueryParams queryParams;
+            queryParams.setResourceInterface(LINK_BATCH);
+
+            m_sceneListResource->set(queryParams, std::move(attrs), std::move(setRequestCB));
+        }
+
+        void SceneListResourceRequestor::requestSetName
+        (const std::string &name, InternalSetNameCallback internalCB)
+        {
+            RCSResourceAttributes attrs;
+            attrs[SCENE_KEY_NAME] = name;
+
+            RCSRemoteResourceObject::SetCallback setRequestCB
+                = std::bind(&SceneListResourceRequestor::onNameSet,
+                std::placeholders::_2, std::placeholders::_3, name, std::move(internalCB),
+                SceneListResourceRequestor::wPtr(shared_from_this()));
+
+            RCSQueryParams queryParams;
+            queryParams.setResourceInterface(SCENE_CLIENT_REQ_IF);
+
+            m_sceneListResource->set(queryParams, std::move(attrs), std::move(setRequestCB));
+        }
+
+        void SceneListResourceRequestor::requestGet(
+            const std::string &ifType, RCSRemoteResourceObject::GetCallback cb)
+        {
+            RCSQueryParams params;
+            params.setResourceInterface(ifType);
+
+            m_sceneListResource->get(params, cb);
+        }
+
+        RCSRemoteResourceObject::Ptr SceneListResourceRequestor::getRemoteResourceObject() const
+        {
+            return m_sceneListResource;
+        }
+
+        void SceneListResourceRequestor::onSceneCollectionCreated(
+            const RCSRepresentation &rep, int eCode,
+            const std::string &name, const InternalCreateSceneCollectionCallback &cb,
+            SceneListResourceRequestor::wPtr ptr)
+        {
+            SceneListResourceRequestor::Ptr listPtr = ptr.lock();
+
+            if (listPtr)
+            {
+                listPtr->onSceneCollectionCreated_impl(std::move(rep), eCode, name, std::move(cb));
+            }
+        }
+
+        void SceneListResourceRequestor::onSceneCollectionCreated_impl(
+            const RCSRepresentation &rep, int eCode,
+            const std::string &name, const InternalCreateSceneCollectionCallback &internalCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            std::string link, id;
+
+            if (eCode == OC_STACK_OK)
+            {
+                try
+                {
+                    RCSResourceAttributes attrs = rep.getAttributes();
+
+                    if (attrs.at(SCENE_KEY_NAME).get< std::string >().compare(name) == 0)
+                    {
+                        link = attrs.at(SCENE_KEY_PAYLOAD_LINK).get< std::string >();
+                        id = attrs.at(SCENE_KEY_ID).get< std::string >();
+                        result = SCENE_RESPONSE_SUCCESS;
+                    }
+                }
+                catch (const std::exception &e)
+                {
+                    SCENE_CLIENT_PRINT_LOG(e.what());
+                    result = SCENE_SERVER_INTERNALSERVERERROR;
+                }
+            }
+
+            internalCB(link, id, name, result);
+        }
+
+        void SceneListResourceRequestor::onNameSet(const RCSRepresentation &rep, int eCode,
+            const std::string &name, const InternalSetNameCallback &internalCB,
+            SceneListResourceRequestor::wPtr ptr)
+        {
+            SceneListResourceRequestor::Ptr listPtr = ptr.lock();
+
+            if (listPtr)
+            {
+                listPtr->onNameSet_impl(std::move(rep), eCode, name, std::move(internalCB));
+            }
+        }
+
+        void SceneListResourceRequestor::onNameSet_impl(
+            const RCSRepresentation &rep, int eCode, const std::string &name,
+            const InternalSetNameCallback &internalCB)
+        {
+            int result = SCENE_CLIENT_BADREQUEST;
+            if (eCode == OC_STACK_OK)
+            {
+                if (rep.getAttributes().at(SCENE_KEY_NAME).get< std::string >() == name)
+                {
+                    result = SCENE_RESPONSE_SUCCESS;
+                }
+
+            }
+
+            internalCB(result);
+        }
+
+    }
+}
diff --git a/service/scene-manager/src/SceneListResourceRequestor.h b/service/scene-manager/src/SceneListResourceRequestor.h
new file mode 100644 (file)
index 0000000..eb7a260
--- /dev/null
@@ -0,0 +1,85 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENELIST_RESOURCE_REQUESTOR_H_
+#define SM_SCENELIST_RESOURCE_REQUESTOR_H_
+
+#include "SceneCommons.h"
+#include "RCSRemoteResourceObject.h"
+#include "RCSRepresentation.h"
+#include "RemoteSceneUtils.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneListResourceRequestor
+            : public std::enable_shared_from_this< SceneListResourceRequestor >
+        {
+            public:
+                typedef std::shared_ptr< SceneListResourceRequestor > Ptr;
+                typedef std::weak_ptr< SceneListResourceRequestor > wPtr;
+
+                typedef std::function<
+                    void(const std::string &link, const std::string &id,
+                            const std::string &name, int eCode) >
+                    InternalCreateSceneCollectionCallback;
+
+                typedef std::function < void(int eCode) > InternalSetNameCallback;
+
+            public:
+                SceneListResourceRequestor(RCSRemoteResourceObject::Ptr listResource);
+                ~SceneListResourceRequestor() = default;
+
+                void requestSceneCollectionCreation(
+                    const std::string &name, InternalCreateSceneCollectionCallback);
+
+                void requestSetName(const std::string &, InternalSetNameCallback);
+
+                void requestGet(const std::string &, RCSRemoteResourceObject::GetCallback);
+
+                RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+            private:
+                static void onSceneCollectionCreated(
+                    const RCSRepresentation &, int eCode,
+                    const std::string &name, const InternalCreateSceneCollectionCallback &,
+                    SceneListResourceRequestor::wPtr);
+
+                void onSceneCollectionCreated_impl(
+                    const RCSRepresentation &, int eCode,
+                    const std::string &name, const InternalCreateSceneCollectionCallback &);
+
+                static void onNameSet(const RCSRepresentation &, int eCode, const std::string &,
+                    const InternalSetNameCallback &, SceneListResourceRequestor::wPtr);
+
+                void onNameSet_impl(const RCSRepresentation &, int eCode, const std::string &,
+                    const InternalSetNameCallback &);
+
+            private:
+                RCSRemoteResourceObject::Ptr m_sceneListResource;
+        };
+
+    }
+}
+
+#endif /* SM_SCENELIST_RESOURCE_REQUESTOR_H_ */
+
diff --git a/service/scene-manager/src/SceneMemberResource.cpp b/service/scene-manager/src/SceneMemberResource.cpp
new file mode 100644 (file)
index 0000000..0de8d6b
--- /dev/null
@@ -0,0 +1,341 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneMemberResource.h"
+
+#include <atomic>
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        namespace
+        {
+            std::atomic_int g_numOfSceneMember(0);
+        }
+
+        SceneMemberResource::Ptr
+        SceneMemberResource::createSceneMemberResource(
+                RCSRemoteResourceObject::Ptr remoteObject)
+        {
+            SceneMemberResource::Ptr sceneMemberResource(new SceneMemberResource());
+
+            sceneMemberResource->m_uri = PREFIX_SCENE_MEMBER_URI + "/" +
+                std::to_string(g_numOfSceneMember++);
+
+            sceneMemberResource->m_remoteMemberObj = remoteObject;
+
+            sceneMemberResource->createResourceObject();
+            sceneMemberResource->initSetRequestHandler();
+            sceneMemberResource->setDefaultAttributes();
+
+            return sceneMemberResource;
+        }
+
+        SceneMemberResource::Ptr
+        SceneMemberResource::createSceneMemberResource(const RCSResourceAttributes & link)
+        {
+            return createSceneMemberResource(RCSResourceAttributes(link));
+        }
+
+        SceneMemberResource::Ptr
+        SceneMemberResource::createSceneMemberResource(RCSResourceAttributes && link)
+        {
+            auto href = link.at(SCENE_KEY_HREF).get<std::string>();
+
+            std::string address;
+            std::string uri;
+
+            SceneUtils::getHostUriString(href, &address, &uri);
+
+            auto ocResourcePtr
+                = OC::OCPlatform::constructResourceObject(
+                    address, uri, OCConnectivityType::CT_ADAPTER_IP, false,
+                    link.at(SCENE_KEY_RT).get<std::vector<std::string>>(),
+                    link.at(SCENE_KEY_IF).get<std::vector<std::string>>());
+
+            return createSceneMemberResource(RCSRemoteResourceObject::fromOCResource(ocResourcePtr));
+        }
+
+        void SceneMemberResource::createResourceObject()
+        {
+            m_sceneMemberResourceObj
+                = RCSResourceObject::Builder(
+                        m_uri, SCENE_MEMBER_RT, OC_RSRVD_INTERFACE_DEFAULT).
+                        setDiscoverable(true).setObservable(false).build();
+        }
+
+        void SceneMemberResource::setDefaultAttributes()
+        {
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_ID, SceneUtils::OICGenerateUUIDStr());
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_NAME, std::string());
+
+            RCSResourceAttributes subAtt;
+            subAtt[SCENE_KEY_HREF]
+                    = RCSResourceAttributes::Value(
+                            m_remoteMemberObj->getAddress() + m_remoteMemberObj->getUri());
+            subAtt[SCENE_KEY_IF] = RCSResourceAttributes::Value(m_remoteMemberObj->getInterfaces());
+            subAtt[SCENE_KEY_RT] = RCSResourceAttributes::Value(m_remoteMemberObj->getTypes());
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_PAYLOAD_LINK, subAtt);
+
+            m_sceneMemberResourceObj->setAttribute(
+                    SCENE_KEY_SCENEMAPPINGS, std::vector<RCSResourceAttributes>());
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_URI, m_uri);
+        }
+
+        void SceneMemberResource::initSetRequestHandler()
+        {
+            m_requestHandler.m_owner = std::weak_ptr<SceneMemberResource>(shared_from_this());
+            m_sceneMemberResourceObj->setSetRequestHandler(std::bind(
+                    &SceneMemberResource::SceneMemberRequestHandler::onSetRequest,
+                    m_requestHandler, std::placeholders::_1, std::placeholders::_2));
+        }
+
+        void SceneMemberResource::addMappingInfo(MappingInfo && mInfo)
+        {
+            RCSResourceAttributes newAtt;
+            {
+                RCSResourceObject::LockGuard guard(m_sceneMemberResourceObj);
+                newAtt = m_sceneMemberResourceObj->getAttributes();
+            }
+
+            auto mappingInfo = newAtt.at(SCENE_KEY_SCENEMAPPINGS).
+                    get<std::vector<RCSResourceAttributes>>();
+
+            auto foundMInfo = std::find_if(mappingInfo.begin(), mappingInfo.end(),
+                    [& mInfo](const RCSResourceAttributes & att) -> bool
+                    {
+                        return (att.at(SCENE_KEY_SCENE).get<std::string>() == mInfo.sceneName) &&
+                                (att.at(SCENE_KEY_MEMBERPROPERTY).get<std::string>() == mInfo.key);
+                    });
+
+            if (foundMInfo != mappingInfo.end())
+            {
+                mappingInfo.erase(foundMInfo);
+            }
+            RCSResourceAttributes newMapInfo;
+            newMapInfo[SCENE_KEY_SCENE] = RCSResourceAttributes::Value(std::move(mInfo.sceneName));
+            newMapInfo[SCENE_KEY_MEMBERPROPERTY] = RCSResourceAttributes::Value(std::move(mInfo.key));
+            newMapInfo[SCENE_KEY_MEMBERVALUE] = std::move(mInfo.value);
+            mappingInfo.push_back(newMapInfo);
+
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_SCENEMAPPINGS, mappingInfo);
+        }
+
+        void SceneMemberResource::addMappingInfo(const MappingInfo & mInfo)
+        {
+            addMappingInfo(MappingInfo(mInfo));
+        }
+
+        std::vector<SceneMemberResource::MappingInfo> SceneMemberResource::getMappingInfos() const
+        {
+            std::vector<MappingInfo> retMInfo;
+
+            auto mInfo = m_sceneMemberResourceObj->getAttributeValue(SCENE_KEY_SCENEMAPPINGS).
+                    get<std::vector<RCSResourceAttributes>>();
+            std::for_each(mInfo.begin(), mInfo.end(),
+                    [& retMInfo](const RCSResourceAttributes & att)
+                    {
+                        retMInfo.push_back(MappingInfo::create(att));
+                    });
+
+            return retMInfo;
+        }
+
+        std::string SceneMemberResource::getId() const
+        {
+            return m_sceneMemberResourceObj->getAttributeValue(SCENE_KEY_ID).get<std::string>();
+        }
+
+        std::string SceneMemberResource::getFullUri() const
+        {
+            return std::string(COAP_TAG + SceneUtils::getNetAddress() + m_uri);
+        }
+
+        std::string SceneMemberResource::getTargetUri() const
+        {
+            return std::string(m_remoteMemberObj->getAddress() + m_remoteMemberObj->getUri());
+        }
+
+        RCSRemoteResourceObject::Ptr SceneMemberResource::getRemoteResourceObject() const
+        {
+            return m_remoteMemberObj;
+        }
+
+        RCSResourceObject::Ptr SceneMemberResource::getRCSResourceObject() const
+        {
+            return m_sceneMemberResourceObj;
+        }
+
+        void SceneMemberResource::execute(std::string && sceneName)
+        {
+            execute(std::move(sceneName), nullptr);
+        }
+
+        void SceneMemberResource::execute(const std::string & sceneName)
+        {
+            execute(std::string(sceneName));
+        }
+
+        void SceneMemberResource::execute(std::string && sceneName, MemberexecuteCallback executeCB)
+        {
+            RCSResourceAttributes setAtt;
+
+            auto mInfo = getMappingInfos();
+            std::for_each(mInfo.begin(), mInfo.end(),
+                    [& setAtt, & sceneName](const MappingInfo & info)
+                    {
+                        if(info.sceneName == sceneName)
+                        {
+                            setAtt[info.key] = info.value;
+                        }
+                    });
+
+            if (setAtt.empty() && executeCB != nullptr)
+            {
+                executeCB(RCSResourceAttributes(), SCENE_RESPONSE_SUCCESS);
+            }
+
+            m_remoteMemberObj->setRemoteAttributes(setAtt, executeCB);
+        }
+
+        void SceneMemberResource::execute(
+                const std::string & sceneName, MemberexecuteCallback executeCB)
+        {
+            execute(std::string(sceneName), std::move(executeCB));
+        }
+
+        void SceneMemberResource::setName(const std::string & name)
+        {
+            setName(std::string(name));
+        }
+
+        void SceneMemberResource::setName(std::string && name)
+        {
+            m_sceneMemberResourceObj->setAttribute(SCENE_KEY_NAME, std::move(name));
+        }
+
+        std::string SceneMemberResource::getName() const
+        {
+            return m_sceneMemberResourceObj->getAttributeValue(SCENE_KEY_NAME).toString();
+        }
+
+        std::vector<SceneMemberResource::MappingInfo> SceneMemberResource::findMappingInfos(
+                const std::string & sceneValue) const
+        {
+            auto mInfo = getMappingInfos();
+            std::vector<MappingInfo> retMInfo;
+
+            std::for_each(mInfo.begin(), mInfo.end(),
+                    [& retMInfo, & sceneValue](const MappingInfo & info)
+                    {
+                        if(info.sceneName == sceneValue)
+                        {
+                            retMInfo.push_back(MappingInfo(info));
+                        }
+                    });
+            return retMInfo;
+        }
+
+        bool SceneMemberResource::hasSceneValue(const std::string & sceneValue) const
+        {
+            auto mInfo = getMappingInfos();
+            if (std::find_if(mInfo.begin(), mInfo.end(),
+                    [& sceneValue](const MappingInfo & info) -> bool
+                    {
+                        return info.sceneName == sceneValue;
+                    }) != mInfo.end())
+            {
+                return true;
+            }
+            return false;
+        }
+
+        SceneMemberResource::MappingInfo
+        SceneMemberResource::MappingInfo::create(const RCSResourceAttributes & att)
+        {
+            return MappingInfo(att.at(SCENE_KEY_SCENE).get<std::string>(),
+                    att.at(SCENE_KEY_MEMBERPROPERTY).get<std::string>(),
+                    att.at(SCENE_KEY_MEMBERVALUE));
+        }
+
+        RCSSetResponse SceneMemberResource::SceneMemberRequestHandler::
+        onSetRequest(const RCSRequest & request, RCSResourceAttributes & attributes)
+        {
+            if (attributes.contains(SCENE_KEY_SCENEMAPPINGS))
+            {
+                addMappingInfos(request, attributes);
+            }
+
+            if (attributes.contains(SCENE_KEY_NAME))
+            {
+                setSceneMemberName(request, attributes);
+            }
+
+            return RCSSetResponse::create(attributes, SCENE_CLIENT_BADREQUEST).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse
+        SceneMemberResource::SceneMemberRequestHandler::addMappingInfos(
+                const RCSRequest & /*request*/, RCSResourceAttributes & attributes)
+        {
+            int eCode = SCENE_RESPONSE_SUCCESS;
+            auto ptr = m_owner.lock();
+            if (!ptr)
+            {
+                eCode = SCENE_CLIENT_BADREQUEST;
+            }
+            else
+            {
+                auto mInfo = attributes.at(SCENE_KEY_SCENEMAPPINGS).
+                        get<std::vector<RCSResourceAttributes>>();
+                std::for_each(mInfo.begin(), mInfo.end(),
+                        [& ptr](const RCSResourceAttributes & att)
+                        {
+                            ptr->addMappingInfo(SceneMemberResource::MappingInfo::create(att));
+                        });
+            }
+
+            return RCSSetResponse::create(attributes, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+
+        RCSSetResponse
+        SceneMemberResource::SceneMemberRequestHandler::setSceneMemberName(
+                const RCSRequest & /*request*/, RCSResourceAttributes & attributes)
+        {
+            int eCode = SCENE_RESPONSE_SUCCESS;
+            auto ptr = m_owner.lock();
+            if (!ptr)
+            {
+                eCode = SCENE_CLIENT_BADREQUEST;
+            }
+            else
+            {
+                ptr->setName(attributes.at(SCENE_KEY_NAME).get<std::string>());
+            }
+
+            return RCSSetResponse::create(attributes, eCode).
+                    setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
+        }
+    }
+}
diff --git a/service/scene-manager/src/SceneMemberResource.h b/service/scene-manager/src/SceneMemberResource.h
new file mode 100644 (file)
index 0000000..cac6ebf
--- /dev/null
@@ -0,0 +1,213 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the declaration of classes and its members related to SceneMemberResrouceObject
+ */
+
+#ifndef SCENE_MEMBER_RESOURCE_OBJECT_H
+#define SCENE_MEMBER_RESOURCE_OBJECT_H
+
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "SceneCommons.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SceneMemberResource
+                : public std::enable_shared_from_this<SceneMemberResource>
+        {
+        public:
+            typedef std::shared_ptr< SceneMemberResource > Ptr;
+
+            /**
+             * Callback definition to be invoked when the response of setRemoteAttribitues is received.
+             *
+             * @param attrs the result attributes
+             * @param eCode the error code received from the resource
+             *
+             * @see RCSRemoteResourceObject::setRemoteAttributes
+             */
+            typedef std::function< void(const RCSResourceAttributes & attrs, int eCode) >
+                MemberexecuteCallback;
+
+            /**
+             * A Mapping information about each scene values.
+             */
+            struct MappingInfo
+            {
+                MappingInfo(
+                        const std::string & scene,
+                        const std::string & keyName,
+                        const RCSResourceAttributes::Value & val)
+                :sceneName(scene), key(keyName), value(val) { }
+
+                MappingInfo(MappingInfo &&) = default;
+                MappingInfo(const MappingInfo &) = default;
+
+                static MappingInfo create(const RCSResourceAttributes &);
+
+                std::string sceneName;              ///< name of scene value
+                std::string key;                    ///< key to set at attributes of remote resource
+                RCSResourceAttributes::Value value; ///< val to set at attributes of remote resource
+            };
+
+            ~SceneMemberResource() = default;
+
+            /**
+             * Register a Scene member resource and return a SceneMemberResourceObject
+             * using link information of remote resource.
+             *
+             * @param attrs information to make scene member resource
+             */
+            static SceneMemberResource::Ptr
+            createSceneMemberResource(RCSResourceAttributes && attrs);
+
+            /**
+             * @overload
+             */
+            static SceneMemberResource::Ptr
+            createSceneMemberResource(const RCSResourceAttributes &);
+
+            /**
+             * Register a Scene member resource and returns a SceneMemberResourceObject
+             * using information of RCSRemoteResourceObject.
+             *
+             * @param remoteObj information to make scene member resource
+             */
+            static SceneMemberResource::Ptr
+            createSceneMemberResource(RCSRemoteResourceObject::Ptr remoteObj);
+
+            /**
+             * Add Scene mapping information at scene member resource.
+             *
+             * @param mappingInfo
+             */
+            void addMappingInfo(MappingInfo && mappingInfo);
+
+            /**
+             * @overload
+             */
+            void addMappingInfo(const MappingInfo &);
+
+            /**
+             * Returns all Mapping information of a scene member resource.
+             */
+            std::vector<MappingInfo> getMappingInfos() const;
+
+            std::vector<MappingInfo> findMappingInfos(const std::string & sceneValue) const;
+
+            bool hasSceneValue(const std::string &) const;
+
+            /**
+             * Returns ID of a Scene member resource.
+             */
+            std::string getId() const;
+
+            /**
+             * Returns Uri of a Scene member resource. (e.g. coap://192.168.0.2.1:12345/SceneMember)
+             */
+            std::string getFullUri() const;
+
+            /**
+             * Returns Uri of a Target resource of scene member. (e.g. coap://192.168.0.2.1:12345/light)
+             */
+            std::string getTargetUri() const;
+
+            /**
+             * Returns RCSRemoteResourceObject about Scene member resource
+             */
+            RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+            /**
+             * Returns RCSResourceObject of Scene member resource
+             */
+            RCSResourceObject::Ptr getRCSResourceObject() const;
+
+            /**
+             * Execute of Scene Action (with callback for response).
+             *
+             * @param sceneValue scene value to execute
+             * @param cb callback to response
+             */
+            void execute(std::string && sceneValue, MemberexecuteCallback cb);
+
+            /**
+             * @overload
+             */
+            void execute(const std::string &, MemberexecuteCallback);
+
+            /**
+             * Execute of Scene Action (without callback for response).
+             *
+             * @param sceneValue scene value to execute
+             */
+            void execute(std::string && sceneValue);
+
+            /**
+             * @overload
+             */
+            void execute(const std::string &);
+
+            void setName(const std::string &);
+            void setName(std::string &&);
+
+            std::string getName() const;
+
+        private:
+            class SceneMemberRequestHandler
+            {
+            public:
+                SceneMemberRequestHandler() = default;
+                ~SceneMemberRequestHandler() = default;
+
+                std::weak_ptr<SceneMemberResource> m_owner;
+
+                RCSSetResponse onSetRequest(const RCSRequest & , RCSResourceAttributes &);
+
+                RCSSetResponse addMappingInfos(const RCSRequest & , RCSResourceAttributes &);
+                RCSSetResponse setSceneMemberName(const RCSRequest & , RCSResourceAttributes &);
+            };
+
+            std::string m_uri;
+            RCSResourceObject::Ptr m_sceneMemberResourceObj;
+            RCSRemoteResourceObject::Ptr m_remoteMemberObj;
+            SceneMemberRequestHandler m_requestHandler;
+
+            SceneMemberResource() = default;
+
+            SceneMemberResource(const SceneMemberResource &) = delete;
+            SceneMemberResource & operator = (const SceneMemberResource &) = delete;
+
+            SceneMemberResource(SceneMemberResource &&) = delete;
+            SceneMemberResource & operator = (SceneMemberResource &&) = delete;
+
+            void createResourceObject();
+            void setDefaultAttributes();
+            void initSetRequestHandler();
+        };
+    }
+}
+
+#endif // SCENE_MEMBER_RESOURCE_OBJECT_H
diff --git a/service/scene-manager/src/SceneMemberResourceRequestor.cpp b/service/scene-manager/src/SceneMemberResourceRequestor.cpp
new file mode 100644 (file)
index 0000000..eaad4b5
--- /dev/null
@@ -0,0 +1,149 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneMemberResourceRequestor.h"
+#include "RemoteSceneUtils.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        SceneMemberResourceRequestor::SceneMemberResourceRequestor(
+            RCSRemoteResourceObject::Ptr memberResource, const std::string &id)
+                : m_id{ id }, m_sceneMemberResource{ memberResource }
+        {
+            SCENE_CLIENT_ASSERT_NOT_NULL(memberResource);
+        }
+
+        void SceneMemberResourceRequestor::requestSceneActionCreation(
+            const std::string &sceneName, const RCSResourceAttributes &attr,
+            InternalAddSceneActionCallback internalCB)
+        {
+            RCSResourceAttributes attributesToSet;
+            std::vector< RCSResourceAttributes > vecSceneMappings;
+
+            for (const auto &itr : attr)
+            {
+                RCSResourceAttributes sceneMappingAttrs;
+                sceneMappingAttrs[SCENE_KEY_SCENE] = sceneName;
+                sceneMappingAttrs[SCENE_KEY_MEMBERPROPERTY] = itr.key();
+                sceneMappingAttrs[SCENE_KEY_MEMBERVALUE] = itr.value();
+
+                vecSceneMappings.push_back(sceneMappingAttrs);
+            }
+
+            attributesToSet[SCENE_KEY_SCENEMAPPINGS] = vecSceneMappings;
+
+            RCSRemoteResourceObject::RemoteAttributesSetCallback setRequestCB
+                = std::bind(&SceneMemberResourceRequestor::onSceneActionCreated,
+                            std::placeholders::_1, std::placeholders::_2,
+                            sceneName, attr, std::move(internalCB),
+                            SceneMemberResourceRequestor::wPtr(shared_from_this()));
+
+            m_sceneMemberResource->setRemoteAttributes(
+                std::move(attributesToSet), std::move(setRequestCB));
+        }
+
+        void SceneMemberResourceRequestor::requestGet(
+            const std::string &ifType, RCSRemoteResourceObject::GetCallback cb)
+        {
+            RCSQueryParams params;
+            params.setResourceInterface(ifType);
+
+            m_sceneMemberResource->get(params, cb);
+        }
+
+        void SceneMemberResourceRequestor::setRemoteResourceObject(
+            RCSRemoteResourceObject::Ptr target)
+        {
+            m_remoteResource = target;
+        }
+
+        RCSRemoteResourceObject::Ptr SceneMemberResourceRequestor::getRemoteResourceObject() const
+        {
+            return m_remoteResource;
+        }
+
+        void SceneMemberResourceRequestor::onSceneActionCreated(
+            const RCSResourceAttributes &attrs, int eCode, const std::string &sceneName,
+            const RCSResourceAttributes &requestedAttrs, const InternalAddSceneActionCallback &cb,
+            SceneMemberResourceRequestor::wPtr ptr)
+        {
+            SceneMemberResourceRequestor::Ptr member = ptr.lock();
+
+            if (member)
+            {
+                member->onSceneActionCreated_impl(
+                    std::move(attrs), eCode, sceneName, std::move(requestedAttrs), std::move(cb));
+            }
+        }
+
+        void SceneMemberResourceRequestor::onSceneActionCreated_impl(
+            const RCSResourceAttributes &attrs, int eCode, const std::string &sceneName,
+            const RCSResourceAttributes &requestedAttrs,
+            const InternalAddSceneActionCallback &internalCB)
+        {
+            // TODO error code
+            int result = SCENE_CLIENT_BADREQUEST;
+
+            if (eCode == OC_STACK_OK)
+            {
+                try
+                {
+                    auto mappings
+                        = attrs.at(SCENE_KEY_SCENEMAPPINGS).get
+                          < std::vector< RCSResourceAttributes > >();
+
+                    // check if the SCENE_MAPPINGS contains requested scene action
+                    int uncreatedActionNum = requestedAttrs.size();
+                    for (const auto &itr : mappings)
+                    {
+                        if (itr.at(SCENE_KEY_SCENE).get< std::string >().compare(sceneName) == 0)
+                        {
+                            std::string key
+                                = itr.at(SCENE_KEY_MEMBERPROPERTY).get< std::string >();
+
+                            if (requestedAttrs.contains(key)
+                                && requestedAttrs.at(key) == itr.at(SCENE_KEY_MEMBERVALUE))
+                            {
+                                uncreatedActionNum--;
+                            }
+                        }
+
+                        if (uncreatedActionNum == 0)
+                        {
+                            result = SCENE_RESPONSE_SUCCESS;
+                            break;
+                        }
+                    }
+                }
+                catch (const std::exception &e)
+                {
+                    SCENE_CLIENT_ASSERT_NOT_NULL(e.what());
+                    result = SCENE_SERVER_INTERNALSERVERERROR;
+                }
+            }
+
+            internalCB(result);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/service/scene-manager/src/SceneMemberResourceRequestor.h b/service/scene-manager/src/SceneMemberResourceRequestor.h
new file mode 100644 (file)
index 0000000..76c1b5e
--- /dev/null
@@ -0,0 +1,77 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SM_SCENEMEMBER_RESOURCE_REQUESTOR_H_
+#define SM_SCENEMEMBER_RESOURCE_REQUESTOR_H_
+
+#include "SceneCommons.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class SceneMemberResourceRequestor
+            : public std::enable_shared_from_this< SceneMemberResourceRequestor >
+        {
+            public:
+                typedef std::shared_ptr< SceneMemberResourceRequestor > Ptr;
+                typedef std::weak_ptr< SceneMemberResourceRequestor > wPtr;
+
+                typedef std::function < void(int eCode) > InternalAddSceneActionCallback;
+
+            public:
+                SceneMemberResourceRequestor(RCSRemoteResourceObject::Ptr memberResource,
+                                             const std::string &id);
+                ~SceneMemberResourceRequestor() = default;
+
+                void requestSceneActionCreation(const std::string &sceneName,
+                                                const RCSResourceAttributes &attr,
+                                                InternalAddSceneActionCallback);
+
+                void requestGet(const std::string &, RCSRemoteResourceObject::GetCallback);
+
+                void setRemoteResourceObject(RCSRemoteResourceObject::Ptr);
+
+                RCSRemoteResourceObject::Ptr getRemoteResourceObject() const;
+
+            private:
+                static void onSceneActionCreated(
+                    const RCSResourceAttributes &, int eCode,
+                    const std::string &sceneName, const RCSResourceAttributes &requestedAttrs,
+                    const InternalAddSceneActionCallback &, SceneMemberResourceRequestor::wPtr);
+
+                void onSceneActionCreated_impl(
+                    const RCSResourceAttributes &, int eCode,
+                    const std::string &sceneName, const RCSResourceAttributes &requestedAttrs,
+                    const InternalAddSceneActionCallback &);
+
+            private:
+                std::string m_id;
+                RCSRemoteResourceObject::Ptr m_remoteResource;
+                RCSRemoteResourceObject::Ptr m_sceneMemberResource;
+        };
+
+    }
+}
+
+#endif /* SM_SCENEMEMBER_RESOURCE_REQUESTOR_H_ */
+
diff --git a/service/scene-manager/src/SceneUtils.cpp b/service/scene-manager/src/SceneUtils.cpp
new file mode 100644 (file)
index 0000000..27eff03
--- /dev/null
@@ -0,0 +1,131 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SceneCommons.h"
+
+#include <string>
+#include "ocrandom.h"
+#include "oic_malloc.h"
+#include "RCSException.h"
+#include "cainterface.h"
+#include "OCPlatform.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        std::string SceneUtils::OICGenerateUUIDStr()
+        {
+            uint8_t uuid[UUID_SIZE] = { 0, };
+            char uuidStr[UUID_STRING_SIZE] = { 0, };
+            if (RAND_UUID_OK == OCGenerateUuid(uuid))
+            {
+                if (RAND_UUID_OK == OCConvertUuidToString(uuid, uuidStr))
+                {
+                    return std::string(uuidStr);
+                }
+            }
+
+            throw RCSException("Failed to generate UUID");
+        }
+
+        void SceneUtils::getHostUriString(
+                const std::string address, std::string *host, std::string *uri)
+        {
+            unsigned int nextStartIndex = 0;
+            int indexOfStr = 3;
+
+            if (address.find(COAP_TAG) == std::string::npos)
+            {
+                indexOfStr = 1;
+            }
+
+            for (int i = 0; i < indexOfStr; i++)
+            {
+                nextStartIndex
+                    = address.find_first_of("/", nextStartIndex);
+                if (nextStartIndex == std::string::npos)
+                {
+                    throw RCSInvalidParameterException("address is invalid");
+                }
+                nextStartIndex += 1;
+            }
+
+            *host = address.substr(0, nextStartIndex - 1);
+            *uri = address.substr(nextStartIndex - 1, std::string::npos);
+        }
+
+        std::string SceneUtils::getNetAddress()
+        {
+            CAEndpoint_t ** netInfo = (CAEndpoint_t **)OICMalloc(sizeof(CAEndpoint_t*)*5);
+
+            if(netInfo == nullptr)
+            {
+                throw RCSException("memory allocation fail");
+            }
+
+            uint32_t size = 0;
+            CAGetNetworkInformation(netInfo, &size);
+
+            if (size == 0)
+            {
+                OICFree(netInfo);
+                throw RCSException("Disabled Network");
+            }
+
+            for (uint32_t i = 0; i < size; ++i)
+            {
+                if (netInfo[i]->adapter == CATransportAdapter_t::CA_ADAPTER_IP)
+                {
+                    std::string retAddress
+                        = std::string(netInfo[i]->addr) + ":" + std::to_string(netInfo[i]->port);
+
+                    OICFree(netInfo);
+                    return retAddress;
+                }
+            }
+
+            OICFree(netInfo);
+            throw RCSException("Not supported Network");
+        }
+
+        RCSRemoteResourceObject::Ptr SceneUtils::createRCSResourceObject(
+            const std::string &address, const OCConnectivityType ct,
+            const std::vector< std::string > &vecRT, const std::vector< std::string > &vecIF)
+        {
+            try
+            {
+                std::string hostaddress, uri;
+                SceneUtils::getHostUriString(address, &hostaddress, &uri);
+
+                OC::OCResource::Ptr pOCResource =
+                    OC::OCPlatform::constructResourceObject(
+                        hostaddress, uri, ct, false, vecRT, vecIF);
+
+                return RCSRemoteResourceObject::fromOCResource(pOCResource);
+            }
+            catch (const std::exception &e)
+            {
+                throw RCSException("Fail to create RCSResourceObject");
+            }
+        }
+
+    }
+}
diff --git a/service/scene-manager/unittests/RemoteSceneActionTest.cpp b/service/scene-manager/unittests/RemoteSceneActionTest.cpp
new file mode 100644 (file)
index 0000000..ac86fa9
--- /dev/null
@@ -0,0 +1,215 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <mutex>
+#include <condition_variable>
+
+#include "RemoteSceneList.h"
+
+#include "UnitTestHelper.h"
+#include "SceneCommons.h"
+#include "SceneList.h"
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+constexpr int DEFAULT_WAITTIME = 2000;
+
+constexpr char RESOURCE_URI[]{ "/a/light" };
+constexpr char RESOURCE_TYPE[]{ "core.light" };
+constexpr char KEY[]{ "power" };
+constexpr char VALUE[]{ "off" };
+
+static int lightNum = 0;
+
+class RemoteSceneActionTest : public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        SceneList::getInstance()->getName();
+        createListServer();
+
+        RemoteSceneList::createInstance(pListResource, std::bind(
+            &RemoteSceneActionTest::onRemoteSceneListCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+
+        pSceneList->addNewSceneCollection(std::bind(
+            &RemoteSceneActionTest::onRemoteSceneCollectionCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+
+        pSceneCollection->addNewScene("Test Scene", std::bind(
+            &RemoteSceneActionTest::onRemoteSceneCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+    }
+
+    void createListServer()
+    {
+        std::vector< std::string > vecRT{ SCENE_LIST_RT };
+        std::vector< std::string > vecIF{ OC_RSRVD_INTERFACE_DEFAULT, OC::BATCH_INTERFACE };
+
+        pListResource = SceneUtils::createRCSResourceObject(
+            "coap://" + SceneUtils::getNetAddress() + SCENE_LIST_URI,
+            SCENE_CONNECTIVITY, vecRT, vecIF);
+    }
+
+    void createLightServer()
+    {
+        RCSResourceObject::Ptr pResource = RCSResourceObject::Builder(
+            RESOURCE_URI, RESOURCE_TYPE, DEFAULT_INTERFACE).build();
+        pResource->setAttribute(KEY, RCSResourceAttributes::Value(VALUE));
+
+        pLightResource
+            = SceneUtils::createRCSResourceObject(
+            "coap://" + SceneUtils::getNetAddress() + RESOURCE_URI
+            + "/" + std::to_string(lightNum++),
+            SCENE_CONNECTIVITY, pResource->getTypes(), pResource->getInterfaces());
+    }
+
+    void waitForCallback(int waitingTime = DEFAULT_WAITTIME)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+public:
+    RCSRemoteResourceObject::Ptr pListResource;
+    RemoteSceneList::Ptr pSceneList;
+    RemoteSceneCollection::Ptr pSceneCollection;
+    RemoteScene::Ptr pScene;
+    RemoteSceneAction::Ptr pSceneAction;
+    RCSRemoteResourceObject::Ptr pLightResource;
+    std::condition_variable cond;
+    std::mutex mutex;
+
+    void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int)
+    {
+        pSceneList = std::move(remoteSceneList);
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCollectionCreated(RemoteSceneCollection::Ptr remoteSceneCol, int)
+    {
+        pSceneCollection = remoteSceneCol;
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCreated(RemoteScene::Ptr remoteScene, int)
+    {
+        pScene = remoteScene;
+        cond.notify_all();
+    }
+
+    void onRemoteSceneActionCreated(RemoteSceneAction::Ptr remoteSceneAction, int)
+    {
+        pSceneAction = remoteSceneAction;
+        cond.notify_all();
+    }
+
+    void onActionUpdated(int)
+    {
+        cond.notify_all();
+    }
+};
+
+TEST_F(RemoteSceneActionTest, createSceneAction)
+{
+    createLightServer();
+
+    pScene->addNewSceneAction(pLightResource, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneActionTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    ASSERT_NE(nullptr, pSceneAction);
+}
+
+TEST_F(RemoteSceneActionTest, createSceneActionWithEmptyRCSRemoteResourceObjectPtr)
+{
+    ASSERT_THROW(pScene->addNewSceneAction(nullptr, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneActionTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2)), RCSInvalidParameterException);
+}
+
+TEST_F(RemoteSceneActionTest, getAllRemoteSceneActions)
+{
+    createLightServer();
+
+    pScene->addNewSceneAction(pLightResource, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneActionTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    vector< RemoteSceneAction::Ptr > actions
+        = pScene->getRemoteSceneActions();
+
+    ASSERT_EQ((unsigned int)1, actions.size());
+    ASSERT_TRUE(actions.at(0)->getExecutionParameter().contains(KEY));
+    ASSERT_EQ(VALUE, actions.at(0)->getExecutionParameter().at(KEY).get< string >());
+}
+
+TEST_F(RemoteSceneActionTest, getRemoteSceneAction)
+{
+    createLightServer();
+
+    pScene->addNewSceneAction(pLightResource, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneActionTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    RemoteSceneAction::Ptr action = pScene->getRemoteSceneAction(pLightResource);
+
+    ASSERT_TRUE(action->getExecutionParameter().contains(KEY));
+    ASSERT_EQ(VALUE, action->getExecutionParameter().at(KEY).get< string >());
+}
+
+TEST_F(RemoteSceneActionTest, updateSceneAction)
+{
+    createLightServer();
+
+    pScene->addNewSceneAction(pLightResource, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneActionTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pSceneAction->resetExecutionParameter(
+        KEY, RCSResourceAttributes::Value("on"), std::bind(
+        &RemoteSceneActionTest::onActionUpdated, this, placeholders::_1));
+
+    waitForCallback();
+
+    ASSERT_EQ("on", pSceneAction->getExecutionParameter().at(KEY).get< string >());
+}
\ No newline at end of file
diff --git a/service/scene-manager/unittests/RemoteSceneCollectionTest.cpp b/service/scene-manager/unittests/RemoteSceneCollectionTest.cpp
new file mode 100644 (file)
index 0000000..bcc0888
--- /dev/null
@@ -0,0 +1,165 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <mutex>
+#include <condition_variable>
+
+#include "RemoteSceneList.h"
+
+#include "UnitTestHelper.h"
+#include "SceneCommons.h"
+#include "SceneList.h"
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+constexpr int DEFAULT_WAITTIME = 2000;
+
+class RemoteSceneCollectionTest : public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        SceneList::getInstance()->getName();
+        createListServer();
+
+        RemoteSceneList::createInstance(pListResource, std::bind(
+            &RemoteSceneCollectionTest::onRemoteSceneListCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+    }
+
+    void createListServer()
+    {
+        std::vector< std::string > vecRT{ SCENE_LIST_RT };
+        std::vector< std::string > vecIF{ OC_RSRVD_INTERFACE_DEFAULT, OC::BATCH_INTERFACE };
+
+        pListResource = SceneUtils::createRCSResourceObject(
+            "coap://" + SceneUtils::getNetAddress() + SCENE_LIST_URI,
+            SCENE_CONNECTIVITY, vecRT, vecIF);
+    }
+
+    void waitForCallback(int waitingTime = DEFAULT_WAITTIME)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+public:
+    RCSRemoteResourceObject::Ptr pListResource;
+    RemoteSceneList::Ptr pSceneList;
+    RemoteSceneCollection::Ptr pSceneCollection;
+    std::condition_variable cond;
+    std::mutex mutex;
+
+    void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int)
+    {
+        pSceneList = std::move(remoteSceneList);
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCollectionCreated(RemoteSceneCollection::Ptr remoteSceneCol, int)
+    {
+        pSceneCollection = remoteSceneCol;
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCreated(RemoteScene::Ptr, int)
+    {
+        cond.notify_all();
+    }
+
+    void onSetName(int)
+    {
+        cond.notify_all();
+    }
+};
+
+TEST_F(RemoteSceneCollectionTest, addNewRemoteSceneCollection)
+{
+    pSceneList->addNewSceneCollection(std::bind(
+        &RemoteSceneCollectionTest::onRemoteSceneCollectionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pSceneCollection->addNewScene("Default", std::bind(
+        &RemoteSceneCollectionTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    EXPECT_NE(nullptr, pSceneCollection);
+}
+
+TEST_F(RemoteSceneCollectionTest, getRemoteSceneCollectionList)
+{
+    std::vector< RemoteSceneCollection::Ptr > sceneCollections
+        = pSceneList->getRemoteSceneCollections();
+
+    bool getCollectionsOK = true;
+
+    if (!sceneCollections.empty())
+    {
+        for (const auto &it : sceneCollections)
+        {
+            if (it->getId() == "")
+            {
+                getCollectionsOK = false;
+                break;
+            }
+        }
+    }
+    else
+    {
+        getCollectionsOK = false;
+    }
+
+    ASSERT_TRUE(getCollectionsOK);
+}
+
+TEST_F(RemoteSceneCollectionTest, setAndGetSceneCollectionName)
+{
+    pSceneList->addNewSceneCollection(std::bind(
+        &RemoteSceneCollectionTest::onRemoteSceneCollectionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pSceneCollection->addNewScene("Default", std::bind(
+        &RemoteSceneCollectionTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pSceneCollection->setName("Kitchen", std::bind(
+        &RemoteSceneCollectionTest::onSetName, this, placeholders::_1));
+
+    waitForCallback();
+
+    EXPECT_EQ("Kitchen", pSceneCollection->getName());
+}
\ No newline at end of file
diff --git a/service/scene-manager/unittests/RemoteSceneListTest.cpp b/service/scene-manager/unittests/RemoteSceneListTest.cpp
new file mode 100644 (file)
index 0000000..b2575b7
--- /dev/null
@@ -0,0 +1,106 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <mutex>
+#include <condition_variable>
+
+#include "RemoteSceneList.h"
+
+#include "UnitTestHelper.h"
+#include "SceneCommons.h"
+#include "SceneList.h"
+#include "RCSRemoteResourceObject.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+constexpr int DEFAULT_WAITTIME = 2000;
+
+class RemoteSceneListTest : public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        SceneList::getInstance()->getName();
+    }
+
+    void createListServer()
+    {
+        std::vector< std::string > vecRT{ SCENE_LIST_RT };
+        std::vector< std::string > vecIF{ OC_RSRVD_INTERFACE_DEFAULT, OC::BATCH_INTERFACE };
+
+        pListResource = SceneUtils::createRCSResourceObject(
+                            "coap://" + SceneUtils::getNetAddress() + SCENE_LIST_URI,
+                            SCENE_CONNECTIVITY, vecRT, vecIF);
+    }
+
+    void waitForCallback(int waitingTime = DEFAULT_WAITTIME)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+public:
+    RCSRemoteResourceObject::Ptr pListResource;
+    RemoteSceneList::Ptr pSceneList;
+    std::condition_variable cond;
+    std::mutex mutex;
+
+    void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int)
+    {
+        pSceneList = std::move(remoteSceneList);
+        cond.notify_all();
+    }
+
+    void onSetName(int)
+    {
+        cond.notify_all();
+    }
+};
+
+TEST_F(RemoteSceneListTest, createRemoteSceneListInstance)
+{
+    createListServer();
+    RemoteSceneList::createInstance(pListResource, std::bind(
+        &RemoteSceneListTest::onRemoteSceneListCreated, this, placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    EXPECT_NE(nullptr, pSceneList);
+}
+
+TEST_F(RemoteSceneListTest, setAndGetRemoteSceneListName)
+{
+    createListServer();
+    RemoteSceneList::createInstance(pListResource, std::bind(
+        &RemoteSceneListTest::onRemoteSceneListCreated, this, placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pSceneList->setName("Test Scene List", std::bind(
+        &RemoteSceneListTest::onSetName, this, placeholders::_1));
+
+    waitForCallback();
+
+    EXPECT_EQ("Test Scene List", pSceneList->getName());
+}
\ No newline at end of file
diff --git a/service/scene-manager/unittests/RemoteSceneTest.cpp b/service/scene-manager/unittests/RemoteSceneTest.cpp
new file mode 100644 (file)
index 0000000..c51ed61
--- /dev/null
@@ -0,0 +1,209 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <mutex>
+#include <condition_variable>
+
+#include "RemoteSceneList.h"
+
+#include "UnitTestHelper.h"
+#include "SceneCommons.h"
+#include "SceneList.h"
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+constexpr int DEFAULT_WAITTIME = 2000;
+
+constexpr char RESOURCE_URI[]{ "/a/light" };
+constexpr char RESOURCE_TYPE[]{ "core.light" };
+constexpr char KEY[]{ "power" };
+constexpr char VALUE[]{ "off" };
+
+static int lightNum = 0;
+
+class RemoteSceneTest : public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        executionSucceeded = false;
+
+        SceneList::getInstance()->getName();
+        createListServer();
+
+        RemoteSceneList::createInstance(pListResource, std::bind(
+            &RemoteSceneTest::onRemoteSceneListCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+
+        pSceneList->addNewSceneCollection(std::bind(
+            &RemoteSceneTest::onRemoteSceneCollectionCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+
+        pSceneCollection->addNewScene("Default", std::bind(
+            &RemoteSceneTest::onRemoteSceneCreated, this,
+            placeholders::_1, placeholders::_2));
+
+        waitForCallback();
+    }
+
+    void createListServer()
+    {
+        std::vector< std::string > vecRT{ SCENE_LIST_RT };
+        std::vector< std::string > vecIF{ OC_RSRVD_INTERFACE_DEFAULT, OC::BATCH_INTERFACE };
+
+        pListResource = SceneUtils::createRCSResourceObject(
+            "coap://" + SceneUtils::getNetAddress() + SCENE_LIST_URI,
+            SCENE_CONNECTIVITY, vecRT, vecIF);
+    }
+
+    void createLightServer()
+    {
+        RCSResourceObject::Ptr pResource = RCSResourceObject::Builder(
+            RESOURCE_URI, RESOURCE_TYPE, DEFAULT_INTERFACE).build();
+        pResource->setAttribute(KEY, RCSResourceAttributes::Value(VALUE));
+
+        pLightResource
+            = SceneUtils::createRCSResourceObject(
+            "coap://" + SceneUtils::getNetAddress() + RESOURCE_URI
+            + "/" + std::to_string(lightNum++),
+            SCENE_CONNECTIVITY, pResource->getTypes(), pResource->getInterfaces());
+    }
+
+    void waitForCallback(int waitingTime = DEFAULT_WAITTIME)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
+    }
+
+public:
+    RCSRemoteResourceObject::Ptr pListResource;
+    RemoteSceneList::Ptr pSceneList;
+    RemoteSceneCollection::Ptr pSceneCollection;
+    RemoteScene::Ptr pScene;
+    RCSRemoteResourceObject::Ptr pLightResource;
+    bool executionSucceeded;
+    std::condition_variable cond;
+    std::mutex mutex;
+
+    void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int)
+    {
+        pSceneList = std::move(remoteSceneList);
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCollectionCreated(RemoteSceneCollection::Ptr remoteSceneCol, int)
+    {
+        pSceneCollection = remoteSceneCol;
+        cond.notify_all();
+    }
+
+    void onRemoteSceneCreated(RemoteScene::Ptr remoteScene, int)
+    {
+        pScene = remoteScene;
+        cond.notify_all();
+    }
+
+    void onRemoteSceneActionCreated(RemoteSceneAction::Ptr, int)
+    {
+        cond.notify_all();
+    }
+
+    void onRemoteSceneExecuted(string, int)
+    {
+        executionSucceeded = true;
+        cond.notify_all();
+    }
+};
+
+TEST_F(RemoteSceneTest, addNewRemoteScene)
+{
+    pSceneCollection->addNewScene("Test Scene", std::bind(
+        &RemoteSceneTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    ASSERT_NE(nullptr, pScene);
+    ASSERT_EQ("Test Scene", pScene->getName());
+}
+
+TEST_F(RemoteSceneTest, createNewRemoteSceneWithEmptyName)
+{
+    ASSERT_THROW(
+        pSceneCollection->addNewScene("", std::bind(
+        &RemoteSceneTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));, RCSInvalidParameterException);
+}
+
+TEST_F(RemoteSceneTest, getRemoteSceneBySceneName)
+{
+    pSceneCollection->addNewScene("Test Scene", std::bind(
+        &RemoteSceneTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    auto scene = pSceneCollection->getRemoteScene("Test Scene");
+
+    EXPECT_NE(nullptr, scene);
+    EXPECT_EQ("Test Scene", scene->getName());
+}
+
+TEST_F(RemoteSceneTest, getAllRemoteScenes)
+{
+    pSceneCollection->addNewScene("Test Scene", std::bind(
+        &RemoteSceneTest::onRemoteSceneCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    auto scenes = pSceneCollection->getRemoteScenes();
+
+    ASSERT_EQ((unsigned int)2, scenes.size());
+    ASSERT_NE(scenes.end(), scenes.find("Test Scene"));
+}
+
+TEST_F(RemoteSceneTest, executeRemoteScene)
+{
+    createLightServer();
+
+    pScene->addNewSceneAction(pLightResource, KEY, RCSResourceAttributes::Value(VALUE),
+        std::bind(&RemoteSceneTest::onRemoteSceneActionCreated, this,
+        placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    pScene->execute(std::bind(
+        &RemoteSceneTest::onRemoteSceneExecuted, this, placeholders::_1, placeholders::_2));
+
+    waitForCallback();
+
+    ASSERT_TRUE(executionSucceeded);
+}
\ No newline at end of file
diff --git a/service/scene-manager/unittests/SConscript b/service/scene-manager/unittests/SConscript
new file mode 100755 (executable)
index 0000000..25d65d8
--- /dev/null
@@ -0,0 +1,132 @@
+#******************************************************************
+#
+# Copyright 2016 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# SceneManager Unit Test build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+    env.AppendUnique(CCFLAGS = ['-Os'])
+    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+######################################################################
+#unit test setting
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+scene_test_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+GTest = File(gtest_dir + '/lib/.libs/libgtest.a')
+GTest_Main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+#scene_test_env.AppendUnique(LIBPATH = [gtest_dir + '/lib/.libs'])
+scene_test_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
+scene_test_env.AppendUnique(LIBS = [
+    'scene_manager', 'rcs_server', 'rcs_client','rcs_common',
+    'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap',
+    GTest_Main, GTest])
+
+if target_os not in ['windows', 'winrt']:
+    scene_test_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os == 'linux':
+    scene_test_env.AppendUnique(CXXFLAGS = ['-pthread'])
+    scene_test_env.AppendUnique(LIBS = ['pthread'])
+
+if not env.get('RELEASE'):
+    scene_test_env.PrependUnique(LIBS = ['gcov'])
+    scene_test_env.AppendUnique(CXXFLAGS = ['--coverage'])
+
+scene_test_env.PrependUnique(CPPPATH = [ src_dir + '/extlibs/hippomocks-master',
+                             gtest_dir + '/include'])
+scene_test_env.AppendUnique(CPPPATH = ['../include'])
+scene_test_env.AppendUnique(CPPPATH = ['../src'])
+scene_test_env.AppendUnique(CPPPATH = ['../../resource-encapsulation/include'])
+scene_test_env.AppendUnique(CPPPATH = ['../../resource-encapsulation/src/common/primitiveResource/include'])
+scene_test_env.AppendUnique(CPPPATH = ['../../resource-encapsulation/src/common/utils/include'])
+######################################################################
+# Build Test
+######################################################################
+
+scene_list_test_src = env.Glob('./SceneListTest.cpp')
+scene_list_test = scene_test_env.Program('scene_list_test', scene_list_test_src)
+Alias("scene_list_test", scene_list_test)
+env.AppendTarget('scene_list_test')
+scene_test_env.InstallTarget(scene_list_test, 'scene_list_test')
+
+scene_collection_test_src = env.Glob('./SceneCollectionTest.cpp')
+scene_collection_test = scene_test_env.Program('scene_collection_test', scene_collection_test_src)
+Alias("scene_collection_test", scene_collection_test)
+env.AppendTarget('scene_collection_test')
+scene_test_env.InstallTarget(scene_collection_test, 'scene_collection_test')
+
+scene_test_src = env.Glob('./SceneTest.cpp')
+scene_test = scene_test_env.Program('scene_test', scene_test_src)
+Alias("scene_test", scene_test)
+env.AppendTarget('scene_test')
+scene_test_env.InstallTarget(scene_test, 'scene_test')
+
+scene_action_test_src = env.Glob('./SceneActionTest.cpp')
+scene_action_test = scene_test_env.Program('scene_action_test', scene_action_test_src)
+Alias("scene_action_test", scene_action_test)
+env.AppendTarget('scene_action_test')
+scene_test_env.InstallTarget(scene_action_test, 'scene_action_test')
+
+remote_scene_list_test_src = env.Glob('./RemoteSceneListTest.cpp')
+remote_scene_list_test = scene_test_env.Program('remote_scene_list_test', remote_scene_list_test_src)
+Alias("remote_scene_list_test", remote_scene_list_test)
+env.AppendTarget('remote_scene_list_test')
+
+remote_scene_col_test_src = env.Glob('./RemoteSceneCollectionTest.cpp')
+remote_scene_col_test = scene_test_env.Program('remote_scene_col_test', remote_scene_col_test_src)
+Alias("remote_scene_col_test", remote_scene_col_test)
+env.AppendTarget('remote_scene_col_test')
+
+remote_scene_test_src = env.Glob('./RemoteSceneTest.cpp')
+remote_scene_test = scene_test_env.Program('remote_scene_test', remote_scene_test_src)
+Alias("remote_scene_test", remote_scene_test)
+env.AppendTarget('remote_scene_test')
+
+remote_scene_action_test_src = env.Glob('./RemoteSceneActionTest.cpp')
+remote_scene_action_test = scene_test_env.Program('remote_scene_action_test', remote_scene_action_test_src)
+Alias("remote_scene_action_test", remote_scene_action_test)
+env.AppendTarget('remote_scene_action_test')
+
+#target_os = env.get('TARGET_OS')
+#if target_os == 'linux':
+#        from tools.scons.RunTest import *
+#        run_test(scene_test_env,
+#                 '',
+#                 'service/scene-manager/unittest/scene_test')
\ No newline at end of file
diff --git a/service/scene-manager/unittests/SceneActionTest.cpp b/service/scene-manager/unittests/SceneActionTest.cpp
new file mode 100755 (executable)
index 0000000..11203f4
--- /dev/null
@@ -0,0 +1,159 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "UnitTestHelper.h"
+
+#include "SceneList.h"
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "SceneCommons.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+typedef std::function<void (int)> ExecuteCallback;
+
+constexpr char RESOURCE_URI[]{ "/a/light" };
+constexpr char RESOURCE_TYPE[]{ "core.light" };
+constexpr char RESOURCE_URI2[]{ "/a/fan" };
+constexpr char RESOURCE_TYPE2[]{ "core.fan" };
+constexpr char KEY[]{ "power" };
+constexpr char VALUE[]{ "on" };
+constexpr char KEY_2[]{ "state" };
+constexpr char VALUE_2[]{ "100" };
+
+class SceneActionTest: public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        pSceneList = SceneList::getInstance();
+    }
+
+    void createServer(const std::string& resourceUri1, const std::string& resourceUri2)
+    {
+        auto pResource1 = RCSResourceObject::Builder(
+                resourceUri1, RESOURCE_TYPE, DEFAULT_INTERFACE).build();
+        pResource1->setAttribute(KEY, VALUE);
+
+        auto ocResourcePtr = OC::OCPlatform::constructResourceObject(
+                "coap://" + SceneUtils::getNetAddress(), resourceUri1,
+                OCConnectivityType::CT_ADAPTER_IP, false,
+                pResource1->getTypes(), pResource1->getInterfaces());
+        pRemoteResource1 = RCSRemoteResourceObject::fromOCResource(ocResourcePtr);
+
+        auto pResource2 = RCSResourceObject::Builder(
+                resourceUri2, RESOURCE_TYPE2, DEFAULT_INTERFACE).build();
+        pResource2->setAttribute(KEY_2, VALUE_2);
+
+        ocResourcePtr = OC::OCPlatform::constructResourceObject(
+                        "coap://" + SceneUtils::getNetAddress(), resourceUri2,
+                        OCConnectivityType::CT_ADAPTER_IP, false,
+                        pResource2->getTypes(), pResource2->getInterfaces());
+        pRemoteResource2 = RCSRemoteResourceObject::fromOCResource(ocResourcePtr);
+    }
+
+    void createSceneCollectionAndScene()
+    {
+        auto pSceneCollection = pSceneList->addNewSceneCollection();
+        pScene1 = pSceneCollection->addNewScene("SceneTestName_1");
+    }
+
+    void createSceneAction()
+    {
+        pSceneAction1 = pScene1->addNewSceneAction(pRemoteResource1, KEY, VALUE);
+        pSceneAction2 = pScene1->addNewSceneAction(pRemoteResource2, KEY_2, VALUE_2);
+    }
+
+public:
+    SceneList* pSceneList;
+    shared_ptr<Scene> pScene1;
+    shared_ptr<Scene> pScene2;
+    shared_ptr<SceneAction> pSceneAction1;
+    shared_ptr<SceneAction> pSceneAction2;
+    RCSRemoteResourceObject::Ptr pRemoteResource1;
+    RCSRemoteResourceObject::Ptr pRemoteResource2;
+
+private:
+    std::condition_variable cond;
+    std::mutex mutex;
+};
+
+TEST_F(SceneActionTest, createSceneActionByEmptyRCSRemoteResourceObjectPtr)
+{
+    createServer("/a/testuri1_1", "/a/testuri1_2");
+    createSceneCollectionAndScene();
+    ASSERT_THROW(pScene1->addNewSceneAction(
+            nullptr, KEY, VALUE), RCSInvalidParameterException);
+}
+
+TEST_F(SceneActionTest, createSceneActionByAlreadyExistedRCSRemoteResourceObjectPtr)
+{
+    createServer("/a/testuri2_1", "/a/testuri2_2");
+    createSceneCollectionAndScene();
+    createSceneAction();
+    ASSERT_THROW(pScene1->addNewSceneAction(
+            pRemoteResource1, KEY, "off"), Scene::InvalidAddMemberRequestException);
+}
+
+TEST_F(SceneActionTest, getSceneActionInstance)
+{
+    createServer("/a/testuri3_1", "/a/testuri3_2");
+    createSceneCollectionAndScene();
+    createSceneAction();
+
+    for(const auto &it : pSceneAction1->getExecutionParameter())
+    {
+        ASSERT_EQ(it.key(), KEY);
+        ASSERT_EQ(it.value(), VALUE);
+    }
+
+    for(const auto &it: pSceneAction2->getExecutionParameter())
+    {
+        ASSERT_EQ(it.key(), KEY_2);
+        ASSERT_EQ(it.value(), VALUE_2);
+    }
+}
+
+TEST_F(SceneActionTest, updateSceneAction)
+{
+    createServer("/a/testuri4_1", "/a/testuri4_2");
+    createSceneCollectionAndScene();
+    createSceneAction();
+
+    pSceneAction1->resetExecutionParameter(KEY, "off");
+    for(const auto &it : pSceneAction1->getExecutionParameter())
+    {
+        ASSERT_EQ(it.key(), KEY);
+        ASSERT_EQ(it.value(), "off");
+    }
+}
+
+TEST_F(SceneActionTest, getRemoteResourceObject)
+{
+    createServer("/a/testuri5_1", "/a/testuri5_2");
+    createSceneCollectionAndScene();
+    createSceneAction();
+
+    ASSERT_EQ(pSceneAction1->getRemoteResourceObject(), pRemoteResource1);
+}
\ No newline at end of file
diff --git a/service/scene-manager/unittests/SceneCollectionTest.cpp b/service/scene-manager/unittests/SceneCollectionTest.cpp
new file mode 100755 (executable)
index 0000000..7c73246
--- /dev/null
@@ -0,0 +1,79 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "UnitTestHelper.h"
+
+#include "SceneList.h"
+#include "OCPlatform.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+class SceneCollectionTest: public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        pSceneList = SceneList::getInstance();
+    }
+
+public:
+    SceneList* pSceneList;
+    std::shared_ptr<SceneCollection> pSceneCollection;
+};
+
+TEST_F(SceneCollectionTest, createSceneCollectionInstanceAndSceneCollectionResource)
+{
+    bool isNullPtr = false;
+    pSceneCollection = pSceneList->addNewSceneCollection();
+
+    if(pSceneCollection->getId() == "")
+    {
+        isNullPtr = true;
+    }
+
+    EXPECT_FALSE(isNullPtr);
+}
+
+TEST_F(SceneCollectionTest, getSceneCollectionInstanceAndSceneCollectionResource)
+{
+    auto sceneCollections = pSceneList->getSceneCollections();
+    bool isNullPtr = false;
+
+    for(const auto &it : sceneCollections)
+    {
+        if(it->getId() == "")
+        {
+            isNullPtr = true;
+        }
+        ASSERT_FALSE(isNullPtr);
+    }
+}
+
+TEST_F(SceneCollectionTest, setAndGetSceneCollectionResourceName)
+{
+    pSceneCollection = pSceneList->addNewSceneCollection();
+    pSceneCollection->setName("Kitchen");
+    auto sceneCollectionName = pSceneCollection->getName();
+
+    EXPECT_EQ("Kitchen", sceneCollectionName);
+}
diff --git a/service/scene-manager/unittests/SceneListTest.cpp b/service/scene-manager/unittests/SceneListTest.cpp
new file mode 100755 (executable)
index 0000000..36cb9a9
--- /dev/null
@@ -0,0 +1,49 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "UnitTestHelper.h"
+
+#include "SceneList.h"
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+class SceneListTest: public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+    }
+};
+
+TEST_F(SceneListTest, sceneListInstance)
+{
+    EXPECT_EQ(SceneList::getInstance(), SceneList::getInstance());
+}
+
+TEST_F(SceneListTest, setAndGetSceneListResourceName)
+{
+    SceneList::getInstance()->setName("House");
+    auto sceneListName = SceneList::getInstance()->getName();
+
+    EXPECT_EQ("House", sceneListName);
+}
diff --git a/service/scene-manager/unittests/SceneTest.cpp b/service/scene-manager/unittests/SceneTest.cpp
new file mode 100755 (executable)
index 0000000..af81258
--- /dev/null
@@ -0,0 +1,199 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "UnitTestHelper.h"
+
+#include "SceneList.h"
+
+#include "RCSResourceObject.h"
+#include "RCSRemoteResourceObject.h"
+#include "SceneCommons.h"
+#include "OCPlatform.h"
+
+#include <condition_variable>
+#include <mutex>
+#include <iostream>
+
+using namespace std;
+using namespace OIC::Service;
+using namespace OC;
+
+typedef std::function<void (int)> ExecuteCallback;
+
+constexpr char RESOURCE_URI[]{ "/a/light" };
+constexpr char RESOURCE_TYPE[]{ "core.light" };
+constexpr char RESOURCE_URI2[]{ "/a/fan" };
+constexpr char RESOURCE_TYPE2[]{ "core.fan" };
+constexpr char KEY[]{ "power" };
+constexpr char VALUE[]{ "off" };
+constexpr char KEY_2[]{ "state" };
+constexpr char VALUE_2[]{ "100" };
+
+class SceneTest: public TestWithMock
+{
+protected:
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+        pSceneList = SceneList::getInstance();
+    }
+    void waitForCb(int watingTime)
+    {
+        std::unique_lock< std::mutex > lock{ mutex };
+        cond.wait_for(lock, std::chrono::milliseconds{ watingTime });
+    }
+    void proceed()
+    {
+        cond.notify_all();
+    }
+    void createSceneCollection()
+    {
+        pSceneCollection = pSceneList->addNewSceneCollection();
+    }
+    void createScene()
+    {
+        pScene1 = pSceneCollection->addNewScene("SceneTestName_1");
+        pScene2 = pSceneCollection->addNewScene("SceneTestName_2");
+    }
+    void createServer(const std::string& resourceUri1, const std::string& resourceUri2)
+    {
+        auto pResource1 = RCSResourceObject::Builder(
+                resourceUri1, RESOURCE_TYPE, DEFAULT_INTERFACE).build();
+        pResource1->setAttribute(KEY, VALUE);
+
+        auto ocResourcePtr = OC::OCPlatform::constructResourceObject(
+                "coap://" + SceneUtils::getNetAddress(), resourceUri1,
+                OCConnectivityType::CT_ADAPTER_IP, false,
+                pResource1->getTypes(), pResource1->getInterfaces());
+        pRemoteResource1 = RCSRemoteResourceObject::fromOCResource(ocResourcePtr);
+
+        auto pResource2 = RCSResourceObject::Builder(
+                resourceUri2, RESOURCE_TYPE2, DEFAULT_INTERFACE).build();
+        pResource2->setAttribute(KEY_2, VALUE_2);
+
+        ocResourcePtr = OC::OCPlatform::constructResourceObject(
+                        "coap://" + SceneUtils::getNetAddress(), resourceUri2,
+                        OCConnectivityType::CT_ADAPTER_IP, false,
+                        pResource2->getTypes(), pResource2->getInterfaces());
+        pRemoteResource2 = RCSRemoteResourceObject::fromOCResource(ocResourcePtr);
+    }
+
+public:
+    SceneList* pSceneList;
+    shared_ptr<SceneCollection> pSceneCollection;
+    shared_ptr<Scene> pScene1;
+    shared_ptr<Scene> pScene2;
+    RCSRemoteResourceObject::Ptr pRemoteResource1;
+    RCSRemoteResourceObject::Ptr pRemoteResource2;
+
+private:
+    std::condition_variable cond;
+    std::mutex mutex;
+};
+void executeCallback(int /*code*/) {};
+
+TEST_F(SceneTest, createSceneInstance)
+{
+    createSceneCollection();
+    createScene();
+    ASSERT_EQ("SceneTestName_1", pScene1->getName());
+    ASSERT_EQ("SceneTestName_2", pScene2->getName());
+}
+
+TEST_F(SceneTest, createSceneInstanceByEmptyName)
+{
+    createSceneCollection();
+    ASSERT_THROW(pSceneCollection->addNewScene(""), RCSInvalidParameterException);
+}
+
+TEST_F(SceneTest, getSceneInstanceBySceneName)
+{
+    createSceneCollection();
+    auto scene = pSceneCollection->getScene("SceneTestName_2");
+    EXPECT_EQ("SceneTestName_2", scene->getName());
+}
+
+TEST_F(SceneTest, getAllSceneInstance)
+{
+    createSceneCollection();
+    createScene();
+
+    vector<string> sceneNames{"SceneTestName_1", "SceneTestName_2"};
+    auto scenes = pSceneCollection->getScenes();
+    int count = 0;
+
+    for(const auto &it : scenes)
+    {
+        ASSERT_EQ(it.first, sceneNames.at(count++));
+    }
+}
+
+TEST_F(SceneTest, getSceneActionUsingRemoteResource)
+{
+    createServer(RESOURCE_URI, RESOURCE_URI2);
+    createSceneCollection();
+    createScene();
+
+    auto pSceneAction1 = pScene1->addNewSceneAction(pRemoteResource1, KEY, VALUE);
+    pSceneAction1->resetExecutionParameter(KEY_2, VALUE_2);
+
+    ASSERT_EQ(pScene1->getSceneAction(pRemoteResource1)->getExecutionParameter(),
+            pSceneAction1->getExecutionParameter());
+}
+
+TEST_F(SceneTest, getSceneActions)
+{
+    createServer("/a/testuri1_1", "/a/testuri1_2");
+    createSceneCollection();
+    createScene();
+
+    auto pSceneAction1 = pScene1->addNewSceneAction(pRemoteResource1, KEY, VALUE);
+    auto pSceneAction2 = pScene1->addNewSceneAction(pRemoteResource2, KEY, VALUE);
+
+    for(const auto & it : pScene1->getSceneActions())
+    {
+        ASSERT_EQ(it->getExecutionParameter(), pSceneAction1->getExecutionParameter());
+    }
+}
+
+TEST_F(SceneTest, executeScene)
+{
+    mocks.ExpectCallFunc(executeCallback).Do([this](int){ proceed(); });
+
+    createServer("/a/testuri2_1", "/a/testuri2_2");
+    createSceneCollection();
+    createScene();
+    pScene1->addNewSceneAction(pRemoteResource1, KEY, "on");
+    pScene1->addNewSceneAction(pRemoteResource2, KEY_2, VALUE_2);
+
+    pScene1->execute(executeCallback);
+    waitForCb(100);
+}
+
+TEST_F(SceneTest, executeSceneUsingEmptyCallback)
+{
+    createServer("/a/testuri3_1", "/a/testuri3_2");
+    createSceneCollection();
+    createScene();
+    pScene1->addNewSceneAction(pRemoteResource1, KEY, "on");
+    pScene1->addNewSceneAction(pRemoteResource2, KEY_2, VALUE_2);
+
+    ASSERT_THROW(pScene1->execute(nullptr), RCSInvalidParameterException);
+}
\ No newline at end of file
index 88e8cf9..4fc2afe 100755 (executable)
@@ -9,7 +9,7 @@ profile = profile.tizen
 #passwd =
 obs = obs.tizen
 #Comma separated list of repositories
-repos = repo.public_latest, repo.devel-gcc49-base, 
+repos = repo.public_latest, repo.devel-gcc49-base,
 #repos = repo.tizen_main, repo.tizen_base
 #Build config for gbs build
 #buildconf = <patch/to/build-config-file>