1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #include "RCSDiscoveryManagerImpl.h"
22 #include "OCPlatform.h"
24 #include "PresenceSubscriber.h"
25 #include "RCSAddressDetail.h"
26 #include "RCSAddress.h"
28 constexpr unsigned int RESETNUMBER = 0;
29 constexpr unsigned int LIMITNUMBER = 1000;
30 constexpr unsigned int INTERVALTIME = 60000;
36 unsigned int RCSDiscoveryManagerImpl::s_uniqueId = RESETNUMBER;
37 RCSDiscoveryManagerImpl * RCSDiscoveryManagerImpl::s_instance(nullptr);
38 std::mutex RCSDiscoveryManagerImpl::s_mutexForCreation;
40 RCSDiscoveryManagerImpl* RCSDiscoveryManagerImpl::getInstance()
44 s_mutexForCreation.lock();
47 s_instance = new RCSDiscoveryManagerImpl();
49 s_instance->initializedDiscoveryEnvironment();
50 s_instance->requestMulticastPresence();
51 s_instance->m_timerHandle = s_instance->m_timer.post(INTERVALTIME, s_instance->m_pollingCB);
53 s_mutexForCreation.unlock();
58 void RCSDiscoveryManagerImpl::findCallback(std::shared_ptr< PrimitiveResource > resource,
59 RCSDiscoveryManagerImpl::ID discoverID)
61 std::unique_lock<std::mutex> lock(m_mutex);
63 if(!isDuplicatedCallback(resource,discoverID))
65 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
67 if(it->first == discoverID)
69 it->second.m_isReceivedFindCallback = true;
70 it->second.m_discoverCB(std::make_shared<RCSRemoteResourceObject>(resource));
76 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> RCSDiscoveryManagerImpl::startDiscovery(const RCSAddress& address,
77 const std::string& relativeURI, const std::string& resourceType,
78 RCSDiscoveryManager::ResourceDiscoveredCallback cb)
82 throw InvalidParameterException { "input Parameter(callback) is NULL" };
85 DiscoverRequestInfo discoveryItem;
86 discoveryItem.m_address = RCSAddressDetail::getDetail(address)->getAddress();
87 discoveryItem.m_relativeUri = relativeURI;
88 discoveryItem.m_resourceType = resourceType;
89 discoveryItem.m_discoverCB = std::move(cb);
90 discoveryItem.m_isReceivedFindCallback = false;
92 ID discoverID = createId();
93 discoveryItem.m_findCB = std::bind(&RCSDiscoveryManagerImpl::findCallback, this,
94 std::placeholders::_1, discoverID);
95 m_discoveryMap.insert(std::make_pair(discoverID, discoveryItem));
97 OIC::Service::discoverResource(RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress(),
98 discoveryItem.m_relativeUri + "?rt=" +discoveryItem.m_resourceType,
99 OCConnectivityType::CT_DEFAULT, discoveryItem.m_findCB);
101 return std::unique_ptr<RCSDiscoveryManager::DiscoveryTask>(new RCSDiscoveryManager::DiscoveryTask(discoverID));
104 void RCSDiscoveryManagerImpl::initializedDiscoveryEnvironment()
106 m_presenceCB = std::bind(&RCSDiscoveryManagerImpl::presenceCallback, this,
107 std::placeholders::_1, std::placeholders::_2,std::placeholders::_3);
108 m_pollingCB = std::bind(&RCSDiscoveryManagerImpl::pollingCallback, this,
109 std::placeholders::_1);
112 void RCSDiscoveryManagerImpl::requestMulticastPresence()
114 static constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX;
115 OCDoHandle presenceHandle;
116 subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS,
117 OCConnectivityType::CT_DEFAULT, std::move(m_presenceCB));
120 bool RCSDiscoveryManagerImpl::isDuplicatedCallback(std::shared_ptr< PrimitiveResource > resource,
123 std::string retID = resource->getSid()+resource->getUri();
124 auto it = m_discoveryMap.find(discoverID);
125 std::list<std::string>::iterator itor;
126 if(it==m_discoveryMap.end())
130 itor = std::find(it->second.m_receivedIds.begin(),it->second.m_receivedIds.end(),retID);
131 if(itor != it->second.m_receivedIds.end())
135 it->second.m_receivedIds.push_back(retID);
140 void RCSDiscoveryManagerImpl::pollingCallback(unsigned int /*msg*/)
142 std::unique_lock<std::mutex> lock(m_mutex);
143 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
145 OIC::Service::discoverResource(it->second.m_address,it->second.m_relativeUri+ "?rt="
146 +it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
148 m_timerHandle = m_timer.post(INTERVALTIME, m_pollingCB);
151 void RCSDiscoveryManagerImpl::presenceCallback(OCStackResult ret,
152 const unsigned int /*seq*/, const std::string& /*address*/)
154 if(ret == OC_STACK_OK || ret == OC_STACK_RESOURCE_CREATED || ret == OC_STACK_RESOURCE_DELETED)
156 std::unique_lock<std::mutex> lock(m_mutex);
157 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
159 if(!it->second.m_isReceivedFindCallback)
161 OIC::Service::discoverResource(it->second.m_address, it->second.m_relativeUri+ "?rt=" +
162 it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
168 RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId()
170 std::unique_lock<std::mutex> lock(m_mutex);
171 if(s_uniqueId<LIMITNUMBER)
177 s_uniqueId = RESETNUMBER;
179 while(m_discoveryMap.size() != LIMITNUMBER)
181 if(m_discoveryMap.find(s_uniqueId) == m_discoveryMap.end())