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() : m_timerHandle(0){}
42 RCSDiscoveryManagerImpl* RCSDiscoveryManagerImpl::getInstance()
46 s_mutexForCreation.lock();
49 s_instance = new RCSDiscoveryManagerImpl();
51 s_instance->initializedDiscoveryEnvironment();
52 s_instance->requestMulticastPresence();
53 s_instance->m_timerHandle = s_instance->m_timer.post(INTERVALTIME, s_instance->m_pollingCB);
55 s_mutexForCreation.unlock();
60 void RCSDiscoveryManagerImpl::findCallback(std::shared_ptr< PrimitiveResource > resource,
61 RCSDiscoveryManagerImpl::ID discoverID)
63 std::lock_guard<std::mutex> lock(m_mutex);
65 if(!isDuplicatedCallback(resource,discoverID))
67 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
69 if(it->first == discoverID)
71 it->second.m_isReceivedFindCallback = true;
72 it->second.m_discoverCB(std::make_shared<RCSRemoteResourceObject>(resource));
78 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> RCSDiscoveryManagerImpl::startDiscovery
79 (const RCSAddress& address, const std::string& relativeURI, const std::string& resourceType,
80 RCSDiscoveryManager::ResourceDiscoveredCallback cb)
84 throw RCSInvalidParameterException { "input Parameter(callback) is NULL" };
87 DiscoverRequestInfo discoveryItem;
88 discoveryItem.m_address = RCSAddressDetail::getDetail(address)->getAddress();
89 discoveryItem.m_relativeUri = relativeURI;
90 discoveryItem.m_resourceType = resourceType;
91 discoveryItem.m_discoverCB = std::move(cb);
92 discoveryItem.m_isReceivedFindCallback = false;
94 ID discoverID = createId();
95 discoveryItem.m_findCB = std::bind(&RCSDiscoveryManagerImpl::findCallback, this,
96 std::placeholders::_1, discoverID);
97 m_discoveryMap.insert(std::make_pair(discoverID, discoveryItem));
99 OIC::Service::discoverResource(RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress(),
100 discoveryItem.m_relativeUri + "?rt=" +discoveryItem.m_resourceType,
101 OCConnectivityType::CT_DEFAULT, discoveryItem.m_findCB);
103 return std::unique_ptr<RCSDiscoveryManager::DiscoveryTask>(
104 new RCSDiscoveryManager::DiscoveryTask(discoverID));
107 void RCSDiscoveryManagerImpl::initializedDiscoveryEnvironment()
109 m_presenceCB = std::bind(&RCSDiscoveryManagerImpl::presenceCallback, this,
110 std::placeholders::_1, std::placeholders::_2,std::placeholders::_3);
111 m_pollingCB = std::bind(&RCSDiscoveryManagerImpl::pollingCallback, this,
112 std::placeholders::_1);
115 void RCSDiscoveryManagerImpl::requestMulticastPresence()
117 static constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX;
118 OCDoHandle presenceHandle;
119 subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS,
120 OCConnectivityType::CT_DEFAULT, std::move(m_presenceCB));
123 bool RCSDiscoveryManagerImpl::isDuplicatedCallback(std::shared_ptr< PrimitiveResource > resource,
126 std::string retID = resource->getSid()+resource->getUri();
127 auto it = m_discoveryMap.find(discoverID);
128 std::list<std::string>::iterator itor;
129 if(it==m_discoveryMap.end())
133 itor = std::find(it->second.m_receivedIds.begin(),it->second.m_receivedIds.end(),retID);
134 if(itor != it->second.m_receivedIds.end())
138 it->second.m_receivedIds.push_back(retID);
143 void RCSDiscoveryManagerImpl::pollingCallback(unsigned int /*msg*/)
145 std::lock_guard<std::mutex> lock(m_mutex);
146 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
148 OIC::Service::discoverResource(it->second.m_address,it->second.m_relativeUri+ "?rt="
149 +it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
151 m_timerHandle = m_timer.post(INTERVALTIME, m_pollingCB);
154 void RCSDiscoveryManagerImpl::presenceCallback(OCStackResult ret,
155 const unsigned int /*seq*/, const std::string& /*address*/)
157 if(ret == OC_STACK_OK || ret == OC_STACK_RESOURCE_CREATED || ret == OC_STACK_RESOURCE_DELETED)
159 std::lock_guard<std::mutex> lock(m_mutex);
160 for(auto it = m_discoveryMap.begin(); it != m_discoveryMap.end(); ++it)
162 if(!it->second.m_isReceivedFindCallback)
164 OIC::Service::discoverResource(it->second.m_address, it->second.m_relativeUri+ "?rt=" +
165 it->second.m_resourceType, OCConnectivityType::CT_DEFAULT, it->second.m_findCB);
171 RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId()
173 std::lock_guard<std::mutex> lock(m_mutex);
174 if(s_uniqueId<LIMITNUMBER)
180 s_uniqueId = RESETNUMBER;
182 while(m_discoveryMap.size() != LIMITNUMBER)
184 if(m_discoveryMap.find(s_uniqueId) == m_discoveryMap.end())
194 void RCSDiscoveryManagerImpl::cancel(ID id)
196 std::lock_guard<std::mutex> lock(m_mutex);
197 m_discoveryMap.erase(id);