RCSDiscovermanager's discovery feature extension for active discovery
authordoil.kwon <doil.kwon@samsung.com>
Fri, 11 Sep 2015 06:14:51 +0000 (15:14 +0900)
committerMadan Lanka <lanka.madan@samsung.com>
Thu, 17 Sep 2015 03:01:18 +0000 (03:01 +0000)
- Previous Versions of RCSDiscoveryManager can discover only things that is available during discovery.
  Now RCSDisvoveryManger's Function is extended for active discovery. It can discover things that is incoming after discovering, andcan discover resource what is not supported presence function.

- RCSDiscoveryManagerImpl codes(.h file and .cpp file) are included.so also added its path in Sconscript.

- RCSDiscoveryManagerImpl Constructor is not setting about default.

- when DiscoveryTask's deconstructor is called, called cancel() API.

- delete white spaces and tabs to spaces.

- modify polling interval time 5sec -> 1min

- modify limited line.

Change-Id: I324d5be818655e258cdd2118ace7cabffae97d36
Signed-off-by: doil.kwon <doil.kwon@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2459
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Madan Lanka <lanka.madan@samsung.com>
service/resource-encapsulation/SConscript
service/resource-encapsulation/include/RCSDiscoveryManager.h [changed mode: 0644->0755]
service/resource-encapsulation/include/RCSDiscoveryManagerImpl.h [new file with mode: 0755]
service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp [changed mode: 0644->0755]
service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp [new file with mode: 0755]

index a4dd00a..e6c3f32 100644 (file)
@@ -88,6 +88,7 @@ client_src = [
         CACHE_SRC_DIR + 'DataCache.cpp',
         CACHE_SRC_DIR + 'ResourceCacheManager.cpp',
         RESOURCECLIENT_DIR + 'RCSDiscoveryManager.cpp',
+        RESOURCECLIENT_DIR + 'RCSDiscoveryManagerImpl.cpp',
         RESOURCECLIENT_DIR + 'RCSRemoteResourceObject.cpp'
                ]
 ResourceClientsdk_static = resourceClient_env.StaticLibrary('rcs_client', client_src)
old mode 100644 (file)
new mode 100755 (executable)
index ec4a817..bb9bd64
@@ -31,6 +31,8 @@
 #include <memory>
 #include <functional>
 
+#include "octypes.h"
+
 namespace OIC
 {
     namespace Service
@@ -38,6 +40,21 @@ namespace OIC
         class RCSRemoteResourceObject;
         class RCSAddress;
 
+        class DiscoveryTask
+        {
+            public:
+
+                DiscoveryTask(unsigned int id) : m_id{ id } {};
+                void cancel();
+                bool isCanceled();
+                ~DiscoveryTask();
+            private:
+
+                unsigned int m_id;
+                friend class RCSDiscoveryManager;
+                friend class RCSDiscoveryManagerImpl;
+        };
+
         /**
          * This class contains the resource discovery methods.
          *
@@ -74,7 +91,8 @@ namespace OIC
                  * @see RCSAddress
                  *
                  */
-                void discoverResource(const RCSAddress& address, ResourceDiscoveredCallback cb);
+                std::unique_ptr<DiscoveryTask> discoverResource(const RCSAddress& address,
+                        ResourceDiscoveredCallback cb);
 
                 /**
                  * API for discovering the resource of Interest, regardless of resource type
@@ -90,8 +108,8 @@ namespace OIC
                  * @see RCSAddress
                  *
                  */
-                void discoverResource(const RCSAddress& address, const std::string& relativeURI,
-                                      ResourceDiscoveredCallback cb);
+                std::unique_ptr<DiscoveryTask> discoverResource(const RCSAddress& address,
+                        const std::string& relativeURI, ResourceDiscoveredCallback cb);
 
                 /**
                  * API for discovering the resource of Interest by Resource type.
@@ -107,8 +125,8 @@ namespace OIC
                  * @see RCSAddress
                  *
                  */
-                void discoverResourceByType(const RCSAddress& address, const std::string& resourceType,
-                                            ResourceDiscoveredCallback cb);
+                std::unique_ptr<DiscoveryTask> discoverResourceByType(const RCSAddress& address,
+                        const std::string& resourceType, ResourceDiscoveredCallback cb);
 
                 /**
                  * API for discovering the resource of Interest by Resource type with provided relativeURI
@@ -125,14 +143,16 @@ namespace OIC
                  * @see RCSAddress
                  *
                  */
-                void discoverResourceByType(const RCSAddress& address, const std::string& relativeURI,
-                                            const std::string& resourceType,
-                                            ResourceDiscoveredCallback cb);
+                std::unique_ptr<DiscoveryTask>  discoverResourceByType(const RCSAddress& address,
+                        const std::string& relativeURI, const std::string& resourceType,
+                        ResourceDiscoveredCallback cb);
 
             private:
 
                 RCSDiscoveryManager() = default;
-                ~RCSDiscoveryManager() = default;
+                ~RCSDiscoveryManager()= default;;
+
+                friend class DiscoveryTask;
         };
     }
 }
