Merge branch 'master' into resource-manipulation
authorhunje.yeon <hunje.yeon@samsung.com>
Mon, 6 Jul 2015 01:23:08 +0000 (10:23 +0900)
committerhunje.yeon <hunje.yeon@samsung.com>
Mon, 6 Jul 2015 01:25:06 +0000 (10:25 +0900)
Apply stack error fix from 'master' branch into 'resource-manipulation' branch

Change-Id: I768f2c4404985e2dd50855a665b6819fa6d97f43
Signed-off-by: hunje.yeon <hunje.yeon@samsung.com>
98 files changed:
service/SConscript
service/resource-manipulation/README [new file with mode: 0644]
service/resource-manipulation/SConscript [new file with mode: 0644]
service/resource-manipulation/include/ReportPolicyProxy.h [new file with mode: 0644]
service/resource-manipulation/include/ResourceClient.h [new file with mode: 0644]
service/resource-manipulation/modules/common/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/include/PresenceSubscriber.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveException.h [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveResource.h [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/include/ResourceAttributes.h [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/include/ResponseStatement.h [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/include/internal/AssertUtils.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/include/internal/PrimitiveResourceImpl.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesConverter.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesUtils.h [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/src/PresenceSubscriber.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/src/PrimitiveResource.cpp [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/src/PrimtiveException.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/src/ResourceAttributes.cpp [new file with mode: 0755]
service/resource-manipulation/modules/common/primitiveResource/src/ResponseStatement.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/unittests/PresenceSubscriberTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/unittests/PrimitiveResourceTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/primitiveResource/unittests/ResourceAttributesTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceBroker/SConscript [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/include/BrokerTypes.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/include/DeviceAssociation.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/include/DevicePresence.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/include/ResourceBroker.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/include/ResourcePresence.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/src/DeviceAssociation.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/src/DevicePresence.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/src/ResourceBroker.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceBroker/src/ResourcePresence.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceCache/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/resourceCache/include/CacheTypes.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceCache/include/DataCache.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceCache/include/ResourceCacheManager.h [new file with mode: 0755]
service/resource-manipulation/modules/resourceCache/src/DataCache.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceCache/src/ResourceCacheManager.cpp [new file with mode: 0755]
service/resource-manipulation/modules/resourceContainer/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueConnector.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueLight.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/ResourceContainerConfig.xml [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensor.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensorResource.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SampleBundle.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SysTimer.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensor.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensorResource.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SampleBundle.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SysTimer.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/BundleActivator.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/BundleInfo.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/BundleInfoInternal.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/BundleResource.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/Configuration.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeConnector.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeResource.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/ResourceContainer.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/ResourceContainerBundleAPI.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/ResourceContainerImpl.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/include/SoftSensorResource.h [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/BundleActivator.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/BundleInfo.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/BundleInfoInternal.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/BundleResource.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/Configuration.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ContainerTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeConnector.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeResource.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ResourceContainer.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ResourceContainerBundleAPI.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/ResourceContainerImpl.cpp [new file with mode: 0644]
service/resource-manipulation/modules/resourceContainer/src/SoftSensorResource.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/include/PrimitiveRequest.h [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/include/PrimitiveResponse.h [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/include/ResourceObject.h [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/include/internal/RequestHandler.h [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/src/PrimitiveRequest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/src/PrimitiveResponse.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/src/RequestHandler.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/src/ResourceObject.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/unittests/PrimitiveResponseTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/unittests/RequestHandlerTest.cpp [new file with mode: 0644]
service/resource-manipulation/modules/serverBuilder/unittests/ResourceObjectTest.cpp [new file with mode: 0644]
service/resource-manipulation/src/ReportPolicyProxy.cpp [new file with mode: 0644]
service/resource-manipulation/src/ResourceClient.cpp [new file with mode: 0644]

index a3bd70e..656a198 100644 (file)
@@ -40,6 +40,9 @@ if target_os not in ['arduino','darwin','ios']:
 
        # Build notification manager project
        SConscript('notification-manager/SConscript')
+
+       # Build resource-manipulation project
+       #SConscript('resource-manipulation/SConscript')
 #else:
 #      SConscript('notification-manager/SampleApp/arduino/SConscript')
 
diff --git a/service/resource-manipulation/README b/service/resource-manipulation/README
new file mode 100644 (file)
index 0000000..1c65801
--- /dev/null
@@ -0,0 +1,14 @@
+== Brief Guide to Service Basis 
+
+Service Basis provides common functions such as resource broker, cache, resource container.
+
+1. resourceBroker 
+resourceBroker checks and monitors the status of resources. 
+This module notifies the change of reachability of selected resource to users. 
+
+2. resourceCache
+resourceCache provides the up-to-date "DATA" of remote resource to users.
+It tracks the most recent value of the selected resource and notifies to users according to the request notifying policy.
+
+3. resourceContainer
+Need to be updated.
diff --git a/service/resource-manipulation/SConscript b/service/resource-manipulation/SConscript
new file mode 100644 (file)
index 0000000..0adb9a1
--- /dev/null
@@ -0,0 +1,90 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# basis build script
+##
+import platform
+
+Import('env')
+
+SConscript('modules/common/SConscript')
+#SConscript('modules/resourceBroker/SConscript')
+#SConscript('modules/resourceCache/SConscript')
+SConscript('modules/serverBuilder/SConscript')
+SConscript('modules/resourceContainer/SConscript')
+#SConscript('sdk/SConscript')
+
+######################################################################
+#building Resource client
+######################################################################
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+resourceClient_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+resourceClient_env.AppendUnique(CPPPATH = ['include'])
+resourceClient_env.AppendUnique(CPPPATH = ['modules/common/primitiveResource/include'])
+resourceClient_env.AppendUnique(CPPPATH = ['modules/resourceBroker/include'])
+resourceClient_env.AppendUnique(CPPPATH = ['modules/resourceCache/include'])
+
+
+resourceClient_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+
+resourceClient_env.PrependUnique(LIBS = ['oc', 'ResourceBroker' , 'ResourceCache', 'service_common', 'octbstack', 'gnustl_shared','oc_logger', 'compatibility', 'log'])
+
+
+if target_os not in ['windows', 'winrt']:
+    resourceClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+if target_os == 'linux':
+   resourceClient_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+resourceClient_src = 'src/'
+client_src = [
+        resourceClient_src+ 'ReportPolicyProxy.cpp',
+        resourceClient_src+ 'ResourceClient.cpp']
+
+ResourceClientsdk = resourceClient_env.StaticLibrary('ResourceClient', client_src)
+
+resourceClient_env.InstallTarget(ResourceClientsdk , 'libResourceClient')
+
+#Go to build sample apps
+SConscript('examples/SConscript')
+
+
+
+
diff --git a/service/resource-manipulation/include/ReportPolicyProxy.h b/service/resource-manipulation/include/ReportPolicyProxy.h
new file mode 100644 (file)
index 0000000..9d87628
--- /dev/null
@@ -0,0 +1,86 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains caching API, it binds the caching call with report policy object.
+ */
+
+#ifndef REPORT_POLICY_PROXY_H_
+#define REPORT_POLICY_PROXY_H_
+
+#include<iostream>
+#include<string>
+#include<functional>
+
+#include "CacheTypes.h"
+#include "PrimitiveResource.h"
+
+/**
+ * @class   ReportPolicyProxy
+ * @brief   This class provides method for initiating caching with given caching method.
+ *         Caching methods are defined in REPORT_FREQUENCY.
+ *
+ * NOTE: REPORT_FREQUENCY is enum class having values as the following:
+ *          NONE(default), UPDATE and PERIODIC.
+*/
+class ReportPolicyProxy
+{
+    public:
+
+        /**
+        *  Typedef to bind ProxyFunc to CacheCB method of PrimitiveResource.
+        */
+        typedef std::function<CacheID (std::shared_ptr<PrimitiveResource>  , CacheCB)> ProxyFunc;
+
+        ReportPolicyProxy(ReportPolicyProxy &&reportPolicyProxy) = default;
+
+        /**
+         * Constructor for ReportPolicyProxy
+         *
+         * @param func - Caching method so as to bind ReportPolicyProxy object to
+         *                      corresponding method of the PrimitiveResource class.
+         *
+         */
+
+        ReportPolicyProxy(ProxyFunc func) : m_proxyFunc(func)
+        {
+        }
+
+        /**
+         * API for initiating caching on given resource and given caching method.
+         *         Caching methods are defined in REPORT_FREQUENCY.
+         *
+         * @param res - resource to start caching for
+         * @param cb - callback to obtain caching data
+         *
+         * @return CacheID
+         */
+        CacheID startProxyCaching(std::shared_ptr<PrimitiveResource> &res, CacheCB cb);
+
+    private:
+
+        /**
+         *  proxy_binded binded to CacheCB method of PrimitiveResource.
+         */
+        ProxyFunc m_proxyFunc;
+};
+#endif //REPORT_POLICY_PROXY_H_
\ No newline at end of file
diff --git a/service/resource-manipulation/include/ResourceClient.h b/service/resource-manipulation/include/ResourceClient.h
new file mode 100644 (file)
index 0000000..63d3723
--- /dev/null
@@ -0,0 +1,428 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the resource client APIs provided to the developer
+ */
+
+#ifndef RESOURCE_CLIENT_H_
+#define RESOURCE_CLIENT_H_
+
+#include<iostream>
+#include<string>
+#include<vector>
+#include<mutex>
+#include<functional>
+
+#include "ResourceAttributes.h"
+
+using namespace OIC::Service;
+
+/*
+* Forward Declaration of Classes
+*/
+
+namespace OIC
+{
+    namespace Service
+    {
+        class PrimitiveResource;
+    }
+}
+class ReportPolicyProxy;
+class PrimitiveClientResource;
+
+/**
+* Cache State enum specify the state of the Cache.
+*/
+enum class CacheState
+{
+    READY = 0,
+    READY_YET,
+    LOST_SIGNAL,
+    DESTROYED,
+    UPDATING,
+    NONE
+};
+
+/**
+* Resource State enum specify the state of the resource.
+*/
+enum class ResourceState
+{
+    NOT_WATCHING,
+    ALIVE, REQUESTED,
+    LOST_SIGNAL,
+    DESTROYED
+};
+
+/**
+* Time unit enum to indicate time duration in report cache policy.
+*/
+enum class TimeUnit
+{
+    MILLISECOND, SECOND, MIN
+};
+
+/**
+ * @class   InvalidParameterException
+ * @brief   This class extends from PrimitiveException class. It is used to
+ *       throw exception to the upper layer if parameter is invalid.
+ *
+ */
+class BadRequestException: public OIC::Service::PrimitiveException
+{
+    public:
+        BadRequestException(const std::string &what) : PrimitiveException { what } {}
+        BadRequestException(std::string &&what) : PrimitiveException { std::move(what) } {}
+};
+
+/**
+ * @class   InvalidParameterException
+ * @brief   This class extends from PrimitiveException class. It is used to
+ *       throw exception to the upper layer if parameter is invalid.
+ *
+ */
+class InvalidParameterException: public OIC::Service::PrimitiveException
+{
+    public:
+        InvalidParameterException(const std::string &what) : PrimitiveException { what } {}
+        InvalidParameterException(std::string &&what) : PrimitiveException { std::move(what) } {}
+};
+
+/**
+ * @class   ReportPolicy
+ * @brief   This class provides a set of method for various caching policies.
+ *        Each method corresponds to REPORT_FREQUENCY values.
+ *
+ * NOTE: REPORT_FREQUENCY is enum class having values as the following:
+ *          NONE(default), UPDATE and PERIODIC.
+ *
+ */
+class ReportPolicy
+{
+    public:
+
+        /**
+         * Destructor for ReportPolicy
+         */
+        ~ReportPolicy(void) {}
+
+        /**
+         * API for setting the caching policy to default.
+         *
+         * @return ReportPolicy - reportPolicy object corresponding to default caching method.
+         *
+         */
+        static ReportPolicy none();
+
+        /**
+          * API for setting the caching policy to updated.
+          *
+          * @return ReportPolicy - reportPolicy object corresponding to updated caching method.
+          *
+          */
+        static ReportPolicy upToDate();
+
+        /**
+         * API for setting the caching policy to periodic with tive interval given.
+         *
+         * @param interval - Duration for the periodic caching of data.
+         * @param unit - unit of the time interval.
+         *
+         * @return ReportPolicy - reportPolicy object corresponding to periodic caching method.
+         *
+         */
+        static ReportPolicy periodic(int interval, TimeUnit unit);
+
+        /**
+         * API for getting the m_proxy data member for the called object.
+         *
+         * @return ReportPolicyProxy - ReportPolicyProxy data member.
+         *
+         */
+        std::shared_ptr<ReportPolicyProxy> getProxy();
+
+    private:
+
+        /**
+         *  constructor for ReportPolicy
+        *
+        * @param reportPolicyProxy - object binded to startCaching method.
+        *
+        */
+        explicit ReportPolicy(ReportPolicyProxy &&reportPolicyProxy);
+
+        /**
+         *  ReportPolicyProxy object to invoke startCaching method.
+         */
+        std::shared_ptr<ReportPolicyProxy> m_proxy;
+
+};
+
+/**
+ * @class   PrimitiveClientResource
+ * @brief   PrimitiveClientResource is an interaction point between Resource
+ *        and the developer.
+ *
+ */
+class PrimitiveClientResource
+{
+    public:
+
+        /**
+         * Constructor for PrimitiveClientResource.
+        */
+        PrimitiveClientResource(std::shared_ptr<OIC::Service::PrimitiveResource>  pResource);
+
+        /**
+         *  Typedef for callbacks
+         */
+        typedef std::function< void(ResourceState) > ResourceStateChangedCallback;
+        typedef std::function< void(const OIC::Service::ResourceAttributes &) > CacheUpdatedCallback;
+        typedef std::function< void(const OIC::Service::ResourceAttributes &) >
+        RemoteAttributesReceivedCallback;
+
+        /**
+         *  Typedef for Broker and Cache ID
+         */
+        typedef int CacheID;
+        typedef unsigned int BrokerID;
+
+        /**
+         * API to get watching state.
+         *
+         * @return bool - watching or not.
+         */
+        bool isWatching() const;
+
+        /**
+         * API to get Caching state.
+         *
+         * @return bool - caching or not.
+         */
+        bool isCaching() const;
+
+        /**
+         * API to get observable state.
+         *
+         * @return bool - observing or not.
+         */
+        bool isObservable() const;
+
+        /**
+         * API to start watching the resource.
+         *
+         * @param ResourceStateChangedCallback - callback to get changed resource state.
+         */
+        void startWatching(ResourceStateChangedCallback);
+
+        /**
+         * API to stop watching the resource.
+         */
+        void stopWatching();
+
+        /**
+         * API to get resource state.
+         *
+         * @return ResourceState - current state of the resource.
+         */
+        ResourceState getState() const ;
+
+        /**
+         * API to start caching for the resource.
+         *
+         * @param ReportPolicy - caching policy.
+         *
+         * @param CacheUpdatedCallback - callback to get updated resourceAttributes.
+         */
+        void startCaching(ReportPolicy , CacheUpdatedCallback);
+
+        /**
+         * API to get the cache State of the resource
+         *
+         *@return CacheState - current state of the Cache.
+         */
+        CacheState getResourceCacheState();
+
+        /**
+         * API to stop caching for the resource.
+         */
+        void stopCaching();
+
+        /**
+         * API to refresh the cache explicitly.
+         */
+        void refreshCache() ;
+
+        /**
+         * API to obtain cached ResourceAttributes data.
+         *
+         *@return ResourceAttributes - cached ResourceAttributes data
+         */
+        ResourceAttributes getCachedAttributes() const;
+
+        /**
+         * API to obtain current resource attributes data.
+         *
+         * @param RemoteAttributesReceivedCallback - callback to get resourceAttributes data.
+         */
+        void getRemoteAttributes(RemoteAttributesReceivedCallback);
+
+        /**
+         * API to Set resource attributes data.
+         *
+         * @param ResourceAttributes - resourceAttributes data to set for the resource.
+         */
+        void setRemoteAttributes(ResourceAttributes &);
+
+        /**
+         * API to get resource uri.
+         *
+         * @return string - uri of the Resource
+         */
+        std::string getUri() const;
+
+        /**
+         * API to get resource address.
+         *
+         * @return string - address of the Resource
+         */
+        std::string getAddress() const;
+
+        /**
+         * API to get resource types.
+         *
+         * @return vector - resource types
+         */
+        std::vector< std::string > getTypes() const;
+
+        /**
+         * API to get resource interfaces.
+         *
+         * @return vector - resource interfaces
+         */
+        std::vector< std::string > getInterfaces() const;
+
+    private:
+
+        /**
+         *  Flag to check watching state.
+         */
+        bool m_watchingFlag;
+
+        /**
+         *  Flag to check caching state.
+         */
+        bool m_cachingFlag;
+
+        /**
+         *  Flag to check observing state.
+         */
+        bool m_observableFlag;
+
+        /**
+         *  resource uri.
+         */
+        std::string m_uri;
+
+        /**
+         *  resource address.
+         */
+        std::string m_address;
+
+        /**
+         *  Resource type(s).
+         */
+        std::vector< std::string > m_types;
+
+        /**
+         *  Resource interface(s).
+         */
+        std::vector< std::string > m_interfaces;
+
+        /**
+         *  PrimitiveResource.
+         */
+        std::shared_ptr<OIC::Service::PrimitiveResource> m_primitiveResource;
+
+        /**
+         *  caching identification number.
+         */
+        CacheID m_cacheId;
+
+        /**
+        *  Broker  identification number.
+        */
+        BrokerID m_brokerId;
+
+};
+
+/**
+ * @class   PrimitiveClient
+ * @brief   It contains the resource discovery method.
+ *
+ */
+class PrimitiveClient
+{
+    public:
+
+        /**
+         *  Typedef for callback
+         */
+        typedef std::function< void( std::shared_ptr< PrimitiveClientResource>) >
+        OnResourceDiscoveredCallback;
+
+        /**
+        * API to get Primitive Client instance.
+        *
+        * @return PrimitiveClient -instance.
+        */
+        static PrimitiveClient *getInstance();
+
+        /**
+        * API for discovey of resource of Interrest.
+        *
+        * @param host - host to search for
+        * @param resourceURI - uri of resource to be searched
+        * @param connectivityType - connection type
+        * @param cb - callback to obtain discovered resource.
+        *
+        */
+        void discoverPrimitiveResource(std::string host, std::string resourceURI,
+                                       OCConnectivityType connectivityType,
+                                       OnResourceDiscoveredCallback cb);
+
+    private:
+
+        /**
+         * Constructor for PrimitiveClient.
+        */
+        PrimitiveClient() = default;
+
+        /**
+         * Destructor for PrimitiveClient.
+        */
+        ~PrimitiveClient();
+
+};
+#endif //RESOURCE_CLIENT_H_
diff --git a/service/resource-manipulation/modules/common/SConscript b/service/resource-manipulation/modules/common/SConscript
new file mode 100644 (file)
index 0000000..70586b3
--- /dev/null
@@ -0,0 +1,30 @@
+#******************************************************************\r
+#\r
+# Copyright 2015 Samsung Electronics All Rights Reserved.\r
+#\r
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+#\r
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+##\r
+# basis build script\r
+##\r
+import platform\r
+\r
+Import('env')\r
+\r
+SConscript('primitiveResource/SConscript')\r
+\r
+\r
diff --git a/service/resource-manipulation/modules/common/expiryTimer/SConscript b/service/resource-manipulation/modules/common/expiryTimer/SConscript
new file mode 100644 (file)
index 0000000..0fd1747
--- /dev/null
@@ -0,0 +1,71 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceCache 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')
+timer_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+timer_env.AppendUnique(CPPPATH = ['include'])
+timer_env.AppendUnique(CPPPATH = ['src'])
+timer_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+
+if target_os not in ['windows', 'winrt']:
+    timer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++11'])
+
+if target_os == 'linux':
+    timer_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+TIMER_SRC_DIR = 'src/'
+timer_src = [
+        TIMER_SRC_DIR + 'ExpiryTimer_Impl.cpp', TIMER_SRC_DIR + 'ExpiryTimer.cpp'
+        ]
+
+if target_os in ['tizen','android'] :
+    timersdk = timer_env.SharedLibrary('ExpiryTimer', timer_src)
+else :
+    timersdk = timer_env.StaticLibrary('ExpiryTimer', timer_src)
+
+timer_env.InstallTarget(timersdk, 'libExpiryTimer')
+
+# Go to build sample apps
+#SConscript('SampleApp/SConscript')
+
diff --git a/service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h b/service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h
new file mode 100644 (file)
index 0000000..8562a31
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_H_
+#define _EXPIRY_TIMER_H_
+
+#include <functional>
+#include <list>
+#include <iostream>
+
+#include "ExpiryTimer_Impl.h"
+
+using namespace std;
+
+typedef unsigned int TimerID;
+typedef function<void*(TimerID)> TimerCB;
+
+class ExpiryTimer
+{
+public:
+    ExpiryTimer();
+    ~ExpiryTimer();
+
+    TimerID requestTimer(long long sec, TimerCB);
+    void cancelTimer(TimerID timerID);
+
+private:
+
+    long long countExpiredTime(long long sec);
+
+    list<TimerID> mTimerIDList;
+    ExpiryTimer_Impl* timerPtr;
+};
+
+#endif //_TIMER_H_
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp
new file mode 100644 (file)
index 0000000..e70cd73
--- /dev/null
@@ -0,0 +1,64 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ExpiryTimer.h"
+
+#include <ctime>
+
+ExpiryTimer::ExpiryTimer()
+{
+    timerPtr = ExpiryTimer_Impl::getInstance();
+}
+
+ExpiryTimer::~ExpiryTimer()
+{
+    // clear ExpiryTimer id
+    for(auto it : mTimerIDList)
+    {
+        timerPtr->cancelTimer(it);
+    }
+    mTimerIDList.clear();
+}
+
+TimerID ExpiryTimer::requestTimer(long long sec, TimerCB cb)
+{
+    TimerID retID;
+    long long expiredTime;
+
+    expiredTime = countExpiredTime(sec);
+    retID = timerPtr->requestTimer(expiredTime, cb);
+
+    mTimerIDList.push_back(retID);
+
+    return retID;
+}
+
+void ExpiryTimer::cancelTimer(TimerID timerID)
+{
+    timerPtr->cancelTimer(timerID);
+    mTimerIDList.remove(timerID);
+}
+
+long long ExpiryTimer::countExpiredTime(long long sec)
+{
+    time_t curSEC;
+    time(&curSEC);
+    return curSEC + sec;
+}
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp
new file mode 100644 (file)
index 0000000..84f489c
--- /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 "ExpiryTimer_Impl.h"
+
+#include <unistd.h>
+#include <algorithm>
+#include <cstdlib>
+#include <utility>
+
+
+ExpiryTimer_Impl* ExpiryTimer_Impl::s_instance = nullptr;
+std::mutex ExpiryTimer_Impl::s_mutexForCreation;
+bool ExpiryTimer_Impl::isDestroyed = false;
+
+ExpiryTimer_Impl::ExpiryTimer_Impl()
+{
+    threadNum = 0;
+    checkThreadRun = false;
+}
+
+ExpiryTimer_Impl::~ExpiryTimer_Impl()
+{
+    isDestroyed = true;
+    int status;
+
+    pthread_join(checker_th, (void **)&status);
+    pthread_detach(checker_th);
+}
+
+void ExpiryTimer_Impl::killTimer()
+{
+    s_instance->~ExpiryTimer_Impl();
+}
+
+ExpiryTimer_Impl* ExpiryTimer_Impl::getInstance()
+{
+    if(isDestroyed)
+    {
+        new(s_instance) ExpiryTimer_Impl;
+        atexit(killTimer);
+        isDestroyed = false;
+    }
+    else if(s_instance == nullptr)
+    {
+        static ExpiryTimer_Impl tmp_instance;
+        s_instance = &tmp_instance;
+    }
+    return s_instance;
+}
+
+TimerID ExpiryTimer_Impl::requestTimer(long long sec, TimerCB cb)
+{
+    if(threadNum < EXPIRY_THREAD_LIST)
+    {
+        unsigned int timerID = generateTimerID();
+        ExpiryTimer_Impl::getInstance()->registerCBTimer(sec, cb, timerID);
+        return timerID;
+    }
+    else
+        return OVERFLOW_THREAD_NUM;
+}
+
+void ExpiryTimer_Impl::cancelTimer(TimerID timerID)
+{
+    for( auto it : mTimerCBList)
+    {
+        if(it.second.m_id == timerID)
+        {
+            mTimerCBList.erase(it.first);
+            timerIDList.remove(it.second.m_id);
+        }
+    }
+}
+
+void ExpiryTimer_Impl::registerCBTimer(long long countSEC, TimerCB _cb, TimerID id)
+{
+    timerCBInfo newInfo = {id, _cb};
+    mTimerCBList.insert(multimap<long long, ExpiryTimer_Impl::timerCBInfo>::value_type(countSEC, newInfo));
+
+    if (checkThreadRun == false)
+    {
+        initThCheck();
+    }
+}
+
+void ExpiryTimer_Impl::checkTimeOut()
+{
+    while (1)
+    {
+        if(mTimerCBList.empty())
+        {
+            checkThreadRun = false;
+            break;
+        }
+       else
+        {
+           long long curSEC = getSeconds(0);
+           long long expireTime;
+           expireTime = mTimerCBList.begin()->first;
+
+           if(curSEC >= expireTime)
+           {
+               initThExecutor(mTimerCBList.begin()->second);
+               mTimerCBList.erase(mTimerCBList.begin());
+           }
+        }
+       usleep(SLEEP_TIME);
+    }
+}
+
+void* ExpiryTimer_Impl::threadChecker(void * msg)
+{
+    if(s_instance != nullptr)
+        s_instance->checkTimeOut();
+    return NULL;
+}
+
+void ExpiryTimer_Impl::initThCheck()
+{
+    int retThreadCreation;
+
+    retThreadCreation = pthread_create(&checker_th, NULL, s_instance->threadChecker, NULL);
+    if (retThreadCreation != 0)
+    {
+        return;
+    }
+    else
+    {
+        checkThreadRun = true;
+    }
+}
+
+void *ExpiryTimer_Impl::threadExecutor(void * msg)
+{
+    TimerCB cb;
+    timerCBInfo *curCBInfo;
+    curCBInfo= (timerCBInfo *) msg;
+
+    cb = curCBInfo->m_pCB;
+    cb(curCBInfo->m_id);
+
+    return NULL;
+}
+
+void ExpiryTimer_Impl::initThExecutor(timerCBInfo cbInfo)
+{
+
+    int retThreadCreation;
+    int status;
+    pthread_t executor_th;
+
+    retThreadCreation = pthread_create(&executor_th, NULL, ExpiryTimer_Impl::threadExecutor, (void *)&cbInfo);
+    threadNum++;
+
+    if (retThreadCreation != 0)
+    {
+        return;
+    }
+    else
+    {
+        pthread_join(executor_th, (void **)&status);
+        pthread_detach(executor_th);
+        threadNum--;
+    }
+}
+
+TimerID ExpiryTimer_Impl::generateTimerID()
+{
+    srand(time(NULL));
+    unsigned int retID = rand();
+
+    for(auto it : timerIDList)
+     {
+       if(it == retID || retID == 0)
+        {
+            retID = rand();
+            it = s_instance->timerIDList.front();
+        }
+     }
+    timerIDList.push_back(retID);
+
+    return retID;
+}
+
+long long ExpiryTimer_Impl::getSeconds(long long sec)
+{
+    time_t curSEC;
+    time(&curSEC);
+    long long retSEC = curSEC + sec;
+    return retSEC;
+}
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h
new file mode 100644 (file)
index 0000000..5c5b526
--- /dev/null
@@ -0,0 +1,95 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_Impl_H_
+#define _EXPIRY_TIMER_Impl_H_
+
+#include <mutex>
+#include <pthread.h>
+#include <functional>
+#include <list>
+#include <map>
+#include <iostream>
+#include <new>
+
+#define EXPIRY_THREAD_LIST 50
+#define OVERFLOW_THREAD_NUM -1
+// Current checker thread design have to get checking interval.
+// SLEEP_TIME value will be removed later.
+#define SLEEP_TIME 50000
+
+using namespace std;
+
+typedef unsigned int TimerID;
+typedef function<void*(TimerID)> TimerCB;
+
+class ExpiryTimer_Impl
+{
+private:
+   struct timerCBInfo
+    {
+       TimerID m_id;
+       TimerCB m_pCB;
+    };
+
+    ExpiryTimer_Impl();
+    ExpiryTimer_Impl(const ExpiryTimer_Impl & other);
+    ~ExpiryTimer_Impl();
+
+public:
+
+     static ExpiryTimer_Impl * getInstance();
+
+    TimerID requestTimer(long long sec, TimerCB);
+    void cancelTimer(TimerID timerID);
+
+private:
+
+   static void killTimer();
+   static void *threadExecutor(void * msg);
+   static void *threadChecker(void * msg);
+
+   void registerCBTimer(long long countSEC, TimerCB _cb, TimerID id);
+   void initThCheck();
+   void initThExecutor(timerCBInfo cbInfo);
+   void checkTimeOut();
+
+   TimerID generateTimerID();
+   long long getSeconds(long long sec);
+
+public:
+
+    list<TimerID> timerIDList;
+
+private:
+
+    static ExpiryTimer_Impl * s_instance;
+    static mutex s_mutexForCreation;
+    static bool isDestroyed;
+
+    multimap<long long, timerCBInfo> mTimerCBList;
+    bool checkThreadRun;
+    list<int> mExecutorIndexList;
+    int threadNum;
+
+    pthread_t checker_th;
+    pthread_mutex_t checker_mutex;
+};
+#endif //_EXPIRY_TIMER_Impl_H_
diff --git a/service/resource-manipulation/modules/common/primitiveResource/SConscript b/service/resource-manipulation/modules/common/primitiveResource/SConscript
new file mode 100644 (file)
index 0000000..9c93386
--- /dev/null
@@ -0,0 +1,99 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# things_manager project build script
+##
+import os
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+src_dir = lib_env.get('SRC_DIR')
+
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+service_common_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+release = env.get('RELEASE')
+
+######################################################################
+# Build flags
+######################################################################
+service_common_env.AppendUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs', 'include', 'src'])
+
+if target_os not in ['windows', 'winrt']:
+    service_common_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    if target_os != 'android':
+        service_common_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os == 'android':
+    service_common_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    service_common_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+
+service_common_env.AppendUnique(LIBS = ['dl'])
+
+if not release:
+    service_common_env.AppendUnique(CXXFLAGS = ['--coverage'])
+    service_common_env.PrependUnique(LIBS = ['gcov'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+service_common_src = env.Glob('src/*.cpp')
+service_common_static = service_common_env.StaticLibrary('service_common', service_common_src)
+service_common_shared = service_common_env.SharedLibrary('service_common', service_common_src)
+
+service_common_env.InstallTarget([service_common_static,service_common_shared], 'service_common')
+
+######################################################################
+# Build Test
+######################################################################
+service_common_test_env = service_common_env.Clone();
+
+service_common_test_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+service_common_test_env.PrependUnique(CPPPATH = [
+    env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+    gtest_dir + '/include'
+    ])
+
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+service_common_test_env.PrependUnique(LIBS = [
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    'service_common',
+    'pthread',
+    gtest,
+    gtest_main
+    ])
+
+service_common_test_src = env.Glob('unittests/*.cpp')
+
+service_common_test = service_common_test_env.Program('service_common_test', service_common_test_src)
+Alias("service_common_test", service_common_test)
+env.AppendTarget('service_common_test')
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/PresenceSubscriber.h b/service/resource-manipulation/modules/common/primitiveResource/include/PresenceSubscriber.h
new file mode 100644 (file)
index 0000000..e986cd3
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_PRESENCESUBSCRIBER_H
+#define COMMON_PRESENCESUBSCRIBER_H
+
+#include <string>
+#include <functional>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        typedef std::function< void(OCStackResult, const unsigned int, const std::string&) >
+            SubscribeCallback;
+
+        class PresenceSubscriber
+        {
+        public:
+            PresenceSubscriber();
+
+            PresenceSubscriber(PresenceSubscriber&&);
+
+            /**
+             * @throw PlatformException
+             */
+            PresenceSubscriber(const std::string& host, OCConnectivityType connectivityType,
+                    SubscribeCallback presenceHandler);
+
+            /**
+             * @throw PlatformException
+             */
+            PresenceSubscriber(const std::string& host, const std::string& resourceType,
+                    OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+            ~PresenceSubscriber();
+
+            PresenceSubscriber& operator=(PresenceSubscriber&&);
+
+            /**
+             * @throw PlatformException
+             */
+            void unsubscribe();
+
+            bool isSubscribing() const;
+
+        private:
+            OCDoHandle m_handle;
+        };
+
+        /**
+         * @throw PlatformException
+         */
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+        /**
+         * @throw PlatformException
+         */
+        void subscribePresence(OCDoHandle& handle, const std::string& host, const std::string& resourceType,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler);
+
+        void unsubscribePresence(OCDoHandle handle);
+
+    }
+}
+
+#endif // COMMON_PRESENCESUBSCRIBER_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveException.h b/service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveException.h
new file mode 100755 (executable)
index 0000000..c623eb1
--- /dev/null
@@ -0,0 +1,63 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RES_MANIPULATION_PRIMITIVEEXCEPTION_H
+#define RES_MANIPULATION_PRIMITIVEEXCEPTION_H
+
+#include <string>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class PrimitiveException: public std::exception
+        {
+        public:
+            PrimitiveException() {}
+            explicit PrimitiveException(const std::string& what) : m_what{ what } {}
+            explicit PrimitiveException(std::string&& what) : m_what{ std::move(what) } {}
+
+            const char* what() const noexcept override
+            {
+                return m_what.c_str();
+            }
+
+        private:
+            std::string m_what;
+        };
+
+        class PlatformException: public PrimitiveException
+        {
+        public:
+            explicit PlatformException(OCStackResult reason);
+
+            OCStackResult getReasonCode() const;
+            std::string getReason() const;
+
+        private:
+            OCStackResult m_reason;
+        };
+    }
+}
+
+#endif // RES_MANIPULATION_PRIMITIVEEXCEPTION_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveResource.h b/service/resource-manipulation/modules/common/primitiveResource/include/PrimitiveResource.h
new file mode 100755 (executable)
index 0000000..9dde868
--- /dev/null
@@ -0,0 +1,92 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_PRIMITIVERESOURCE_H
+#define COMMON_PRIMITIVERESOURCE_H
+
+#include <functional>
+#include <string>
+#include <vector>
+
+#include <OCResource.h>
+#include <ResponseStatement.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        using HeaderOption = OC::HeaderOption::OCHeaderOption;
+        using HeaderOptions = std::vector<HeaderOption>;
+
+        class ResourceAttributes;
+        class ResponseStatement;
+
+        class PrimitiveResource
+        {
+        public:
+            using Ptr = std::shared_ptr<PrimitiveResource>;
+
+            using GetCallback = std::function<
+                    void(const HeaderOptions&, const ResponseStatement&, int)>;
+
+            using SetCallback = std::function<
+                    void(const HeaderOptions&, const ResponseStatement&, int)>;
+
+            using ObserveCallback = std::function<
+                    void(const HeaderOptions&, const ResponseStatement&, int, int)>;
+
+        public:
+            static PrimitiveResource::Ptr create(const std::shared_ptr<OC::OCResource>&);
+
+            virtual ~PrimitiveResource() = default;
+
+            virtual void requestGet(GetCallback) = 0;
+            virtual void requestSet(const ResourceAttributes&, SetCallback) = 0;
+            virtual void requestObserve(ObserveCallback) = 0;
+            virtual void cancelObserve() = 0;
+
+            virtual std::string getSid() const = 0;
+            virtual std::string getUri() const = 0;
+            virtual std::string getHost() const = 0;
+            virtual std::vector< std::string > getTypes() const = 0;
+            virtual std::vector< std::string > getInterfaces() const = 0;
+
+            virtual bool isObservable() const = 0;
+
+        protected:
+            PrimitiveResource() = default;
+
+            PrimitiveResource(const PrimitiveResource&) = delete;
+            PrimitiveResource(PrimitiveResource&&) = delete;
+
+            PrimitiveResource& operator=(const PrimitiveResource&) = delete;
+            PrimitiveResource& operator=(PrimitiveResource&&) = delete;
+        };
+
+        using DiscoverCallback = std::function<void(std::shared_ptr<PrimitiveResource>)>;
+
+        void discoverResource(const std::string& host, const std::string& resourceURI,
+                OCConnectivityType, DiscoverCallback);
+
+    }
+}
+
+#endif // COMMON_PRIMITIVERESOURCE_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/ResourceAttributes.h b/service/resource-manipulation/modules/common/primitiveResource/include/ResourceAttributes.h
new file mode 100755 (executable)
index 0000000..40af425
--- /dev/null
@@ -0,0 +1,396 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RES_MANIPULATION_RESOURCEATTRIBUTES_H
+#define RES_MANIPULATION_RESOURCEATTRIBUTES_H
+
+// To avoid conflict using different boost::variant configuration with OC.
+// It causes compile errors.
+#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#define BOOST_MPL_LIMIT_LIST_SIZE 30
+#define BOOST_MPL_LIMIT_VECTOR_SIZE 30
+
+#include <functional>
+#include <unordered_map>
+
+#include <boost/variant.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <PrimitiveException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class BadGetException: public PrimitiveException
+        {
+        public:
+            BadGetException(const std::string& what) : PrimitiveException{ what } {}
+            BadGetException(std::string&& what) : PrimitiveException{ std::move(what) } {}
+        };
+
+        class InvalidKeyException: public PrimitiveException
+        {
+        public:
+            InvalidKeyException(const std::string& what) : PrimitiveException{ what } {}
+            InvalidKeyException(std::string&& what) : PrimitiveException{ std::move(what) } {}
+        };
+
+        class ResourceAttributes
+        {
+        private:
+            template< typename T > struct is_supported_type_helper;
+
+            using ValueVariant = boost::variant<
+                std::nullptr_t,
+                int,
+                double,
+                bool,
+                std::string,
+                ResourceAttributes
+            >;
+
+            template< typename T >
+            using mpl_begin = typename boost::mpl::begin<T>::type;
+
+            template< typename T, typename V = void >
+            using enable_if_supported = typename std::enable_if<
+                    is_supported_type_helper< T >::type::value, V >::type;
+
+            template< typename T, typename V = void >
+            using enable_if_unsupported = typename std::enable_if<
+                    !is_supported_type_helper< T >::type::value, V >::type;
+
+            template< typename VISITOR >
+            class KeyValueVisitorHelper: public boost::static_visitor< >
+            {
+            public:
+                KeyValueVisitorHelper(VISITOR& visitor) :
+                        m_visitor( visitor )
+                {
+                }
+
+                template< typename T >
+                void operator()(const std::string& key, const T& value) const
+                {
+                    m_visitor(key, value);
+                }
+
+            private:
+                VISITOR& m_visitor;
+            };
+
+        public:
+            template< typename T >
+            using is_supported_type = typename is_supported_type_helper< T >::type;
+
+            class Value
+            {
+            public:
+                Value();
+                Value(const Value&);
+                Value(Value&&);
+
+                template< typename T, typename = enable_if_supported< T > >
+                Value(T&& value) :
+                        m_data{ new ValueVariant{ std::forward< T >(value) } }
+                {
+                }
+
+                Value& operator=(const Value&);
+                Value& operator=(Value&&);
+
+                template< typename T, typename = enable_if_supported< T > >
+                Value& operator=(T&& rhs)
+                {
+                    *m_data = std::forward< T >(rhs);
+                    return *this;
+                }
+
+                Value& operator=(const char*);
+                Value& operator=(std::nullptr_t);
+
+                template< typename T >
+                typename std::add_lvalue_reference< const T >::type get() const
+                {
+                    return checkedGet< T >();
+                }
+
+                template< typename T >
+                typename std::add_lvalue_reference< T >::type get()
+                {
+                    return checkedGet< T >();
+                }
+
+                bool isTypeEqualWith(const Value& rhs) const
+                {
+                    return m_data->which() == rhs.m_data->which();
+                }
+
+                template< typename T >
+                enable_if_supported< T, bool > isTypeOf() const
+                {
+                    using iter = typename boost::mpl::find< ValueVariant::types, T >::type;
+
+                    return m_data->which()
+                            == boost::mpl::distance< mpl_begin< ValueVariant::types >, iter >::value;
+                }
+
+                template< typename T >
+                enable_if_unsupported< T, bool > isTypeOf() const
+                {
+                    return false;
+                }
+
+                std::string toString() const;
+
+                friend bool operator==(const Value&, const Value&);
+
+                template< typename T >
+                friend typename std::enable_if< ResourceAttributes::is_supported_type< T >::value,
+                    bool >::type operator==(const Value&, const T&);
+
+                bool operator==(const char*) const;
+
+            private:
+                template< typename T, typename = enable_if_supported< T > >
+                typename std::add_lvalue_reference< T >::type checkedGet() const
+                {
+                    try
+                    {
+                        return boost::get< T >(*m_data);
+                    }
+                    catch (const boost::bad_get&)
+                    {
+                        throw BadGetException{ "Wrong type" };
+                    }
+                }
+
+                template< typename T, typename U >
+                bool equals(const U& rhs) const
+                {
+                    try
+                    {
+                        return get< T >() == rhs;
+                    }
+                    catch (const BadGetException&)
+                    {
+                        return false;
+                    }
+                }
+
+            private:
+                boost::scoped_ptr< ValueVariant > m_data;
+
+                friend class ResourceAttributes;
+            };
+
+            class KeyValuePair;
+            class iterator;
+            class const_iterator;
+
+        public:
+            ResourceAttributes() = default;
+            ResourceAttributes(const ResourceAttributes&) = default;
+            ResourceAttributes(ResourceAttributes&&) = default;
+
+            ResourceAttributes& operator=(const ResourceAttributes&) = default;
+            ResourceAttributes& operator=(ResourceAttributes&&) = default;
+
+            iterator begin();
+            iterator end();
+
+            const_iterator begin() const;
+            const_iterator end() const;
+
+            const_iterator cbegin() const;
+            const_iterator cend() const;
+
+            Value& operator[](const std::string&);
+            Value& operator[](std::string&&);
+
+            Value& at(const std::string&);
+            const Value& at(const std::string&) const;
+
+            bool erase(const std::string&);
+
+            bool contains(const std::string&) const;
+            bool empty() const;
+            size_t size() const;
+
+            friend bool operator==(const ResourceAttributes&, const ResourceAttributes&);
+
+        private:
+            template< typename VISITOR >
+            void visit(VISITOR& visitor) const
+            {
+                KeyValueVisitorHelper< VISITOR > helper{ visitor };
+
+                for (const auto& i : m_values)
+                {
+                    boost::variant< const std::string& > key{ i.first };
+                    boost::apply_visitor(helper, key, *i.second.m_data);
+                }
+            }
+
+        private:
+            std::unordered_map< std::string, Value > m_values;
+
+            friend class ResourceAttributesConverter;
+        };
+
+        template< typename T > struct ResourceAttributes::is_supported_type_helper
+        {
+            using type = boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type>;
+        };
+
+        template< typename T >
+        typename std::enable_if< ResourceAttributes::is_supported_type< T >::value, bool >::type
+        operator==(const ResourceAttributes::Value& lhs, const T& rhs)
+        {
+            return lhs.equals< T >(rhs);
+        }
+
+        template< typename T >
+        bool operator==(const T& lhs, const ResourceAttributes::Value& rhs)
+        {
+            return rhs == lhs;
+        }
+
+        bool operator==(const char* lhs, const ResourceAttributes::Value& rhs);
+
+        class ResourceAttributes::KeyValuePair
+        {
+        private:
+            class KeyVisitor: public boost::static_visitor< const std::string& >
+            {
+            public:
+                result_type operator()(iterator*) const;
+                result_type operator()(const_iterator*) const;
+            };
+
+            class ValueVisitor: public boost::static_visitor< Value& >
+            {
+            public:
+                result_type operator()(iterator*);
+                result_type operator()(const_iterator*);
+            };
+
+            class ConstValueVisitor: public boost::static_visitor< const Value& >
+            {
+            public:
+                result_type operator()(iterator*) const;
+                result_type operator()(const_iterator*) const;
+            };
+
+        public:
+            const std::string& key() const;
+            const ResourceAttributes::Value& value() const;
+            ResourceAttributes::Value& value();
+
+        private:
+            KeyValuePair(const KeyValuePair&) = default;
+            KeyValuePair(boost::variant< iterator*, const_iterator* >&&);
+
+            KeyValuePair& operator=(const KeyValuePair&) = default;
+
+        private:
+            boost::variant< iterator*, const_iterator* > m_iterRef;
+
+            KeyVisitor m_keyVisitor;
+            ValueVisitor m_valueVisitor;
+            ConstValueVisitor m_constValueVisitor;
+
+            friend class iterator;
+            friend class const_iterator;
+        };
+
+        class ResourceAttributes::iterator: public std::iterator< std::forward_iterator_tag,
+                ResourceAttributes::KeyValuePair >
+        {
+        private:
+            using base_iterator = std::unordered_map< std::string, Value >::iterator;
+
+        public:
+            iterator();
+            iterator(const iterator&) = default;
+
+            iterator& operator=(const iterator&) = default;
+
+            reference operator*();
+            pointer operator->();
+
+            iterator& operator++();
+            iterator operator++(int);
+
+            bool operator==(const iterator&) const;
+            bool operator!=(const iterator&) const;
+
+        private:
+            explicit iterator(base_iterator&&);
+
+        private:
+            base_iterator m_cur;
+            ResourceAttributes::KeyValuePair m_keyValuePair;
+
+            friend class ResourceAttributes;
+        };
+
+        class ResourceAttributes::const_iterator: public std::iterator< std::forward_iterator_tag,
+                const ResourceAttributes::KeyValuePair >
+        {
+        private:
+            using base_iterator = std::unordered_map< std::string, Value >::const_iterator;
+
+        public:
+            const_iterator();
+            const_iterator(const const_iterator&) = default;
+            const_iterator(const ResourceAttributes::iterator&);
+
+            const_iterator& operator=(const const_iterator&) = default;
+            const_iterator& operator=(const ResourceAttributes::iterator&);
+
+            reference operator*() const;
+            pointer operator->() const;
+
+            const_iterator& operator++();
+            const_iterator operator++(int);
+
+            bool operator==(const const_iterator&) const;
+            bool operator!=(const const_iterator&) const;
+
+        private:
+            explicit const_iterator(base_iterator&&);
+
+        private:
+            base_iterator m_cur;
+            ResourceAttributes::KeyValuePair m_keyValuePair;
+
+            friend class ResourceAttributes;
+        };
+
+    }
+}
+
+#endif // RES_MANIPULATION_RESOURCEATTRIBUTES_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/ResponseStatement.h b/service/resource-manipulation/modules/common/primitiveResource/include/ResponseStatement.h
new file mode 100755 (executable)
index 0000000..e19f9a3
--- /dev/null
@@ -0,0 +1,74 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_RESPONSESTATEMENT_H
+#define COMMON_RESPONSESTATEMENT_H
+
+#include <string>
+#include <vector>
+
+#include <ResourceAttributes.h>
+
+namespace OC
+{
+    class OCRepresentation;
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceAttributes;
+
+        class ResponseStatement
+        {
+        public:
+            static ResponseStatement create(const OC::OCRepresentation&);
+            static ResponseStatement create(ResourceAttributes&&);
+
+            explicit ResponseStatement(const ResourceAttributes&);
+            explicit ResponseStatement(ResourceAttributes&&);
+
+            ResponseStatement(ResourceAttributes&&, std::string&& uri,
+                    std::vector< std::string >&& resourceTypes,
+                    std::vector< std::string >&& resourceInterfaces);
+
+            ResponseStatement(ResponseStatement&&) = default;
+
+            ResponseStatement& operator=(ResponseStatement&&) = default;
+
+            std::string getUri() const;
+            std::vector< std::string > getResourceTypes() const;
+            std::vector< std::string > getResourceInterfaces() const;
+
+            const ResourceAttributes& getAttributes() const;
+
+        private:
+            ResourceAttributes m_attrs;
+
+            std::string m_uri;
+            std::vector< std::string > m_resourceTypes;
+            std::vector< std::string > m_resourceInterfaces;
+        };
+
+    }
+}
+
+#endif // COMMON_RESPONSESTATEMENT_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/internal/AssertUtils.h b/service/resource-manipulation/modules/common/primitiveResource/include/internal/AssertUtils.h
new file mode 100644 (file)
index 0000000..eccc51e
--- /dev/null
@@ -0,0 +1,195 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_ASSERTUTILS_H
+#define COMMON_INTERNAL_ASSERTUTILS_H
+
+#include <cstdint>
+
+#include <memory>
+
+#include <octypes.h>
+#include <OCException.h>
+
+#include <PrimitiveException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        namespace Detail
+        {
+            struct NotOCStackResult;
+
+            template <typename FUNC, typename ...PARAMS>
+            struct ResultType
+            {
+                using type = decltype(std::declval<FUNC>()(std::declval<PARAMS>()...));
+            };
+
+            template< typename A, typename B, typename ENABLER = void >
+            struct EnableIfTypeIs;
+
+            template< typename A >
+            struct EnableIfTypeIs< A, OCStackResult,
+                    typename std::enable_if< std::is_same< A, OCStackResult >::value >::type >
+            {
+                using type = void;
+            };
+
+            template< typename A >
+            struct EnableIfTypeIs< A, NotOCStackResult,
+                    typename std::enable_if< !std::is_same< A, OCStackResult >::value >::type >
+            {
+                using type = A;
+            };
+
+
+            template< typename T, typename = typename std::enable_if<
+                    std::is_class<T>::value && std::is_pointer<T>::value>::type >
+            struct EnableIfClassPointer
+            {
+                using type = void;
+            };
+
+            template< typename T, typename = typename std::enable_if<std::is_class<T>::value > >
+             struct EnableIfClass
+             {
+                 using type = void;
+             };
+        }
+
+        inline void expectOCStackResult(OCStackResult actual, OCStackResult expected)
+        {
+            if (actual != expected)
+            {
+                throw PlatformException(actual);
+            }
+        }
+
+        inline void expectOCStackResultOK(OCStackResult actual)
+        {
+            expectOCStackResult(actual, OC_STACK_OK);
+        }
+
+        template< typename FUNC, typename ...PARAMS >
+        typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
+                OCStackResult >::type
+        invokeOCFunc(FUNC&& fn, PARAMS&& ...params)
+        {
+            try
+            {
+                expectOCStackResultOK(fn(std::forward< PARAMS >(params)...));
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename FUNC, typename ...PARAMS >
+        typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
+                        Detail::NotOCStackResult >::type
+        invokeOC(FUNC* fn, PARAMS&& ...params)
+        {
+            try
+            {
+                return fn(std::forward< PARAMS >(params)...);
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
+            typename Detail::EnableIfTypeIs<
+                decltype((obj->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
+                type
+        {
+            try
+            {
+                expectOCStackResultOK(obj->*fn(std::forward< PARAMS >(params)...));
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
+                typename Detail::EnableIfTypeIs<
+                    decltype((obj->*fn)(std::forward< PARAMS >(params)...)),
+                    Detail::NotOCStackResult>::
+                    type
+        {
+            try
+            {
+                obj->*fn(std::forward< PARAMS >(params)...);
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClass<OBJ>::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(const std::shared_ptr< OBJ >& obj, FUNC&& fn, PARAMS&& ...params) ->
+                typename Detail::EnableIfTypeIs<
+                    decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
+                    type
+        {
+            try
+            {
+                expectOCStackResultOK((obj.get()->*fn)(std::forward< PARAMS >(params)...));
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+        template< typename OBJ, typename = typename Detail::EnableIfClass< OBJ >::type,
+                typename FUNC, typename ...PARAMS >
+        inline auto invokeOC(const std::shared_ptr<OBJ>& obj, FUNC&& fn, PARAMS&& ...params) ->
+            typename Detail::EnableIfTypeIs<
+                   decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)),
+                   Detail::NotOCStackResult>::
+                   type
+        {
+            try
+            {
+                return (obj.get()->*fn)(std::forward< PARAMS >(params)...);
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+        }
+
+    }
+}
+
+#endif // COMMON_INTERNAL_ASSERTUTILS_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/internal/PrimitiveResourceImpl.h b/service/resource-manipulation/modules/common/primitiveResource/include/internal/PrimitiveResourceImpl.h
new file mode 100644 (file)
index 0000000..d56d05d
--- /dev/null
@@ -0,0 +1,138 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
+#define COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
+
+#include <PrimitiveResource.h>
+#include <ResponseStatement.h>
+#include <internal/AssertUtils.h>
+
+#include <internal/ResourceAttributesConverter.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        template< typename BaseResource >
+        class PrimitiveResourceImpl: public PrimitiveResource
+        {
+        private:
+            using BaseResourcePtr = std::shared_ptr< BaseResource >;
+
+        private:
+            static ResponseStatement createResponseStatement(
+                    const OC::OCRepresentation& ocRepresentation)
+            {
+                return ResponseStatement::create(
+                        ResourceAttributesConverter::fromOCRepresentation(ocRepresentation));
+            }
+
+        public:
+            PrimitiveResourceImpl(const BaseResourcePtr& baseResource) :
+                    m_baseResource{ baseResource }
+            {
+            }
+
+            void requestGet(GetCallback callback) override
+            {
+                using namespace std::placeholders;
+
+                using GetFunc = OCStackResult(BaseResource::*)(
+                        const OC::QueryParamsMap&, OC::GetCallback);
+
+                invokeOC(m_baseResource, static_cast< GetFunc >(&BaseResource::get),
+                        OC::QueryParamsMap(),
+                        std::bind(callback, _1, std::bind(createResponseStatement, _2), _3));
+            }
+
+            void requestSet(const ResourceAttributes& attrs, SetCallback callback) override
+            {
+                using namespace std::placeholders;
+
+                using PutFunc = OCStackResult(BaseResource::*)(
+                        const OC::OCRepresentation&,
+                        const OC::QueryParamsMap&, OC::PutCallback);
+
+                invokeOC(m_baseResource, static_cast< PutFunc >(&BaseResource::put),
+                        ResourceAttributesConverter::toOCRepresentation(attrs),
+                        OC::QueryParamsMap{ },
+                        std::bind(callback, _1, std::bind(createResponseStatement, _2), _3));
+            }
+
+            void requestObserve(ObserveCallback callback) override
+            {
+                using namespace std::placeholders;
+
+                using ObserveFunc = OCStackResult (BaseResource::*)(OC::ObserveType,
+                        const OC::QueryParamsMap&, OC::ObserveCallback);
+
+                invokeOC(m_baseResource, static_cast< ObserveFunc >(&BaseResource::observe),
+                        OC::ObserveType::ObserveAll, OC::QueryParamsMap{ },
+                        bind(callback, _1, bind(createResponseStatement, _2), _3, _4));
+            }
+
+            void cancelObserve() override
+            {
+                using CancelObserveFunc = OCStackResult (BaseResource::*)();
+
+                invokeOC(m_baseResource,
+                        static_cast< CancelObserveFunc >(&BaseResource::cancelObserve));
+            }
+
+            std::string getSid() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::sid);
+            }
+
+            std::string getUri() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::uri);
+            }
+
+            std::string getHost() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::host);
+            }
+
+            std::vector< std::string > getTypes() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::getResourceTypes);
+            }
+
+            std::vector< std::string > getInterfaces() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::getResourceInterfaces);
+            }
+
+            bool isObservable() const override
+            {
+                return invokeOC(m_baseResource, &BaseResource::isObservable);
+            }
+
+        private:
+            BaseResourcePtr m_baseResource;
+        };
+
+    }
+}
+
+#endif // COMMON_INTERNAL_PRIMITIVERESOURCEIMPL_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesConverter.h b/service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesConverter.h
new file mode 100644 (file)
index 0000000..b17fc49
--- /dev/null
@@ -0,0 +1,164 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+#define COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
+
+#include <ResourceAttributes.h>
+
+#include <OCRepresentation.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class ResourceAttributesConverter
+        {
+        private:
+            ResourceAttributesConverter() = delete;
+
+            template< typename T >
+            using SupportedType = typename std::enable_if<
+                    ResourceAttributes::is_supported_type< T >::type::value, T >::type;
+
+            template< typename T >
+            using UnsupportedType = typename std::enable_if<
+                    !ResourceAttributes::is_supported_type< T >::type::value, T >::type;
+
+            class ResourceAttributesBuilder
+            {
+            public:
+                ResourceAttributesBuilder() = default;
+
+                void insertItemTo(const OC::OCRepresentation::AttributeItem& item)
+                {
+                    switch (item.type())
+                    {
+                        case OC::AttributeType::Null:
+                            return putValue(item.attrname(), nullptr);
+
+                        case OC::AttributeType::Integer:
+                            return putValue(item.attrname(), item.getValue< int >());
+
+                        case OC::AttributeType::Double:
+                            return putValue(item.attrname(), item.getValue< double >());
+
+                        case OC::AttributeType::Boolean:
+                            return putValue(item.attrname(), item.getValue< bool >());
+
+                        case OC::AttributeType::String:
+                            return putValue(item.attrname(), item.getValue< std::string >());
+
+                        case OC::AttributeType::OCRepresentation:
+                            return putValue(item.attrname(),
+                                    ResourceAttributesConverter::fromOCRepresentation(
+                                            item.getValue< OC::OCRepresentation >()));
+
+                        case OC::AttributeType::Vector:
+                            // ResourceAttributes doesn't support vector yet!
+                            return;
+                    }
+                }
+
+                ResourceAttributes&& extract()
+                {
+                    return std::move(m_target);
+                }
+
+            private:
+                template< typename T >
+                void putValue(const std::string key, T&& value)
+                {
+                    putValue< T >(key, std::forward< T >(value));
+                }
+
+                template< typename T >
+                void putValue(const std::string key, SupportedType< T > && value)
+                {
+                    m_target[key] = std::forward< T >(value);
+                }
+
+                template< typename T >
+                void putValue(const std::string key, UnsupportedType< T > && value)
+                {
+                }
+
+            private:
+                ResourceAttributes m_target;
+            };
+
+            class OCRepresentationBuilder
+            {
+            public:
+                OCRepresentationBuilder() = default;
+
+                template< typename T >
+                void operator()(const std::string& key, const T& value)
+                {
+                    m_target[key] = value;
+                }
+
+                void operator()(const std::string& key, const std::nullptr_t&)
+                {
+                    m_target.setNULL(key);
+                }
+
+                void operator()(const std::string& key, const ResourceAttributes& value)
+                {
+                    m_target[key] = ResourceAttributesConverter::toOCRepresentation(value);
+                }
+
+                OC::OCRepresentation&& extract()
+                {
+                    return std::move(m_target);
+                }
+
+            private:
+                OC::OCRepresentation m_target;
+            };
+
+        public:
+            static ResourceAttributes fromOCRepresentation(const OC::OCRepresentation& ocRepresentation)
+            {
+                ResourceAttributesBuilder builder;
+
+                for (const auto& item : ocRepresentation)
+                {
+                    builder.insertItemTo(item);
+                }
+
+                return builder.extract();
+            }
+
+            static OC::OCRepresentation toOCRepresentation(const ResourceAttributes& resourceAttributes)
+            {
+                OCRepresentationBuilder builder;
+
+                resourceAttributes.visit(builder);
+
+                return builder.extract();
+            }
+        };
+
+    }
+}
+
+#endif // COMMON_INTERNAL_RESOURCEATTRIBUTESCONVERTER_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesUtils.h b/service/resource-manipulation/modules/common/primitiveResource/include/internal/ResourceAttributesUtils.h
new file mode 100644 (file)
index 0000000..a61cd00
--- /dev/null
@@ -0,0 +1,40 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef COMMON_INTERNAL_RESOURCEATTRIBUTESUTILS_H
+#define COMMON_INTERNAL_RESOURCEATTRIBUTESUTILS_H
+
+namespace OIC
+{
+    namespace Service
+    {
+        bool acceptableAttributes(const ResourceAttributes& dest, const ResourceAttributes& attr);
+
+        bool acceptableAttributeValue(const ResourceAttributes::Value& dest,
+                const ResourceAttributes::Value& value);
+
+        void replaceAttributesRecursively(ResourceAttributes& dest, const ResourceAttributes& attr);
+
+        void replaceAttributeValueRecursively(ResourceAttributes::Value& dest,
+                const ResourceAttributes::Value& value);
+    }
+}
+
+#endif // COMMON_INTERNAL_RESOURCEATTRIBUTESUTILS_H
diff --git a/service/resource-manipulation/modules/common/primitiveResource/src/PresenceSubscriber.cpp b/service/resource-manipulation/modules/common/primitiveResource/src/PresenceSubscriber.cpp
new file mode 100644 (file)
index 0000000..2b35cb6
--- /dev/null
@@ -0,0 +1,121 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <PresenceSubscriber.h>
+
+#include <internal/AssertUtils.h>
+
+#include <OCPlatform.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler)
+        {
+            using SubscribePresence = OCStackResult (*)(OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, OCConnectivityType, SubscribeCallback);
+
+            invokeOCFunc(static_cast<SubscribePresence>(OC::OCPlatform::subscribePresence),
+                    handle, host, connectivityType, presenceHandler);
+        }
+
+        void subscribePresence(OCDoHandle& handle, const std::string& host,
+                const std::string& resourceType, OCConnectivityType connectivityType,
+                SubscribeCallback presenceHandler)
+        {
+            using SubscribePresence = OCStackResult (*)(OC::OCPlatform::OCPresenceHandle&,
+                    const std::string&, const std::string&, OCConnectivityType, SubscribeCallback);
+
+            invokeOCFunc(static_cast<SubscribePresence>(OC::OCPlatform::subscribePresence),
+                    handle, host, resourceType, connectivityType, presenceHandler);
+        }
+
+        void unsubscribePresence(OCDoHandle handle)
+        {
+            invokeOCFunc(OC::OCPlatform::unsubscribePresence, handle);
+        }
+
+
+        PresenceSubscriber::PresenceSubscriber() :
+            m_handle{ nullptr }
+        {
+        }
+
+        PresenceSubscriber::PresenceSubscriber(PresenceSubscriber&& from) :
+            m_handle{ nullptr }
+        {
+            std::swap(m_handle, from.m_handle);
+        }
+
+        PresenceSubscriber::PresenceSubscriber(const std::string& host,
+                OCConnectivityType connectivityType, SubscribeCallback presenceHandler) :
+                m_handle{ nullptr }
+        {
+            subscribePresence(m_handle, host, connectivityType, presenceHandler);
+        }
+
+        PresenceSubscriber::PresenceSubscriber(const std::string& host,
+                const std::string& resourceType, OCConnectivityType connectivityType,
+                SubscribeCallback presenceHandler) :
+                m_handle{ nullptr }
+        {
+            subscribePresence(m_handle, host, resourceType, connectivityType, presenceHandler);
+        }
+
+        PresenceSubscriber::~PresenceSubscriber()
+        {
+            if (m_handle)
+            {
+                try
+                {
+                    unsubscribe();
+                }
+                catch (...)
+                {
+                }
+            }
+        }
+
+        PresenceSubscriber& PresenceSubscriber::operator=(PresenceSubscriber&& from)
+        {
+            unsubscribe();
+            std::swap(m_handle, from.m_handle);
+            return *this;
+        }
+
+        void PresenceSubscriber::unsubscribe()
+        {
+            if (m_handle == nullptr) return;
+
+            unsubscribePresence(m_handle);
+
+            m_handle = nullptr;
+        }
+
+        bool PresenceSubscriber::isSubscribing() const
+        {
+            return m_handle != nullptr;
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/common/primitiveResource/src/PrimitiveResource.cpp b/service/resource-manipulation/modules/common/primitiveResource/src/PrimitiveResource.cpp
new file mode 100755 (executable)
index 0000000..0f18065
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <PrimitiveResource.h>
+
+#include <internal/PrimitiveResourceImpl.h>
+#include <internal/AssertUtils.h>
+
+#include <OCPlatform.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        PrimitiveResource::Ptr PrimitiveResource::create(
+                const std::shared_ptr<OC::OCResource>& ptr)
+        {
+            return std::shared_ptr< PrimitiveResource >(
+                    new PrimitiveResourceImpl< OC::OCResource >{ ptr });
+        }
+
+        void discoverResource(const std::string& host, const std::string& resourceURI,
+                OCConnectivityType connectivityType, DiscoverCallback callback)
+        {
+            using FindResource = OCStackResult (*)(const std::string&, const std::string&,
+                    OCConnectivityType, OC::FindCallback);
+
+            invokeOCFunc(static_cast<FindResource>(OC::OCPlatform::findResource),
+                    host, resourceURI, connectivityType, (OC::FindCallback) std::bind(callback,
+                           std::bind(&PrimitiveResource::create, std::placeholders::_1)));
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/common/primitiveResource/src/PrimtiveException.cpp b/service/resource-manipulation/modules/common/primitiveResource/src/PrimtiveException.cpp
new file mode 100644 (file)
index 0000000..ae1a99a
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <PrimitiveException.h>
+
+#include <OCException.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        PlatformException::PlatformException(OCStackResult reason) :
+            PrimitiveException{ "Failed : " + OC::OCException::reason(reason) },
+            m_reason { reason }
+        {
+        }
+
+        OCStackResult PlatformException::getReasonCode() const
+        {
+            return m_reason;
+        }
+
+        std::string PlatformException::getReason() const
+        {
+            return  OC::OCException::reason(m_reason);
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/common/primitiveResource/src/ResourceAttributes.cpp b/service/resource-manipulation/modules/common/primitiveResource/src/ResourceAttributes.cpp
new file mode 100755 (executable)
index 0000000..3b1b156
--- /dev/null
@@ -0,0 +1,442 @@
+//******************************************************************
+//
+// 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 <ResourceAttributes.h>
+
+#include <internal/ResourceAttributesUtils.h>
+#include <internal/ResourceAttributesConverter.h>
+
+#include <boost/lexical_cast.hpp>
+
+namespace
+{
+
+    class ToStringVisitor : public boost::static_visitor<std::string>
+    {
+    public:
+        ToStringVisitor() = default;
+        ToStringVisitor(const ToStringVisitor&) = delete;
+        ToStringVisitor(ToStringVisitor&&) = delete;
+
+        ToStringVisitor& operator=(const ToStringVisitor&) = delete;
+        ToStringVisitor& operator=(ToStringVisitor&&) = delete;
+
+        template < typename T >
+        std::string operator()(const T& value) const
+        {
+            return boost::lexical_cast<std::string>(value);
+        }
+
+        std::string operator()(std::nullptr_t) const
+        {
+            return "";
+        }
+
+        std::string operator()(bool value) const
+        {
+            return value ? "true" : "false";
+        }
+
+        std::string operator()(const std::string& value) const
+        {
+            return value;
+        }
+
+        std::string operator()(const OIC::Service::ResourceAttributes&) const
+        {
+            return "Attributes";
+        }
+    };
+
+} // unnamed namespace
+
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        bool operator==(const char* lhs, const ResourceAttributes::Value& rhs)
+        {
+            return rhs == lhs;
+        }
+
+        bool operator==(const ResourceAttributes::Value& lhs, const ResourceAttributes::Value& rhs)
+        {
+            return *lhs.m_data == *rhs.m_data;
+        }
+
+        bool operator==(const ResourceAttributes& lhs, const ResourceAttributes& rhs)
+        {
+            return lhs.m_values == rhs.m_values;
+        }
+
+        ResourceAttributes::Value::Value() :
+                m_data{ new ValueVariant{} }
+        {
+        }
+
+        ResourceAttributes::Value::Value(const Value& from) :
+                m_data{ new ValueVariant{ *from.m_data } }
+        {
+        }
+
+        ResourceAttributes::Value::Value(Value&& from) :
+                m_data{ new ValueVariant{} }
+        {
+            m_data->swap(*from.m_data);
+        }
+
+
+        auto ResourceAttributes::Value::operator=(const Value& rhs) -> Value&
+        {
+            *m_data = *rhs.m_data;
+            return *this;
+        }
+
+        auto ResourceAttributes::Value::operator=(Value&& rhs) -> Value&
+        {
+            *m_data = ValueVariant{};
+            m_data->swap(*rhs.m_data);
+            return *this;
+        }
+
+        auto ResourceAttributes::Value::operator=(const char* rhs) -> Value&
+        {
+            *m_data = std::string{ rhs };
+            return *this;
+        }
+
+        auto ResourceAttributes::Value::operator=(std::nullptr_t) -> Value&
+        {
+            *m_data = nullptr;
+            return *this;
+        }
+
+        bool ResourceAttributes::Value::operator==(const char* rhs) const
+        {
+            return equals< std::string >(rhs);
+        }
+
+        std::string ResourceAttributes::Value::toString() const
+        {
+            return boost::apply_visitor(ToStringVisitor(), *m_data);
+        }
+
+        auto ResourceAttributes::KeyValuePair::KeyVisitor::operator() (iterator* iter) const
+                -> result_type {
+            return iter->m_cur->first;
+        }
+
+        auto ResourceAttributes::KeyValuePair::KeyVisitor::operator() (const_iterator* iter) const
+                -> result_type {
+            return iter->m_cur->first;
+        }
+
+        auto ResourceAttributes::KeyValuePair::ValueVisitor::operator() (iterator* iter)
+                -> result_type {
+            return iter->m_cur->second;
+        }
+
+        auto ResourceAttributes::KeyValuePair::ValueVisitor::operator() (const_iterator* iter)
+                -> result_type {
+            // should not reach here.
+            throw BadGetException("");
+        }
+
+        auto ResourceAttributes::KeyValuePair::ConstValueVisitor::operator() (iterator*iter) const
+                -> result_type {
+            return iter->m_cur->second;
+        }
+
+        auto ResourceAttributes::KeyValuePair::ConstValueVisitor::operator() (const_iterator* iter) const
+                -> result_type {
+            return iter->m_cur->second;
+        }
+
+        auto ResourceAttributes::KeyValuePair::key() const -> const std::string&
+        {
+            return boost::apply_visitor(m_keyVisitor, m_iterRef);
+        }
+
+        auto ResourceAttributes::KeyValuePair::value() const -> const Value&
+        {
+            return boost::apply_visitor(m_constValueVisitor, m_iterRef);
+        }
+
+        auto ResourceAttributes::KeyValuePair::value() -> Value&
+        {
+            return boost::apply_visitor(m_valueVisitor, m_iterRef);
+        }
+
+
+        ResourceAttributes::KeyValuePair::KeyValuePair(boost::variant<iterator*, const_iterator*>&& ref) :
+                m_iterRef{ ref }
+        {
+        }
+
+
+        ResourceAttributes::iterator::iterator() :
+                iterator{ base_iterator{} }
+        {
+        }
+
+        ResourceAttributes::iterator::iterator(base_iterator&& iter) :
+                m_cur{ std::move(iter) },
+                m_keyValuePair{ this }
+        {
+        }
+
+        auto ResourceAttributes::iterator::operator*() -> KeyValuePair&
+        {
+            return m_keyValuePair;
+        }
+
+        auto ResourceAttributes::iterator::iterator::operator->() -> KeyValuePair*
+        {
+            return &m_keyValuePair;
+        }
+
+        auto ResourceAttributes::iterator::operator++() -> iterator&
+        {
+            ++m_cur;
+            return *this;
+        }
+
+        auto ResourceAttributes::iterator::operator++(int) -> iterator
+        {
+            iterator iter(*this);
+            ++(*this);
+            return iter;
+        }
+
+        bool ResourceAttributes::iterator::operator==(const iterator& rhs) const
+        {
+            return m_cur == rhs.m_cur;
+        }
+
+        bool ResourceAttributes::iterator::operator!=(const iterator& rhs) const
+        {
+            return !(*this == rhs);
+        }
+
+
+        ResourceAttributes::const_iterator::const_iterator() :
+                const_iterator{ base_iterator{} }
+        {
+        }
+
+        ResourceAttributes::const_iterator::const_iterator(base_iterator&& iter) :
+                m_cur{ iter }, m_keyValuePair{ this }
+        {
+        }
+
+        ResourceAttributes::const_iterator::const_iterator(const ResourceAttributes::iterator& iter) :
+                m_cur{ iter.m_cur }, m_keyValuePair{ this }
+        {
+        }
+
+        auto ResourceAttributes::const_iterator::operator=(const ResourceAttributes::iterator& iter) -> const_iterator& {
+            m_cur = iter.m_cur;
+            return *this;
+        }
+
+        auto ResourceAttributes::const_iterator::operator*() const -> reference
+        {
+            return m_keyValuePair;
+        }
+        auto ResourceAttributes::const_iterator::operator->() const -> pointer
+        {
+            return &m_keyValuePair;
+        }
+
+        auto ResourceAttributes::const_iterator::operator++() -> const_iterator&
+        {
+            ++m_cur;
+            return *this;
+        }
+
+        auto ResourceAttributes::const_iterator::operator++(int) -> const_iterator
+        {
+            const_iterator iter(*this);
+            ++(*this);
+            return iter;
+        }
+
+        bool ResourceAttributes::const_iterator::operator==(const const_iterator& rhs) const
+        {
+            return m_cur == rhs.m_cur;
+        }
+
+        bool ResourceAttributes::const_iterator::operator!=(const const_iterator& rhs) const
+        {
+            return !(*this == rhs);
+        }
+
+        auto ResourceAttributes::begin() -> iterator
+        {
+            return iterator{ m_values.begin() };
+        }
+
+        auto ResourceAttributes::end() -> iterator
+        {
+            return iterator{ m_values.end() };
+        }
+
+        auto ResourceAttributes::begin() const -> const_iterator
+        {
+            return const_iterator{ m_values.begin() };
+        }
+
+        auto ResourceAttributes::end() const -> const_iterator
+        {
+            return const_iterator{ m_values.end() };
+        }
+
+        auto ResourceAttributes::cbegin() const -> const_iterator
+        {
+            return const_iterator{ m_values.begin() };
+        }
+
+        auto ResourceAttributes::cend() const -> const_iterator
+        {
+            return const_iterator{ m_values.end() };
+        }
+
+        auto ResourceAttributes::operator[](const std::string& key) -> Value&
+        {
+            return m_values[key];
+        }
+
+        auto ResourceAttributes::operator[](std::string&& key) -> Value&
+        {
+            return m_values[std::move(key)];
+        }
+
+        auto ResourceAttributes::at(const std::string& key) -> Value&
+        {
+            try
+            {
+                return m_values.at(key);
+            }
+            catch (const std::out_of_range&)
+            {
+                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+            }
+        }
+
+        auto ResourceAttributes::at(const std::string& key) const -> const Value&
+        {
+            try
+            {
+                return m_values.at(key);
+            }
+            catch (const std::out_of_range&)
+            {
+                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+            }
+        }
+
+        bool ResourceAttributes::erase(const std::string& key)
+        {
+            return m_values.erase(key) == 1U;
+        }
+
+        bool ResourceAttributes::contains(const std::string& key) const
+        {
+            return m_values.find(key) != m_values.end();
+        }
+
+        bool ResourceAttributes::empty() const
+        {
+            return m_values.empty();
+        }
+
+        size_t ResourceAttributes::size() const
+        {
+            return m_values.size();
+        }
+
+
+        bool acceptableAttributeValue(const ResourceAttributes::Value& dest,
+                const ResourceAttributes::Value& value)
+        {
+            if (!dest.isTypeEqualWith(value))
+            {
+                return false;
+            }
+
+            static_assert(ResourceAttributes::is_supported_type< ResourceAttributes >::value,
+                    "ResourceAttributes doesn't have ResourceAttributes recursively.");
+
+            if (dest.isTypeOf< ResourceAttributes >()
+                    && !acceptableAttributes(dest.get< ResourceAttributes >(),
+                            value.get< ResourceAttributes >()))
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        bool acceptableAttributes(const ResourceAttributes& dest, const ResourceAttributes& attr)
+        {
+            for (const auto& kv : attr)
+            {
+                if (!dest.contains(kv.key()))
+                {
+                    return false;
+                }
+
+                if (!acceptableAttributeValue(dest.at(kv.key()), kv.value()))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        void replaceAttributeValueRecursively(ResourceAttributes::Value& dest,
+                     const ResourceAttributes::Value& value)
+        {
+            static_assert(ResourceAttributes::is_supported_type< ResourceAttributes >::value,
+                    "ResourceAttributes doesn't have ResourceAttributes recursively.");
+
+            if (dest.isTypeOf< ResourceAttributes >())
+            {
+                replaceAttributesRecursively(dest.get< ResourceAttributes >(),
+                        value.get< ResourceAttributes >());
+            }
+            else
+            {
+                dest = value;
+            }
+        }
+
+        void replaceAttributesRecursively(ResourceAttributes& dest, const ResourceAttributes& attr)
+        {
+            for (const auto& kv : attr)
+            {
+                replaceAttributeValueRecursively(dest[kv.key()], kv.value());
+            }
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/common/primitiveResource/src/ResponseStatement.cpp b/service/resource-manipulation/modules/common/primitiveResource/src/ResponseStatement.cpp
new file mode 100644 (file)
index 0000000..41299af
--- /dev/null
@@ -0,0 +1,82 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <ResponseStatement.h>
+
+#include <internal/ResourceAttributesConverter.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResponseStatement ResponseStatement::create(const OC::OCRepresentation& ocRepresentation)
+        {
+            return ResponseStatement::create(
+                    ResourceAttributesConverter::fromOCRepresentation(ocRepresentation));
+        }
+
+        ResponseStatement ResponseStatement::create(ResourceAttributes&& attrs)
+        {
+            return ResponseStatement(std::move(attrs));
+        }
+
+        ResponseStatement::ResponseStatement(const ResourceAttributes& attrs) :
+                m_attrs{ attrs }
+        {
+        }
+
+        ResponseStatement::ResponseStatement(ResourceAttributes&& attrs) :
+                ResponseStatement{ std::move(attrs), "", { }, { } }
+        {
+        }
+
+        ResponseStatement::ResponseStatement(ResourceAttributes&& attrs, std::string&& uri,
+                std::vector< std::string >&& resourceTypes,
+                std::vector< std::string >&& resourceInterfaces) :
+                m_attrs{ std::move(attrs) },
+                m_uri{ std::move(uri) },
+                m_resourceTypes { std::move(resourceTypes) },
+                m_resourceInterfaces{ std::move(resourceInterfaces) }
+        {
+        }
+
+        std::string ResponseStatement::getUri() const
+        {
+            return m_uri;
+        }
+
+        std::vector< std::string > ResponseStatement::getResourceTypes() const
+        {
+            return m_resourceTypes;
+        }
+
+        std::vector< std::string > ResponseStatement::getResourceInterfaces() const
+        {
+            return m_resourceInterfaces;
+        }
+
+        const ResourceAttributes& ResponseStatement::getAttributes() const
+        {
+            return m_attrs;
+        }
+
+    }
+}
+
diff --git a/service/resource-manipulation/modules/common/primitiveResource/unittests/PresenceSubscriberTest.cpp b/service/resource-manipulation/modules/common/primitiveResource/unittests/PresenceSubscriberTest.cpp
new file mode 100644 (file)
index 0000000..dd204ce
--- /dev/null
@@ -0,0 +1,172 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include <PresenceSubscriber.h>
+#include <PrimitiveException.h>
+
+#include <OCPlatform.h>
+
+using namespace testing;
+using namespace OIC::Service;
+
+typedef OCStackResult (*subscribePresenceSig1)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, OCConnectivityType, SubscribeCallback);
+typedef OCStackResult (*subscribePresenceSig2)(OC::OCPlatform::OCPresenceHandle&,
+        const std::string&, const std::string&, OCConnectivityType, SubscribeCallback);
+
+const std::string HOST{ "host" };
+const OCConnectivityType CONTYPE{ };
+
+class PresenceSubscriberNonMemberTest: public Test
+{
+public:
+    OCDoHandle handle;
+    MockRepository mocks;
+
+};
+
+TEST_F(PresenceSubscriberNonMemberTest, OCPlatformSubscribePresenceWillBeCalled)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence))
+                        .With(_, HOST,CONTYPE, _).Return(OC_STACK_OK);
+
+    subscribePresence(handle, HOST, CONTYPE, SubscribeCallback());
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, SubscribePresenceThrowsIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< subscribePresenceSig1>(OC::OCPlatform::subscribePresence))
+                    .Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(subscribePresence(handle, "", CONTYPE, SubscribeCallback()), PlatformException);
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, OCPlatformUnsubscribePresenceWillBeCalled)
+{
+    mocks.ExpectCallFuncOverload(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+
+    unsubscribePresence(handle);
+}
+
+TEST_F(PresenceSubscriberNonMemberTest, UnsubscribePresenceThrowIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(unsubscribePresence(handle), PlatformException);
+}
+
+
+
+class PresenceSubscriberTest: public Test
+{
+public:
+    MockRepository mocks;
+
+protected:
+    void SetUp() override {
+        mocks.OnCallFuncOverload(
+                static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence)).Do(
+
+            [](OC::OCPlatform::OCPresenceHandle& handle, const std::string&,
+                    OCConnectivityType, SubscribeCallback) -> OCStackResult
+            {
+                handle = reinterpret_cast<OC::OCPlatform::OCPresenceHandle>(1);
+                return OC_STACK_OK;
+            }
+        );
+
+        mocks.OnCallFunc(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(PresenceSubscriberTest, IsNotSubscribingWhenCreatedWithDefaultConstructor)
+{
+    PresenceSubscriber subscriber;
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorCallOCPlatformSubscribe)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence))
+                     .With(_, HOST, CONTYPE, _).Return(OC_STACK_OK);
+
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorWithResourceTypeCallOCPlatformSubscribe)
+{
+    const std::string resType { "resType" };
+
+    mocks.ExpectCallFuncOverload(
+            static_cast< subscribePresenceSig2 >(OC::OCPlatform::subscribePresence))
+                     .With(_, HOST, resType, CONTYPE, _).Return(OC_STACK_OK);
+
+    PresenceSubscriber subscriber{ HOST, resType, CONTYPE, SubscribeCallback() };
+}
+
+TEST_F(PresenceSubscriberTest, ConstructorThrowsIfResultIsNotOK)
+{
+    mocks.ExpectCallFuncOverload(
+            static_cast< subscribePresenceSig1 >(OC::OCPlatform::subscribePresence))
+                    .Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(PresenceSubscriber(HOST, CONTYPE, SubscribeCallback()), PlatformException);
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingIfConstructedWithoutException)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    ASSERT_TRUE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingOfMovedSubscriberReturnsFalse)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    PresenceSubscriber newSubscriber{ std::move(subscriber) };
+
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, IsSubscribingOfMovedSubscriberWithAssignmentReturnsFalse)
+{
+    PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+
+    PresenceSubscriber newSubscriber;
+
+    newSubscriber = std::move(subscriber);
+
+    ASSERT_FALSE(subscriber.isSubscribing());
+}
+
+TEST_F(PresenceSubscriberTest, UnsubscribeWillBeCalledWhenSubscriberIsDestoryed)
+{
+    mocks.ExpectCallFunc(OC::OCPlatform::unsubscribePresence).Return(OC_STACK_OK);
+    {
+        PresenceSubscriber subscriber{ HOST, CONTYPE, SubscribeCallback() };
+    }
+}
diff --git a/service/resource-manipulation/modules/common/primitiveResource/unittests/PrimitiveResourceTest.cpp b/service/resource-manipulation/modules/common/primitiveResource/unittests/PrimitiveResourceTest.cpp
new file mode 100644 (file)
index 0000000..a0ec6f3
--- /dev/null
@@ -0,0 +1,219 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include <internal/PrimitiveResourceImpl.h>
+#include <internal/AssertUtils.h>
+
+#include <OCResource.h>
+#include <OCPlatform.h>
+
+using namespace testing;
+using namespace OIC::Service;
+
+const std::string KEY{ "key" };
+
+class FakeOCResource
+{
+public:
+    virtual ~FakeOCResource() = default;
+
+    virtual OCStackResult get(const OC::QueryParamsMap&, OC::GetCallback) = 0;
+
+    virtual OCStackResult put(
+            const OC::OCRepresentation&, const OC::QueryParamsMap&, OC::PutCallback) = 0;
+
+    virtual OCStackResult observe(
+            OC::ObserveType, const OC::QueryParamsMap&, OC::ObserveCallback) = 0;
+
+    virtual OCStackResult cancelObserve() = 0;
+
+    virtual std::string sid() const = 0;
+    virtual std::string uri() const = 0;
+    virtual std::string host() const = 0;
+    virtual std::vector<std::string> getResourceTypes() const = 0;
+    virtual std::vector<std::string> getResourceInterfaces() const = 0;
+
+    virtual bool isObservable() const = 0;
+};
+
+class PrimitiveResourceTest: public Test
+{
+public:
+    MockRepository mocks;
+    PrimitiveResource::Ptr resource;
+    FakeOCResource* fakeResource;
+
+protected:
+    void SetUp() override {
+        fakeResource = mocks.Mock< FakeOCResource >();
+
+        resource.reset(new PrimitiveResourceImpl< FakeOCResource >{
+            std::shared_ptr< FakeOCResource >(fakeResource, [](FakeOCResource*) {}) });
+    }
+
+    void TearDown() override {
+    }
+};
+
+TEST_F(PrimitiveResourceTest, RequestGetInvokesOCResourceGet)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::get).Return(OC_STACK_OK);
+
+    resource->requestGet(PrimitiveResource::GetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestGetThrowsOCResourceGetReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::get).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestGet(PrimitiveResource::GetCallback()), PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetInvokesOCResourcePut)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::put).Return(OC_STACK_OK);
+
+    resource->requestSet(ResourceAttributes(), PrimitiveResource::SetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetThrowsOCResourcePutReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::put).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestSet(ResourceAttributes(), PrimitiveResource::SetCallback()),
+            PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, RequestSetPassResourceAttributesToOCResourcePut)
+{
+    constexpr int value{ -200 };
+
+    ResourceAttributes attrs;
+
+    mocks.ExpectCall(fakeResource, FakeOCResource::put).Match(
+            [](const OC::OCRepresentation& ocRep, const OC::QueryParamsMap&, OC::PutCallback)
+            {
+                return ocRep.getValue<int>(KEY) == value;
+            }
+        ).Return(OC_STACK_OK);
+
+    attrs[KEY] = value;
+
+    resource->requestSet(attrs, PrimitiveResource::SetCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestObserveInvokesOCResourceObserve)
+{
+    mocks.ExpectCall(fakeResource, FakeOCResource::observe).Return(OC_STACK_OK);
+
+    resource->requestObserve(PrimitiveResource::ObserveCallback());
+}
+
+TEST_F(PrimitiveResourceTest, RequestObserveThrowsOCResourceObserveReturnsNotOK)
+{
+    mocks.OnCall(fakeResource, FakeOCResource::observe).Return(OC_STACK_ERROR);
+
+    ASSERT_THROW(resource->requestObserve(PrimitiveResource::ObserveCallback()), PlatformException);
+}
+
+TEST_F(PrimitiveResourceTest, DelegteGettersToOCResource)
+{
+    const std::string host{ "host_test_" };
+    const std::string uri{ "uri/test/" };
+
+    mocks.OnCall(fakeResource, FakeOCResource::isObservable).Return(false);
+    mocks.OnCall(fakeResource, FakeOCResource::host).Return(host);
+    mocks.OnCall(fakeResource, FakeOCResource::uri).Return(uri);
+
+    ASSERT_FALSE(resource->isObservable());
+    ASSERT_EQ(host, resource->getHost());
+    ASSERT_EQ(uri, resource->getUri());
+}
+
+
+TEST_F(PrimitiveResourceTest, ResponseStatementHasSameValuesWithOCRepresentationReceived)
+{
+    constexpr int errorCode{ 202 };
+    constexpr int value{ 1999 };
+
+    mocks.OnCall(fakeResource, FakeOCResource::get).Do(
+            [](const OC::QueryParamsMap&, OC::GetCallback cb)
+            {
+                OC::OCRepresentation ocRep;
+                ocRep[KEY] = value;
+
+                cb(OC::HeaderOptions(), ocRep, errorCode);
+                return OC_STACK_OK;
+            }
+        ).Return(OC_STACK_OK);
+
+    resource->requestGet(
+            [&](const HeaderOptions&, const ResponseStatement& response, int e)
+            {
+                ASSERT_EQ(e, errorCode);
+                ASSERT_EQ(response.getAttributes().at(KEY).get<int>(), value);
+            }
+        );
+}
+
+
+class DiscoverResourceTest: public Test
+{
+public:
+    MockRepository mocks;
+
+    typedef OCStackResult (*FindResource)(const std::string&, const std::string&,
+            OCConnectivityType, OC::FindCallback);
+
+    static void discovered(std::shared_ptr< PrimitiveResource >)
+    {
+    }
+
+};
+
+
+
+TEST_F(DiscoverResourceTest, CallbackIsInvokedWhenResourceIsDiscovered)
+{
+    mocks.ExpectCallFuncOverload(static_cast<FindResource>(OC::OCPlatform::findResource)).Do(
+            [](const std::string&, const std::string&, OCConnectivityType,
+                    OC::FindCallback callback) -> OCStackResult
+            {
+                callback(nullptr);
+                return OC_STACK_OK;
+            }
+        ).Return(OC_STACK_OK);
+
+    mocks.ExpectCallFunc(discovered);
+
+    discoverResource("", "", OCConnectivityType{ }, discovered);
+}
+
+TEST_F(DiscoverResourceTest, ThrowsdWhenOCPlatformFindResourceReturnsNotOK)
+{
+    mocks.ExpectCallFuncOverload(static_cast<FindResource>(OC::OCPlatform::findResource)).
+            Return(OC_STACK_ERROR);
+
+    EXPECT_THROW(discoverResource("", "", OCConnectivityType{ }, discovered), PlatformException);
+}
+
diff --git a/service/resource-manipulation/modules/common/primitiveResource/unittests/ResourceAttributesTest.cpp b/service/resource-manipulation/modules/common/primitiveResource/unittests/ResourceAttributesTest.cpp
new file mode 100644 (file)
index 0000000..30aaf1c
--- /dev/null
@@ -0,0 +1,394 @@
+//******************************************************************
+//
+// 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 <ResourceAttributes.h>
+#include <internal/ResourceAttributesConverter.h>
+#include <internal/ResourceAttributesUtils.h>
+
+#include <gtest/gtest.h>
+
+using namespace testing;
+using namespace OIC::Service;
+
+constexpr char KEY[]{ "key" };
+
+class ResourceAttributesTest: public Test
+{
+public:
+    ResourceAttributes resourceAttributes;
+};
+
+TEST_F(ResourceAttributesTest, InitialSizeIsZero)
+{
+    ASSERT_EQ(0U, resourceAttributes.size());
+    ASSERT_TRUE(resourceAttributes.empty());
+}
+
+TEST_F(ResourceAttributesTest, InsertWithSquareBracket)
+{
+    resourceAttributes[KEY] = 1;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == 1);
+}
+
+TEST_F(ResourceAttributesTest, ValueThrowsIfTypeDoesNotMatch)
+{
+     resourceAttributes[KEY] = 1;
+    auto& valueRef = resourceAttributes[KEY];
+
+    ASSERT_THROW(valueRef.get< std::string >(), BadGetException);
+}
+
+TEST_F(ResourceAttributesTest, GettingWithAtThrowsIfThereIsNoMatchedValue)
+{
+    ASSERT_THROW(resourceAttributes.at(KEY), InvalidKeyException);
+}
+
+TEST_F(ResourceAttributesTest, CopyingValueDoesNotShareState)
+{
+    const char arbitraryStr[] { "ftryb457" };
+    resourceAttributes[KEY] = 1;
+
+    ResourceAttributes::Value copied { resourceAttributes[KEY] };
+    copied = arbitraryStr;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == 1);
+    ASSERT_TRUE(copied == arbitraryStr);
+}
+
+TEST_F(ResourceAttributesTest, IsNullWhenAssignmentNullptr)
+{
+    resourceAttributes[KEY] = nullptr;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == nullptr);
+}
+
+TEST_F(ResourceAttributesTest, ValueChangedIfPutWithSameKey)
+{
+    resourceAttributes[KEY] = "string";
+    resourceAttributes[KEY] = true;
+
+    ASSERT_TRUE(resourceAttributes[KEY] == true);
+}
+
+TEST_F(ResourceAttributesTest, ObjectIsEmptyAfterMoved)
+{
+    resourceAttributes[KEY] = 1;
+
+    ResourceAttributes moved{ std::move(resourceAttributes) };
+
+    ASSERT_TRUE(resourceAttributes.empty());
+}
+
+TEST_F(ResourceAttributesTest, GettingWithAtThrowsAfterRemoved)
+{
+    resourceAttributes[KEY] = 1;
+
+    resourceAttributes.erase(KEY);
+
+    ASSERT_THROW(resourceAttributes.at(KEY), InvalidKeyException);
+}
+
+TEST_F(ResourceAttributesTest, NoDataErasedIfKeyDoesNotMatch)
+{
+    ASSERT_FALSE(resourceAttributes.erase(KEY));
+}
+
+TEST_F(ResourceAttributesTest, ChangeValueWithAtGetter)
+{
+    resourceAttributes[KEY] = 1;
+
+    resourceAttributes.at(KEY) = "after";
+
+    ASSERT_TRUE(resourceAttributes[KEY] == "after");
+}
+
+TEST_F(ResourceAttributesTest, CanHaveNestedResourceAttributes)
+{
+    ResourceAttributes nested;
+    nested["nested"] = "nested_value";
+    resourceAttributes[KEY] = nested;
+
+    ASSERT_TRUE("nested_value" == resourceAttributes[KEY].get<ResourceAttributes>()["nested"]);
+}
+
+TEST_F(ResourceAttributesTest, ToStringReturnsStringForValue)
+{
+    resourceAttributes[KEY] = true;
+
+    ASSERT_EQ("true", resourceAttributes[KEY].toString());
+}
+
+TEST_F(ResourceAttributesTest, ToStringReturnsEmptyStringForNullValue)
+{
+    resourceAttributes[KEY] = nullptr;
+
+    ASSERT_EQ("", resourceAttributes[KEY].toString());
+}
+
+
+class ResourceAttributesIteratorTest: public Test
+{
+public:
+    ResourceAttributes resourceAttributes;
+};
+
+TEST_F(ResourceAttributesIteratorTest, BeginEqualsEndWhenEmpty)
+{
+    ASSERT_TRUE(resourceAttributes.begin() == resourceAttributes.end());
+}
+
+TEST_F(ResourceAttributesIteratorTest, CanIteratesWithForeach)
+{
+    resourceAttributes["first"] = 1;
+    resourceAttributes["second"] = 2;
+
+    int count = 0;
+
+    for (auto& i : resourceAttributes) {
+        i.key();
+        ++count;
+    }
+
+    ASSERT_EQ(2, count);
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratesWithRef)
+{
+    const char arbitraryStr[] { "ftryb457" };
+    resourceAttributes[KEY] = 1;
+
+    for (auto& i : resourceAttributes) {
+        i.value() = arbitraryStr;
+    }
+
+    ASSERT_TRUE(resourceAttributes[KEY] == arbitraryStr);
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorIsCopyable)
+{
+    ResourceAttributes::iterator it;
+
+    it = resourceAttributes.begin();
+
+    ASSERT_EQ(it, resourceAttributes.begin());
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorIndicateNextItemAfterIncreased)
+{
+    resourceAttributes[KEY] = 1;
+
+    ResourceAttributes::iterator it = resourceAttributes.begin();
+
+    it++;
+
+    ASSERT_TRUE(it == resourceAttributes.end());
+}
+
+TEST_F(ResourceAttributesIteratorTest, IteratorCanBeConvertedIntoConstIterator)
+{
+    resourceAttributes[KEY] = 1;
+    ResourceAttributes::const_iterator it { resourceAttributes.begin() };
+    it = resourceAttributes.cbegin();
+
+    it++;
+
+    ASSERT_TRUE(it == resourceAttributes.cend());
+}
+
+TEST_F(ResourceAttributesIteratorTest, ConstIteratorIsUsedForConst)
+{
+    resourceAttributes[KEY] = 1;
+    const ResourceAttributes& constAttrs = resourceAttributes;
+
+    auto iter = constAttrs.begin();
+
+    ASSERT_TRUE((std::is_same<decltype(iter), ResourceAttributes::const_iterator>::value));
+}
+
+
+TEST(ResourceAttributesValueTest, MovedValueHasNull)
+{
+    ResourceAttributes::Value one { 1 };
+    ResourceAttributes::Value another { std::move(one) };
+
+    ASSERT_EQ(nullptr, one);
+}
+
+TEST(ResourceAttributesValueTest, MovedValueWithAssignmentHasNull)
+{
+    ResourceAttributes::Value one { 1 };
+    ResourceAttributes::Value another;
+
+    another = std::move(one);
+
+    ASSERT_EQ(nullptr, one);
+}
+
+TEST(ResourceAttributesValueTest, SameValuesAreEqual)
+{
+    ResourceAttributes::Value one { 1 };
+    ResourceAttributes::Value another { 1 };
+
+    ASSERT_EQ(one, another);
+}
+
+
+
+
+TEST(ResourceAttributesConverterTest, OCRepresentationCanBeConvertedIntoResourceAttributes)
+{
+    constexpr double value = 9876;
+    OC::OCRepresentation ocRep;
+    ocRep[KEY] = value;
+
+    ResourceAttributes resourceAttributes = ResourceAttributesConverter::fromOCRepresentation(ocRep);
+
+    ASSERT_TRUE(value == resourceAttributes[KEY]);
+}
+
+
+TEST(ResourceAttributesConverterTest, NestedOCRepresentationCanBeConvertedIntoResourceAttributes)
+{
+    std::string nested_value { "nested" };
+    OC::OCRepresentation ocRep;
+    OC::OCRepresentation nested;
+    nested[KEY] = nested_value;
+    ocRep[KEY] = nested;
+
+    ResourceAttributes resourceAttributes = ResourceAttributesConverter::fromOCRepresentation(ocRep);
+
+    ASSERT_TRUE(nested_value == resourceAttributes[KEY].get<ResourceAttributes>()[KEY]);
+}
+
+
+TEST(ResourceAttributesConverterTest, ResourceAttributesCanBeConvertedIntoOCRepresentation)
+{
+    double value { 3453453 };
+    ResourceAttributes resourceAttributes;
+    resourceAttributes[KEY] = value;
+
+    OC::OCRepresentation ocRep = ResourceAttributesConverter::toOCRepresentation(resourceAttributes);
+
+    ASSERT_TRUE(value == ocRep[KEY].getValue<double>());
+}
+
+TEST(ResourceAttributesConverterTest, NestedResourceAttributesCanBeConvertedIntoOCRepresentation)
+{
+    std::string nested_value { "nested" };
+    ResourceAttributes resourceAttributes;
+    ResourceAttributes nested;
+    nested[KEY] = nested_value;
+    resourceAttributes[KEY] = nested;
+
+    OC::OCRepresentation ocRep = ResourceAttributesConverter::toOCRepresentation(resourceAttributes);
+
+    ASSERT_TRUE(nested_value == ocRep[KEY].getValue<OC::OCRepresentation>()[KEY].getValue<std::string>());
+}
+
+TEST(ResourceAttributesConverterTest, OCRepresentationNullTypeIsNullptrInResourceAttributes)
+{
+    OC::OCRepresentation ocRep;
+    ocRep.setNULL(KEY);
+
+    ResourceAttributes resourceAttributes = ResourceAttributesConverter::fromOCRepresentation(ocRep);
+
+    ASSERT_EQ(nullptr, resourceAttributes[KEY]);
+}
+
+TEST(ResourceAttributesConverterTest, OCRepresentationHasNullWhenResourceAttributeIsNullptr)
+{
+    ResourceAttributes resourceAttributes;
+    resourceAttributes[KEY] = nullptr;
+
+    OC::OCRepresentation ocRep = ResourceAttributesConverter::toOCRepresentation(resourceAttributes);
+
+    ASSERT_TRUE(ocRep.isNULL(KEY));
+}
+
+
+
+class ResourceAttributesUtilTest: public Test
+{
+public:
+    ResourceAttributes resourceAttributes;
+
+protected:
+    void SetUp() override
+    {
+        resourceAttributes[KEY] = 1;
+    }
+};
+
+TEST_F(ResourceAttributesUtilTest, EmptyAttributesIsAcceptable)
+{
+    ASSERT_TRUE(acceptableAttributes(resourceAttributes, ResourceAttributes()));
+}
+
+TEST_F(ResourceAttributesUtilTest, AttributesItselfIsAcceptable)
+{
+    ASSERT_TRUE(acceptableAttributes(resourceAttributes, resourceAttributes));
+}
+
+TEST_F(ResourceAttributesUtilTest, UnknownKeyIsNotAcceptable)
+{
+    ResourceAttributes newAttrs;
+    newAttrs["unknown"] = 1;
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+TEST_F(ResourceAttributesUtilTest, DifferentTypeWithOriginalIsNotAcceptable)
+{
+    ResourceAttributes newAttrs;
+    newAttrs[KEY] = "";
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+
+TEST_F(ResourceAttributesUtilTest, DifferentTypeOfNestedAttributeIsNotAcceptable)
+{
+    constexpr char KEY_NESTED_ATTR[]{ "nested" };
+    constexpr char KEY_NESTED_VALUE[]{ "nested_value" };
+
+    ResourceAttributes nested;
+    nested[KEY_NESTED_VALUE] = -99;
+    resourceAttributes[KEY_NESTED_ATTR] = nested;
+
+
+    ResourceAttributes newAttrs;
+    nested[KEY_NESTED_VALUE] = "abc";
+    newAttrs[KEY_NESTED_ATTR] = nested;
+
+    ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
+}
+
+TEST_F(ResourceAttributesUtilTest, ReplaceWillOverwriteOriginal)
+{
+    constexpr char NEW_VALUE[]{ "newValue" };
+
+    ResourceAttributes newAttrs;
+    newAttrs[KEY] = NEW_VALUE;
+
+    replaceAttributesRecursively(resourceAttributes, newAttrs);
+
+    ASSERT_EQ(NEW_VALUE, resourceAttributes[KEY]);
+}
diff --git a/service/resource-manipulation/modules/resourceBroker/SConscript b/service/resource-manipulation/modules/resourceBroker/SConscript
new file mode 100755 (executable)
index 0000000..ce90192
--- /dev/null
@@ -0,0 +1,81 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceBroker 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')
+resourcebroker_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+resourcebroker_env.AppendUnique(CPPPATH = ['include'])
+resourcebroker_env.AppendUnique(CPPPATH = ['../common/primitiveResource/include'])
+resourcebroker_env.AppendUnique(CPPPATH = ['../common/primitiveTimer/include'])
+resourcebroker_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+resourcebroker_env.PrependUnique(LIBS = ['service_common', 'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+
+
+if target_os not in ['windows', 'winrt']:
+    resourcebroker_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os == 'linux':
+    resourcebroker_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+BROKER_SRC_DIR = 'src/'
+resourcebroker_src = [
+        BROKER_SRC_DIR + 'DeviceAssociation.cpp',
+        BROKER_SRC_DIR + 'DevicePresence.cpp',
+        BROKER_SRC_DIR + 'ResourcePresence.cpp',
+        BROKER_SRC_DIR + 'ResourceBroker.cpp',
+        BROKER_SRC_DIR + '../../common/primitiveTimer/src/PrimitiveTimer.cpp',
+        BROKER_SRC_DIR + '../../common/primitiveTimer/src/PrimitiveTimer_Impl.cpp'
+        ]
+
+
+if target_os in ['tizen','android'] :
+    resourcebrokersdk = resourcebroker_env.SharedLibrary('ResourceBroker', resourcebroker_src)
+else :
+    resourcebrokersdk = resourcebroker_env.StaticLibrary('ResourceBroker', resourcebroker_src)
+
+resourcebroker_env.InstallTarget(resourcebrokersdk, 'libResouceBroker')
+
+# Go to build sample apps
+#SConscript('SampleApp/SConscript')
+
+
diff --git a/service/resource-manipulation/modules/resourceBroker/include/BrokerTypes.h b/service/resource-manipulation/modules/resourceBroker/include/BrokerTypes.h
new file mode 100755 (executable)
index 0000000..2ff1303
--- /dev/null
@@ -0,0 +1,116 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BROKERTYPES_H_
+#define BROKERTYPES_H_
+
+#include <iostream>
+#include <functional>
+#include <list>
+
+#include "logger.h"
+#include "PrimitiveResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        #define BROKER_TAG PCF("BROKER")
+        #define SAFE_TIME (5l)
+        #define BROKER_TRANSPORT OCConnectivityType::CT_ADAPTER_IP
+
+        /*
+         * @BROKER_STATE
+         * brief : resourcePresence state
+         * ALIVE       - It means that 'getCB' function receives 'OK' message
+         * REQUESTED   - It means that broker receives the request for presence checking
+         * LOST_SIGNAL - In case that 'getCB' function receives the message except 'OK'
+         * DESTROYED   - In case that the presence checking is dismissed for the resource ,
+         *               or there is no matched value in the Broker Callback list
+         * NONE        - To be determined.
+         */
+        enum class BROKER_STATE
+        {
+            ALIVE = 0,
+            REQUESTED,
+            LOST_SIGNAL,
+            DESTROYED,
+            NONE
+        };
+
+        /*
+         * @DEVICE_STATE
+         * brief : devicePresence state
+         * ALIVE       - It means that 'subscribeCB' function receives 'OK' message
+         * REQUESTED   - It means that broker receives the request for presence checking
+         * LOST_SIGNAL - In case that 'subscribeCB' function receives the message except 'OK'
+         */
+        enum class DEVICE_STATE
+        {
+            ALIVE = 0,
+            REQUESTED,
+            LOST_SIGNAL
+        };
+
+        enum class BROKER_MODE
+        {
+            DEVICE_PRESENCE_MODE = 0,
+            NON_PRESENCE_MODE
+        };
+
+        typedef unsigned int BrokerID;
+
+        typedef std::function<void(BROKER_STATE)> BrokerCB;
+        struct BrokerRequesterInfo
+        {
+            BrokerID brockerId;
+            BrokerCB brockerCB;
+        };
+        typedef std::shared_ptr<BrokerRequesterInfo> BrokerRequesterInfoPtr;
+
+        class ResourcePresence;
+        class DevicePresence;
+
+        typedef std::function<void(std::shared_ptr<OC::OCResource>)> FindCB;
+
+        typedef std::shared_ptr<PrimitiveResource> PrimitiveResourcePtr;
+
+        typedef std::shared_ptr<ResourcePresence> ResourcePresencePtr;
+        typedef std::shared_ptr<DevicePresence> DevicePresencePtr;
+        typedef std::list< ResourcePresencePtr > PresenceList;
+
+        struct BrokerCBResourcePair
+        {
+            BrokerCBResourcePair(ResourcePresencePtr pResource, BrokerCB cb)
+            : pResource(pResource), brokerCB(cb){}
+            ResourcePresencePtr pResource;
+            BrokerCB brokerCB;
+        };
+        typedef std::map<BrokerID, BrokerCBResourcePair> BrokerIDMap;
+
+        typedef std::function<void(OCStackResult, const unsigned int,
+                const std::string&)> SubscribeCB;
+
+        typedef std::function<void(const HeaderOptions&, const ResponseStatement&, int)> RequestGetCB;
+        typedef std::function<void * (unsigned int)> TimeoutCB;
+    } // namespace Service
+} // namespace OIC
+
+#endif // BROKERTYPES_H_
diff --git a/service/resource-manipulation/modules/resourceBroker/include/DeviceAssociation.h b/service/resource-manipulation/modules/resourceBroker/include/DeviceAssociation.h
new file mode 100755 (executable)
index 0000000..b173c36
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef DEVICEASSOCIATION_H_
+#define DEVICEASSOCIATION_H_
+
+#include <list>
+#include <string>
+#include <algorithm>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        class DeviceAssociation {
+        public:
+
+            static DeviceAssociation * getInstance();
+
+            DevicePresencePtr findDevice(const std::string & address);
+            void addDevice(DevicePresencePtr dPresence);
+            void removeDevice(DevicePresencePtr dPresence);
+
+        private:
+            DeviceAssociation();
+            ~DeviceAssociation();
+
+            static DeviceAssociation * s_instance;
+            static std::mutex s_mutexForCreation;
+            static std::list< DevicePresencePtr > s_deviceList;
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* DEVICEASSOCIATION_H_ */
diff --git a/service/resource-manipulation/modules/resourceBroker/include/DevicePresence.h b/service/resource-manipulation/modules/resourceBroker/include/DevicePresence.h
new file mode 100755 (executable)
index 0000000..a215cc2
--- /dev/null
@@ -0,0 +1,67 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef DEVICEPRESENCE_H_
+#define DEVICEPRESENCE_H_
+
+#include <list>
+#include <string>
+
+#include "BrokerTypes.h"
+#include "ResourcePresence.h"
+#include "PresenceSubscriber.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class DevicePresence
+        {
+        public:
+            DevicePresence();
+            ~DevicePresence();
+
+            void initializeDevicePresence(PrimitiveResourcePtr pResource);
+
+            void addPresenceResource(ResourcePresence * rPresence);
+            void removePresenceResource(ResourcePresence * rPresence);
+
+            bool isEmptyResourcePresence() const;
+            const std::string getAddress() const;
+
+        private:
+            void requestAllResourcePresence();
+            void subscribeCB(OCStackResult ret,const unsigned int seq, const std::string& Hostaddress);
+            void * timeOutCB(unsigned int msg);
+
+            std::list<ResourcePresence * > resourcePresenceList;
+
+            std::string address;
+            DEVICE_STATE state;
+            bool isWithinTime;
+
+            SubscribeCB pSubscribeRequestCB;
+            TimeoutCB pTimeoutCB;
+            PresenceSubscriber presenceSubscriber;
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* DEVICEPRESENCE_H_ */
diff --git a/service/resource-manipulation/modules/resourceBroker/include/ResourceBroker.h b/service/resource-manipulation/modules/resourceBroker/include/ResourceBroker.h
new file mode 100755 (executable)
index 0000000..20992e8
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCEBROKER_H_
+#define RESOURCEBROKER_H_
+
+#include <functional>
+#include <list>
+#include <string>
+#include <algorithm>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+#include "ResourcePresence.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceBroker
+        {
+        public:
+            class InvalidParameter: public PrimitiveException
+            {
+            public:
+                InvalidParameter(std::string&& what) : PrimitiveException{ std::move(what) } {}
+            };
+
+            static ResourceBroker * getInstance();
+
+            const BrokerID hostResource(PrimitiveResourcePtr pResource, BrokerCB cb);
+            void cancelHostResource(BrokerID brokerId);
+
+            BROKER_STATE getResourceState(BrokerID brokerId);
+            BROKER_STATE getResourceState(PrimitiveResourcePtr pResource);
+
+        private:
+            static ResourceBroker * s_instance;
+            static std::mutex s_mutexForCreation;
+            static std::unique_ptr<PresenceList>  s_presenceList;
+            static std::unique_ptr<BrokerIDMap> s_brokerIDMap;
+
+            ResourceBroker() = default;
+            ~ResourceBroker();
+            ResourceBroker(const ResourceBroker&) = delete;
+            ResourceBroker(ResourceBroker&&) = delete;
+
+            ResourceBroker& operator=(const ResourceBroker&) const = delete;
+            ResourceBroker& operator=(ResourceBroker&&) const = delete;
+
+            void initializeResourceBroker();
+            BrokerID generateBrokerID();
+            ResourcePresencePtr findResourcePresence(PrimitiveResourcePtr pResource);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RESOURCEBROKER_H_ */
diff --git a/service/resource-manipulation/modules/resourceBroker/include/ResourcePresence.h b/service/resource-manipulation/modules/resourceBroker/include/ResourcePresence.h
new file mode 100755 (executable)
index 0000000..81cbf85
--- /dev/null
@@ -0,0 +1,91 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCEPRESENCE_H_
+#define RESOURCEPRESENCE_H_
+
+#include <functional>
+#include <list>
+#include <string>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
+#include "BrokerTypes.h"
+#include "PrimitiveTimer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourcePresence
+        {
+        public:
+            ResourcePresence();
+            ~ResourcePresence();
+
+            void initializeResourcePresence(PrimitiveResourcePtr pResource);
+
+            void addBrokerRequester(BrokerID _id, BrokerCB _cb);
+            void removeBrokerRequester(BrokerID _id);
+            void removeAllBrokerRequester();
+
+            void requestResourceState() const;
+            void changePresenceMode(BROKER_MODE newMode);
+
+            bool isEmptyRequester() const;
+
+            const PrimitiveResourcePtr getPrimitiveResource() const;
+            BROKER_STATE getResourceState() const;
+
+        private:
+            std::unique_ptr<std::list<BrokerRequesterInfoPtr>> requesterList;
+            PrimitiveResourcePtr primitiveResource;
+            PrimitiveTimer primitiveTimer;
+
+            BROKER_STATE state;
+            BROKER_MODE mode;
+
+            bool isWithinTime;
+            std::atomic_bool isTimeoutCB;
+            std::atomic_long receivedTime;
+            std::mutex cbMutex;
+            std::condition_variable cbCondition;
+            unsigned int timeoutHandle;
+
+            RequestGetCB pGetCB;
+            TimeoutCB pTimeoutCB;
+            TimeoutCB pPollingCB;
+
+            void registerDevicePresence();
+            void getCB(const HeaderOptions &hos, const ResponseStatement& rep, int eCode);
+            void verifiedGetResponse(int eCode);
+
+            void * timeOutCB(unsigned int msg);
+            void * pollingCB(unsigned int msg = 0);
+
+            void executeAllBrokerCB(BROKER_STATE changedState);
+            void setResourcestate(BROKER_STATE _state);
+        };
+    } // namespace Service
+} // namespace OIC
+
+#endif /* RESOURCEPRESENCE_H_ */
+
diff --git a/service/resource-manipulation/modules/resourceBroker/src/DeviceAssociation.cpp b/service/resource-manipulation/modules/resourceBroker/src/DeviceAssociation.cpp
new file mode 100755 (executable)
index 0000000..d08a82d
--- /dev/null
@@ -0,0 +1,90 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "DeviceAssociation.h"
+#include "DevicePresence.h"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        DeviceAssociation * DeviceAssociation::s_instance = nullptr;
+        std::mutex DeviceAssociation::s_mutexForCreation;
+        std::list< DevicePresencePtr >  DeviceAssociation::s_deviceList;
+
+        DeviceAssociation::DeviceAssociation()
+        {
+            // TODO Auto-generated constructor stub
+        }
+
+        DeviceAssociation::~DeviceAssociation()
+        {
+            // TODO Auto-generated destructor stub
+        }
+
+        DeviceAssociation * DeviceAssociation::getInstance()
+        {
+            if (!s_instance)
+            {
+                s_mutexForCreation.lock();
+                if (!s_instance)
+                {
+                    s_instance = new DeviceAssociation();
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        DevicePresencePtr DeviceAssociation::findDevice(const std::string & address)
+        {
+            DevicePresencePtr retDevice = nullptr;
+            for(auto it : s_deviceList)
+            {
+                if(address == it->getAddress())
+                {
+                    retDevice = it;
+                }
+            }
+
+            return retDevice;
+        }
+
+        void DeviceAssociation::addDevice(DevicePresencePtr dPresence)
+        {
+            DevicePresencePtr foundDevice = findDevice(dPresence->getAddress());
+            if(foundDevice == nullptr)
+            {
+                s_deviceList.push_back(dPresence);
+            }
+        }
+
+        void DeviceAssociation::removeDevice(DevicePresencePtr dPresence)
+        {
+            DevicePresencePtr foundDevice = findDevice(dPresence->getAddress());
+            if(foundDevice != nullptr)
+            {
+                s_deviceList.remove(foundDevice);
+                foundDevice.reset();
+            }
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-manipulation/modules/resourceBroker/src/DevicePresence.cpp b/service/resource-manipulation/modules/resourceBroker/src/DevicePresence.cpp
new file mode 100755 (executable)
index 0000000..0f29102
--- /dev/null
@@ -0,0 +1,162 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "DevicePresence.h"
+#include "PrimitiveException.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        DevicePresence::DevicePresence()
+        {
+            state = DEVICE_STATE::REQUESTED;
+            isWithinTime = true;
+            pSubscribeRequestCB = std::bind(&DevicePresence::subscribeCB, this,
+                        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
+            pTimeoutCB = std::bind(&DevicePresence::timeOutCB, this, std::placeholders::_1);
+        }
+
+        DevicePresence::~DevicePresence()
+        {
+            resourcePresenceList.clear();
+        }
+
+        void DevicePresence::initializeDevicePresence(PrimitiveResourcePtr pResource)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "%s",pResource->getHost().c_str());
+
+            try
+            {
+                presenceSubscriber
+                = PresenceSubscriber(pResource->getHost(), BROKER_TRANSPORT, pSubscribeRequestCB);
+
+                OC_LOG_V(DEBUG, BROKER_TAG, "subscribe Presence");
+            } catch(PrimitiveException & e)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "exception in subscribe Presence %s",e.what());
+                throw PrimitiveException(e);
+            }
+            //TODO generate Timer(if(!isTimer))
+        }
+
+        const std::string DevicePresence::getAddress() const
+        {
+            return address;
+        }
+
+        void DevicePresence::addPresenceResource(ResourcePresence * rPresence)
+        {
+            resourcePresenceList.push_back(rPresence);
+        }
+
+        void DevicePresence::removePresenceResource(ResourcePresence * rPresence)
+        {
+            resourcePresenceList.remove(rPresence);
+        }
+
+        void DevicePresence::requestAllResourcePresence()
+        {
+            for(auto it : resourcePresenceList)
+            {
+                it->requestResourceState();
+            }
+        }
+
+        bool DevicePresence::isEmptyResourcePresence() const
+        {
+            return resourcePresenceList.empty();
+        }
+
+        void DevicePresence::subscribeCB(OCStackResult ret,
+                const unsigned int seq, const std::string& hostAddress)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "Received presence CB from: %s",hostAddress.c_str());
+            OC_LOG_V(DEBUG, BROKER_TAG, "In subscribeCB: %d",ret);
+
+            if(isWithinTime)
+            {
+                switch(ret)
+                {
+                    case OC_STACK_OK:
+                    case OC_STACK_RESOURCE_CREATED:
+                    case OC_STACK_CONTINUE:
+                        OC_LOG_V(DEBUG, BROKER_TAG, "SEQ# %d",seq);
+                        state = DEVICE_STATE::ALIVE;
+                        OC_LOG_V(DEBUG, BROKER_TAG, "device state : %d",(int)state);
+                        if(!resourcePresenceList.empty())
+                        {
+                            requestAllResourcePresence();
+                        }
+                        break;
+
+                    case OC_STACK_INVALID_REQUEST_HANDLE:
+                    case OC_STACK_RESOURCE_DELETED:
+                    case OC_STACK_TIMEOUT:
+                    case OC_STACK_COMM_ERROR:
+                        //TODO get request
+                        state = DEVICE_STATE::REQUESTED;
+                        if(!resourcePresenceList.empty())
+                        {
+                            OC_LOG_V(DEBUG, BROKER_TAG,
+                                    "ready to execute requestAllResourcePresence()");
+                            requestAllResourcePresence();
+                        }
+                        break;
+
+                    case OC_STACK_PRESENCE_STOPPED:
+                    case OC_STACK_PRESENCE_TIMEOUT:
+                        OC_LOG_V(DEBUG, BROKER_TAG, "Server Presence Stop!!");
+                        state = DEVICE_STATE::LOST_SIGNAL;
+                        requestAllResourcePresence();
+                        break;
+
+                    case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+                        OC_LOG_V(DEBUG, BROKER_TAG, "Presence Lost Signal because do not handled");
+                        state = DEVICE_STATE::LOST_SIGNAL;
+                        requestAllResourcePresence();
+                        break;
+
+                    default:
+                        OC_LOG_V(DEBUG, BROKER_TAG, "Presence Lost Signal because unknown type");
+                        state = DEVICE_STATE::LOST_SIGNAL;
+                        requestAllResourcePresence();
+                        break;
+                }
+            }
+            else
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "This response is Timeout but device steel alive");
+                this->state = DEVICE_STATE::ALIVE;
+                isWithinTime = true;
+            }
+        }
+
+        void * DevicePresence::timeOutCB(unsigned int msg)
+        {
+            this->isWithinTime = false;
+            OC_LOG_V(DEBUG, BROKER_TAG,
+                    "Timeout execution. will be discard after receiving cb message");
+            state = DEVICE_STATE::LOST_SIGNAL;
+
+            return NULL;
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-manipulation/modules/resourceBroker/src/ResourceBroker.cpp b/service/resource-manipulation/modules/resourceBroker/src/ResourceBroker.cpp
new file mode 100755 (executable)
index 0000000..6bf7b83
--- /dev/null
@@ -0,0 +1,217 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <time.h>
+
+#include "BrokerTypes.h"
+#include "ResourceBroker.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourceBroker * ResourceBroker::s_instance = NULL;
+        std::mutex ResourceBroker::s_mutexForCreation;
+        std::unique_ptr<PresenceList>  ResourceBroker::s_presenceList(nullptr);
+        std::unique_ptr<BrokerIDMap> ResourceBroker::s_brokerIDMap(nullptr);
+
+        ResourceBroker::~ResourceBroker()
+        {
+            if(s_presenceList != nullptr)
+            {
+                s_presenceList->erase(s_presenceList->begin(), s_presenceList->end());
+                s_presenceList->clear();
+            }
+            if(s_brokerIDMap != nullptr)
+            {
+                s_brokerIDMap->erase(s_brokerIDMap->begin(), s_brokerIDMap->end());
+                s_brokerIDMap->clear();
+            }
+        }
+
+        ResourceBroker * ResourceBroker::getInstance()
+        {
+            if (!s_instance)
+            {
+                s_mutexForCreation.lock();
+                if (!s_instance)
+                {
+                    s_instance = new ResourceBroker();
+                    s_instance->initializeResourceBroker();
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        const BrokerID ResourceBroker::hostResource(PrimitiveResourcePtr pResource, BrokerCB cb)
+        {
+            if(pResource == nullptr || cb == nullptr || cb == NULL)
+            {
+                throw InvalidParameter("[hostResource] input PrimitiveResource is Invalid");
+            }
+
+            BrokerID retID = generateBrokerID();
+
+            ResourcePresencePtr presenceItem = findResourcePresence(pResource);
+            if(presenceItem == nullptr)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "Not found any Handled Resource.");
+                OC_LOG_V(DEBUG, BROKER_TAG, "Create New Resource Presence Handler.");
+
+                presenceItem.reset(new ResourcePresence());
+                presenceItem->initializeResourcePresence(pResource);
+                if(s_presenceList != nullptr)
+                {
+                    s_presenceList->push_back(presenceItem);
+                }
+            }
+            presenceItem->addBrokerRequester(retID, cb);
+
+            BrokerCBResourcePair pair(presenceItem, cb);
+            s_brokerIDMap->insert(std::pair<BrokerID, BrokerCBResourcePair>
+                (retID, BrokerCBResourcePair(presenceItem, cb)));
+
+            return retID;
+        }
+
+        void ResourceBroker::cancelHostResource(BrokerID brokerId)
+        {
+            if(brokerId == 0)
+            {
+                // input parameter is wrong.
+                // hostResource never return value 0;
+                throw InvalidParameter("[cancelHostResource] input BrokerID is Invalid");
+            }
+
+            BrokerIDMap::iterator it = s_brokerIDMap->find(brokerId);
+            if(it == s_brokerIDMap->end())
+            {
+                // not found requested brokerId in BrokerMap;
+                throw InvalidParameter("[cancelHostResource] input BrokerID is unknown ID");
+            }
+            else
+            {
+                ResourcePresencePtr presenceItem = it->second.pResource;
+                presenceItem->removeBrokerRequester(brokerId);
+                s_brokerIDMap->erase(brokerId);
+
+                if(presenceItem->isEmptyRequester())
+                {
+                    auto iter = std::find(s_presenceList->begin(),
+                            s_presenceList->end(), presenceItem);
+                    s_presenceList->erase(iter);
+                    presenceItem.reset();
+                }
+            }
+        }
+
+        BROKER_STATE ResourceBroker::getResourceState(BrokerID brokerId)
+        {
+            if(brokerId == 0)
+            {
+                throw InvalidParameter("[getResourceState] input BrokerID is Invalid");
+            }
+
+            BROKER_STATE retState = BROKER_STATE::NONE;
+
+            BrokerIDMap::iterator it = s_brokerIDMap->find(brokerId);
+            if(it == s_brokerIDMap->end())
+            {
+                // not found requested brokerId in BrokerMap;
+                throw InvalidParameter("[getResourceState] input BrokerID is unknown ID");
+            }
+            else
+            {
+                ResourcePresencePtr foundResource = it->second.pResource;
+                retState = foundResource->getResourceState();
+            }
+
+            return retState;
+        }
+
+        BROKER_STATE ResourceBroker::getResourceState(PrimitiveResourcePtr pResource)
+        {
+            if(pResource == nullptr)
+            {
+                throw InvalidParameter("[getResourceState] input PrimitiveResource is Invalid");
+            }
+
+            BROKER_STATE retState = BROKER_STATE::NONE;
+
+            ResourcePresencePtr foundResource = findResourcePresence(pResource);
+            if(foundResource != nullptr)
+            {
+                retState = foundResource->getResourceState();
+            }
+
+            return retState;
+        }
+
+        void ResourceBroker::initializeResourceBroker()
+        {
+            if(s_presenceList == nullptr)
+            {
+                s_presenceList = std::unique_ptr<PresenceList>(new PresenceList);
+            }
+            if(s_brokerIDMap == nullptr)
+            {
+                s_brokerIDMap = std::unique_ptr<BrokerIDMap>(new BrokerIDMap);
+            }
+        }
+
+        ResourcePresencePtr ResourceBroker::findResourcePresence(PrimitiveResourcePtr pResource)
+        {
+            ResourcePresencePtr retResource(nullptr);
+
+            if(s_presenceList->empty() != true)
+            {
+                for(auto & it : * s_presenceList)
+                {
+                    PrimitiveResourcePtr temp = it->getPrimitiveResource();
+                    if(temp == pResource)
+                    {
+                        retResource = it;
+                        break;
+                    }
+                }
+            }
+
+            return retResource;
+        }
+
+        BrokerID ResourceBroker::generateBrokerID()
+        {
+            BrokerID retID = 0;
+            srand(time(NULL));
+
+            while(1)
+            {
+                if(retID != 0 && s_brokerIDMap->find(retID) == s_brokerIDMap->end())
+                {
+                    break;
+                }
+                retID = (unsigned int)rand();
+            }
+
+            return retID;
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-manipulation/modules/resourceBroker/src/ResourcePresence.cpp b/service/resource-manipulation/modules/resourceBroker/src/ResourcePresence.cpp
new file mode 100755 (executable)
index 0000000..4f30037
--- /dev/null
@@ -0,0 +1,289 @@
+//******************************************************************
+//
+// 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 "../include/ResourcePresence.h"
+
+#include <bits/atomic_base.h>
+#include <bits/shared_ptr_base.h>
+#include <time.h>
+#include <unistd.h>
+#include <cstdbool>
+#include <exception>
+#include <iostream>
+#include <memory>
+
+#include "PrimitiveResource.h"
+#include "DeviceAssociation.h"
+#include "DevicePresence.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourcePresence::ResourcePresence()
+        {
+            primitiveResource = nullptr;
+            isTimeoutCB = false;
+            receivedTime = 0L;
+            state = BROKER_STATE::REQUESTED;
+            isWithinTime = true;
+            mode = BROKER_MODE::NON_PRESENCE_MODE;
+
+            requesterList = nullptr;
+
+            pGetCB = std::bind(&ResourcePresence::getCB, this,
+                    std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
+            pTimeoutCB = std::bind(&ResourcePresence::timeOutCB, this,std::placeholders::_1);
+            pPollingCB = std::bind(&ResourcePresence::pollingCB, this,std::placeholders::_1);
+        }
+
+        void ResourcePresence::initializeResourcePresence(PrimitiveResourcePtr pResource)
+        {
+            primitiveResource = pResource;
+            requesterList
+            = std::unique_ptr<std::list<BrokerRequesterInfoPtr>>
+            (new std::list<BrokerRequesterInfoPtr>);
+
+            timeoutHandle = primitiveTimer.requestTimer(SAFE_TIME, pTimeoutCB);
+
+            primitiveResource->requestGet(pGetCB);
+
+            registerDevicePresence();
+        }
+
+
+        ResourcePresence::~ResourcePresence()
+        {
+            std::string deviceAddress = primitiveResource->getHost();
+
+            DevicePresencePtr foundDevice
+            = DeviceAssociation::getInstance()->findDevice(deviceAddress);
+
+            if(foundDevice != nullptr)
+            {
+                foundDevice->removePresenceResource(this);
+
+                if(foundDevice->isEmptyResourcePresence())
+                {
+                    DeviceAssociation::getInstance()->removeDevice(foundDevice);
+                }
+            }
+
+            requesterList->clear();
+
+            state = BROKER_STATE::DESTROYED;
+        }
+
+        void ResourcePresence::addBrokerRequester(BrokerID _id, BrokerCB _cb)
+        {
+            BrokerRequesterInfoPtr newRequester;
+            newRequester.reset(new BrokerRequesterInfo());
+
+            newRequester->brockerId = _id;
+            newRequester->brockerCB = _cb;
+            requesterList->push_back(newRequester);
+        }
+
+        void ResourcePresence::removeAllBrokerRequester()
+        {
+            if(requesterList != nullptr)
+            {
+                requesterList->erase(requesterList->begin(), requesterList->end());
+            }
+        }
+
+        void ResourcePresence::removeBrokerRequester(BrokerID _id)
+        {
+            std::list<BrokerRequesterInfoPtr>::iterator iter = requesterList->begin();
+            for(; iter != requesterList->end(); ++iter)
+            {
+                if(iter->get()->brockerId == _id)
+                {
+                    requesterList->erase(iter);
+                    break;
+                }
+            }
+        }
+
+        bool ResourcePresence::isEmptyRequester() const
+        {
+            return requesterList->empty();
+        }
+
+        void ResourcePresence::requestResourceState() const
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "Request Get\n");
+            primitiveResource->requestGet(pGetCB);
+        }
+
+        void ResourcePresence::registerDevicePresence()
+        {
+            std::string deviceAddress = primitiveResource->getHost();
+
+            DevicePresencePtr foundDevice
+            = DeviceAssociation::getInstance()->findDevice(deviceAddress);
+
+            if(foundDevice == nullptr)
+            {
+                foundDevice.reset(new DevicePresence());
+                foundDevice->initializeDevicePresence(primitiveResource);
+                DeviceAssociation::getInstance()->addDevice(foundDevice);
+            }
+            foundDevice->addPresenceResource(this);
+        }
+
+        void ResourcePresence::executeAllBrokerCB(BROKER_STATE changedState)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "executeAllBrokerCB()");
+            if(state != changedState)
+            {
+                setResourcestate(changedState);
+                if(requesterList->empty() != true)
+                {
+                    for(BrokerRequesterInfoPtr & item : * requesterList)
+                    {
+                        item->brockerCB(state);
+                    }
+                }
+            }
+        }
+
+        void ResourcePresence::setResourcestate(BROKER_STATE _state)
+        {
+            this->state = _state;
+
+        }
+
+        void * ResourcePresence::timeOutCB(unsigned int msg)
+        {
+            std::unique_lock<std::mutex> lock(cbMutex);
+            isTimeoutCB = true;
+
+            time_t currentTime;
+            time(&currentTime);
+            currentTime+=0L;
+
+            if((receivedTime == 0L) || ((receivedTime+SAFE_TIME) > currentTime))
+            {
+                return NULL;
+            }
+            this->isWithinTime = false;
+            OC_LOG_V(DEBUG, BROKER_TAG,
+                    "Timeout execution. will be discard after receiving cb message");
+
+            executeAllBrokerCB(BROKER_STATE::LOST_SIGNAL);
+            pollingCB();
+
+            isTimeoutCB = false;
+            cbCondition.notify_all();
+
+            return NULL;
+        }
+
+        void * ResourcePresence::pollingCB(unsigned int msg)
+        {
+            this->requestResourceState();
+            timeoutHandle = primitiveTimer.requestTimer(SAFE_TIME,pTimeoutCB);
+
+            return NULL;
+        }
+
+        void ResourcePresence::getCB(const HeaderOptions &hos,
+                const ResponseStatement& rep, int eCode)
+        {
+            OC_LOG_V(DEBUG, BROKER_TAG, "response getCB\n");
+            while(isTimeoutCB)
+            {
+                OC_LOG_V(DEBUG, BROKER_TAG, "waiting for terminate TimeoutCB\n");
+                std::unique_lock<std::mutex> lock(cbMutex);
+                cbCondition.wait(lock);
+            }
+
+            time_t currentTime;
+            time(&currentTime);
+            receivedTime = currentTime;
+
+            verifiedGetResponse(eCode);
+
+            if(isWithinTime)
+            {
+                primitiveTimer.cancelTimer(timeoutHandle);
+                isWithinTime = true;
+            }
+
+            if(mode == BROKER_MODE::NON_PRESENCE_MODE)
+            {
+                // TODO set timer & request get
+                primitiveTimer.requestTimer(SAFE_TIME,pPollingCB);
+            }
+
+        }
+
+        void ResourcePresence::verifiedGetResponse(int eCode)
+        {
+            BROKER_STATE verifiedState = BROKER_STATE::NONE;
+            switch(eCode)
+            {
+            case OC_STACK_OK:
+            case OC_STACK_CONTINUE:
+                verifiedState = BROKER_STATE::ALIVE;
+                break;
+
+            case OC_STACK_RESOURCE_DELETED:
+                verifiedState = BROKER_STATE::DESTROYED;
+                break;
+
+            case OC_STACK_INVALID_REQUEST_HANDLE:
+            case OC_STACK_TIMEOUT:
+            case OC_STACK_COMM_ERROR:
+            case OC_STACK_PRESENCE_STOPPED:
+            case OC_STACK_PRESENCE_TIMEOUT:
+            default:
+                verifiedState = BROKER_STATE::LOST_SIGNAL;
+                break;
+            }
+
+            executeAllBrokerCB(verifiedState);
+            OC_LOG_V(DEBUG, BROKER_TAG, "resource state : %d",(int)state);
+        }
+
+        const PrimitiveResourcePtr ResourcePresence::getPrimitiveResource() const
+        {
+            return primitiveResource;
+        }
+
+        BROKER_STATE ResourcePresence::getResourceState() const
+        {
+            return state;
+        }
+
+        void ResourcePresence::changePresenceMode(BROKER_MODE newMode)
+        {
+            if(newMode != mode)
+            {
+                if(newMode == BROKER_MODE::NON_PRESENCE_MODE)
+                {
+                    requestResourceState();
+                }
+                mode = newMode;
+            }
+        }
+    } // namespace Service
+} // namespace OIC
diff --git a/service/resource-manipulation/modules/resourceCache/SConscript b/service/resource-manipulation/modules/resourceCache/SConscript
new file mode 100644 (file)
index 0000000..55bd996
--- /dev/null
@@ -0,0 +1,73 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceCache 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')
+resourcecache_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+resourcecache_env.AppendUnique(CPPPATH = ['include'])
+resourcecache_env.AppendUnique(CPPPATH = ['../common/primitiveResource/include'])
+resourcecache_env.AppendUnique(CPPPATH = ['../common/primitiveTimer/include'])
+resourcecache_env.PrependUnique(LIBS = ['service_common', 'PrimitiveTimer', 'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+
+if target_os not in ['windows', 'winrt']:
+       resourcecache_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++11'])
+
+if target_os == 'linux':
+       resourcecache_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+CACHE_SRC_DIR = 'src/'
+resourcecache_src = [
+        CACHE_SRC_DIR + 'DataCache.cpp',
+        CACHE_SRC_DIR + 'ResourceCacheManager.cpp'
+        ]
+
+if target_os in ['tizen','android'] :
+    resourcecachesdk = resourcecache_env.SharedLibrary('ResourceCache', resourcecache_src)
+else :
+    resourcecachesdk = resourcecache_env.StaticLibrary('ResourceCache', resourcecache_src)
+
+resourcecache_env.InstallTarget(resourcecachesdk, 'libResouceCache')
+
+# Go to build sample apps
+#SConscript('SampleApp/SConscript')
+
diff --git a/service/resource-manipulation/modules/resourceCache/include/CacheTypes.h b/service/resource-manipulation/modules/resourceCache/include/CacheTypes.h
new file mode 100755 (executable)
index 0000000..50eb43e
--- /dev/null
@@ -0,0 +1,81 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef CACHETYPES_H
+#define CACHETYPES_H
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+#include "ocstack.h"
+#include "OCResource.h"
+
+#include "PrimitiveResource.h"
+#include "ResourceAttributes.h"
+
+#define CACHE_TAG  PCF("CACHE")
+#define DEFAULT_REPORT_TIME 30
+#define DEFAULT_EXPIRED_TIME 15l
+
+using namespace OIC::Service;
+
+class DataCache;
+
+enum class REPORT_FREQUENCY
+{
+    NONE = 0,
+    UPTODATE,
+    PERIODICTY
+};
+
+struct Report_Info
+{
+    REPORT_FREQUENCY rf;
+    int reportID;
+    long latestReportTime;
+    long repeatTime;
+};
+
+enum class CACHE_STATE
+{
+    READY = 0,
+    READY_YET,
+    LOST_SIGNAL,
+    DESTROYED,
+    UPDATING,
+    NONE
+};
+
+typedef int CacheID;
+
+typedef std::function<OCStackResult(std::shared_ptr<PrimitiveResource>, const ResourceAttributes &)> CacheCB;
+typedef std::map<int, std::pair<Report_Info, CacheCB>> SubscriberInfo;
+typedef std::pair<int, std::pair<Report_Info, CacheCB>> SubscriberInfoPair;
+
+typedef OC::OCResource BaseResource;
+typedef PrimitiveResource::GetCallback GetCB;
+typedef PrimitiveResource::ObserveCallback ObserveCB;
+
+typedef std::shared_ptr<DataCache> DataCachePtr;
+typedef std::shared_ptr<PrimitiveResource> PrimitiveResourcePtr;
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceCache/include/DataCache.h b/service/resource-manipulation/modules/resourceCache/include/DataCache.h
new file mode 100755 (executable)
index 0000000..1c53b31
--- /dev/null
@@ -0,0 +1,86 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef DATACACHE_H_
+#define DATACACHE_H_
+
+#include <list>
+#include <string>
+#include <memory>
+
+#include "OCResource.h"
+#include "logger.h"
+
+#include "CacheTypes.h"
+#include "PrimitiveTimer.h"
+
+class DataCache
+{
+public:
+    DataCache(
+            PrimitiveResourcePtr pResource,
+            CacheCB func,
+            REPORT_FREQUENCY rf,
+            long repeatTime);
+    ~DataCache();
+
+    CacheID addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime);
+    CacheID deleteSubscriber(CacheID id);
+
+    CACHE_STATE getCacheState() const;
+    const ResourceAttributes getCachedData() const;
+    const PrimitiveResourcePtr getPrimitiveResource() const;
+
+    SubscriberInfoPair findSubscriber(CacheID id);
+
+private:
+    // origin resource info
+    std::string uri;
+    std::string address;
+
+    // resource instance
+    PrimitiveResourcePtr sResource;
+    std::shared_ptr<BaseResource> baseHandler;
+
+    // cached data info
+    ResourceAttributes attributes;
+    long updateTime;
+    CACHE_STATE state;
+
+    // subscriber info
+    std::unique_ptr<SubscriberInfo> subscriberList;
+
+    PrimitiveTimer *timerInstance;
+    TimerID expiredTimerId;
+
+    // for requestCB from base
+    void onObserve(const HeaderOptions& _hos,
+            const ResponseStatement& _rep, int _result, int _seq);
+    void onGet(const HeaderOptions& _hos, const ResponseStatement& _rep, int _result);
+    void *onTimer(const unsigned int timerID);
+    ObserveCB pObserveCB;
+    GetCB pGetCB;
+    TimerCB pTimerCB;
+
+    OCStackResult updateCacheData();
+
+};
+
+#endif /* DATACACHE_H_ */
diff --git a/service/resource-manipulation/modules/resourceCache/include/ResourceCacheManager.h b/service/resource-manipulation/modules/resourceCache/include/ResourceCacheManager.h
new file mode 100755 (executable)
index 0000000..040c3fc
--- /dev/null
@@ -0,0 +1,63 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECACHEMANAGER_H_
+#define RESOURCECACHEMANAGER_H_
+
+#include <list>
+#include <string>
+#include <mutex>
+
+#include "OCPlatform.h"
+#include "CacheTypes.h"
+#include "DataCache.h"
+
+#define CACHE_TAG PCF("CACHE")
+
+class ResourceCacheManager
+{
+public:
+    static ResourceCacheManager * getInstance();
+
+    CacheID requestResourceCache(
+            PrimitiveResourcePtr pResource,
+                CacheCB func = NULL, REPORT_FREQUENCY rf = REPORT_FREQUENCY::NONE, long time = 0l);
+    CacheID cancelResourceCache(CacheID id);
+    OCStackResult updateResourceCache(PrimitiveResourcePtr pResource);
+
+    const ResourceAttributes getCachedData(PrimitiveResourcePtr pResource) const;
+    const ResourceAttributes getCachedData(CacheID id) const;
+
+    CACHE_STATE getResourceCacheState(PrimitiveResourcePtr pResource) const;
+    CACHE_STATE getResourceCacheState(CacheID id) const;
+
+    ~ResourceCacheManager();
+private:
+    ResourceCacheManager();
+
+    static ResourceCacheManager * s_instance;
+    static std::mutex s_mutexForCreation;
+    static std::unique_ptr<std::list<DataCachePtr>> s_cacheDataList;
+
+    DataCachePtr findDataCache(PrimitiveResourcePtr pResource) const;
+    DataCachePtr findDataCache(CacheID id) const;
+};
+
+#endif /* RESOURCECACHEMANAGER_H_ */
diff --git a/service/resource-manipulation/modules/resourceCache/src/DataCache.cpp b/service/resource-manipulation/modules/resourceCache/src/DataCache.cpp
new file mode 100755 (executable)
index 0000000..61f6dd8
--- /dev/null
@@ -0,0 +1,226 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <memory>
+#include <cstdlib>
+#include <functional>
+#include <map>
+#include <utility>
+#include <ctime>
+
+#include "OCApi.h"
+
+#include "DataCache.h"
+
+#include "ResponseStatement.h"
+#include "ResourceAttributes.h"
+#include "PrimitiveTimer.h"
+
+DataCache::DataCache(
+            PrimitiveResourcePtr pResource,
+            CacheCB func,
+            REPORT_FREQUENCY rf,
+            long repeatTime
+            ):sResource(pResource)
+{
+    subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
+
+    timerInstance = new PrimitiveTimer;
+    state = CACHE_STATE::READY_YET;
+    updateTime = 0l;
+
+    pObserveCB = (ObserveCB)(std::bind(&DataCache::onObserve, this,
+            std::placeholders::_1, std::placeholders::_2,
+            std::placeholders::_3, std::placeholders::_4));
+    pGetCB = (GetCB)(std::bind(&DataCache::onGet, this,
+            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+    pTimerCB = (TimerCB)(std::bind(&DataCache::onTimer, this, std::placeholders::_1));
+
+    pResource->requestGet(pGetCB);
+    if(pResource->isObservable())
+    {
+        pResource->requestObserve(pObserveCB);
+        expiredTimerId = timerInstance->requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
+    }
+    else
+    {
+        // TODO set timer
+        TimerID timerId = timerInstance->requestTimer(repeatTime, pTimerCB);
+    }
+}
+
+DataCache::~DataCache()
+{
+    // TODO Auto-generated destructor stub
+
+    // TODO delete all node!!
+    subscriberList->clear();
+    subscriberList.release();
+}
+
+CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
+{
+    Report_Info newItem;
+    newItem.rf = rf;
+    newItem.latestReportTime = 0l;
+    newItem.repeatTime = repeatTime;
+
+    srand(time(NULL));
+    newItem.reportID = rand();
+
+    while(1)
+    {
+        if(findSubscriber(newItem.reportID).first != 0 || newItem.reportID == 0)
+        {
+            newItem.reportID = rand();
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    subscriberList->insert(std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
+
+    return newItem.reportID;
+}
+
+CacheID DataCache::deleteSubscriber(CacheID id)
+{
+    CacheID ret = 0;
+
+    SubscriberInfoPair pair = findSubscriber(id);
+    if(pair.first != 0)
+    {
+        ret = pair.first;
+        subscriberList->erase(pair.first);
+    }
+
+    return ret;
+}
+
+SubscriberInfoPair DataCache::findSubscriber(CacheID id)
+{
+    SubscriberInfoPair ret;
+
+    for(auto & i : *subscriberList)
+    {
+        if(i.first == id)
+        {
+            ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first, (CacheCB)i.second.second));
+        }
+    }
+
+    return ret;
+}
+
+const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
+{
+    return sResource;
+}
+
+const ResourceAttributes DataCache::getCachedData() const
+{
+    if(state != CACHE_STATE::READY)
+    {
+        return ResourceAttributes();
+    }
+    const ResourceAttributes retAtt = attributes;
+    return retAtt;
+}
+
+void DataCache::onObserve(
+        const HeaderOptions& _hos, const ResponseStatement& _rep, int _result, int _seq)
+{
+
+    if(_result != OC_STACK_OK)
+    {
+        // TODO handle error
+        return;
+    }
+
+    if(_rep.getAttributes().empty())
+    {
+        return;
+    }
+
+    state = CACHE_STATE::READY;
+
+    attributes = _rep.getAttributes();
+
+    // notify!!
+    ResourceAttributes retAtt = attributes;
+    for(auto & i : * subscriberList)
+    {
+        if(i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
+        {
+            i.second.second(this->sResource, retAtt);
+        }
+    }
+}
+
+void DataCache::onGet(const HeaderOptions& _hos,
+        const ResponseStatement& _rep, int _result)
+{
+    if(state == CACHE_STATE::READY_YET)
+    {
+        state = CACHE_STATE::READY;
+        attributes = _rep.getAttributes();
+        if(sResource->isObservable())
+        {
+            timerInstance->cancelTimer(expiredTimerId);
+            expiredTimerId = timerInstance->requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
+        }
+    }
+    else
+    {
+        attributes = _rep.getAttributes();
+        if(sResource->isObservable())
+        {
+            timerInstance->cancelTimer(expiredTimerId);
+            expiredTimerId = timerInstance->requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
+        }
+
+        ResourceAttributes retAtt = attributes;
+        for(auto & i : * subscriberList)
+        {
+            if(i.second.first.rf != REPORT_FREQUENCY::NONE)
+            {
+                i.second.second(this->sResource, retAtt);
+            }
+        }
+    }
+}
+
+CACHE_STATE DataCache::getCacheState() const
+{
+    return state;
+}
+
+void *DataCache::onTimer(const unsigned int timerID)
+{
+    sResource->requestGet(pGetCB);
+    if(sResource->isObservable())
+    {
+        expiredTimerId = timerInstance->requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
+    }
+    else
+        TimerID timerId = timerInstance->requestTimer(5l, pTimerCB);
+}
\ No newline at end of file
diff --git a/service/resource-manipulation/modules/resourceCache/src/ResourceCacheManager.cpp b/service/resource-manipulation/modules/resourceCache/src/ResourceCacheManager.cpp
new file mode 100755 (executable)
index 0000000..aa36896
--- /dev/null
@@ -0,0 +1,186 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ResourceCacheManager.h"
+
+ResourceCacheManager * ResourceCacheManager::s_instance = NULL;
+std::mutex ResourceCacheManager::s_mutexForCreation;
+std::unique_ptr<std::list<DataCachePtr>> ResourceCacheManager::s_cacheDataList(nullptr);
+
+ResourceCacheManager::ResourceCacheManager()
+{
+    // TODO Auto-generated constructor stub
+    if(!s_cacheDataList)
+    {
+        s_cacheDataList = std::unique_ptr<std::list<DataCachePtr>>(new std::list<DataCachePtr>);
+    }
+}
+
+ResourceCacheManager::~ResourceCacheManager()
+{
+    // TODO Auto-generated destructor stub
+    if(s_cacheDataList)
+    {
+        s_cacheDataList->clear();
+    }
+}
+
+ResourceCacheManager * ResourceCacheManager::getInstance()
+{
+    if(s_instance == nullptr)
+    {
+        s_mutexForCreation.lock();
+        if(s_instance == nullptr)
+        {
+            s_instance = new ResourceCacheManager();
+        }
+        s_mutexForCreation.unlock();
+    }
+    return s_instance;
+}
+
+CacheID ResourceCacheManager::requestResourceCache(
+        PrimitiveResourcePtr pResource, CacheCB func,
+        REPORT_FREQUENCY rf, long reportTime)
+{
+    CacheID retID = 0;
+
+    if(rf != REPORT_FREQUENCY::NONE)
+    {
+        if(func == NULL)
+        {
+            return retID;
+        }
+        if(!reportTime)
+        {
+            // default setting
+            reportTime = DEFAULT_REPORT_TIME;
+        }
+    }
+
+    DataCachePtr newHandler = findDataCache(pResource);
+    if(newHandler == nullptr)
+    {
+        newHandler = std::make_shared<DataCache>(pResource, func, rf, reportTime);
+        s_cacheDataList->push_back(newHandler);
+    }
+    retID = newHandler->addSubscriber(func, rf, reportTime);
+
+    return retID;
+}
+
+CacheID ResourceCacheManager::cancelResourceCache(CacheID id)
+{
+    CacheID retID = 0;
+    if(id == 0)
+    {
+        return retID;
+    }
+
+    DataCachePtr foundCacheHandler = findDataCache(id);
+    if(foundCacheHandler == nullptr)
+    {
+        return retID;
+    }
+    else
+    {
+        retID = foundCacheHandler->deleteSubscriber(id);
+    }
+
+    return retID;
+}
+
+DataCachePtr ResourceCacheManager::findDataCache(PrimitiveResourcePtr pResource) const
+{
+    DataCachePtr retHandler = nullptr;
+    for (auto & i : * s_cacheDataList)
+    {
+        if(i->getPrimitiveResource()->getUri() == pResource->getUri() &&
+                i->getPrimitiveResource()->getHost() == pResource->getHost())
+        {
+            retHandler = i;
+            break;
+        }
+    }
+    return retHandler;
+}
+
+DataCachePtr ResourceCacheManager::findDataCache(CacheID id) const
+{
+    DataCachePtr retHandler = nullptr;
+    for (auto & i : * s_cacheDataList)
+    {
+        SubscriberInfoPair pair = i->findSubscriber(id);
+        if(pair.first != 0)
+        {
+            retHandler = i;
+            break;
+        }
+    }
+    return retHandler;
+}
+
+OCStackResult ResourceCacheManager::updateResourceCache(PrimitiveResourcePtr pResource)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    // TODO update now (request get)
+
+    return ret;
+}
+
+const ResourceAttributes ResourceCacheManager::getCachedData(PrimitiveResourcePtr pResource) const
+{
+    DataCachePtr handler = findDataCache(pResource);
+    if(handler == nullptr)
+    {
+        return ResourceAttributes();
+    }
+    return handler->getCachedData();
+}
+
+const ResourceAttributes ResourceCacheManager::getCachedData(CacheID id) const
+{
+    DataCachePtr handler = findDataCache(id);
+    if(handler == nullptr)
+    {
+        return ResourceAttributes();
+    }
+    return handler->getCachedData();
+}
+
+CACHE_STATE ResourceCacheManager::getResourceCacheState(PrimitiveResourcePtr pResource) const
+{
+    DataCachePtr handler = findDataCache(pResource);
+    if(handler == nullptr)
+    {
+        return CACHE_STATE::NONE;
+    }
+    return handler->getCacheState();
+}
+CACHE_STATE ResourceCacheManager::getResourceCacheState(CacheID id) const
+{
+    DataCachePtr handler = findDataCache(id);
+    if(handler == nullptr)
+    {
+        return CACHE_STATE::NONE;
+    }
+    return handler->getCacheState();
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/SConscript b/service/resource-manipulation/modules/resourceContainer/SConscript
new file mode 100644 (file)
index 0000000..1441c73
--- /dev/null
@@ -0,0 +1,129 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# resource container build script
+##
+import os
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+resource_container_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+resource_container_env.AppendUnique(
+       CPPPATH = [
+               env.get('SRC_DIR')+'/extlibs', 
+               'include', 
+               'src',
+               '../serverBuilder/include',
+               '../common/primitiveResource/include'
+       ])
+
+if target_os not in ['windows', 'winrt']:
+    resource_container_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    if target_os != 'android':
+        resource_container_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os == 'android':
+    resource_container_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    resource_container_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+       
+#resource_container_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+resource_container_env.PrependUnique(LIBS = ['server_builder', 'service_common', 'oc','octbstack', 'oc_logger', 'oc_logger_core', 'connectivity_abstraction'])
+resource_container_env.AppendUnique(LIBS = ['dl'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+res_container_src = env.Glob('src/*.cpp')
+res_container_static = resource_container_env.StaticLibrary('ResContainerLib', res_container_src)
+res_container_shared = resource_container_env.SharedLibrary('ResContainerLib', res_container_src)
+
+resource_container_env.InstallTarget([res_container_static,res_container_shared], 'libResContainer')
+
+#resource_container_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+
+#containertestapp = resource_container_env.Program('ContainerTest', res_container_src)
+#Alias("containertest", containertestapp)
+#env.AppendTarget('containertest')
+
+#Go to build sample apps
+#SConscript('resource-container/examples/SHPBundle/SConscript')
+
+######################################################################
+# build Sample Resource Bundle
+######################################################################
+#SConscript('resource-container/examples/SampleBundle/SConscript')
+
+sample_resource_bundle_env = resource_container_env.Clone()
+sample_resource_bundle_env.AppendUnique(CCFLAGS = ['-fPIC'])
+
+SAMPLE_RESOURCE_BUNDLE_DIR = 'examples/SampleBundle/'
+sample_resource_bundle_env.AppendUnique(CPPPATH = [
+               SAMPLE_RESOURCE_BUNDLE_DIR + 'include',
+               'include/'
+               ])              
+               
+
+sample_resource_bundle_src = [ Glob(SAMPLE_RESOURCE_BUNDLE_DIR + 'src/*.cpp'), Glob('src/*.cpp')]
+
+SampleBundle = sample_resource_bundle_env.SharedLibrary('SampleBundle', sample_resource_bundle_src)
+sample_resource_bundle_env.InstallTarget(SampleBundle, 'libSampleBundle')
+
+######################################################################
+# build hue sample bundle
+######################################################################
+
+hue_resource_bundle_env = resource_container_env.Clone()
+hue_resource_bundle_env.AppendUnique(CCFLAGS = ['-fPIC'])
+
+HUE_RESOURCE_BUNDLE_DIR = 'examples/HueSampleBundle/'
+hue_resource_bundle_env.AppendUnique(CPPPATH = [
+               HUE_RESOURCE_BUNDLE_DIR + 'include',
+               'include/'
+               ])              
+               
+hue_resource_bundle_env.PrependUnique(LIBS = ['curl'])
+               
+hue_resource_bundle_src = [ Glob(HUE_RESOURCE_BUNDLE_DIR + 'src/*.cpp'), Glob('src/*.cpp')]
+
+HueBundle = hue_resource_bundle_env.SharedLibrary('HueBundle', hue_resource_bundle_src)
+hue_resource_bundle_env.InstallTarget(HueBundle, 'libHueBundle')
+
+
+######################################################################
+# Build Container Test
+######################################################################
+containertest_env = resource_container_env.Clone();
+#containertest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+
+# Copy test configuration
+Command("examples/ResourceContainerConfig.xml","examples/ResourceContainerConfig.xml", Copy("$TARGET", "$SOURCE"))
+Ignore("examples/ResourceContainerConfig.xml", "examples/ResourceContainerConfig.xml")
+
+containertestapp = containertest_env.Program('ContainerTest', res_container_src)
+Alias("containertest", containertestapp)
+env.AppendTarget('containertest')
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueConnector.h b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueConnector.h
new file mode 100644 (file)
index 0000000..7a6ed67
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUECONNECTOR_H_
+#define HUECONNECTOR_H_
+
+#include "ProtocolBridgeConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueConnector: public ProtocolBridgeConnector
+        {
+
+        public:
+            HueConnector();
+            virtual ~HueConnector();
+            void connect();
+            void disconnect();
+            std::string transmit(std::string target, std::string data);
+            std::string read(std::string target);
+        };
+    }
+}
+
+#endif /* HUECONNECTOR_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueLight.h b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueLight.h
new file mode 100644 (file)
index 0000000..34269b2
--- /dev/null
@@ -0,0 +1,50 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUELIGHT_H_
+#define HUELIGHT_H_
+
+#include "ProtocolBridgeResource.h"
+#include "HueConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueLight: public ProtocolBridgeResource
+        {
+
+        public:
+            HueLight();
+            HueLight(HueConnector* connector, std::string address);
+            virtual ~HueLight();
+            void getAttribute(string attributeName);
+            void setAttribute(string attributeName, string value);
+            virtual void initAttributes();
+        private:
+            std::string m_address;
+            HueConnector* m_connector;
+        };
+    }
+}
+
+#endif /* HUEGATEWAYCLIENT_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/include/HueSampleBundleActivator.h
new file mode 100644 (file)
index 0000000..3fff8eb
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef HUESAMPLEBUNDLEACTIVATOR_H_
+#define HUESAMPLEBUNDLEACTIVATOR_H_
+
+#include "ResourceContainerBundleAPI.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+#include "HueConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class HueSampleBundleActivator: public BundleActivator
+        {
+        public:
+            HueSampleBundleActivator();
+            ~HueSampleBundleActivator();
+
+            void activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                    std::string bundleId);
+            void deactivateBundle();
+
+            void createResource(Configuration::resourceInfo);
+            void destroyResource(BundleResource *);
+
+            std::string m_bundleId;
+            ResourceContainerBundleAPI *m_pResourceContainer;
+            std::vector< BundleResource * > m_vecResources;
+        private:
+            HueConnector* m_connector;
+        };
+    }
+}
+
+#endif /* SAMPLEBUNDLE_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueConnector.cpp
new file mode 100644 (file)
index 0000000..96f64bc
--- /dev/null
@@ -0,0 +1,124 @@
+//******************************************************************
+//
+// 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 "HueConnector.h"
+#include <curl/curl.h>
+#include <string.h>
+#include <iostream>
+
+using namespace OIC::Service;
+
+HueConnector::HueConnector(){
+
+}
+
+HueConnector::~HueConnector(){
+
+}
+
+void HueConnector::connect(){
+
+}
+
+void HueConnector::disconnect(){
+
+}
+
+std::string HueConnector::transmit(std::string target, std::string payload){
+    std::cout << "Transmitting to " << target << " "  << payload << endl;
+    CURL *curl;
+    CURLcode res;
+    struct curl_slist *headers = NULL;                      /* http headers to send with request */
+    /* set content type */
+    headers = curl_slist_append(headers, "Accept: application/json");
+    headers = curl_slist_append(headers, "Content-Type: application/json");
+
+    const char *cstr = payload.c_str();
+
+    curl = curl_easy_init();
+
+    if(curl) {
+        curl_easy_setopt(curl, CURLOPT_URL, target.c_str());
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, cstr);
+        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+
+        /* if we don't provide POSTFIELDSIZE, libcurl will strlen() by
+       itself */
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(cstr));
+
+        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
+        /* Perform the request, res will get the return code */
+        res = curl_easy_perform(curl);
+        /* Check for errors */
+        if(res != CURLE_OK)
+            fprintf(stderr, "curl_easy_perform() failed: %s\n",
+              curl_easy_strerror(res));
+
+        /* always cleanup */
+        curl_easy_cleanup(curl);
+    }
+    return "";
+}
+
+static int writer(char* data, size_t size, size_t nmemb, std::string *buffer_in){
+    buffer_in->append(data, size * nmemb);
+    return size * nmemb;
+}
+
+std::string HueConnector::read(std::string target){
+    std::cout << "Reading from to " << target << endl;
+    CURL *curl;
+    CURLcode res;
+    struct curl_slist *headers = NULL;                      /* http headers to send with request */
+    /* set content type */
+    headers = curl_slist_append(headers, "Accept: application/json");
+    headers = curl_slist_append(headers, "Content-Type: application/json");
+
+
+    curl = curl_easy_init();
+
+    if(curl) {
+        curl_easy_setopt(curl, CURLOPT_URL, target.c_str());
+        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
+        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+
+        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
+        std::string response;
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
+
+        /* Perform the request, res will get the return code */
+        res = curl_easy_perform(curl);
+        /* Check for errors */
+        if(res != CURLE_OK){
+            fprintf(stderr, "curl_easy_perform() failed: %s\n",
+              curl_easy_strerror(res));
+        }
+        else{
+            cout << "Response is: " << response << endl;
+        }
+
+        /* always cleanup */
+        curl_easy_cleanup(curl);
+    }
+    return "";
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueLight.cpp
new file mode 100644 (file)
index 0000000..619852d
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "HueLight.h"
+
+#include <iostream>
+
+using namespace OIC::Service;
+
+HueLight::HueLight(){
+
+}
+
+HueLight::HueLight(HueConnector* connector, std::string address){
+    m_address = address;
+    m_connector = connector;
+    initAttributes();
+    std::cout << "Number of Attributes: " << m_mapAttributes.size() << "" << endl;
+
+}
+
+HueLight::~HueLight(){
+
+}
+
+void HueLight::getAttribute(string attributeName){
+
+}
+
+void HueLight::initAttributes(){
+    m_mapAttributes.insert(std::pair<string, string>("on-off", "false"));
+    m_mapAttributes.insert(std::pair<string, string>("dim", "0"));
+    m_mapAttributes.insert(std::pair<string, string>("color", "0"));
+}
+
+void HueLight::setAttribute(string attributeName, string value){
+    cout << "HueLight::setAttribute setting " << attributeName << " to " << value << std::endl;
+    this->m_mapAttributes[attributeName] = value;
+
+    if(attributeName == "on-off"){
+        m_connector->transmit(this->m_address + "/state", "{\"on\":" + value + "}");
+    }
+
+    if(attributeName == "dim"){
+        //m_connector->transmit(this->m_address + "/state", "{\"bri\":" + (value * 2.5) + "}");
+        m_connector->transmit(this->m_address + "/state", "{\"bri\":" + value + "}");
+    }
+
+    if(attributeName == "color"){
+        //m_connector->transmit(this->m_address+ "/state", "{\"hue\":" + (value * 650)  + "}");
+        m_connector->transmit(this->m_address+ "/state", "{\"hue\":" + value   + "}");
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp b/service/resource-manipulation/modules/resourceContainer/examples/HueSampleBundle/src/HueSampleBundleActivator.cpp
new file mode 100644 (file)
index 0000000..120cdb0
--- /dev/null
@@ -0,0 +1,120 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "HueSampleBundleActivator.h"
+#include "HueLight.h"
+
+#include <algorithm>
+#include <vector>
+
+using namespace OIC::Service;
+
+HueSampleBundleActivator *bundle;
+
+HueSampleBundleActivator::HueSampleBundleActivator()
+{
+}
+
+HueSampleBundleActivator::~HueSampleBundleActivator()
+{
+}
+
+void HueSampleBundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                  std::string bundleId)
+{
+    std::cout << "HueSampleBundle::activateBundle called" << std::endl;
+
+    m_pResourceContainer = resourceContainer;
+    m_bundleId = bundleId;
+    m_connector = new HueConnector();
+
+    vector<Configuration::resourceInfo> resourceConfig;
+
+    resourceContainer->getResourceConfiguration(m_bundleId, &resourceConfig);
+
+    for (vector<Configuration::resourceInfo>::iterator itor = resourceConfig.begin();
+         itor != resourceConfig.end(); itor++)
+    {
+        createResource(*itor);
+    }
+}
+
+void HueSampleBundleActivator::deactivateBundle()
+{
+    std::cout << "HueSampleBundle::deactivateBundle called" << std::endl;
+
+    for (std::vector<BundleResource *>::iterator itor = m_vecResources.begin();
+         itor != m_vecResources.end(); itor++)
+    {
+        destroyResource(*itor);
+    }
+}
+
+
+void HueSampleBundleActivator::createResource(Configuration::resourceInfo resourceInfo)
+{
+    std::cout << "HueSampleBundle::createResource called" << std::endl;
+
+    if(resourceInfo.resourceType == "oic.light.control"){
+        static int lightCount = 1;
+        HueLight* hueLight = new HueLight(m_connector, resourceInfo.address);
+        resourceInfo.uri = "/hue/light/" + std::to_string(lightCount++);
+        std::cout << "Registering resource " << resourceInfo.uri << std::endl;
+        hueLight->m_uri = resourceInfo.uri;
+        hueLight->m_resourceType = resourceInfo.resourceType;
+        hueLight->m_name = resourceInfo.name;
+
+        m_pResourceContainer->registerResource(hueLight);
+        m_vecResources.push_back(hueLight);
+    }
+}
+
+
+void HueSampleBundleActivator::destroyResource(BundleResource *resource)
+{
+    std::cout << "HueSampleBundle::destroyResource called" << std::endl;
+
+    std::vector <BundleResource *>::iterator itor;
+
+    itor = std::find(m_vecResources.begin(), m_vecResources.end(), resource);
+
+    if (itor != m_vecResources.end())
+        m_vecResources.erase(itor);
+
+    // check
+    //delete resource;
+
+    m_pResourceContainer->unregisterResource(resource);
+}
+
+extern "C" void externalActivateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                       std::string bundleId)
+{
+    bundle = new HueSampleBundleActivator();
+    bundle->activateBundle(resourceContainer, bundleId);
+}
+
+extern "C" void externalDeactivateBundle()
+{
+    if (!bundle)
+    {
+        bundle->deactivateBundle();
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/ResourceContainerConfig.xml b/service/resource-manipulation/modules/resourceContainer/examples/ResourceContainerConfig.xml
new file mode 100644 (file)
index 0000000..4bceb0f
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<container>      
+    <bundle>
+        <id>oic.bundle.discomfortIndexSensor</id>
+        <path>libSampleBundle.so</path>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>DiscomfortIndexSensor1</name>
+                               <resourceType>core.softsensor</resourceType>
+                <attributes>
+                  <attribute>
+                    <name>version</name>
+                    <type>string</type>
+                    <value>1.0</value>
+                  </attribute>
+                  <attribute>
+                    <name>lifetime</name>
+                    <type>int</type>
+                    <value>60</value>
+                  </attribute>
+                </attributes>
+                <outputs>
+                  <output>
+                    <name>timestamp</name>
+                    <type>string</type>
+                  </output>
+                  <output>
+                    <name>temperature</name>
+                    <type>string</type>
+                  </output>
+                  <output>
+                    <name>humidity</name>
+                    <type>string</type>
+                  </output>
+                  <output>
+                    <name>discomfortIndex</name>
+                    <type>int</type>
+                  </output>
+                </outputs>
+                <inputs>
+                  <input>Thing_TempHumSensor</input>
+                  <input>Thing_TempHumSensor1</input>
+                </inputs>
+            </resourceInfo>       
+        </resources>
+    </bundle>
+    <bundle>
+        <id>oic.bundle.hueSample</id>
+        <path>libHueBundle.so</path>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>light</name>
+                               <resourceType>oic.light.control</resourceType>
+                <address>http://192.168.0.2/api/newdeveloper/lights/1</address>
+            </resourceInfo>       
+        </resources>
+    </bundle>
+</container>
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensor.h b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensor.h
new file mode 100644 (file)
index 0000000..87d830e
--- /dev/null
@@ -0,0 +1,85 @@
+/******************************************************************
+*
+* Copyright 2015 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/*
+* DiscomfortIndexSensor.h
+*/
+
+#ifndef DISCOMFORTINDEXSENSOR_H_
+#define DISCOMFORTINDEXSENSOR_H_
+
+/**
+* This header file is included to define _EXPORT_.
+*/
+
+#include <iostream>
+
+#include "SoftSensorResource.h"
+
+using namespace OIC::Service;
+
+namespace DiscomfortIndexSensorName
+{
+#define PHYSICAL_EA 2
+
+    typedef struct _physicalInput_
+    {
+        char *m_thingName;
+        int m_inputNum;
+        void *m_pInputStruct;
+    } physicalInput;
+
+    typedef enum
+    {
+        SUCCESS = 0, ERROR, ALL_DISCOMPORT, HALF_DISCOMPORT, LITTLE_DISCOMPORT, ALL_COMPORT
+    } DIResult;
+
+    class DiscomfortIndexSensor
+    {
+        private:
+
+            static physicalInput s_PHYSICAL_SOFTSENSORs[PHYSICAL_EA];
+
+            class InValue
+            {
+                public:
+                    std::string m_timestamp; // .
+                    std::string m_discomfortIndex; // Discomfort Index. ( 2 ~ 5 )
+                    std::string m_humidity; // relative humidity.
+                    std::string m_temperature; // celsius temperature.
+            };
+
+            InValue m_DI[PHYSICAL_EA];
+            InValue m_result;
+
+        public:
+            DiscomfortIndexSensor();
+
+            int runLogic(std::vector< SoftSensorResource::SensorData > &sensorData);
+            DIResult getInput(std::vector< SoftSensorResource::SensorData > &contextDataList,
+                              InValue *data);
+            DIResult makeDiscomfortIndex(InValue *data);
+            SoftSensorResource::SensorData setOutput(int property_count, InValue *data);
+
+            SoftSensorResource::SensorData m_output;
+    };
+};
+
+#endif /* DISCOMFORTINDEXSENSOR_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensorResource.h b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/DiscomfortIndexSensorResource.h
new file mode 100644 (file)
index 0000000..216b954
--- /dev/null
@@ -0,0 +1,48 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef DISCOMFORTINDEXSENSORRESOURCE_H_
+#define DISCOMFORTINDEXSENSORRESOURCE_H_
+
+#include <iostream>
+
+#include "SoftSensorResource.h"
+#include "DiscomfortIndexSensor.h"
+
+using namespace DiscomfortIndexSensorName;
+using namespace OIC::Service;
+
+class DiscomfortIndexSensorResource : public SoftSensorResource
+{
+    public:
+        DiscomfortIndexSensorResource();
+        ~DiscomfortIndexSensorResource();
+
+        void getAttribute(string attributeName);
+        void setAttribute(string attributeName, string value);
+        virtual void initAttributes();
+
+        void setInputAttributes(vector < SensorData > inputs);
+
+    private:
+        DiscomfortIndexSensor *m_pDiscomfortIndexSensor;
+};
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SampleBundle.h b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SampleBundle.h
new file mode 100644 (file)
index 0000000..8a1aad4
--- /dev/null
@@ -0,0 +1,50 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SAMPLEBUNDLE_H_
+#define SAMPLEBUNDLE_H_
+
+#include <algorithm>
+#include <vector>
+
+#include "ResourceContainerBundleAPI.h"
+#include "BundleActivator.h"
+#include "BundleResource.h"
+
+using namespace OIC::Service;
+
+class SampleBundle: public BundleActivator
+{
+    public:
+        SampleBundle();
+        ~SampleBundle();
+
+        void activateBundle(ResourceContainerBundleAPI *resourceContainer, std::string bundleId);
+        void deactivateBundle();
+
+        void createResource(Configuration::resourceInfo);
+        void destroyResource(BundleResource *);
+
+        std::string m_bundleId;
+        ResourceContainerBundleAPI *m_pResourceContainer;
+        std::vector<BundleResource *> m_vecResources;
+};
+
+#endif /* SAMPLEBUNDLE_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SysTimer.h b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/include/SysTimer.h
new file mode 100644 (file)
index 0000000..496d4a4
--- /dev/null
@@ -0,0 +1,37 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+/*
+ * SysTimer.h
+ */
+
+#ifndef SYSTIMER_H_
+#define SYSTIMER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+class SysTimer
+{
+    public:
+        static std::string MilliSecondAsString();
+        static std::string UTCSecondAsString();
+};
+
+#endif /* SYSTIMER_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensor.cpp b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensor.cpp
new file mode 100644 (file)
index 0000000..ac3fe2f
--- /dev/null
@@ -0,0 +1,249 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * This file contains the exported symbol.
+ */
+#include "DiscomfortIndexSensor.h"
+#include "SysTimer.h"
+
+#ifdef __ANDROID__
+#include "OCAndroid.h"
+#endif
+
+using namespace DiscomfortIndexSensorName;
+
+#define SENSOR_NAME "DiscomfortIndexSensor"
+
+char *inputName[2] =
+{ (char *)"temperature", (char *)"humidity" };
+
+physicalInput DiscomfortIndexSensor::s_PHYSICAL_SOFTSENSORs[PHYSICAL_EA] =
+{
+    { (char *)"Thing_TempHumSensor", 2, (void *) &inputName },
+    { (char *)"Thing_TempHumSensor1", 2, (void *) &inputName }
+};
+
+DiscomfortIndexSensor::DiscomfortIndexSensor()
+{
+    m_result.m_timestamp = "";
+    m_result.m_humidity = "";
+    m_result.m_temperature = "";
+    m_result.m_discomfortIndex = "";
+}
+
+int DiscomfortIndexSensor::runLogic(std::vector< OIC::Service::SoftSensorResource::SensorData > &sensorData)
+{
+    std::cout << "[DiscomfortIndexSensor] DiscomfortIndexSensor::" << __func__ << " is called."
+              << std::endl;
+
+    DIResult result;
+
+    if (getInput(sensorData, m_DI) == SUCCESS)
+    {
+        if ((result = makeDiscomfortIndex(m_DI)) != SUCCESS)
+        {
+            std::cout << "Error : makeDiscomfortIndex() result = " << result << std::endl;
+            return -1;
+        }
+
+        m_output = setOutput(4, m_DI);
+
+        return 0;
+    }
+
+    return -1;
+}
+
+/**
+ * Get Input data (temperature, humidity) using resource Client of Iotivity base.
+ */
+DIResult DiscomfortIndexSensor::getInput(std::vector< OIC::Service::SoftSensorResource::SensorData >
+        &sensorData, InValue *data)
+{
+    int result_flag = 0;
+    int contextSize = 0;
+
+    if ((contextSize = sensorData.size()) == 0)
+    {
+        std::cout << "Physical Context data is not exist." << std::endl;
+        return ERROR;
+    }
+
+    for (int i = 0; i < contextSize; i++)
+    {
+        for (int k = 0; k < PHYSICAL_EA; k++)
+        {
+            if (sensorData[i].sensorName == s_PHYSICAL_SOFTSENSORs[k].m_thingName)
+            {
+                std::vector < std::map< std::string, std::string > > lVector =
+                    sensorData[i].data;
+                int requiredInputNum = s_PHYSICAL_SOFTSENSORs[k].m_inputNum;
+                char **pchar = (char **) (s_PHYSICAL_SOFTSENSORs[k].m_pInputStruct);
+                if (requiredInputNum == 0)
+                {
+                    std::cout << "No input List." << std::endl;
+                    return ERROR;
+                }
+
+                for (unsigned int j = 0; j < lVector.size(); j++)
+                {
+                    std::string name = lVector[j]["name"];
+
+                    if (name.compare(*pchar) == 0)
+                    {
+                        data->m_temperature = lVector[j]["value"];
+                        requiredInputNum--;
+                    }
+                    else if (name.compare(*(++pchar)) == 0)
+                    {
+                        data->m_humidity = lVector[j]["value"];
+                        requiredInputNum--;
+                    }
+                }
+
+                if (requiredInputNum == 0)
+                {
+                    data++;
+                    result_flag++;
+                }
+                break;
+            } // if
+        } // for
+    }
+
+    if (result_flag == PHYSICAL_EA)
+    {
+        std::cout << "Success : getInput()" << std::endl;
+        return SUCCESS;
+    }
+
+    return ERROR;
+}
+
+/**
+ * Calculation of DiscomfortIndex with TEMP&HUMI of InValue.
+ */
+DIResult DiscomfortIndexSensor::makeDiscomfortIndex(InValue *data)
+{
+    int discomfortIndex = (int) ERROR;
+    double sumDI = 0.0;
+
+    m_result.m_temperature = "";
+    m_result.m_humidity = "";
+
+    for (int i = 0; i < PHYSICAL_EA; i++)
+    {
+        if (i != 0)
+        {
+            m_result.m_temperature += ", ";
+            m_result.m_humidity += ", ";
+        }
+
+        double dI = 0.0;
+        int t = std::stoi((data + i)->m_temperature);
+        int h = std::stoi((data + i)->m_humidity);
+        double F = (9.0 * (double) t) / 5.0 + 32.0;
+
+        std::cout << "Device Number : " << i << std::endl;
+
+        dI = F - (F - 58.0) * (double) ((100 - h) * 55) / 10000.0;
+
+        std::cout << "Discomfort level : " << dI << ", Temperature :" << t << ", Humidity :" << h
+                  << std::endl;
+
+        (data + i)->m_discomfortIndex = std::to_string(0);
+        m_result.m_temperature += std::to_string(t) + ", ";
+        m_result.m_humidity += std::to_string(h) + ", ";
+        sumDI += dI;
+    }
+
+    sumDI = sumDI / PHYSICAL_EA;
+    std::cout << "[result] Avg. DI level : " << sumDI << std::endl;
+    if (sumDI >= 80.0)
+    {
+        discomfortIndex = (int) ALL_DISCOMPORT;
+        std::cout << "DI : " << discomfortIndex << " : All person discomfort. : " << sumDI
+                  << std::endl;
+    }
+    else if (sumDI >= 75.0)
+    {
+        discomfortIndex = (int) HALF_DISCOMPORT;
+        std::cout << "DI : " << discomfortIndex << " : Half of person discomfort. : " << sumDI
+                  << std::endl;
+    }
+    else if (sumDI >= 68.0)
+    {
+        discomfortIndex = (int) LITTLE_DISCOMPORT;
+        std::cout << "DI : " << discomfortIndex << " : A little person discomfort. : " << sumDI
+                  << std::endl;
+    }
+    else
+    {
+        discomfortIndex = (int) ALL_COMPORT;
+        std::cout << "DI : " << discomfortIndex << " : All person comfort. : " << sumDI
+                  << std::endl;
+    }
+
+    m_result.m_discomfortIndex = std::to_string(discomfortIndex);
+    std::cout << "[result] Discomfort Index : " << m_result.m_discomfortIndex << std::endl;
+
+    return SUCCESS;
+}
+
+OIC::Service::SoftSensorResource::SensorData DiscomfortIndexSensor::setOutput(int property_count,
+        InValue *data)
+{
+    OIC::Service::SoftSensorResource::SensorData out;
+
+    std::map < std::string, std::string > output_property;
+
+    out.sensorName = SENSOR_NAME;
+
+    output_property.insert(std::make_pair("name", "timestamp"));
+    output_property.insert(std::make_pair("type", "string"));
+    output_property.insert(std::make_pair("value", m_result.m_timestamp));
+
+    out.data.push_back(output_property);
+
+    output_property.clear();
+    output_property.insert(std::make_pair("name", "temperature"));
+    output_property.insert(std::make_pair("type", "string"));
+    output_property.insert(std::make_pair("value", m_result.m_temperature));
+
+    out.data.push_back(output_property);
+
+    output_property.clear();
+    output_property.insert(std::make_pair("name", "humidity"));
+    output_property.insert(std::make_pair("type", "string"));
+    output_property.insert(std::make_pair("value", m_result.m_humidity));
+
+    out.data.push_back(output_property);
+
+    output_property.clear();
+    output_property.insert(std::make_pair("name", "discomfortIndex"));
+    output_property.insert(std::make_pair("type", "int"));
+    output_property.insert(std::make_pair("value", m_result.m_discomfortIndex));
+
+    out.data.push_back(output_property);
+
+    return out;
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensorResource.cpp b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/DiscomfortIndexSensorResource.cpp
new file mode 100644 (file)
index 0000000..1a791a9
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "DiscomfortIndexSensorResource.h"
+
+DiscomfortIndexSensorResource::DiscomfortIndexSensorResource()
+{
+    m_pDiscomfortIndexSensor = new DiscomfortIndexSensor();
+    initAttributes();
+}
+
+DiscomfortIndexSensorResource::~DiscomfortIndexSensorResource()
+{
+    delete m_pDiscomfortIndexSensor;
+}
+
+void DiscomfortIndexSensorResource::initAttributes()
+{
+    m_mapAttributes.insert(std::pair<string, string>("temperature", "23"));
+    m_mapAttributes.insert(std::pair<string, string>("humidity", "40"));
+    m_mapAttributes.insert(std::pair<string, string>("discomfortIndex", "5"));
+}
+
+void DiscomfortIndexSensorResource::getAttribute(string attributeName)
+{
+    cout << "DiscomfortIndexSensorResource::getAttribute called !!" << endl;
+}
+
+void DiscomfortIndexSensorResource::setAttribute(string attributeName, string value)
+{
+    cout << "DiscomfortIndexSensorResource::setAttribute called !!" << endl;
+
+    m_mapAttributes[attributeName] = value;
+}
+
+void DiscomfortIndexSensorResource::setInputAttributes(vector < SensorData > inputs)
+{
+    m_pDiscomfortIndexSensor->runLogic(inputs);
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SampleBundle.cpp b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SampleBundle.cpp
new file mode 100644 (file)
index 0000000..5ed7fa8
--- /dev/null
@@ -0,0 +1,115 @@
+//******************************************************************
+//
+// 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 "SampleBundle.h"
+#include "DiscomfortIndexSensorResource.h"
+
+using namespace OIC::Service;
+
+SampleBundle *bundle;
+
+SampleBundle::SampleBundle()
+{
+}
+
+SampleBundle::~SampleBundle()
+{
+}
+
+void SampleBundle::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                  std::string bundleId)
+{
+    std::cout << "SampleBundle::activateBundle called" << std::endl;
+
+    m_pResourceContainer = resourceContainer;
+    m_bundleId = bundleId;
+
+    vector<Configuration::resourceInfo> resourceConfig;
+
+    resourceContainer->getResourceConfiguration(m_bundleId, &resourceConfig);
+
+    for (vector<Configuration::resourceInfo>::iterator itor = resourceConfig.begin();
+         itor != resourceConfig.end(); itor++)
+    {
+        createResource(*itor);
+    }
+}
+
+void SampleBundle::deactivateBundle()
+{
+    std::cout << "SampleBundle::deactivateBundle called" << std::endl;
+
+    for (std::vector<BundleResource *>::iterator itor = m_vecResources.begin();
+         itor != m_vecResources.end(); itor++)
+    {
+        destroyResource(*itor);
+    }
+}
+
+// TODO : has to be updated for setting the info
+void SampleBundle::createResource(Configuration::resourceInfo resourceInfo)
+{
+    std::cout << "SampleBundle::createResource called" << std::endl;
+    static int discomfortIndexSensorCount = 0;
+    DiscomfortIndexSensorResource *newResource = new DiscomfortIndexSensorResource();
+    if(!resourceInfo.uri.empty()){
+        newResource->m_uri = resourceInfo.uri;
+    }
+    else{
+        newResource->m_uri = "sampleBundle/discomfortIndex/" + std::to_string(discomfortIndexSensorCount++);
+    }
+    newResource->m_resourceType = resourceInfo.resourceType;
+
+    m_pResourceContainer->registerResource(newResource);
+
+    m_vecResources.push_back(newResource);
+}
+
+void SampleBundle::destroyResource(BundleResource *resource)
+{
+    std::cout << "SampleBundle::destroyResource called" << std::endl;
+
+    std::vector <BundleResource *>::iterator itor;
+
+    itor = std::find(m_vecResources.begin(), m_vecResources.end(), resource);
+
+    if (itor != m_vecResources.end())
+        m_vecResources.erase(itor);
+
+    // check
+    //delete resource;
+
+    m_pResourceContainer->unregisterResource(resource);
+}
+
+extern "C" void externalActivateBundle(ResourceContainerBundleAPI *resourceContainer,
+                                       std::string bundleId)
+{
+    bundle = new SampleBundle();
+    bundle->activateBundle(resourceContainer, bundleId);
+}
+
+extern "C" void externalDeactivateBundle()
+{
+    if (!bundle)
+    {
+        bundle->deactivateBundle();
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SysTimer.cpp b/service/resource-manipulation/modules/resourceContainer/examples/SampleBundle/src/SysTimer.cpp
new file mode 100644 (file)
index 0000000..032e0fc
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <cstdlib>
+#include <sys/time.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include "SysTimer.h"
+
+#include <stdint.h>
+std::string SysTimer::MilliSecondAsString()
+{
+    std::stringstream ss;
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    long long val = tv.tv_sec * (long long) 1000 + tv.tv_usec / 1000;
+
+    ss << val;
+    std::string strTime = ss.str();
+
+    return strTime;
+}
+
+std::string SysTimer::UTCSecondAsString()
+{
+    std::stringstream ss;
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    unsigned long val = tv.tv_sec;
+
+    ss << val;
+    std::string strTime = ss.str();
+
+    return strTime;
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/include/BundleActivator.h b/service/resource-manipulation/modules/resourceContainer/include/BundleActivator.h
new file mode 100644 (file)
index 0000000..eeae19c
--- /dev/null
@@ -0,0 +1,45 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLEACTIVATOR_H_
+#define BUNDLEACTIVATOR_H_
+
+#include "ResourceContainerBundleAPI.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class BundleActivator
+        {
+
+        public:
+            BundleActivator();
+            virtual ~BundleActivator();
+            virtual void activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                    std::string bundleId);
+            virtual void deactivateBundle();
+        };
+    }
+}
+
+#endif /* RESOURCEBUNDLE_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/include/BundleInfo.h b/service/resource-manipulation/modules/resourceContainer/include/BundleInfo.h
new file mode 100644 (file)
index 0000000..d8d6036
--- /dev/null
@@ -0,0 +1,54 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLEINFO_H_
+#define BUNDLEINFO_H_
+
+#include <string>
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        /*
+         * Describes a bundle with resources, that can be loaded dynamically.
+         */
+        class BundleInfo
+        {
+        public:
+            BundleInfo();
+            virtual ~BundleInfo();
+            virtual void setID(string name) = 0;
+            virtual string getID() = 0;
+            virtual void setPath(string path) = 0;
+            virtual string getPath() = 0;
+            virtual void setVersion(string version) = 0;
+            virtual string getVersion() = 0;
+            virtual int getId() = 0; // will be set by container
+            static BundleInfo* createBundleInfo();
+        protected:
+            string m_ID, m_path, m_version;
+        };
+    }
+}
+
+#endif /* BUNDLEINFO_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/include/BundleInfoInternal.h b/service/resource-manipulation/modules/resourceContainer/include/BundleInfoInternal.h
new file mode 100644 (file)
index 0000000..e88e66c
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLEINFOINTERNAL_H_
+#define BUNDLEINFOINTERNAL_H_
+
+#include <string>
+#include "BundleInfo.h"
+#include "ResourceContainerBundleAPI.h"
+
+using namespace std;
+using namespace OIC::Service;
+
+namespace OIC{
+    namespace Service{
+
+        typedef void activator_t(ResourceContainerBundleAPI *, std::string bundleId);
+        typedef void deactivator_t(void);
+
+        class BundleInfoInternal: public BundleInfo
+        {
+            public:
+                BundleInfoInternal();
+                BundleInfoInternal(BundleInfo *info);
+                virtual ~BundleInfoInternal();
+                void setID(string id);
+                string getID();
+                void setPath(string path);
+                string getPath();
+                void setVersion(string version);
+                string getVersion();
+
+                void setLoaded(bool loaded);
+                bool isLoaded();
+                void setActivated(bool activated);
+                bool isActivated();
+                int getId();
+                void setId(int id);
+
+                void setBundleActivator(activator_t *);
+                activator_t *getBundleActivator();
+
+                void setBundleDeactivator(deactivator_t *);
+                deactivator_t *getBundleDeactivator();
+
+                void setBundleHandle(void *);
+                void *getBundleHandle();
+
+            private:
+                bool m_loaded, m_activated;
+                int m_id;
+                activator_t *m_activator;
+                deactivator_t *m_deactivator;
+                void *m_bundleHandle;
+        };
+    }
+}
+
+#endif /* BUNDLEINFOINTERNAL_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/include/BundleResource.h b/service/resource-manipulation/modules/resourceContainer/include/BundleResource.h
new file mode 100644 (file)
index 0000000..12aab49
--- /dev/null
@@ -0,0 +1,53 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef BUNDLERESOURCE_H_
+#define BUNDLERESOURCE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class BundleResource
+        {
+        public:
+            BundleResource();
+            virtual ~BundleResource();
+
+            // TODO use type variant mechanism
+            virtual void getAttribute(string attributeName) = 0;
+            virtual void setAttribute(string attributeName, string value) = 0;
+            virtual void initAttributes() = 0;
+
+        public:
+            string m_name, m_uri, m_resourceType, m_address;
+            map< string, vector< map< string, string > > > m_mapResourceProperty;
+            map< string, string > m_mapAttributes;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/Configuration.h b/service/resource-manipulation/modules/resourceContainer/include/Configuration.h
new file mode 100644 (file)
index 0000000..20f61ce
--- /dev/null
@@ -0,0 +1,73 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef CONFIGURATION_H_
+#define CONFIGURATION_H_
+
+#include <unistd.h>
+#include <string.h>
+#include <fstream>
+
+#include "rapidxml/rapidxml.hpp"
+#include "rapidxml/rapidxml_print.hpp"
+
+#include "ResourceContainer.h"
+#include "BundleInfo.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class Configuration
+        {
+        public:
+            typedef vector< std::map< std::string, std::string > > configInfo;
+            struct resourceInfo
+            {
+                std::string name;
+                std::string uri;
+                std::string resourceType;
+                std::string address;
+                std::map< std::string, std::vector< std::map< std::string, std::string > > > resourceProperty;
+            };
+
+            Configuration();
+            ~Configuration();
+
+            Configuration(string configFile);
+
+            void getCommonConfiguration(configInfo *configOutput);
+            void getBundleConfiguration(std::string bundleId, configInfo *configOutput);
+            void getResourceConfiguration(std::string bundleId,
+                    std::vector< resourceInfo > *configOutput);
+            void getConfiguredBundles(configInfo *configOutput);
+
+        private:
+            void getConfigDocument(std::string pathConfigFile, std::string *pConfigData);
+            void getCurrentPath(std::string *path);
+
+            string m_pathConfigFile, m_configFile;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeConnector.h b/service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeConnector.h
new file mode 100644 (file)
index 0000000..88d033b
--- /dev/null
@@ -0,0 +1,43 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef PROTOCOLBRIDGECONNECTOR_H_
+#define PROTOCOLBRIDGECONNECTOR_H_
+
+#include "BundleResource.h"
+#include <map>
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ProtocolBridgeConnector
+        {
+        public:
+            ProtocolBridgeConnector();
+            virtual ~ProtocolBridgeConnector();
+            virtual void connect() = 0;
+            virtual void disconnect() = 0;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeResource.h b/service/resource-manipulation/modules/resourceContainer/include/ProtocolBridgeResource.h
new file mode 100644 (file)
index 0000000..03543ed
--- /dev/null
@@ -0,0 +1,43 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef PROTOCOLBRIDGERESOURCE_H_
+#define PROTOCOLBRIDGERESOURCE_H_
+
+#include "BundleResource.h"
+#include <map>
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ProtocolBridgeResource: public BundleResource
+        {
+        public:
+            ProtocolBridgeResource();
+            virtual ~ProtocolBridgeResource();
+            virtual void getAttribute(string attributeName) = 0;
+            virtual void setAttribute(string attributeName, string value) = 0;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/ResourceContainer.h b/service/resource-manipulation/modules/resourceContainer/include/ResourceContainer.h
new file mode 100644 (file)
index 0000000..16643d8
--- /dev/null
@@ -0,0 +1,66 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECONTAINER_H_
+#define RESOURCECONTAINER_H_
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+
+#include "BundleInfo.h"
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        // placeholder
+        class Resource
+        {
+
+        };
+
+        class ResourceContainer
+        {
+        public:
+            ResourceContainer();
+            virtual ~ResourceContainer();
+            virtual void init() = 0;
+            virtual void init(string configFile) = 0;
+            virtual void registerBundle(BundleInfo *bundleinfo) = 0;
+            virtual void unregisterBundle(BundleInfo *bundleinfo) = 0;
+            virtual void unregisterBundle(int id) = 0;
+            virtual void activateBundle(int id) = 0;
+            virtual void deactivateBundle(int id) = 0;
+            virtual void activateBundleByName(string name) = 0;
+            virtual void deactivateBundleByName(string id) = 0;
+            virtual void activateBundle(BundleInfo *bundleInfo) = 0;
+            virtual void deactivateBundle(BundleInfo *bundleInfo) = 0;
+            virtual vector< Resource * > listBundleResources(string id) = 0;
+
+            static ResourceContainer *getInstance();
+        };
+    }
+}
+
+#endif /* RESOURCECONTAINER_H_ */
diff --git a/service/resource-manipulation/modules/resourceContainer/include/ResourceContainerBundleAPI.h b/service/resource-manipulation/modules/resourceContainer/include/ResourceContainerBundleAPI.h
new file mode 100644 (file)
index 0000000..74a925a
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECONTAINERBUNDLEAPI_H_
+#define RESOURCECONTAINERBUNDLEAPI_H_
+
+#include <unistd.h>
+#include <string.h>
+#include <fstream>
+
+#include "ResourceContainer.h"
+#include "BundleInfo.h"
+#include "Configuration.h"
+#include "BundleResource.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceContainerBundleAPI: public Configuration
+        {
+        public:
+            typedef std::map< std::string, std::string > configInfo;
+            ResourceContainerBundleAPI();
+            virtual ~ResourceContainerBundleAPI();
+            virtual void registerResource(BundleResource *resource) = 0;
+            virtual void unregisterResource(BundleResource *resource) = 0;
+            virtual void getCommonConfiguration(configInfo *configOutput) = 0;
+            virtual void getBundleConfiguration(std::string bundleId, configInfo *configOutput) = 0;
+            virtual void getResourceConfiguration(std::string bundleId,
+                    std::vector< resourceInfo > *configOutput) = 0;
+
+            static ResourceContainerBundleAPI *getInstance();
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/ResourceContainerImpl.h b/service/resource-manipulation/modules/resourceContainer/include/ResourceContainerImpl.h
new file mode 100644 (file)
index 0000000..feb70e5
--- /dev/null
@@ -0,0 +1,85 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef RESOURCECONTAINERIMPL_H_
+#define RESOURCECONTAINERIMPL_H_
+
+#include "ResourceContainer.h"
+#include "ResourceContainerBundleAPI.h"
+#include "BundleInfoInternal.h"
+
+#include "PrimitiveRequest.h"
+#include "PrimitiveResponse.h"
+#include "PrimitiveServerResource.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class ResourceContainerImpl: public ResourceContainer, public ResourceContainerBundleAPI
+        {
+        public:
+            ResourceContainerImpl();
+            virtual ~ResourceContainerImpl();
+
+            // methods from ResourceContainer
+            void init();
+            void init(string configFile);
+            void activateBundle(int id);
+            void deactivateBundle(int id);
+            void activateBundleByName(string name);
+            void deactivateBundleByName(string id);
+            void activateBundle(BundleInfo *bundleInfo);
+            void deactivateBundle(BundleInfo *bundleInfo);
+            vector< Resource * > listBundleResources(string id);
+
+            // methods from ResourceContainerBundleAPI
+            void registerBundle(BundleInfo *bundleinfo);
+            void unregisterBundle(BundleInfo *bundleinfo);
+            void unregisterBundle(int id);
+            void registerResource(BundleResource *resource);
+            void unregisterResource(BundleResource *resource);
+
+            void getCommonConfiguration(configInfo *configOutput);
+            void getBundleConfiguration(std::string bundleId, configInfo *configOutput);
+            void getResourceConfiguration(std::string bundleId,
+                    std::vector< resourceInfo > *configOutput);
+
+            PrimitiveGetResponse getRequestHandler(const PrimitiveRequest &request,
+                    const ResourceAttributes &attributes);
+
+            PrimitiveSetResponse setRequestHandler(const PrimitiveRequest &request,
+                    const ResourceAttributes &attributes);
+
+            static ResourceContainerImpl *getImplInstance();
+
+        private:
+            vector< BundleInfoInternal * > m_bundles;
+            map< std::string, PrimitiveServerResource::Ptr > m_mapServers; //<uri, serverPtr>
+            map< std::string, BundleResource * > m_mapResources; //<uri, resourcePtr>
+            string m_configFile;
+            Configuration *m_config;
+        };
+    }
+}
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/include/SoftSensorResource.h b/service/resource-manipulation/modules/resourceContainer/include/SoftSensorResource.h
new file mode 100644 (file)
index 0000000..da12fc2
--- /dev/null
@@ -0,0 +1,51 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef SOFTSENSORRESOURCE_H_
+#define SOFTSENSORRESOURCE_H_
+
+#include "BundleResource.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class SoftSensorResource: public BundleResource
+        {
+        public:
+            struct SensorData
+            {
+                string sensorName;
+                vector< map< string, string > > data;
+            };
+
+            SoftSensorResource();
+            virtual ~SoftSensorResource();
+
+            virtual void setInputAttributes(vector< SensorData > inputs) = 0;
+
+            int inputCount;
+            map< string, SensorData > m_mapStoredInputData;
+            SensorData m_outputs;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/resourceContainer/src/BundleActivator.cpp b/service/resource-manipulation/modules/resourceContainer/src/BundleActivator.cpp
new file mode 100644 (file)
index 0000000..fc39ed9
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "BundleActivator.h"
+#include "ResourceContainer.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        BundleActivator::BundleActivator()
+        {
+
+        }
+
+        BundleActivator::~BundleActivator()
+        {
+
+        }
+
+        void BundleActivator::activateBundle(ResourceContainerBundleAPI *resourceContainer,
+                std::string bundleId)
+        {
+
+        }
+
+        void BundleActivator::deactivateBundle()
+        {
+
+        }
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/BundleInfo.cpp b/service/resource-manipulation/modules/resourceContainer/src/BundleInfo.cpp
new file mode 100644 (file)
index 0000000..bcdb88f
--- /dev/null
@@ -0,0 +1,44 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "BundleInfo.h"
+#include "BundleInfoInternal.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        BundleInfo::BundleInfo()
+        {
+
+        }
+
+        BundleInfo::~BundleInfo()
+        {
+
+        }
+
+        BundleInfo *BundleInfo::createBundleInfo()
+        {
+            BundleInfoInternal *newBundleInfo = new BundleInfoInternal();
+            return newBundleInfo;
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/src/BundleInfoInternal.cpp b/service/resource-manipulation/modules/resourceContainer/src/BundleInfoInternal.cpp
new file mode 100644 (file)
index 0000000..eee04ae
--- /dev/null
@@ -0,0 +1,127 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "BundleInfoInternal.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        BundleInfoInternal::BundleInfoInternal()
+        {
+
+        }
+
+        BundleInfoInternal::~BundleInfoInternal()
+        {
+
+        }
+
+        void BundleInfoInternal::setID(string id)
+        {
+            m_ID = id;
+        }
+
+        string BundleInfoInternal::getID()
+        {
+            return m_ID;
+        }
+
+        void BundleInfoInternal::setPath(string path)
+        {
+            m_path = path;
+        }
+        string BundleInfoInternal::getPath()
+        {
+            return m_path;
+        }
+
+        void BundleInfoInternal::setVersion(string version)
+        {
+            m_version = version;
+        }
+
+        string BundleInfoInternal::getVersion()
+        {
+            return m_version;
+        }
+
+        void BundleInfoInternal::setLoaded(bool loaded)
+        {
+            m_loaded = loaded;
+        }
+
+        bool BundleInfoInternal::isLoaded()
+        {
+            return m_loaded;
+        }
+
+        void BundleInfoInternal::setActivated(bool activated)
+        {
+            m_activated = activated;
+        }
+
+        bool BundleInfoInternal::isActivated()
+        {
+            return m_activated;
+        }
+
+        int BundleInfoInternal::getId()
+        {
+            return m_id;
+        }
+
+        void BundleInfoInternal::setId(int id)
+        {
+            m_id = id;
+        }
+
+        void BundleInfoInternal::setBundleActivator(activator_t *activator)
+        {
+            m_activator = activator;
+        }
+
+        activator_t *BundleInfoInternal::getBundleActivator()
+        {
+            return m_activator;
+        }
+
+        void BundleInfoInternal::setBundleDeactivator(deactivator_t *deactivator)
+        {
+            m_deactivator = deactivator;
+        }
+
+        deactivator_t *BundleInfoInternal::getBundleDeactivator()
+        {
+            return m_deactivator;
+        }
+
+        void BundleInfoInternal::setBundleHandle(void *handle)
+        {
+            m_bundleHandle = handle;
+        }
+
+        void *BundleInfoInternal::getBundleHandle()
+        {
+            return m_bundleHandle;
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/src/BundleResource.cpp b/service/resource-manipulation/modules/resourceContainer/src/BundleResource.cpp
new file mode 100644 (file)
index 0000000..d10bec0
--- /dev/null
@@ -0,0 +1,37 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "BundleResource.h"
+#include "Configuration.h"
+
+
+namespace OIC{
+    namespace Service{
+        BundleResource::BundleResource()
+        {
+            cout << "BundleResource constructor called\n";
+        }
+
+        BundleResource::~BundleResource()
+        {
+
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/src/Configuration.cpp b/service/resource-manipulation/modules/resourceContainer/src/Configuration.cpp
new file mode 100644 (file)
index 0000000..89f96ed
--- /dev/null
@@ -0,0 +1,387 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "Configuration.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        static inline std::string trim_both(const std::string &str)
+        {
+            int npos = str.find_first_not_of(" \t\v\n\r");
+
+            if (npos == -1)
+            {
+                return "";
+            }
+
+            unsigned int n = (unsigned int) npos;
+            std::string tempString = n == std::string::npos ? str : str.substr(n, str.length());
+
+            n = tempString.find_last_not_of(" \t\v\n\r");
+
+            return n == std::string::npos ? tempString : tempString.substr(0, n + 1);
+        }
+
+        Configuration::Configuration()
+        {
+            // TODO: temporary path and config file name
+            getCurrentPath(&m_pathConfigFile);
+            m_pathConfigFile.append("/");
+            m_pathConfigFile.append("ResourceContainerConfig.xml");
+        }
+
+        Configuration::~Configuration()
+        {
+        }
+
+        Configuration::Configuration(string configFile)
+        {
+            m_configFile = configFile;
+            getCurrentPath(&m_pathConfigFile);
+            m_pathConfigFile.append("/");
+            m_pathConfigFile.append(m_configFile);
+        }
+
+        void Configuration::getCommonConfiguration(configInfo *configOutput)
+        {
+            string strConfigData;
+
+            rapidxml::xml_document< char > xmlDoc;
+
+            rapidxml::xml_node< char > *root;
+            rapidxml::xml_node< char > *item;
+            rapidxml::xml_node< char > *subItem;
+
+            string strKey, strValue;
+
+            getConfigDocument(m_pathConfigFile, &strConfigData);
+
+            try
+            {
+                xmlDoc.parse< 0 >((char *) strConfigData.c_str());
+
+                // <container>
+                root = xmlDoc.first_node();
+
+                if (!root)
+                {
+                    throw rapidxml::parse_error("No Root Element", 0);
+                }
+                std::map< std::string, std::string > bundleMap;
+                for (item = root->first_node(); item; item = item->next_sibling())
+                {
+                    strKey = item->name();
+                    strValue = item->value();
+
+                    // <config>
+                    if (!strKey.compare("config"))
+                    {
+                        for (subItem = item->first_node(); subItem; subItem =
+                                subItem->next_sibling())
+                        {
+                            strKey = subItem->name();
+                            strValue = subItem->value();
+
+                            bundleMap.insert(
+                                    std::make_pair(trim_both(strKey), trim_both(strValue)));
+                        }
+                        break;
+                    }
+                }
+                configOutput->push_back(bundleMap);
+            }
+            catch (rapidxml::parse_error &e)
+            {
+                cout << "xml parsing failed !!" << endl;
+                cout << e.what() << endl;
+            }
+        }
+
+        void Configuration::getConfiguredBundles(configInfo *configOutput)
+        {
+            string strConfigData;
+
+            rapidxml::xml_document< char > xmlDoc;
+
+            rapidxml::xml_node< char > *bundle;
+            rapidxml::xml_node< char > *subItem;
+
+            string strKey, strValue;
+
+            cout << "Opening: " << m_pathConfigFile << endl;
+
+            getConfigDocument(m_pathConfigFile, &strConfigData);
+
+            //cout << strConfigData.c_str() << endl;
+            try
+            {
+
+                xmlDoc.parse< 0 >((char *) strConfigData.c_str());
+                //cout << "Name of first node is: " << xmlDoc.first_node()->name() << endl;
+
+                for (bundle = xmlDoc.first_node()->first_node("bundle"); bundle;
+                        bundle = bundle->next_sibling())
+                {
+                    std::map< std::string, std::string > bundleMap;
+                    //cout << "Bundle: " << bundle->name() << endl;
+                    for (subItem = bundle->first_node(); subItem; subItem = subItem->next_sibling())
+                    {
+                        strKey = subItem->name();
+                        strValue = subItem->value();
+                        if (strlen(subItem->value()) > 0)
+                        {
+                            bundleMap.insert(
+                                    std::make_pair(trim_both(strKey), trim_both(strValue)));
+                            //cout << strKey << " " << strValue << endl;
+
+                        }
+                    }
+                    configOutput->push_back(bundleMap);
+                }
+
+            }
+            catch (rapidxml::parse_error &e)
+            {
+                cout << "xml parsing failed !!" << endl;
+                cout << e.what() << endl;
+            }
+        }
+
+        void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
+        {
+            string strConfigData;
+
+            rapidxml::xml_document< char > xmlDoc;
+
+            rapidxml::xml_node< char > *root;
+            rapidxml::xml_node< char > *item;
+            rapidxml::xml_node< char > *subItem;
+
+            string strKey, strValue;
+
+            getConfigDocument(m_pathConfigFile, &strConfigData);
+
+            try
+            {
+                xmlDoc.parse< 0 >((char *) strConfigData.c_str());
+
+                // <container>
+                root = xmlDoc.first_node();
+
+                if (!root)
+                {
+                    throw rapidxml::parse_error("No Root Element", 0);
+                }
+                std::map< std::string, std::string > bundleMap;
+                for (item = root->first_node(); item; item = item->next_sibling())
+                {
+                    strKey = item->name();
+                    strValue = item->value();
+
+                    // <bundle>
+                    if (!strKey.compare("bundle"))
+                    {
+                        for (subItem = item->first_node(); subItem; subItem =
+                                subItem->next_sibling())
+                        {
+                            strKey = subItem->name();
+                            strValue = subItem->value();
+
+                            if (!strKey.compare("bundleID") && strValue.compare(bundleId))
+                                break;
+
+                            // bundle info (except resource data)
+                            if (strKey.compare("resources"))
+                            {
+                                bundleMap.insert(
+                                        std::make_pair(trim_both(strKey), trim_both(strValue)));
+                            }
+                        }
+                    }
+                }
+                configOutput->push_back(bundleMap);
+
+            }
+            catch (rapidxml::parse_error &e)
+            {
+                cout << "xml parsing failed !!" << endl;
+                cout << e.what() << endl;
+            }
+        }
+
+        void Configuration::getResourceConfiguration(string bundleId,
+                vector< resourceInfo > *configOutput)
+        {
+            string strConfigData;
+
+            rapidxml::xml_document< char > xmlDoc;
+
+            rapidxml::xml_node< char > *root;
+            rapidxml::xml_node< char > *item;
+            rapidxml::xml_node< char > *subItem, *subItem2, *subItem3, *subItem4, *subItem5;
+
+            string strKey, strValue;
+
+            getConfigDocument(m_pathConfigFile, &strConfigData);
+
+            try
+            {
+                xmlDoc.parse< 0 >((char *) strConfigData.c_str());
+
+                // <container>
+                root = xmlDoc.first_node();
+
+                if (!root)
+                {
+                    throw rapidxml::parse_error("No Root Element", 0);
+                }
+
+                for (item = root->first_node(); item; item = item->next_sibling())
+                {
+                    strKey = item->name();
+                    strValue = item->value();
+
+                    // <bundle>
+                    if (!strKey.compare("bundle"))
+                    {
+                        for (subItem = item->first_node(); subItem; subItem =
+                                subItem->next_sibling())
+                        {
+                            strKey = subItem->name();
+                            strValue = subItem->value();
+
+                            if (!strKey.compare("bundleID") && strValue.compare(bundleId))
+                                break;
+
+                            // <resources>
+                            if (!strKey.compare("resources"))
+                            {
+                                for (subItem2 = subItem->first_node(); subItem2;
+                                        subItem2 = subItem2->next_sibling())
+                                {
+                                    strKey = subItem2->name();
+                                    strValue = subItem2->value();
+
+                                    // <resourceInfo> : for 1 resource
+                                    if (!strKey.compare("resourceInfo"))
+                                    {
+                                        resourceInfo tempResourceInfo;
+
+                                        for (subItem3 = subItem2->first_node(); subItem3; subItem3 =
+                                                subItem3->next_sibling())
+                                        {
+
+                                            strKey = subItem3->name();
+                                            strValue = subItem3->value();
+
+                                            if (!strKey.compare("name"))
+                                                tempResourceInfo.name = trim_both(strValue);
+
+                                            else if (!strKey.compare("uri"))
+                                                tempResourceInfo.uri = trim_both(strValue);
+
+                                            else if (!strKey.compare("address"))
+                                                tempResourceInfo.address = trim_both(strValue);
+
+                                            else if (!strKey.compare("resourceType"))
+                                                tempResourceInfo.resourceType = trim_both(strValue);
+
+                                            else
+                                            {
+                                                for (subItem4 = subItem3->first_node(); subItem4;
+                                                        subItem4 = subItem4->next_sibling())
+                                                {
+                                                    map< string, string > propertyMap;
+
+                                                    strKey = subItem4->name();
+
+                                                    for (subItem5 = subItem4->first_node();
+                                                            subItem5;
+                                                            subItem5 = subItem5->next_sibling())
+                                                    {
+                                                        string newStrKey = subItem5->name();
+                                                        string newStrValue = subItem5->value();
+
+                                                        propertyMap[trim_both(newStrKey)] =
+                                                                trim_both(newStrValue);
+                                                    }
+
+                                                    tempResourceInfo.resourceProperty[trim_both(
+                                                            strKey)].push_back(propertyMap);
+                                                }
+                                            }
+                                        }
+                                        configOutput->push_back(tempResourceInfo);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (rapidxml::parse_error &e)
+            {
+                cout << "xml parsing failed !!" << endl;
+                cout << e.what() << endl;
+            }
+        }
+
+        void Configuration::getConfigDocument(std::string pathConfigFile, std::string *pConfigData)
+        {
+            std::basic_ifstream< char > xmlFile(pathConfigFile.c_str());
+
+            if (!xmlFile.fail())
+            {
+                xmlFile.seekg(0, std::ios::end);
+                unsigned int size = (unsigned int) xmlFile.tellg();
+                xmlFile.seekg(0);
+
+                std::vector< char > xmlData(size + 1);
+                xmlData[size] = 0;
+
+                xmlFile.read(&xmlData.front(), (std::streamsize) size);
+                xmlFile.close();
+                *pConfigData = std::string(xmlData.data());
+            }
+            else
+            {
+                std::cout << "Configuration File load failed !!" << std::endl;
+            }
+        }
+
+        void Configuration::getCurrentPath(std::string *path)
+        {
+            char buffer[2048];
+            char *strPath = NULL;
+
+            int length = readlink("/proc/self/exe", buffer, 2047);
+
+            buffer[length] = '\0';
+
+            strPath = strrchr(buffer, '/');
+
+            *strPath = '\0';
+
+            path->append(buffer);
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ContainerTest.cpp b/service/resource-manipulation/modules/resourceContainer/src/ContainerTest.cpp
new file mode 100644 (file)
index 0000000..d05b2f5
--- /dev/null
@@ -0,0 +1,53 @@
+//******************************************************************
+//
+// 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 "ResourceContainer.h"
+#include "BundleInfo.h"
+#include "oc_logger.hpp"
+
+using namespace OIC::Service;
+using OC::oc_log_stream;
+
+
+/* Annother way to create a context: */
+auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+
+    return os;
+};
+
+int main()
+{
+    info_logger()->set_module("ContainerTest");
+    info_logger()->set_level(OC_LOG_INFO);
+
+    info_logger() << "Starting container test." << std::flush;
+
+    ResourceContainer *container = ResourceContainer::getInstance();
+    container->init("examples/ResourceContainerConfig.xml");
+
+    while (1)
+    {
+        ;
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeConnector.cpp b/service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeConnector.cpp
new file mode 100644 (file)
index 0000000..f55d8af
--- /dev/null
@@ -0,0 +1,40 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ProtocolBridgeConnector.h"
+
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+        ProtocolBridgeConnector::ProtocolBridgeConnector()
+        {
+
+        }
+
+        ProtocolBridgeConnector::~ProtocolBridgeConnector()
+        {
+
+        }
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeResource.cpp b/service/resource-manipulation/modules/resourceContainer/src/ProtocolBridgeResource.cpp
new file mode 100644 (file)
index 0000000..0e0eed0
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ProtocolBridgeResource.h"
+
+using namespace OIC::Service;
+
+namespace OIC{
+    namespace Service{
+        ProtocolBridgeResource::ProtocolBridgeResource()
+        {
+
+        }
+
+        ProtocolBridgeResource::~ProtocolBridgeResource()
+        {
+
+        }
+    }
+}
+
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ResourceContainer.cpp b/service/resource-manipulation/modules/resourceContainer/src/ResourceContainer.cpp
new file mode 100644 (file)
index 0000000..ff28c4c
--- /dev/null
@@ -0,0 +1,42 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ResourceContainer.h"
+#include "ResourceContainerImpl.h"
+
+namespace OIC{
+    namespace Service{
+        ResourceContainer::ResourceContainer()
+        {
+
+        }
+
+        ResourceContainer::~ResourceContainer()
+        {
+
+        }
+
+        ResourceContainer *ResourceContainer::getInstance()
+        {
+            return (ResourceContainer *)ResourceContainerImpl::getImplInstance();
+        }
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ResourceContainerBundleAPI.cpp b/service/resource-manipulation/modules/resourceContainer/src/ResourceContainerBundleAPI.cpp
new file mode 100644 (file)
index 0000000..2a78c9d
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ResourceContainerBundleAPI.h"
+
+using namespace OIC::Service;
+
+namespace OIC{
+    namespace Service{
+
+        ResourceContainerBundleAPI::ResourceContainerBundleAPI()
+        {
+
+        }
+
+        ResourceContainerBundleAPI::~ResourceContainerBundleAPI()
+        {
+
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/resourceContainer/src/ResourceContainerImpl.cpp b/service/resource-manipulation/modules/resourceContainer/src/ResourceContainerImpl.cpp
new file mode 100644 (file)
index 0000000..b9b7c87
--- /dev/null
@@ -0,0 +1,342 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ResourceContainerImpl.h"
+#include "BundleActivator.h"
+#include "ResourceContainer.h"
+#include "BundleInfoInternal.h"
+#include "logger.h"
+#include <dlfcn.h>
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+#include "oc_logger.hpp"
+
+using OC::oc_log_stream;
+using namespace OIC::Service;
+
+/* Annother way to create a context: */
+auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+    os->set_level(OC_LOG_INFO);
+    os->set_module("ResourceContainerImpl");
+    return os;
+};
+
+/* Annother way to create a context: */
+auto error_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
+{
+    static OC::oc_log_stream ols(oc_make_ostream_logger);
+    static boost::iostreams::stream<OC::oc_log_stream> os(ols);
+    os->set_level(OC_LOG_ERROR);
+    os->set_module("ResourceContainerImpl");
+    return os;
+};
+
+using namespace std;
+using namespace OIC::Service;
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        ResourceContainerImpl::ResourceContainerImpl()
+        {
+            // TODO Auto-generated constructor stub
+
+        }
+
+        ResourceContainerImpl::~ResourceContainerImpl()
+        {
+            // TODO Auto-generated destructor stub
+        }
+
+        void ResourceContainerImpl::init()
+        {
+
+        }
+
+        void ResourceContainerImpl::init(string configFile)
+        {
+            m_config = new Configuration(configFile);
+            Configuration::configInfo bundles;
+            m_config->getConfiguredBundles(&bundles);
+            for (int i = 0; i < bundles.size(); i++)
+            {
+                BundleInfo *bundleInfo = BundleInfo::createBundleInfo();
+                bundleInfo->setPath(bundles[i]["path"]);
+                bundleInfo->setVersion(bundles[i]["version"]);
+                bundleInfo->setID(bundles[i]["id"]);
+                cout << "Init Bundle:" << bundles[i]["id"] << ";" << bundles[i]["path"] << endl;
+                registerBundle(bundleInfo);
+                activateBundle(bundleInfo);
+            }
+        }
+
+        // loads the bundle
+        void ResourceContainerImpl::registerBundle(BundleInfo *bundleInfo)
+        {
+            info_logger() << "Registering bundle: " << bundleInfo->getPath() << endl;
+
+            m_bundles.push_back((BundleInfoInternal *) bundleInfo);
+            ((BundleInfoInternal *) bundleInfo)->setId(m_bundles.size() - 1);
+
+            char *error;
+
+            activator_t *bundleActivator = NULL;
+            deactivator_t *bundleDeactivator = NULL;
+
+            //sstream << bundleInfo.path << std::ends;
+
+            void *bundleHandle = NULL;
+            bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
+
+            if (bundleHandle != NULL)
+            {
+                bundleActivator = (activator_t *) dlsym(bundleHandle, "externalActivateBundle");
+                bundleDeactivator = (deactivator_t *) dlsym(bundleHandle,
+                        "externalDeactivateBundle");
+                if ((error = dlerror()) != NULL)
+                {
+                    error_logger() << error << endl;
+                }
+                else
+                {
+                    ((BundleInfoInternal *) bundleInfo)->setBundleActivator(bundleActivator);
+                    ((BundleInfoInternal *) bundleInfo)->setBundleDeactivator(bundleDeactivator);
+                    ((BundleInfoInternal *) bundleInfo)->setLoaded(true);
+                    ((BundleInfoInternal *) bundleInfo)->setBundleHandle(bundleHandle);
+                }
+            }
+            else
+            {
+                if ((error = dlerror()) != NULL)
+                {
+                    error_logger() << error << endl;
+                }
+            }
+        }
+
+        void ResourceContainerImpl::activateBundle(int id)
+        {
+            activator_t *bundleActivator = m_bundles[id]->getBundleActivator();
+            info_logger() << "Activating bundle: " << m_bundles[id]->getID() << ", "
+                    << m_bundles[id]->getId() << endl;
+
+            if (bundleActivator != NULL)
+            {
+                bundleActivator(this, m_bundles[id]->getID());
+                m_bundles[id]->setActivated(true);
+            }
+            else
+            {
+                //Unload module and return error
+                error_logger() << "Activation unsuccessful." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::activateBundle(BundleInfo *bundleInfo)
+        {
+            if (((BundleInfoInternal *) bundleInfo)->isLoaded())
+            {
+                activateBundle(bundleInfo->getId());
+            }
+        }
+
+        void ResourceContainerImpl::deactivateBundle(BundleInfo *bundleInfo)
+        {
+            if (((BundleInfoInternal *) bundleInfo)->isActivated())
+            {
+                deactivateBundle(bundleInfo->getId());
+            }
+        }
+
+        void ResourceContainerImpl::deactivateBundle(int id)
+        {
+            deactivator_t *bundleDeactivator = m_bundles[id]->getBundleDeactivator();
+            info_logger() << "De-activating bundle: " << m_bundles[id]->getID() << ", "
+                    << m_bundles[id]->getId() << endl;
+
+            if (bundleDeactivator != NULL)
+            {
+                bundleDeactivator();
+                m_bundles[id]->setActivated(false);
+            }
+            else
+            {
+                //Unload module and return error
+                error_logger() << "De-activation unsuccessful." << endl;
+            }
+        }
+
+        void ResourceContainerImpl::activateBundleByName(string name)
+        {
+
+        }
+
+        void ResourceContainerImpl::deactivateBundleByName(string id)
+        {
+
+        }
+
+        vector< Resource * > ResourceContainerImpl::listBundleResources(string id)
+        {
+            vector< Resource * > ret;
+            return ret;
+        }
+
+        void ResourceContainerImpl::registerResource(BundleResource *resource)
+        {
+            cout << "Register resource called. " << resource->m_uri << " "
+                    << resource->m_resourceType << endl;
+
+            string strUri = resource->m_uri;
+            string strResourceType = resource->m_resourceType;
+
+            PrimitiveServerResource::Ptr server =
+                    PrimitiveServerResource::Builder(strUri, strResourceType, "DEFAULT_INTERFACE").setObservable(
+                            false).setDiscoverable(true).create();
+
+            m_mapServers[strUri] = server;
+            m_mapResources[strUri] = resource;
+
+            cout << "Registered resource has " << m_mapResources[strUri]->m_mapAttributes.size()
+                    << " attributes.\n" << endl;
+
+            server->setGetRequestHandler(
+                    std::bind(&ResourceContainerImpl::getRequestHandler, this,
+                            std::placeholders::_1, std::placeholders::_2));
+
+            server->setSetRequestHandler(
+                    std::bind(&ResourceContainerImpl::setRequestHandler, this,
+                            std::placeholders::_1, std::placeholders::_2));
+        }
+
+        PrimitiveGetResponse ResourceContainerImpl::getRequestHandler(
+                const PrimitiveRequest &request, const ResourceAttributes &attributes)
+        {
+            ResourceAttributes attr;
+
+            if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
+                    && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
+            {
+                // temp
+                m_mapResources[request.getResourceUri()]->getAttribute("");
+
+                for (auto i : m_mapResources[request.getResourceUri()]->m_mapAttributes)
+                {
+                    cout << "Setting attribute " << i.first.c_str() << ", " << i.second.c_str()
+                            << endl;
+                    attr[i.first.c_str()] = i.second.c_str();
+                }
+            }
+
+            return PrimitiveGetResponse::create(attr);
+        }
+
+        PrimitiveSetResponse ResourceContainerImpl::setRequestHandler(
+                const PrimitiveRequest &request, const ResourceAttributes &attributes)
+        {
+            ResourceAttributes attr = attributes;
+
+            cout << "Set request handler resource called.\n";
+
+            if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
+                    && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
+            {
+
+                cout << "Setting the attributes of the resource." << request.getResourceUri()
+                        << " it has "
+                        << m_mapResources[request.getResourceUri()]->m_mapAttributes.size()
+                        << " attributes " << std::endl;
+
+                for (auto i : m_mapResources[request.getResourceUri()]->m_mapAttributes)
+                {
+                    if (!attr[i.first].toString().empty())
+                    {
+                        cout << "Setting " << i.first << endl;
+                        m_mapResources[request.getResourceUri()]->setAttribute(i.first,
+                                attr[i.first].toString());
+                    }
+                }
+
+                // set m_mapAttributes to attributes
+            }
+
+            return PrimitiveSetResponse::create(attr);
+        }
+
+        void ResourceContainerImpl::unregisterResource(BundleResource *resource)
+        {
+
+        }
+
+        void ResourceContainerImpl::unregisterBundle(BundleInfo *bundleInfo)
+        {
+            if (((BundleInfoInternal *) bundleInfo)->isLoaded()
+                    && !((BundleInfoInternal *) bundleInfo)->isActivated())
+            {
+                unregisterBundle(bundleInfo->getId());
+            }
+        }
+
+        void ResourceContainerImpl::unregisterBundle(int id)
+        {
+            void *bundleHandle = m_bundles[id]->getBundleHandle();
+            info_logger() << "Unregister bundle: " << m_bundles[id]->getID() << ", "
+                    << m_bundles[id]->getId() << endl;
+            char *error;
+            dlclose(bundleHandle);
+            if ((error = dlerror()) != NULL)
+            {
+                error_logger() << error << endl;
+            }
+        }
+
+        ResourceContainerImpl *ResourceContainerImpl::getImplInstance()
+        {
+            ResourceContainerImpl *ret = new ResourceContainerImpl();
+            return ret;
+        }
+
+        void ResourceContainerImpl::getCommonConfiguration(configInfo *configOutput)
+        {
+            m_config->getCommonConfiguration((Configuration::configInfo *) configOutput);
+        }
+
+        void ResourceContainerImpl::getBundleConfiguration(std::string bundleId,
+                configInfo *configOutput)
+        {
+            m_config->getBundleConfiguration(bundleId, (Configuration::configInfo *) configOutput);
+        }
+
+        void ResourceContainerImpl::getResourceConfiguration(std::string bundleId,
+                std::vector< resourceInfo > *configOutput)
+        {
+            m_config->getResourceConfiguration(bundleId, configOutput);
+        }
+    }
+}
+
diff --git a/service/resource-manipulation/modules/resourceContainer/src/SoftSensorResource.cpp b/service/resource-manipulation/modules/resourceContainer/src/SoftSensorResource.cpp
new file mode 100644 (file)
index 0000000..24fe7b1
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "SoftSensorResource.h"
+
+using namespace OIC::Service;
+namespace OIC
+{
+    namespace Service
+    {
+        SoftSensorResource::SoftSensorResource()
+        {
+
+        }
+
+        SoftSensorResource::~SoftSensorResource()
+        {
+
+        }
+    }
+}
+
diff --git a/service/resource-manipulation/modules/serverBuilder/SConscript b/service/resource-manipulation/modules/serverBuilder/SConscript
new file mode 100644 (file)
index 0000000..30fd4f0
--- /dev/null
@@ -0,0 +1,105 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# things_manager project build script
+##
+import os
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+src_dir = lib_env.get('SRC_DIR')
+
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+server_builder_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+release = env.get('RELEASE')
+
+######################################################################
+# Build flags
+######################################################################
+server_builder_env.AppendUnique(CPPPATH = [
+    '../common/primitiveResource/include/',
+    ])
+
+server_builder_env.AppendUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs', 'include'])
+
+if target_os not in ['windows', 'winrt']:
+    server_builder_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    if target_os != 'android':
+        server_builder_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os == 'android':
+    server_builder_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+    server_builder_env.PrependUnique(LIBS = ['gnustl_shared', 'compatibility', 'log'])
+
+server_builder_env.AppendUnique(LIBS = ['dl'])
+
+if not release:
+    server_builder_env.AppendUnique(CXXFLAGS = ['--coverage'])
+    server_builder_env.PrependUnique(LIBS = ['gcov'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+server_builder_src = env.Glob('src/*.cpp')
+
+server_builder_static = server_builder_env.StaticLibrary('server_builder', server_builder_src)
+server_builder_shared = server_builder_env.SharedLibrary('server_builder', server_builder_src)
+
+server_builder_env.InstallTarget([server_builder_static, server_builder_shared], 'server_builder')
+
+######################################################################
+# Build Test
+######################################################################
+server_builder_test_env = server_builder_env.Clone();
+
+server_builder_test_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+server_builder_test_env.AppendUnique(CPPPATH = [
+    env.get('SRC_DIR')+'/extlibs/hippomocks-master',
+    gtest_dir + '/include'
+    ])
+
+gtest = File(gtest_dir + '/lib/.libs/libgtest.a')
+gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+server_builder_test_env.PrependUnique(LIBS = [
+    'server_builder',
+    'service_common',
+    'pthread',
+    'oc',
+    'octbstack',
+    'oc_logger',
+    'connectivity_abstraction',
+    'coap',
+    gtest,
+    gtest_main,
+    ])
+
+server_builder_test_src = env.Glob('unittests/*.cpp')
+
+server_builder_test = server_builder_test_env.Program('server_builder_test', server_builder_test_src)
+Alias("server_builder_test", server_builder_test)
+env.AppendTarget('server_builder_test')
diff --git a/service/resource-manipulation/modules/serverBuilder/include/PrimitiveRequest.h b/service/resource-manipulation/modules/serverBuilder/include/PrimitiveRequest.h
new file mode 100644 (file)
index 0000000..a73ea95
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __PRIMITIVEREQUEST_H
+#define __PRIMITIVEREQUEST_H
+
+#include <string>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class PrimitiveRequest
+        {
+        public:
+            explicit PrimitiveRequest(const std::string& resourceUri);
+
+            PrimitiveRequest& operator=(PrimitiveRequest&) = delete;
+
+            std::string getResourceUri() const;
+
+        private:
+            std::string m_resourceUri;
+        };
+
+    }
+}
+
+#endif // __PRIMITIVEREQUEST_H
diff --git a/service/resource-manipulation/modules/serverBuilder/include/PrimitiveResponse.h b/service/resource-manipulation/modules/serverBuilder/include/PrimitiveResponse.h
new file mode 100644 (file)
index 0000000..717a873
--- /dev/null
@@ -0,0 +1,89 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __PRIMITIVERESPONSE_H
+#define __PRIMITIVERESPONSE_H
+
+#include <cstdint>
+#include <memory>
+
+#include <octypes.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class ResourceAttributes;
+
+        class RequestHandler;
+
+        class PrimitiveGetResponse
+        {
+        public:
+            static PrimitiveGetResponse defaultAction();
+
+            static PrimitiveGetResponse create(const OCEntityHandlerResult&, int errorCode);
+
+            static PrimitiveGetResponse create(const ResourceAttributes&);
+            static PrimitiveGetResponse create(const ResourceAttributes&,
+                    const OCEntityHandlerResult&, int errorCode);
+
+            static PrimitiveGetResponse create(ResourceAttributes&&);
+            static PrimitiveGetResponse create(ResourceAttributes&&, const OCEntityHandlerResult&,
+                    int errorCode);
+
+            RequestHandler* getHandler() const;
+
+        private:
+            PrimitiveGetResponse(std::shared_ptr< RequestHandler >&&);
+
+        private:
+            std::shared_ptr< RequestHandler > m_handler;
+        };
+
+        class PrimitiveSetResponse
+        {
+        public:
+            static PrimitiveSetResponse defaultAction();
+
+            static PrimitiveSetResponse create(const OCEntityHandlerResult&, int errorCode);
+
+            static PrimitiveSetResponse create(const ResourceAttributes&);
+            static PrimitiveSetResponse create(const ResourceAttributes&,
+                    const OCEntityHandlerResult&, int errorCode);
+
+            static PrimitiveSetResponse create(ResourceAttributes&&);
+            static PrimitiveSetResponse create(ResourceAttributes&&, const OCEntityHandlerResult&,
+                    int errorCode);
+
+            RequestHandler* getHandler() const;
+
+        private:
+            PrimitiveSetResponse(std::shared_ptr< RequestHandler >&&);
+
+            static PrimitiveSetResponse withProxy(std::shared_ptr< RequestHandler >&&);
+
+        private:
+            std::shared_ptr< RequestHandler > m_handler;
+        };
+    }
+}
+
+#endif
diff --git a/service/resource-manipulation/modules/serverBuilder/include/ResourceObject.h b/service/resource-manipulation/modules/serverBuilder/include/ResourceObject.h
new file mode 100644 (file)
index 0000000..61382a3
--- /dev/null
@@ -0,0 +1,212 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __OIC_RESOURCEOBJECT_H
+#define __OIC_RESOURCEOBJECT_H
+
+#include <string>
+#include <mutex>
+#include <atomic>
+#include <thread>
+
+#include <ResourceAttributes.h>
+#include <PrimitiveResponse.h>
+#include <PrimitiveRequest.h>
+
+namespace OC
+{
+    class OCResourceRequest;
+}
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        class NoLockException: public PrimitiveException
+        {
+        public:
+            NoLockException(std::string&& what) : PrimitiveException{ std::move(what) } {}
+        };
+
+        class DeadLockException: public PrimitiveException
+        {
+        public:
+            DeadLockException(std::string&& what) : PrimitiveException{ std::move(what) } {}
+        };
+
+        class ResourceObject
+        {
+        private:
+            class WeakGuard;
+
+        public:
+        //    enum class AutoNotifyPolicy {
+        //        NEVER,
+        //        ALWAYS,
+        //        UPDATED
+        //    };
+
+            using Ptr = std::shared_ptr< ResourceObject >;
+            using ConstPtr = std::shared_ptr< const ResourceObject >;
+
+            class Builder
+            {
+            public:
+                Builder(const std::string& uri, const std::string& type,
+                        const std::string& interface);
+
+                Builder& setDiscoverable(bool discoverable);
+                Builder& setObservable(bool observable);
+
+                Builder& setAttributes(const ResourceAttributes&);
+                Builder& setAttributes(ResourceAttributes&&);
+
+                /**
+                 * @throw PlatformException
+                 */
+                ResourceObject::Ptr build();
+
+            private:
+                std::string m_uri;
+                std::string m_type;
+                std::string m_interface;
+
+                uint8_t m_properties;
+
+                ResourceAttributes m_resourceAttributes;
+            };
+
+            class LockGuard;
+
+            using GetRequestHandler = std::function< PrimitiveGetResponse(const PrimitiveRequest&,
+                    ResourceAttributes&) >;
+            using SetRequestHandler = std::function< PrimitiveSetResponse(const PrimitiveRequest&,
+                    ResourceAttributes&) >;
+
+        public:
+            ResourceObject(ResourceObject&&) = delete;
+            ResourceObject(const ResourceObject&) = delete;
+
+            ResourceObject& operator=(ResourceObject&&) = delete;
+            ResourceObject& operator=(const ResourceObject&) = delete;
+
+            virtual ~ResourceObject();
+
+            template< typename T >
+            void setAttribute(const std::string& key, T&& value)
+            {
+                WeakGuard lock(*this);
+                m_resourceAttributes[key] = std::forward<T>(value);
+            }
+
+            template< typename T >
+            void setAttribute(std::string&& key, T&& value)
+            {
+                WeakGuard lock(*this);
+                m_resourceAttributes[std::move(key)] = std::forward<T>(value);
+            }
+
+            template< typename T >
+            T getAttribute(const std::string& key) const
+            {
+                WeakGuard lock(*this);
+                return m_resourceAttributes.at(key).get< T >();
+            }
+
+            bool removeAttribute(const std::string& key);
+
+            bool hasAttribute(const std::string& key) const;
+
+            ResourceAttributes& getAttributes();
+            const ResourceAttributes& getAttributes() const;
+
+            virtual bool isObservable() const;
+            virtual bool isDiscoverable() const;
+
+            virtual void setGetRequestHandler(GetRequestHandler);
+            virtual void setSetRequestHandler(SetRequestHandler);
+
+            virtual void notify() const;
+
+        //    void setAutoNotifyPolicy(AutoNotifyPolicy);
+
+        private:
+            ResourceObject(uint8_t, ResourceAttributes&&);
+
+            OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest >);
+
+            OCEntityHandlerResult handleRequest(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleRequestGet(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleRequestSet(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleObserve(std::shared_ptr< OC::OCResourceRequest >);
+
+            void expectOwnLock() const;
+
+        private:
+            const uint8_t m_properties;
+
+            OCResourceHandle m_resourceHandle;
+            ResourceAttributes m_resourceAttributes;
+
+            GetRequestHandler m_getRequestHandler;
+            SetRequestHandler m_setRequestHandler;
+
+            mutable std::atomic< std::thread::id > m_lockOwner;
+            mutable std::mutex m_mutex;
+        };
+
+        class ResourceObject::LockGuard
+        {
+        public:
+            LockGuard(const ResourceObject&);
+            LockGuard(const ResourceObject::Ptr);
+            ~LockGuard();
+
+            LockGuard(const LockGuard&) = delete;
+            LockGuard(LockGuard&&) = delete;
+
+            LockGuard& operator=(const LockGuard&) = delete;
+            LockGuard& operator=(LockGuard&&) = delete;
+
+        private:
+            const ResourceObject& m_resourceObject;
+        };
+
+        class ResourceObject::WeakGuard
+        {
+        public:
+            WeakGuard(const ResourceObject&);
+            ~WeakGuard();
+
+            WeakGuard(const WeakGuard&) = delete;
+            WeakGuard(WeakGuard&&) = delete;
+
+            WeakGuard& operator=(const WeakGuard&) = delete;
+            WeakGuard& operator=(WeakGuard&&) = delete;
+
+        private:
+            const ResourceObject& m_serverResource;
+            bool m_hasLocked;
+        };
+    }
+}
+
+#endif // __OIC_RESOURCEOBJECT_H
diff --git a/service/resource-manipulation/modules/serverBuilder/include/internal/RequestHandler.h b/service/resource-manipulation/modules/serverBuilder/include/internal/RequestHandler.h
new file mode 100644 (file)
index 0000000..b7f97cc
--- /dev/null
@@ -0,0 +1,101 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __REQUESTHANDLER_H
+#define __REQUESTHANDLER_H
+
+#include <ResourceObject.h>
+
+#include <OCResourceResponse.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RequestHandler
+        {
+        public:
+            using Ptr = std::shared_ptr< RequestHandler >;
+
+            static constexpr int DEFAULT_ERROR_CODE = 200;
+            static constexpr OCEntityHandlerResult DEFAULT_RESULT = OC_EH_OK;
+
+            virtual ~RequestHandler()
+            {
+            }
+
+            virtual std::shared_ptr< OC::OCResourceResponse > buildResponse(
+                    ResourceObject&, const ResourceAttributes& requestAttrs) = 0;
+        };
+
+        class SimpleRequestHandler: public RequestHandler
+        {
+        public:
+            SimpleRequestHandler(const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE);
+
+            std::shared_ptr< OC::OCResourceResponse > buildResponse(
+                    ResourceObject&, const ResourceAttributes&) override;
+
+        protected:
+            virtual int getErrorCode(ResourceObject&);
+            virtual OCEntityHandlerResult getResponseResult(ResourceObject&);
+            virtual OC::OCRepresentation getOCRepresentation(ResourceObject& resource);
+
+        private:
+            OCEntityHandlerResult m_result;
+            int m_errorCode;
+        };
+
+
+        class CustomAttrRequestHandler: public SimpleRequestHandler
+        {
+        public:
+            template <typename T>
+            CustomAttrRequestHandler(T&& attrs,
+                    const OCEntityHandlerResult& result = DEFAULT_RESULT,
+                    int errorCode = DEFAULT_ERROR_CODE) :
+                SimpleRequestHandler{ result, errorCode }, m_attrs{ std::forward< T >(attrs) }
+            {
+            }
+
+        protected:
+            OC::OCRepresentation getOCRepresentation(ResourceObject& resource) override;
+
+        private:
+            ResourceAttributes m_attrs;
+        };
+
+        class SetRequestProxyHandler: public RequestHandler
+        {
+        public:
+            SetRequestProxyHandler(RequestHandler::Ptr requestHandler);
+
+            std::shared_ptr< OC::OCResourceResponse > buildResponse(
+                    ResourceObject& resource,
+                    const ResourceAttributes& requestAttrs) override;
+
+        private:
+            RequestHandler::Ptr m_requestHandler;
+        };
+    }
+}
+
+#endif // __REQUESTHANDLER_H
diff --git a/service/resource-manipulation/modules/serverBuilder/src/PrimitiveRequest.cpp b/service/resource-manipulation/modules/serverBuilder/src/PrimitiveRequest.cpp
new file mode 100644 (file)
index 0000000..e0a32b5
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <PrimitiveRequest.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        PrimitiveRequest::PrimitiveRequest(const std::string& resourceUri) :
+                m_resourceUri{ resourceUri }
+        {
+        }
+
+        std::string PrimitiveRequest::getResourceUri() const
+        {
+            return m_resourceUri;
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/src/PrimitiveResponse.cpp b/service/resource-manipulation/modules/serverBuilder/src/PrimitiveResponse.cpp
new file mode 100644 (file)
index 0000000..5bcc5f9
--- /dev/null
@@ -0,0 +1,137 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <PrimitiveResponse.h>
+
+#include <internal/RequestHandler.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        PrimitiveGetResponse PrimitiveGetResponse::defaultAction()
+        {
+            static PrimitiveGetResponse defaultRes { std::make_shared<SimpleRequestHandler>() };
+
+            return defaultRes;
+        }
+
+        PrimitiveGetResponse PrimitiveGetResponse::create(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return PrimitiveGetResponse {
+                std::make_shared<SimpleRequestHandler>( result, errorCode) };
+        }
+
+        PrimitiveGetResponse PrimitiveGetResponse::create(const ResourceAttributes& attrs)
+        {
+            return PrimitiveGetResponse { std::make_shared<CustomAttrRequestHandler>(attrs) };
+        }
+
+        PrimitiveGetResponse PrimitiveGetResponse::create(const ResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return PrimitiveGetResponse {
+                std::make_shared<CustomAttrRequestHandler>(attrs, result, errorCode) };
+        }
+
+        PrimitiveGetResponse PrimitiveGetResponse::create(ResourceAttributes&& result)
+        {
+            return PrimitiveGetResponse {
+                std::make_shared<CustomAttrRequestHandler>(std::move(result)) };
+        }
+
+        PrimitiveGetResponse PrimitiveGetResponse::create(ResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return PrimitiveGetResponse { std::make_shared<CustomAttrRequestHandler>(
+                std::move(attrs), result, errorCode) };
+        }
+
+        PrimitiveGetResponse::PrimitiveGetResponse(std::shared_ptr< RequestHandler >&& handler) :
+                m_handler{ std::move(handler) }
+        {
+            assert(m_handler);
+        }
+
+        RequestHandler* PrimitiveGetResponse::getHandler() const
+        {
+            return m_handler.get();
+        }
+
+
+        PrimitiveSetResponse PrimitiveSetResponse::defaultAction()
+        {
+            static PrimitiveSetResponse defaultRes {
+                withProxy(std::make_shared<SimpleRequestHandler>()) };
+
+            return defaultRes;
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::create(const OCEntityHandlerResult& result,
+                int errorCode)
+        {
+            return withProxy(std::make_shared<SimpleRequestHandler>(result, errorCode));
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::create(const ResourceAttributes& attrs)
+        {
+            return withProxy(std::make_shared<CustomAttrRequestHandler>(attrs));
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::create(const ResourceAttributes& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return withProxy(std::make_shared<CustomAttrRequestHandler>(attrs, result, errorCode));
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::create(ResourceAttributes&& result)
+        {
+            return withProxy(std::make_shared<CustomAttrRequestHandler>(std::move(result)));
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::create(ResourceAttributes&& attrs,
+                const OCEntityHandlerResult& result, int errorCode)
+        {
+            return withProxy(
+                std::make_shared<CustomAttrRequestHandler>(std::move(attrs), result, errorCode));
+        }
+
+        PrimitiveSetResponse::PrimitiveSetResponse(std::shared_ptr< RequestHandler >&& handler) :
+                m_handler{ handler }
+        {
+            assert(m_handler);
+        }
+
+        PrimitiveSetResponse PrimitiveSetResponse::withProxy(
+                std::shared_ptr< RequestHandler >&& handler)
+        {
+            assert(handler);
+
+            return PrimitiveSetResponse{
+                std::make_shared<SetRequestProxyHandler>(std::move(handler)) };
+        }
+
+        RequestHandler* PrimitiveSetResponse::getHandler() const
+        {
+            return m_handler.get();
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/src/RequestHandler.cpp b/service/resource-manipulation/modules/serverBuilder/src/RequestHandler.cpp
new file mode 100644 (file)
index 0000000..0bd8848
--- /dev/null
@@ -0,0 +1,99 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <internal/RequestHandler.h>
+
+#include <internal/ResourceAttributesConverter.h>
+#include <internal/ResourceAttributesUtils.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        constexpr OCEntityHandlerResult RequestHandler::DEFAULT_RESULT;
+
+        SimpleRequestHandler::SimpleRequestHandler(const OCEntityHandlerResult& result,
+                int errorCode) :
+                m_result{ result }, m_errorCode{ errorCode }
+        {
+        }
+
+        std::shared_ptr< OC::OCResourceResponse > SimpleRequestHandler::buildResponse(
+                ResourceObject& resource, const ResourceAttributes&)
+        {
+            auto response = std::make_shared< OC::OCResourceResponse >();
+
+            response->setErrorCode(getErrorCode(resource));
+            response->setResponseResult(getResponseResult(resource));
+            response->setResourceRepresentation(getOCRepresentation(resource));
+
+            return response;
+        }
+
+        int SimpleRequestHandler::getErrorCode(ResourceObject&)
+        {
+            return m_errorCode;
+        }
+
+        OCEntityHandlerResult SimpleRequestHandler::getResponseResult(ResourceObject&)
+        {
+            return m_result;
+        }
+
+        OC::OCRepresentation SimpleRequestHandler::getOCRepresentation(
+                ResourceObject& resource)
+        {
+            ResourceObject::LockGuard lock{ resource };
+            return ResourceAttributesConverter::toOCRepresentation(resource.getAttributes());
+        }
+
+
+        OC::OCRepresentation CustomAttrRequestHandler::getOCRepresentation(
+                ResourceObject& resource)
+        {
+            return ResourceAttributesConverter::toOCRepresentation(m_attrs);
+        }
+
+
+        SetRequestProxyHandler::SetRequestProxyHandler(RequestHandler::Ptr requestHandler) :
+                m_requestHandler{ requestHandler }
+        {
+            assert(m_requestHandler);
+        }
+
+        std::shared_ptr< OC::OCResourceResponse > SetRequestProxyHandler::buildResponse(
+                ResourceObject& resource, const ResourceAttributes& requestAttrs)
+        {
+            {
+                ResourceObject::LockGuard lock(resource);
+
+                if (!acceptableAttributes(resource.getAttributes(), requestAttrs))
+                {
+                    throw PrimitiveException("Resource can't accept request Attributes!");
+                }
+
+                replaceAttributesRecursively(resource.getAttributes(), requestAttrs);
+            }
+            return m_requestHandler->buildResponse(resource, requestAttrs);
+        }
+
+    }
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/src/ResourceObject.cpp b/service/resource-manipulation/modules/serverBuilder/src/ResourceObject.cpp
new file mode 100644 (file)
index 0000000..36309a9
--- /dev/null
@@ -0,0 +1,368 @@
+//******************************************************************
+//
+// 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 <ResourceObject.h>
+
+#include <string>
+#include <functional>
+#include <vector>
+
+#include <internal/RequestHandler.h>
+#include <internal/AssertUtils.h>
+#include <internal/ResourceAttributesConverter.h>
+
+#include <logger.h>
+#include <OCPlatform.h>
+
+namespace
+{
+    using namespace OIC::Service;
+
+    constexpr const char LOG_TAG[]{ "PrimitiveServerResource" };
+
+    namespace Detail
+    {
+        template <typename RESPONSE>
+        OCEntityHandlerResult sendResponse(ResourceObject& resource,
+                std::shared_ptr< OC::OCResourceRequest > ocRequest,
+                const ResourceAttributes& requestAttrs, RESPONSE&& response)
+        {
+            auto ocResponse = response.getHandler()->buildResponse(resource, requestAttrs);
+
+            ocResponse->setRequestHandle(ocRequest->getRequestHandle());
+            ocResponse->setResourceHandle(ocRequest->getResourceHandle());
+
+            try
+            {
+                if (OC::OCPlatform::sendResponse(ocResponse) == OC_STACK_OK)
+                {
+                    return OC_EH_OK;
+                }
+            }
+            catch (const OC::OCException& e)
+            {
+                OC_LOG(WARNING, LOG_TAG, e.what());
+            }
+
+            return OC_EH_ERROR;
+        }
+    }
+
+    inline bool hasProperty(uint8_t base, uint8_t target)
+    {
+        return (base & target) == target;
+    }
+
+    inline uint8_t makePropertyFlags(uint8_t base, uint8_t target, bool add)
+    {
+        if (add)
+        {
+            return base | target;
+        }
+
+        return base & ~target;
+    }
+
+    template< typename HANDLER, typename RESPONSE = typename std::decay<HANDLER>::type::result_type>
+    OCEntityHandlerResult handleRequest(ResourceObject& resource,
+            std::shared_ptr< OC::OCResourceRequest > ocRequest, HANDLER&& handler)
+    {
+        ResourceAttributes attrs{ ResourceAttributesConverter::fromOCRepresentation(
+                ocRequest->getResourceRepresentation()) };
+
+        if (handler)
+        {
+            return Detail::sendResponse(resource, ocRequest, attrs, handler(
+                    PrimitiveRequest{ ocRequest->getResourceUri() }, attrs));
+        }
+
+        return Detail::sendResponse(resource, ocRequest, attrs, RESPONSE::defaultAction());
+    }
+
+} // unnamed namespace
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        ResourceObject::ResourceObject(uint8_t properties,
+                ResourceAttributes&& attrs) :
+                m_properties { properties }, m_resourceHandle{},
+                m_resourceAttributes{ std::move(attrs) }, m_getRequestHandler{ },
+                m_setRequestHandler{ }, m_mutex { }
+        {
+        }
+
+        ResourceObject::Builder::Builder(const std::string& uri, const std::string& type,
+                const std::string& interface) :
+                m_uri{ uri }, m_type{ type }, m_interface{ interface },
+                m_properties{ OC_DISCOVERABLE | OC_OBSERVABLE }
+        {
+        }
+
+        ResourceObject::Builder& ResourceObject::Builder::setDiscoverable(
+                bool discoverable)
+        {
+            m_properties = ::makePropertyFlags(m_properties, OC_DISCOVERABLE, discoverable);
+            return *this;
+        }
+
+        ResourceObject::Builder& ResourceObject::Builder::setObservable(
+                bool observable)
+        {
+            m_properties = ::makePropertyFlags(m_properties, OC_OBSERVABLE, observable);
+            return *this;
+        }
+
+        ResourceObject::Builder& ResourceObject::Builder::setAttributes(
+                const ResourceAttributes& attrs)
+        {
+            m_resourceAttributes = attrs;
+            return *this;
+        }
+
+        ResourceObject::Builder& ResourceObject::Builder::setAttributes(
+                ResourceAttributes&& attrs)
+        {
+            m_resourceAttributes = std::move(attrs);
+            return *this;
+        }
+
+        ResourceObject::Ptr ResourceObject::Builder::build()
+        {
+            OCResourceHandle handle{ nullptr };
+
+            ResourceObject::Ptr server {
+                new ResourceObject{ m_properties, std::move(m_resourceAttributes) } };
+
+            OC::EntityHandler entityHandler{ std::bind(&ResourceObject::entityHandler,
+                    server.get(), std::placeholders::_1) };
+
+            try
+            {
+                using RegisterResource = OCStackResult (*)(OCResourceHandle&, std::string&,
+                        const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+
+                invokeOCFunc(static_cast<RegisterResource>(OC::OCPlatform::registerResource),
+                        handle, m_uri, m_type, m_interface, entityHandler, m_properties);
+            }
+            catch (OC::OCException& e)
+            {
+                throw PlatformException(e.code());
+            }
+
+            server->m_resourceHandle = handle;
+
+            return server;
+        }
+
+
+        ResourceObject::~ResourceObject()
+        {
+            if (m_resourceHandle)
+            {
+                try
+                {
+                    OC::OCPlatform::unregisterResource(m_resourceHandle);
+                }
+                catch (...)
+                {
+                    OC_LOG(WARNING, LOG_TAG, "Failed to unregister resource.");
+                }
+            }
+        }
+
+        bool ResourceObject::removeAttribute(const std::string& key)
+        {
+            WeakGuard lock(*this);
+            return m_resourceAttributes.erase(key);
+        }
+
+        bool ResourceObject::hasAttribute(const std::string& key) const
+        {
+            WeakGuard lock(*this);
+            return m_resourceAttributes.contains(key);
+        }
+
+        ResourceAttributes& ResourceObject::getAttributes()
+        {
+            expectOwnLock();
+            return m_resourceAttributes;
+        }
+
+        const ResourceAttributes& ResourceObject::getAttributes() const
+        {
+            expectOwnLock();
+            return m_resourceAttributes;
+        }
+
+        void ResourceObject::expectOwnLock() const
+        {
+            if (m_lockOwner != std::this_thread::get_id())
+            {
+                throw NoLockException{ "Must acquire the lock first using LockGuard." };
+            }
+        }
+
+        bool ResourceObject::isObservable() const
+        {
+            return ::hasProperty(m_properties, OC_OBSERVABLE);
+        }
+
+        bool ResourceObject::isDiscoverable() const
+        {
+            return ::hasProperty(m_properties, OC_DISCOVERABLE);
+        }
+
+        void ResourceObject::setGetRequestHandler(GetRequestHandler h)
+        {
+            m_getRequestHandler = h;
+        }
+
+        void ResourceObject::setSetRequestHandler(SetRequestHandler h)
+        {
+            m_setRequestHandler = h;
+        }
+
+        void ResourceObject::notify() const
+        {
+            using NotifyAllObservers = OCStackResult (*)(OCResourceHandle);
+
+            invokeOCFunc(static_cast<NotifyAllObservers>(OC::OCPlatform::notifyAllObservers),
+                    m_resourceHandle);
+        }
+
+        OCEntityHandlerResult ResourceObject::entityHandler(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            if (!request)
+            {
+                return OC_EH_ERROR;
+            }
+
+            try
+            {
+                if (request->getRequestHandlerFlag() & OC::RequestHandlerFlag::RequestFlag)
+                {
+                    return handleRequest(request);
+                }
+
+                if (request->getRequestHandlerFlag() & OC::RequestHandlerFlag::ObserverFlag)
+                {
+                    return handleObserve(request);
+                }
+            }
+            catch (const std::exception& e)
+            {
+                OC_LOG_V(WARNING, LOG_TAG, "Failed to handle request : %s", e.what());
+            }
+            catch (...)
+            {
+                OC_LOG(WARNING, LOG_TAG, "Failed to handle request.");
+                // TODO : how to notify the error?
+            }
+
+            return OC_EH_ERROR;
+        }
+
+        OCEntityHandlerResult ResourceObject::handleRequest(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            if (request->getRequestType() == "GET")
+            {
+                return handleRequestGet(request);
+            }
+
+            if (request->getRequestType() == "PUT" || request->getRequestType() == "POST")
+            {
+                return handleRequestSet(request);
+            }
+
+            return OC_EH_ERROR;
+        }
+
+        OCEntityHandlerResult ResourceObject::handleRequestGet(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            return ::handleRequest(*this, request, m_getRequestHandler);
+        }
+
+        OCEntityHandlerResult ResourceObject::handleRequestSet(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            return ::handleRequest(*this, request, m_setRequestHandler);
+        }
+
+        OCEntityHandlerResult ResourceObject::handleObserve(
+                std::shared_ptr< OC::OCResourceRequest > request)
+        {
+            if (!isObservable())
+            {
+                return OC_EH_ERROR;
+            }
+
+            return OC_EH_OK;
+        }
+
+        ResourceObject::LockGuard::LockGuard(const ResourceObject::Ptr ptr) :
+                LockGuard{ *ptr }
+        {
+        }
+
+        ResourceObject::LockGuard::LockGuard(
+                const ResourceObject& serverResource) :
+                m_resourceObject(serverResource)
+        {
+            if (m_resourceObject.m_lockOwner == std::this_thread::get_id())
+            {
+                throw DeadLockException{ "Can't lock recursively in same thread." };
+            }
+
+            m_resourceObject.m_mutex.lock();
+            m_resourceObject.m_lockOwner = std::this_thread::get_id();
+        }
+
+        ResourceObject::LockGuard::~LockGuard()
+        {
+            m_resourceObject.m_lockOwner = std::thread::id();
+            m_resourceObject.m_mutex.unlock();
+        }
+
+        ResourceObject::WeakGuard::WeakGuard(
+                const ResourceObject& serverResource) :
+                m_serverResource(serverResource), m_hasLocked{ false }
+        {
+            if (m_serverResource.m_lockOwner != std::this_thread::get_id())
+            {
+                m_serverResource.m_mutex.lock();
+                m_hasLocked = true;
+            }
+        }
+
+        ResourceObject::WeakGuard::~WeakGuard()
+        {
+            if (m_hasLocked)
+            {
+                m_serverResource.m_mutex.unlock();
+            }
+        }
+    }
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/unittests/PrimitiveResponseTest.cpp b/service/resource-manipulation/modules/serverBuilder/unittests/PrimitiveResponseTest.cpp
new file mode 100644 (file)
index 0000000..eb18e4f
--- /dev/null
@@ -0,0 +1,177 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include <PrimitiveResponse.h>
+#include <ResourceObject.h>
+
+#include <internal/RequestHandler.h>
+#include <internal/ResourceAttributesConverter.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+
+using namespace testing;
+
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*registerResourceSig)(OCResourceHandle&,
+                       string&,
+                       const string&,
+                       const string&,
+                       EntityHandler,
+                       uint8_t );
+
+static constexpr char KEY[] = "key";
+
+
+void EXPECT_RESPONSE(shared_ptr< OCResourceResponse > ocResponse,
+        const OCEntityHandlerResult& result, int errorCode, const ResourceAttributes& attrs)
+{
+    EXPECT_EQ(ocResponse->getResponseResult(), result);
+    EXPECT_EQ(ocResponse->getErrorCode(), errorCode);
+    EXPECT_EQ(ResourceAttributesConverter::fromOCRepresentation(
+                    ocResponse->getResourceRepresentation()), attrs);
+}
+
+
+class PrimitiveResponseTest: public Test
+{
+public:
+    MockRepository mocks;
+    ResourceObject::Ptr server;
+
+public:
+    template< typename T >
+    shared_ptr< OCResourceResponse > buildResponse(const T& response)
+    {
+        ResourceObject::Ptr server =
+                ResourceObject::Builder("a/test", "", "").build();
+
+        return response.getHandler()->buildResponse(*server, ResourceAttributes());
+    }
+
+protected:
+    void SetUp() override
+    {
+        mocks.OnCallFuncOverload(static_cast< registerResourceSig >(OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+
+        server = ResourceObject::Builder("a/test", "", "").build();
+    }
+};
+
+TEST_F(PrimitiveResponseTest, GetDefaultActionHasEmptyAttrs)
+{
+    EXPECT_RESPONSE(buildResponse(PrimitiveGetResponse::defaultAction()),
+            RequestHandler::DEFAULT_RESULT, RequestHandler::DEFAULT_ERROR_CODE,
+            ResourceAttributes());
+}
+
+TEST_F(PrimitiveResponseTest, GetResponseHasResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    EXPECT_RESPONSE(buildResponse(PrimitiveGetResponse::create(result, errorCode)),
+            result, errorCode, ResourceAttributes());
+}
+
+TEST_F(PrimitiveResponseTest, GetResponseHasAttrsAndResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    ResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    EXPECT_RESPONSE(buildResponse(PrimitiveGetResponse::create(attrs, result, errorCode)),
+            result, errorCode, attrs);
+}
+
+TEST_F(PrimitiveResponseTest, GetResponseCanMoveAttrs)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    ResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    ResourceAttributes attrsClone;
+    attrsClone[KEY] = 100;
+
+    EXPECT_RESPONSE(
+            buildResponse(PrimitiveGetResponse::create(std::move(attrs), result, errorCode)),
+            result, errorCode, attrsClone);
+
+    EXPECT_TRUE(attrs.empty());
+}
+
+TEST_F(PrimitiveResponseTest, SetDefaultActionHasEmptyAttrs)
+{
+    EXPECT_RESPONSE(buildResponse(PrimitiveSetResponse::defaultAction()),
+            RequestHandler::DEFAULT_RESULT, RequestHandler::DEFAULT_ERROR_CODE,
+            ResourceAttributes());
+}
+
+TEST_F(PrimitiveResponseTest, SetResponseHasResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    EXPECT_RESPONSE(buildResponse(PrimitiveSetResponse::create(result, errorCode)),
+            result, errorCode, ResourceAttributes());
+}
+
+TEST_F(PrimitiveResponseTest, SetResponseHasAttrsAndResultsPassedCodes)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    ResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    EXPECT_RESPONSE(buildResponse(PrimitiveSetResponse::create(attrs, result, errorCode)),
+            result, errorCode, attrs);
+}
+
+TEST_F(PrimitiveResponseTest, SetResponseCanMoveAttrs)
+{
+    constexpr OCEntityHandlerResult result{ OC_EH_ERROR };
+    constexpr int errorCode{ -10 };
+
+    ResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    ResourceAttributes attrsClone;
+    attrsClone[KEY] = 100;
+
+    EXPECT_RESPONSE(
+            buildResponse(PrimitiveSetResponse::create(std::move(attrs), result, errorCode)),
+            result, errorCode, attrsClone);
+
+    EXPECT_TRUE(attrs.empty());
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/unittests/RequestHandlerTest.cpp b/service/resource-manipulation/modules/serverBuilder/unittests/RequestHandlerTest.cpp
new file mode 100644 (file)
index 0000000..dee1f94
--- /dev/null
@@ -0,0 +1,154 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include <internal/RequestHandler.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+
+using namespace testing;
+using namespace OIC::Service;
+
+constexpr char EXISTING[]{ "ext" };
+constexpr int ORIGIN_VALUE{ 100 };
+
+using RegisterResource = OCStackResult (*)(OCResourceHandle&, std::string&,
+        const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+
+class SimpleRequestHandlerTest: public Test
+{
+public:
+    ResourceObject::Ptr server;
+
+    ResourceAttributes requestAttrs;
+
+    MockRepository mocks;
+
+protected:
+    void SetUp() override
+    {
+        mocks.OnCallFuncOverload(static_cast<RegisterResource>(OC::OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+
+        server = ResourceObject::Builder("a/test", "resourceType", "").build();
+
+        server->setAttribute(EXISTING, ORIGIN_VALUE);
+    }
+};
+
+TEST_F(SimpleRequestHandlerTest, ResponseHasSameValuesPassedToHandlerConstructor)
+{
+    SimpleRequestHandler handler{ OC_EH_ERROR, -1000 };
+
+    auto response = handler.buildResponse(*server, requestAttrs);
+
+    ASSERT_EQ(OC_EH_ERROR, response->getResponseResult());
+    ASSERT_EQ(-1000, response->getErrorCode());
+}
+
+TEST_F(SimpleRequestHandlerTest, ResponseHasSameAttrsWithServerAttrs)
+{
+    SimpleRequestHandler handler{};
+
+    auto response = handler.buildResponse(*server, requestAttrs);
+
+    ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[EXISTING].getValue<int>());
+}
+
+TEST_F(SimpleRequestHandlerTest, ResponseHasAttrsSetByCustomAttrRequestHandler)
+{
+    constexpr char key[] { "key" };
+    constexpr int newValue{ 100 };
+
+    ResourceAttributes attrs;
+    attrs[key] = newValue;
+    CustomAttrRequestHandler handler{ attrs };
+
+    auto response = handler.buildResponse(*server, requestAttrs);
+
+    ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[key].getValue<int>());
+}
+
+
+
+class SetRequestProxyHandlerTest: public Test
+{
+public:
+    ResourceObject::Ptr server;
+    ResourceAttributes requestAttrs;
+    RequestHandler::Ptr setRequestProxyHandler;
+
+    MockRepository mocks;
+
+protected:
+    void SetUp() override
+    {
+        mocks.OnCallFuncOverload(static_cast<RegisterResource>(OC::OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+
+        setRequestProxyHandler = make_shared<SetRequestProxyHandler>(
+                make_shared<SimpleRequestHandler>());
+
+        server = ResourceObject::Builder("a/test", "resourceType", "").build();
+
+        server->setAttribute(EXISTING, ORIGIN_VALUE);
+    }
+};
+
+TEST_F(SetRequestProxyHandlerTest, NothingHappenedWithEmptyAttrs)
+{
+
+    setRequestProxyHandler->buildResponse(*server, requestAttrs);
+
+    ASSERT_EQ(ORIGIN_VALUE, server->getAttribute<int>(EXISTING));
+}
+
+
+TEST_F(SetRequestProxyHandlerTest, ServerAttributesChangedIfOnlySameKeyExists)
+{
+    constexpr int newValue{ 100 };
+
+    requestAttrs[EXISTING] = newValue;
+
+    setRequestProxyHandler->buildResponse(*server, requestAttrs);
+
+    ASSERT_EQ(newValue, server->getAttribute<int>(EXISTING));
+}
+
+TEST_F(SetRequestProxyHandlerTest, ThrowIfTypeMismatch)
+{
+    requestAttrs[EXISTING] = "";
+
+    ASSERT_THROW(setRequestProxyHandler->buildResponse(*server, requestAttrs), PrimitiveException);
+}
+
+TEST_F(SetRequestProxyHandlerTest, ThrowIfRequestAttrsHasUnknownKey)
+{
+    constexpr char unknownKey[]{ "???" };
+
+    requestAttrs[EXISTING] = ORIGIN_VALUE;
+    requestAttrs[unknownKey] = ORIGIN_VALUE;
+
+    ASSERT_THROW(setRequestProxyHandler->buildResponse(*server, requestAttrs), PrimitiveException);
+}
diff --git a/service/resource-manipulation/modules/serverBuilder/unittests/ResourceObjectTest.cpp b/service/resource-manipulation/modules/serverBuilder/unittests/ResourceObjectTest.cpp
new file mode 100644 (file)
index 0000000..74577d2
--- /dev/null
@@ -0,0 +1,378 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+
+#include <ResourceObject.h>
+
+#include <OCPlatform.h>
+
+using namespace std;
+using namespace std::placeholders;
+
+using namespace testing;
+
+using namespace OIC::Service;
+using namespace OC;
+
+typedef OCStackResult (*registerResourceSig)(OCResourceHandle&,
+                       string&,
+                       const string&,
+                       const string&,
+                       EntityHandler,
+                       uint8_t );
+
+static constexpr char RESOURCE_URI[]{ "a/test" };
+static constexpr char RESOURCE_TYPE[]{ "resourceType" };
+static constexpr char KEY[]{ "key" };
+
+TEST(ResourceObjectBuilderCreateTest, ThrowIfUriIsInvalid)
+{
+    ASSERT_THROW(ResourceObject::Builder("", "", "").build(), PlatformException);
+}
+
+class ResourceObjectBuilderTest: public Test
+{
+public:
+    MockRepository mocks;
+
+protected:
+    void SetUp() override
+    {
+        mocks.OnCallFuncOverload(static_cast<registerResourceSig>(OCPlatform::registerResource))
+                .Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(ResourceObjectBuilderTest, RegisterResourceWhenCallCreate)
+{
+    mocks.ExpectCallFuncOverload(static_cast<registerResourceSig>(OCPlatform::registerResource))
+            .Return(OC_STACK_OK);
+    ResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
+}
+
+TEST_F(ResourceObjectBuilderTest, ResourceServerHasPropertiesSetByBuilder)
+{
+    auto serverResource = ResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
+            setDiscoverable(false).setObservable(true).build();
+
+    EXPECT_FALSE(serverResource->isDiscoverable());
+    EXPECT_TRUE(serverResource->isObservable());
+}
+
+TEST_F(ResourceObjectBuilderTest, ResourceServerHasAttrsSetByBuilder)
+{
+    ResourceAttributes attrs;
+    attrs[KEY] = 100;
+
+    auto serverResource = ResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
+            setAttributes(attrs).build();
+
+    ResourceObject::LockGuard lock{ serverResource };
+    EXPECT_EQ(attrs, serverResource->getAttributes());
+}
+
+
+class ResourceObjectTest: public Test
+{
+public:
+    MockRepository mocks;
+    ResourceObject::Ptr server;
+
+protected:
+    void SetUp() override
+    {
+        initMocks();
+        server = ResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
+    }
+
+    virtual void initMocks()
+    {
+        mocks.OnCallFuncOverload(static_cast< registerResourceSig >(OCPlatform::registerResource)).
+                Return(OC_STACK_OK);
+
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(ResourceObjectTest, AccessAttributesWithLock)
+{
+    constexpr int value{ 100 };
+
+    {
+        ResourceObject::LockGuard lock{ server };
+        auto& attr = server->getAttributes();
+        attr[KEY] = value;
+    }
+
+    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+}
+
+TEST_F(ResourceObjectTest, ThrowIfTryToAccessAttributesWithoutLock)
+{
+    ASSERT_THROW(server->getAttributes(), NoLockException);
+}
+
+TEST_F(ResourceObjectTest, ThrowIfLockRecursively)
+{
+    ResourceObject::LockGuard lock{ server };
+
+    ASSERT_THROW(ResourceObject::LockGuard again{ server }, DeadLockException);
+}
+
+TEST_F(ResourceObjectTest, AccessingAttributesWithMethodsWithinLockDoesntCauseDeadLock)
+{
+    constexpr int value{ 100 };
+
+    {
+        ResourceObject::LockGuard lock{ server };
+        server->setAttribute(KEY, value);
+    }
+
+    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+}
+
+
+
+class ResourceObjectHandlingRequestTest: public ResourceObjectTest
+{
+public:
+    EntityHandler handler;
+
+    static constexpr OCRequestHandle fakeRequestHandle =
+            reinterpret_cast<OCRequestHandle>(0x1234);
+    static constexpr OCResourceHandle fakeResourceHandle =
+            reinterpret_cast<OCResourceHandle>(0x4321);
+
+public:
+    OCResourceRequest::Ptr createRequest(OCMethod method = OC_REST_GET)
+    {
+        auto request = make_shared<OCResourceRequest>();
+
+        OCEntityHandlerRequest ocEntityHandlerRequest { 0 };
+        OC::MessageContainer mc;
+        OCRepresentation ocRep;
+
+        mc.addRepresentation(ocRep);
+
+        string json = mc.getJSONRepresentation(OCInfoFormat::ExcludeOC);
+
+        ocEntityHandlerRequest.requestHandle = fakeRequestHandle;
+        ocEntityHandlerRequest.resource = fakeResourceHandle;
+        ocEntityHandlerRequest.method = method;
+        ocEntityHandlerRequest.reqJSONPayload = &json[0];
+
+        formResourceRequest(OC_REQUEST_FLAG, &ocEntityHandlerRequest, request);
+
+        return request;
+    }
+
+protected:
+    OCStackResult registerResourceFake(OCResourceHandle&, string&, const string&,
+            const string&, EntityHandler handler, uint8_t)
+    {
+        this->handler = handler;
+        return OC_STACK_OK;
+    }
+
+    void initMocks() override
+    {
+        mocks.OnCallFuncOverload(
+            static_cast<registerResourceSig>(OCPlatform::registerResource)).Do(
+                    bind(&ResourceObjectHandlingRequestTest::registerResourceFake,
+                            this, _1, _2, _3, _4, _5, _6));
+
+        mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
+    }
+};
+
+TEST_F(ResourceObjectHandlingRequestTest, CallSendResponseWhenReceiveRequest)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, ReturnErrorCodeWhenSendResponseFailed)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_ERROR);
+
+    ASSERT_EQ(OC_EH_ERROR, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithSameHandlesPassedByRequest)
+{
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return response->getRequestHandle() == fakeRequestHandle &&
+                        response->getResourceHandle() == fakeResourceHandle;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithPrimitiveResponseResults)
+{
+    constexpr int errorCode{ 1999 };
+    constexpr OCEntityHandlerResult result{ OC_EH_SLOW };
+
+    server->setGetRequestHandler(
+            [](const PrimitiveRequest&, ResourceAttributes&) -> PrimitiveGetResponse
+            {
+                return PrimitiveGetResponse::create(result, errorCode);
+            }
+    );
+
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return response->getErrorCode() == errorCode &&
+                        response->getResponseResult() == result;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest()));
+}
+
+TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrsAndResults)
+{
+    constexpr int errorCode{ 1999 };
+    constexpr OCEntityHandlerResult result{ OC_EH_SLOW };
+    constexpr char value[]{ "value" };
+
+    server->setSetRequestHandler(
+            [](const PrimitiveRequest&, ResourceAttributes&) -> PrimitiveSetResponse
+            {
+                ResourceAttributes attrs;
+                attrs[KEY] = value;
+                return PrimitiveSetResponse::create(attrs, result, errorCode);
+            }
+    );
+
+    mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
+            [](const shared_ptr<OCResourceResponse> response)
+            {
+                return value == response->getResourceRepresentation()[KEY].getValue<std::string>()
+                        && response->getErrorCode() == errorCode
+                        && response->getResponseResult() == result;
+            }
+    ).Return(OC_STACK_OK);
+
+    ASSERT_EQ(OC_EH_OK, handler(createRequest(OC_REST_PUT)));
+}
+
+
+
+class ResourceObjectSynchronizationTest: public ResourceObjectHandlingRequestTest
+{
+public:
+
+    static void withLock(ResourceObject::Ptr serverResource, int count)
+    {
+        for (int i=0; i<count; ++i)
+        {
+            ResourceObject::LockGuard lock{ serverResource };
+
+            auto& attrs = serverResource->getAttributes();
+
+            attrs[KEY] = attrs[KEY].get<int>() + 1;
+        }
+    }
+
+    static void withSetter(ResourceObject::Ptr serverResource, int count)
+    {
+        for (int i=0; i<count; ++i)
+        {
+            ResourceObject::LockGuard lock{ serverResource };
+
+            serverResource->setAttribute(KEY, serverResource->getAttribute<int>(KEY) + 1);
+        }
+    }
+};
+
+TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResource)
+{
+    int expected { 0 };
+    vector<thread> threads;
+
+    server->setAttribute(KEY, 0);
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread { withLock, server, count });
+        expected += count;
+    }
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread { withSetter, server, count });
+        expected +=count;
+    }
+
+    for (auto& t : threads)
+    {
+        t.join();
+    }
+
+    ASSERT_EQ(expected, server->getAttribute<int>(KEY));
+}
+
+TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResourceWithRequests)
+{
+    int expected { 0 };
+    vector<thread> threads;
+
+    mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+
+    server->setAttribute(KEY, 0);
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread{ withLock, server, count });
+        expected += count;
+    }
+
+    for (int i = 20; i >= 0; --i) {
+        int count = 5000 + i * 100;
+        threads.push_back(thread{ withSetter, server, count });
+        expected +=count;
+    }
+
+    threads.push_back(thread{
+        [this]()
+        {
+            for (int i=0; i<10000; ++i)
+            {
+                if (i % 5 == 0) handler(createRequest(OC_REST_OBSERVE));
+                handler(createRequest((i & 1) ? OC_REST_GET : OC_REST_PUT));
+            }
+        }
+    });
+
+    for (auto& t : threads)
+    {
+        t.join();
+    }
+
+    ASSERT_EQ(expected, server->getAttribute<int>(KEY));
+}
diff --git a/service/resource-manipulation/src/ReportPolicyProxy.cpp b/service/resource-manipulation/src/ReportPolicyProxy.cpp
new file mode 100644 (file)
index 0000000..2b46d66
--- /dev/null
@@ -0,0 +1,26 @@
+//******************************************************************
+//
+// 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 "ReportPolicyProxy.h"
+
+CacheID ReportPolicyProxy::startProxyCaching(std::shared_ptr<PrimitiveResource> &res, CacheCB cb)
+{
+    return m_proxyFunc(res, cb);
+}
\ No newline at end of file
diff --git a/service/resource-manipulation/src/ResourceClient.cpp b/service/resource-manipulation/src/ResourceClient.cpp
new file mode 100644 (file)
index 0000000..025c95e
--- /dev/null
@@ -0,0 +1,477 @@
+//******************************************************************
+//
+// 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 "ResourceClient.h"
+#include "ResourceBroker.h"
+#include "ResourceCacheManager.h"
+#include "ReportPolicyProxy.h"
+
+#define CLIENT_W_TAG  PCF("ResourceClient")
+
+namespace
+{
+    ResourceState getResourceStateFromBrokerState(BROKER_STATE state)
+    {
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "getResourceStateFromBrokerState entry");
+
+        if (state == BROKER_STATE::ALIVE)
+        {
+            return ResourceState::ALIVE;
+        }
+        else if (state == BROKER_STATE::REQUESTED)
+        {
+            return ResourceState::REQUESTED;
+        }
+        else if (state == BROKER_STATE::LOST_SIGNAL)
+        {
+            return ResourceState::LOST_SIGNAL;
+        }
+        else if (state == BROKER_STATE::DESTROYED)
+        {
+            return ResourceState::DESTROYED;
+        }
+
+        OC_LOG(ERROR, CLIENT_W_TAG, "getResourceStateFromBrokerState ERROR");
+
+        //Default return value
+        return ResourceState::DESTROYED;
+    }
+
+    CacheState getCacheState(CACHE_STATE state)
+    {
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "getCacheState (from CACHE_STATE) entry");
+
+        if (state == CACHE_STATE::READY)
+        {
+            return CacheState::READY;
+        }
+        else if (state == CACHE_STATE::READY_YET)
+        {
+            return CacheState::READY_YET;
+        }
+        else if (state == CACHE_STATE::LOST_SIGNAL)
+        {
+            return CacheState::LOST_SIGNAL;
+        }
+        else if (state == CACHE_STATE::DESTROYED)
+        {
+            return CacheState::DESTROYED;
+        }
+        else if (state == CACHE_STATE::UPDATING)
+        {
+            return CacheState::UPDATING;
+        }
+        else if (state == CACHE_STATE::NONE)
+        {
+            return CacheState::NONE;
+        }
+        OC_LOG(ERROR, CLIENT_W_TAG, "getCacheState (from CACHE_STATE) ERROR");
+
+        //Default return value
+        return CacheState::NONE;
+    }
+
+    OCStackResult hosting_cb(BROKER_STATE state,
+                             PrimitiveClientResource::ResourceStateChangedCallback onResourceStateChanged)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "hosting_cb entry");
+
+        ResourceState rState = getResourceStateFromBrokerState(state);
+
+        onResourceStateChanged(rState); //passing ResourceState to application
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "hosting_cb exit");
+        return OC_STACK_OK;
+    }
+
+    OCStackResult caching_cb(std::shared_ptr<PrimitiveResource> resource,
+                             const ResourceAttributes &data,
+                             PrimitiveClientResource::CacheUpdatedCallback onCacheUpdated)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "caching_cb entry");
+
+        onCacheUpdated(data); //passing ResourceAttribute to application
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "caching_cb exit");
+        return OC_STACK_OK;
+    }
+
+    void set_cb(const HeaderOptions &header, const ResponseStatement &response, int n)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "set_cb");
+
+    }
+
+    void get_cb(const HeaderOptions &headerOption, const ResponseStatement &response, int n,
+                PrimitiveClientResource::RemoteAttributesReceivedCallback onRemoteAttributesReceived)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "get_cb entry");
+
+        const ResourceAttributes &attributes = response.getAttributes();
+        onRemoteAttributesReceived(attributes); //passing ResourceAttribute to application
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "get_cb exit");
+    }
+
+    void find_cb(std::shared_ptr<PrimitiveResource> primitiveResource,
+                 PrimitiveClient::OnResourceDiscoveredCallback OnResourceDiscovered )
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "findcb entry");
+
+        if (nullptr == primitiveResource)
+        {
+            OC_LOG(ERROR, CLIENT_W_TAG, "find_cb::primitiveResource NULL Parameter");
+            return ;
+        }
+
+        std::shared_ptr< PrimitiveClientResource>  primitiveClientResource =
+            std::shared_ptr< PrimitiveClientResource>(new PrimitiveClientResource(primitiveResource));
+
+        OnResourceDiscovered(primitiveClientResource); //passing PrimitiveClientResource to application
+
+        OC_LOG(DEBUG, CLIENT_W_TAG, "findcb exit");
+    }
+
+}
+
+//*******************************Primitive Client Resource*************************************
+
+PrimitiveClientResource:: PrimitiveClientResource(std::shared_ptr<PrimitiveResource>  pResource) :
+    m_primitiveResource(pResource), m_uri(pResource->getUri()),
+    m_address(pResource->getHost()), m_types(pResource->getTypes()),
+    m_interfaces(pResource->getInterfaces()), m_observableFlag(pResource->isObservable()) {}
+
+
+bool PrimitiveClientResource::isWatching() const
+{
+    return m_watchingFlag;
+}
+
+bool PrimitiveClientResource::isCaching() const
+{
+    return m_cachingFlag;
+}
+
+void PrimitiveClientResource::startWatching(ResourceStateChangedCallback cb)
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startWatching entry");
+    if (true == m_watchingFlag)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startWatching : Already started");
+    }
+    else
+    {
+        BrokerID brokerId =  ResourceBroker::getInstance()->hostResource(m_primitiveResource,
+                             std::bind(hosting_cb, std::placeholders::_1,
+                                       cb));
+        if (0 == brokerId)
+        {
+            m_watchingFlag = false;
+            throw BadRequestException { "Failed to start watching resource "};
+        }
+        else
+        {
+            m_watchingFlag = true;
+            m_brokerId = brokerId;
+        }
+    }
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startWatching exit");
+}
+
+void PrimitiveClientResource::stopWatching()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::stopWatching entry");
+    if (true == m_watchingFlag)
+    {
+        BrokerID brokerId = ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
+        if (0 == brokerId)
+        {
+            OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource:: Failed to terminate hosting");
+            throw BadRequestException { "Failed to terminate hosting " };
+        }
+        else
+        {
+            m_watchingFlag = false;
+        }
+    }
+    else
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource:: stopWatching : already terminated");
+    }
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::stopWatching exit");
+}
+
+ResourceState PrimitiveClientResource::getState() const
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, " PrimitiveClientResource::getState entry");
+
+    BROKER_STATE brokerState = ResourceBroker::getInstance()->getResourceState(m_primitiveResource);
+    return getResourceStateFromBrokerState(brokerState);
+}
+
+void PrimitiveClientResource::startCaching(ReportPolicy reportPolicy, CacheUpdatedCallback cb)
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startCaching entry");
+    if (true == m_cachingFlag)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startCaching : already Started");
+    }
+    else
+    {
+        CacheID cacheId = reportPolicy.getProxy()->startProxyCaching(m_primitiveResource,
+                          std::bind(caching_cb, std::placeholders::_1, std::placeholders::_2, cb));
+
+        OC_LOG_V(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startCaching CACHE ID %d", cacheId);
+        if (0 == cacheId)
+        {
+            m_cachingFlag = false;
+            OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startCaching FAILED");
+            throw BadRequestException { "Failed to generate Cache ID" };
+        }
+        else
+        {
+            m_cacheId = cacheId;
+            m_cachingFlag = true;
+        }
+    }
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::startCaching exit");
+}
+
+void PrimitiveClientResource::stopCaching()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::stopCaching entry");
+    OCStackResult result = OC_STACK_ERROR;
+
+    if (true == m_cachingFlag)
+    {
+        result = ResourceCacheManager::getInstance()->cancelResourceCache(m_primitiveResource,
+                 m_cacheId);
+        if (result == OC_STACK_OK)
+        {
+            m_cachingFlag = false;
+            OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource:: SUCCESS");
+        }
+        else
+        {
+            OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource:: Failed to terminate Caching");
+            throw BadRequestException { "Failed to terminate Caching " };
+        }
+    }
+    else
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource:: Caching already terminated");
+    }
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::stopCaching exit");
+}
+
+CacheState  PrimitiveClientResource::getResourceCacheState()
+{
+    CACHE_STATE cacheState = ResourceCacheManager::getInstance()->getResourceCacheState(
+                                 m_primitiveResource);
+    return getCacheState(cacheState);
+}
+
+void PrimitiveClientResource::refreshCache()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::refreshCache entry");
+
+    OCStackResult result = ResourceCacheManager::getInstance()->updateResourceCache(
+                               m_primitiveResource);
+    if (result == OC_STACK_OK)
+    {
+        OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::refreshCache Success");
+    }
+    else
+    {
+        OC_LOG_V(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::refreshCache FAILED %d", result);
+        throw BadRequestException { "Failed to refresh Caching " };
+    }
+}
+
+ResourceAttributes PrimitiveClientResource:: getCachedAttributes() const
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ResourceAttributes getCachedAttributes ");
+    return  ResourceCacheManager::getInstance()->getCachedData(m_primitiveResource);
+}
+
+std::string PrimitiveClientResource::getUri() const
+{
+    return m_uri;
+}
+
+std::string PrimitiveClientResource::getAddress() const
+{
+    return m_address;
+}
+
+bool PrimitiveClientResource::isObservable() const
+{
+    return m_observableFlag;
+}
+
+std::vector < std::string > PrimitiveClientResource::getTypes() const
+{
+    return m_types;
+}
+
+std::vector < std::string > PrimitiveClientResource::getInterfaces() const
+{
+    return m_interfaces;
+}
+
+void PrimitiveClientResource::getRemoteAttributes(RemoteAttributesReceivedCallback cb)
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::getRemoteAttributes entry");
+
+    m_primitiveResource->requestGet(std::bind(get_cb, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3, cb));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::getRemoteAttributes exit");
+}
+
+void PrimitiveClientResource::setRemoteAttributes(ResourceAttributes &attribute)
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::setRemoteAttributes entry");
+
+    m_primitiveResource->requestSet(attribute, std::bind(set_cb, std::placeholders::_1,
+                                    std::placeholders::_2, std::placeholders::_3));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClientResource::setRemoteAttributes exit");
+}
+
+//*******************************Report Policy**********************************************
+
+ReportPolicy::ReportPolicy(ReportPolicyProxy &&reportPolicyProxy)
+{
+    m_proxy = std::shared_ptr< ReportPolicyProxy>(new ReportPolicyProxy(std::forward<ReportPolicyProxy>
+              (reportPolicyProxy)));
+}
+
+ReportPolicy ReportPolicy::none()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::none entry");
+
+    ReportPolicyProxy::ProxyFunc func = std::bind(&ResourceCacheManager::requestResourceCache,
+                                        ResourceCacheManager::getInstance(), std::placeholders::_1, std::placeholders::_2,
+                                        REPORT_FREQUENCY::NONE, 0l);
+    ReportPolicy reportPolicy = ReportPolicy(ReportPolicyProxy(func));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::none exit");
+    return reportPolicy;
+}
+
+ReportPolicy ReportPolicy::upToDate()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::upToDate entry");
+
+    ReportPolicyProxy::ProxyFunc func = std::bind(&ResourceCacheManager::requestResourceCache,
+                                        ResourceCacheManager::getInstance(), std::placeholders::_1, std::placeholders::_2,
+                                        REPORT_FREQUENCY::UPTODATE, 0l);
+    ReportPolicy reportPolicy = ReportPolicy((ReportPolicyProxy(func)));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::upToDate exit");
+    return reportPolicy;
+}
+
+ReportPolicy ReportPolicy::periodic(int interval, TimeUnit unit)
+{
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::periodic entry");
+    if (0 > interval)
+    {
+        OC_LOG(ERROR, CLIENT_W_TAG, "ReportPolicy::periodic Invalid interval ");
+        throw InvalidParameterException { "Invalid interval value " };
+    }
+    long long timeInMillis;
+    if (unit == TimeUnit::MILLISECOND)
+    {
+        timeInMillis = interval;
+    }
+    else if (unit == TimeUnit::SECOND)
+    {
+        timeInMillis = interval * 60;
+    }
+    else if (unit == TimeUnit::MIN)
+    {
+        timeInMillis = interval * 60 * 60;
+    }
+    ReportPolicyProxy::ProxyFunc func = std::bind(&ResourceCacheManager::requestResourceCache,
+                                        ResourceCacheManager::getInstance(), std::placeholders::_1, std::placeholders::_2,
+                                        REPORT_FREQUENCY::PERIODICTY, timeInMillis);
+    ReportPolicy reportPolicy = ReportPolicy((ReportPolicyProxy(func)));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "ReportPolicy::periodic exit");
+    return reportPolicy;
+}
+
+std::shared_ptr<ReportPolicyProxy>  ReportPolicy::getProxy()
+{
+    return m_proxy;
+}
+
+//*******************************primitive client*********************************************
+
+PrimitiveClient *PrimitiveClient:: getInstance()
+{
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClient:: getInstance entry");
+
+    static PrimitiveClient *s_instance;
+    static std::mutex s_mutex;
+    if (!s_instance)
+    {
+        std::lock_guard<std::mutex> lock(s_mutex);
+        if (!s_instance)
+        {
+            s_instance = new PrimitiveClient();
+        }
+    }
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClient:: getInstance exit");
+    return s_instance;
+}
+
+void PrimitiveClient::discoverPrimitiveResource(std::string host, std::string resourceURI,
+        OCConnectivityType connectivityType,
+        OnResourceDiscoveredCallback cb)
+{
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClient::discoverResource entry");
+
+    if ( resourceURI.empty() )
+    {
+        OC_LOG(ERROR, CLIENT_W_TAG, "discoverPrimitiveResource NULL resourceURI");
+        throw InvalidParameterException { "discoverPrimitiveResource NULL resourceURI'" };
+    }
+    else if ( !cb )
+    {
+        OC_LOG(ERROR, CLIENT_W_TAG, "discoverPrimitiveResource NULL Callback");
+        throw InvalidParameterException { "discoverPrimitiveResource NULL Callback'" };
+    }
+    discoverResource(host, resourceURI, connectivityType, std::bind(find_cb, std::placeholders::_1,
+                     cb));
+
+    OC_LOG(DEBUG, CLIENT_W_TAG, "PrimitiveClient::discoverResource exit");
+}