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"
23 #include "PresenceSubscriber.h"
24 #include "RCSAddressDetail.h"
25 #include "RCSAddress.h"
29 constexpr unsigned int POLLING_INTERVAL_TIME = 60000;
36 RCSDiscoveryManagerImpl::RCSDiscoveryManagerImpl()
39 requestMulticastPresence();
40 m_timer.post(POLLING_INTERVAL_TIME, std::bind(&RCSDiscoveryManagerImpl::onPolling, this));
43 RCSDiscoveryManagerImpl* RCSDiscoveryManagerImpl::getInstance()
45 static RCSDiscoveryManagerImpl instance;
49 void RCSDiscoveryManagerImpl::onResourceFound(std::shared_ptr<PrimitiveResource> resource,
50 RCSDiscoveryManagerImpl::ID discoveryId,
51 const RCSDiscoveryManager::ResourceDiscoveredCallback& discoverCB)
54 std::lock_guard < std::mutex > lock(m_mutex);
55 auto it = m_discoveryMap.find(discoveryId);
57 if (it == m_discoveryMap.end()) return;
58 if (it->second.isKnownResource(resource)) return;
60 discoverCB(std::make_shared < RCSRemoteResourceObject > (resource));
63 RCSDiscoveryManager::DiscoveryTask::Ptr RCSDiscoveryManagerImpl::startDiscovery(
64 const RCSAddress& address, const std::string& relativeUri,
65 const std::string& resourceType, RCSDiscoveryManager::ResourceDiscoveredCallback cb)
69 throw RCSInvalidParameterException { "Callback is empty" };
72 ID discoveryId = createId();
73 auto discoverCb = std::bind(&RCSDiscoveryManagerImpl::onResourceFound, this,
74 std::placeholders::_1, discoveryId, std::move(cb));
75 DiscoveryRequestInfo discoveryInfo(RCSAddressDetail::getDetail(address)->getAddress(),
76 relativeUri, resourceType, std::move(discoverCb));
77 discoveryInfo.discover();
80 std::lock_guard < std::mutex > lock(m_mutex);
81 m_discoveryMap.insert(std::make_pair(discoveryId, std::move(discoveryInfo)));
84 return std::unique_ptr < RCSDiscoveryManager::DiscoveryTask> (
85 new RCSDiscoveryManager::DiscoveryTask(discoveryId));
88 void RCSDiscoveryManagerImpl::requestMulticastPresence()
90 constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX;
91 OCDoHandle presenceHandle;
92 subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS,
93 OCConnectivityType::CT_DEFAULT,
94 std::move(std::bind(&RCSDiscoveryManagerImpl::onPresence, this,
95 std::placeholders::_1, std::placeholders::_2,
96 std::placeholders::_3)));
99 void RCSDiscoveryManagerImpl::onPolling()
101 std::lock_guard < std::mutex > lock(m_mutex);
103 for (const auto& it : m_discoveryMap)
105 it.second.discover();
107 m_timer.post(POLLING_INTERVAL_TIME, std::bind(&RCSDiscoveryManagerImpl::onPolling, this));
110 void RCSDiscoveryManagerImpl::onPresence(OCStackResult ret, const unsigned int /*seq*/,
111 const std::string& address)
113 if (ret != OC_STACK_OK && ret != OC_STACK_RESOURCE_CREATED) return;
115 std::lock_guard < std::mutex > lock(m_mutex);
116 for (const auto& it : m_discoveryMap)
118 if (it.second.isMatchingAddress(address))
120 it.second.discover();
125 RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId()
127 std::lock_guard < std::mutex > lock(m_mutex);
128 static ID s_uniqueId;
131 while (m_discoveryMap.find(s_uniqueId) != m_discoveryMap.end())
138 void RCSDiscoveryManagerImpl::cancel(ID id)
140 std::lock_guard < std::mutex > lock(m_mutex);
141 m_discoveryMap.erase(id);
144 bool RCSDiscoveryManagerImpl::isCanceled(ID id)
146 std::lock_guard < std::mutex > lock(m_mutex);
147 auto it = m_discoveryMap.find(id);
148 if (it == m_discoveryMap.end()) return true;
153 DiscoveryRequestInfo::DiscoveryRequestInfo(const std::string &address,
154 const std::string &relativeUri, const std::string &resourceType,
155 DiscoverCallback cb) :
156 m_address(address), m_relativeUri(relativeUri), m_resourceType(resourceType),
157 m_discoverCb(std::move(cb))
161 void DiscoveryRequestInfo::discover() const
163 OIC::Service::discoverResource(m_address, m_relativeUri + "?rt=" + m_resourceType,
164 OCConnectivityType::CT_DEFAULT, m_discoverCb);
167 bool DiscoveryRequestInfo::isKnownResource(
168 const std::shared_ptr<PrimitiveResource>& resource)
170 std::string resourceId = resource->getSid() + resource->getUri();
172 auto it = std::find(m_receivedIds.begin(), m_receivedIds.end(), resourceId);
174 if (it != m_receivedIds.end()) return true;
175 m_receivedIds.insert(resourceId);
179 bool DiscoveryRequestInfo::isMatchingAddress(const std::string& address) const
181 return m_address == RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress()
182 || m_address == address;