diff --git a/service/resource-encapsulation/include/RCSDiscoveryManagerImpl.h b/service/resource-encapsulation/include/RCSDiscoveryManagerImpl.h
new file mode 100755 (executable)
index 0000000..0d69301
--- /dev/null
@@ -0,0 +1,117 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file contains the RCSActiveDiscoveryManager class which provide APIs to discover the Resource in the network
+ *
+ */
+
+#ifndef RCSDISCOVERYMANAGER_IMPL_H
+#define RCSDISCOVERYMANAGER_IMPL_H
+
+#include <memory>
+#include <functional>
+#include <list>
+#include <mutex>
+#include <unordered_map>
+#include <algorithm>
+
+#include "octypes.h"
+
+#include "RCSDiscoveryManager.h"
+#include "RCSAddress.h"
+#include "ExpiryTimer.h"
+#include "PrimitiveResource.h"
+#include "RCSRemoteResourceObject.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSDiscoveryManager;
+        class PrimitiveResource;
+        class RCSAddress;
+        class DiscoveryTask;
+        class DiscoverRequestInfo
+        {
+            public:
+
+                std::string m_address;
+                std::string m_relativeUri;
+                std::string m_resourceType;
+                std::list<std::string> m_receivedIds;
+                bool m_isReceivedFindCallback;
+                DiscoverCallback m_findCB;
+                RCSDiscoveryManager::ResourceDiscoveredCallback m_discoverCB;
+        };
+
+        class RCSDiscoveryManagerImpl
+        {
+            static unsigned int s_uniqueId;
+
+            public:
+
+                typedef std::function<void(OCStackResult, const unsigned int,
+                        const std::string&)> PresenceCallback;
+                typedef unsigned int ID;
+                typedef std::function<void(std::shared_ptr< PrimitiveResource >, ID)> FindCallback;
+
+            public:
+
+                static RCSDiscoveryManagerImpl* getInstance();
+
+                DiscoverRequestInfo m_discoveryItem;
+                std::unordered_map<ID,DiscoverRequestInfo> m_discoveryMap;
+                PresenceCallback m_presenceCB;
+                ExpiryTimer::Callback m_pollingCB;
+                ExpiryTimer m_timer;
+                ID m_timerHandle;
+
+            private:
+                static RCSDiscoveryManagerImpl * s_instance;
+                static std::mutex s_mutexForCreation;
+                std::mutex m_mutex;
+
+            public:
+
+                std::unique_ptr<DiscoveryTask> startDiscovery(const RCSAddress& address,
+                        const std::string& relativeURI,const std::string& resourceType,
+                        RCSDiscoveryManager::ResourceDiscoveredCallback cb);
+
+            private:
+
+                void requestMulticastPresence();
+                void initializedDiscoveryEnvironment();
+                void findCallback(std::shared_ptr< PrimitiveResource > resource, ID discoverID);
+                void pollingCallback(unsigned int /*msg*/);
+                void presenceCallback(OCStackResult, const unsigned int,const std::string&);
+                bool isDuplicatedCallback(std::shared_ptr<PrimitiveResource> resource,ID discoverID);
+                ID createId();
+
+            private:
+
+                RCSDiscoveryManagerImpl() = default;;
+                ~RCSDiscoveryManagerImpl() = default;
+        };
+    }
+}
+#endif // RCSDISCOVERYMANAGER_IMPL_H
old mode 100644 (file)
new mode 100755 (executable)
index 318d602..6bfdd30
 // limitations under the License.
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
 #include "RCSDiscoveryManager.h"
-
-#include "RCSRemoteResourceObject.h"
-#include "PrimitiveResource.h"
-
-#include "ScopeLogger.h"
+#include "RCSDiscoveryManagerImpl.h"
 
 #define TAG "RCSDiscoveryManager"
 
-using namespace OIC::Service;
-
-namespace
-{
-    void findCallback(std::shared_ptr< PrimitiveResource > primitiveResource,
-            RCSDiscoveryManager::ResourceDiscoveredCallback cb)
-    {
-        SCOPE_LOG_F(DEBUG, TAG);
-
-        if (!primitiveResource)
-        {
-            OC_LOG(ERROR, TAG, "findCallback : primitiveResource is null.");
-            return;
-        }
-
-        cb(std::make_shared< RCSRemoteResourceObject >(primitiveResource));
-    }
-}
+namespace OIC {
+    namespace Service {
 
-namespace OIC
-{
-    namespace Service
-    {
-        RCSDiscoveryManager* RCSDiscoveryManager::getInstance()
-        {
+        RCSDiscoveryManager* RCSDiscoveryManager::getInstance() {
             static RCSDiscoveryManager instance;
             return &instance;
         }
 
-        void RCSDiscoveryManager::discoverResource(const RCSAddress& address,
-                ResourceDiscoveredCallback cb)
-        {
-            discoverResourceByType(address, OC_RSRVD_WELL_KNOWN_URI, "", std::move(cb));
+        std::unique_ptr<DiscoveryTask> RCSDiscoveryManager::discoverResource(const RCSAddress& address,
+                ResourceDiscoveredCallback cb) {
+            return discoverResourceByType(address, OC_RSRVD_WELL_KNOWN_URI, "",
+                    std::move(cb));
         }
 
-        void RCSDiscoveryManager::discoverResource(const RCSAddress& address,
-                const std::string& relativeURI, ResourceDiscoveredCallback cb)
-        {
-            discoverResourceByType(address, relativeURI, "", std::move(cb));
+        std::unique_ptr<DiscoveryTask> RCSDiscoveryManager::discoverResource(const RCSAddress& address,
+                const std::string& relativeURI, ResourceDiscoveredCallback cb) {
+            return discoverResourceByType(address, relativeURI, "", std::move(cb));
         }
 
-        void RCSDiscoveryManager::discoverResourceByType(const RCSAddress& address,
-                const std::string& resourceType,
-                ResourceDiscoveredCallback cb)
-        {
-            discoverResourceByType(address, OC_RSRVD_WELL_KNOWN_URI, resourceType, std::move(cb));
+        std::unique_ptr<DiscoveryTask> RCSDiscoveryManager::discoverResourceByType(
+                const RCSAddress& address, const std::string& resourceType, ResourceDiscoveredCallback cb) {
+            return discoverResourceByType(address, OC_RSRVD_WELL_KNOWN_URI,
+                    resourceType, std::move(cb));
         }
 
-        void RCSDiscoveryManager::discoverResourceByType(const RCSAddress& address,
-                const std::string& relativeURI, const std::string& resourceType,
-                ResourceDiscoveredCallback cb)
-        {
-            if (!cb)
-            {
-                OC_LOG(ERROR, TAG, "discoverResourceByType NULL Callback");
-                throw InvalidParameterException { "discoverResourceByType NULL Callback'" };
-            }
-            else
+        std::unique_ptr<DiscoveryTask> RCSDiscoveryManager::discoverResourceByType(
+                const RCSAddress& address, const std::string& relativeURI,
+                const std::string& resourceType, ResourceDiscoveredCallback cb) {
+           return RCSDiscoveryManagerImpl::getInstance()->startDiscovery(address,
+                   relativeURI, resourceType, std::move(cb));
+        }
+        DiscoveryTask::~DiscoveryTask(){
+            cancel();
+        }
+        bool DiscoveryTask::isCanceled() {
+            auto it = RCSDiscoveryManagerImpl::getInstance();
+
+            if(it->m_discoveryMap.find(m_id) == it->m_discoveryMap.end())
             {
-                std::string resourceURI = relativeURI + "?rt=" + resourceType;
-                OIC::Service::discoverResource(address, resourceURI,
-                    std::bind(findCallback, std::placeholders::_1, std::move(cb)));
+                    return true;
             }
+            return false;
+        }
+
+        void DiscoveryTask::cancel(){
+            RCSDiscoveryManagerImpl::getInstance()->m_discoveryMap.erase(m_id);
         }
     }
 }
diff --git a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp
new file mode 100755 (executable)
index 0000000..28be1fa
--- /dev/null
@@ -0,0 +1,191 @@
+//******************************************************************
+//
+// 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 "RCSDiscoveryManagerImpl.h"
+
+#include "OCPlatform.h"
+
+#include "PresenceSubscriber.h"
+#include "RCSAddressDetail.h"
+#include "RCSAddress.h"
+
+constexpr unsigned int RESETNUMBER = 0;
+constexpr unsigned int LIMITNUMBER = 1000;
+constexpr unsigned int INTERVALTIME = 60000;
+
+namespace OIC
+{
+    namespace Service
+    {
+        unsigned int RCSDiscoveryManagerImpl::s_uniqueId = RESETNUMBER;
+        RCSDiscoveryManagerImpl * RCSDiscoveryManagerImpl::s_instance(nullptr);
+        std::mutex RCSDiscoveryManagerImpl::s_mutexForCreation;
+
+        RCSDiscoveryManagerImpl* RCSDiscoveryManagerImpl::getInstance()
+        {
+            if (!s_instance)
+            {
+                s_mutexForCreation.lock();
+                if (!s_instance)
+                {
+                    s_instance = new RCSDiscoveryManagerImpl();
+                    srand(time(NULL));
+                    s_instance->initializedDiscoveryEnvironment();
+                    s_instance->requestMulticastPresence();
+                    s_instance->m_timerHandle = s_instance->m_timer.post(INTERVALTIME, s_instance->m_pollingCB);
+                }
+                s_mutexForCreation.unlock();
+            }
+            return s_instance;
+        }
+
+        void RCSDiscoveryManagerImpl::findCallback(std::shared_ptr< PrimitiveResource > resource,
+            RCSDiscoveryManagerImpl::ID discoverID)
+        {
+            std::unique_lock<std::mutex> lock(m_mutex);
+
+           if(!isDuplicatedCallback(resource,discoverID))
+            {
+               for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
+               {
+                   if(it->first == discoverID)
+                   {
+                        it->second.m_isReceivedFindCallback = true;
+                        it->second.m_discoverCB(std::make_shared<RCSRemoteResourceObject>(resource));
+                   }
+                }
+            }
+        }
+
+        std::unique_ptr<DiscoveryTask> RCSDiscoveryManagerImpl::startDiscovery(const RCSAddress& address,
+                const std::string& relativeURI, const std::string& resourceType,
+                RCSDiscoveryManager::ResourceDiscoveredCallback cb)
+        {
+            if (!cb)
+            {
+                throw InvalidParameterException { "input Parameter(callback) is NULL" };
+            }
+
+            DiscoverRequestInfo discoveryItem;
+            discoveryItem.m_address = RCSAddressDetail::getDetail(address)->getAddress();
+            discoveryItem.m_relativeUri = relativeURI;
+            discoveryItem.m_resourceType = resourceType;
+            discoveryItem.m_discoverCB = std::move(cb);
+            discoveryItem.m_isReceivedFindCallback = false;
+
+            ID discoverID = createId();
+            discoveryItem.m_findCB = std::bind(&RCSDiscoveryManagerImpl::findCallback, this,
+                    std::placeholders::_1, discoverID);
+            m_discoveryMap.insert(std::make_pair(discoverID, discoveryItem));
+
+            OIC::Service::discoverResource(RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress(),
+                    discoveryItem.m_relativeUri + "?rt=" +discoveryItem.m_resourceType,
+                    OCConnectivityType::CT_DEFAULT, discoveryItem.m_findCB);
+
+            return std::unique_ptr<DiscoveryTask>(new DiscoveryTask(discoverID));
+        }
+
+        void RCSDiscoveryManagerImpl::initializedDiscoveryEnvironment()
+        {
+            m_presenceCB = std::bind(&RCSDiscoveryManagerImpl::presenceCallback, this,
+                    std::placeholders::_1, std::placeholders::_2,std::placeholders::_3);
+            m_pollingCB = std::bind(&RCSDiscoveryManagerImpl::pollingCallback, this,
+                std::placeholders::_1);
+        }
+
+        void RCSDiscoveryManagerImpl::requestMulticastPresence()
+        {
+            static constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX;
+            OCDoHandle presenceHandle;
+            subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS,
+                            OCConnectivityType::CT_DEFAULT, std::move(m_presenceCB));
+        }
+
+        bool RCSDiscoveryManagerImpl::isDuplicatedCallback(std::shared_ptr< PrimitiveResource > resource,
+                ID discoverID)
+        {
+            std::string retID = resource->getSid()+resource->getUri();
+            auto it = m_discoveryMap.find(discoverID);
+            std::list<std::string>::iterator itor;
+            if(it==m_discoveryMap.end())
+            {
+                return false;
+            }
+            itor = std::find(it->second.m_receivedIds.begin(),it->second.m_receivedIds.end(),retID);
+            if(itor != it->second.m_receivedIds.end())
+            {
+              return true;
+            }
+            it->second.m_receivedIds.push_back(retID);
+
+            return false;
+        }
+
+        void RCSDiscoveryManagerImpl::pollingCallback(unsigned int /*msg*/)
+        {
+            std::unique_lock<std::mutex> lock(m_mutex);
+            for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
+            {
+                OIC::Service::discoverResource(it->second.m_address,it->second.m_relativeUri+ "?rt="
+                        +it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
+            }
+            m_timerHandle = m_timer.post(INTERVALTIME, m_pollingCB);
+        }
+
+        void RCSDiscoveryManagerImpl::presenceCallback(OCStackResult ret,
+                const unsigned int /*seq*/, const std::string& /*address*/)
+        {
+            if(ret == OC_STACK_OK || ret == OC_STACK_RESOURCE_CREATED || ret == OC_STACK_RESOURCE_DELETED)
+            {
+                std::unique_lock<std::mutex> lock(m_mutex);
+                for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
+                {
+                    if(!it->second.m_isReceivedFindCallback)
+                    {
+                        OIC::Service::discoverResource(it->second.m_address, it->second.m_relativeUri+ "?rt=" +
+                            it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
+                    }
+                }
+            }
+        }
+
+        RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId()
+        {
+            std::unique_lock<std::mutex> lock(m_mutex);
+            if(s_uniqueId<LIMITNUMBER)
+            {
+                 s_uniqueId++;
+            }
+            else
+            {
+                s_uniqueId = RESETNUMBER;
+            }
+            while(m_discoveryMap.size() != LIMITNUMBER)
+            {
+                if(m_discoveryMap.find(s_uniqueId) == m_discoveryMap.end())
+                {
+                    return s_uniqueId;
+                }
+                s_uniqueId++;
+            }
+
+            return RESETNUMBER;
+        }
+    }
+}