X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=service%2Fresource-encapsulation%2Fsrc%2FresourceClient%2FRCSDiscoveryManagerImpl.cpp;h=319c9b8ca51e429f95b067cc1625f48b438f6547;hb=refs%2Ftags%2Fsubmit%2Ftizen_4.0%2F20171010.021147;hp=8d2ea81e626eacefb73d1b5656e72b60b7dddca6;hpb=db190254d8421cdbcea1c5c9292bb07d7fe29800;p=platform%2Fupstream%2Fiotivity.git diff --git a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp index 8d2ea81..319c9b8 100755 --- a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp +++ b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp @@ -17,7 +17,6 @@ // limitations under the License. // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#include #include "RCSDiscoveryManagerImpl.h" @@ -25,22 +24,44 @@ #include "PresenceSubscriber.h" #include "RCSAddressDetail.h" #include "RCSAddress.h" +#include "RCSRemoteResourceObject.h" namespace { - constexpr unsigned int LIMITNUMBER = std::numeric_limits::max();; - constexpr unsigned int INTERVALTIME = 60000; + constexpr unsigned int POLLING_INTERVAL_TIME = 60000; + + std::string makeResourceId(const std::shared_ptr< OIC::Service::PrimitiveResource >& resource) + { + return resource->getSid() + resource->getUri(); + } + + void validateTypes(const std::vector< std::string >& resourceTypes) { + if (resourceTypes.size() == 1) return; + + for (const auto& type : resourceTypes) + { + if (type == OIC::Service::RCSDiscoveryManagerImpl::ALL_RESOURCE_TYPE) + { + throw OIC::Service::RCSBadRequestException{ + "resource types must have no empty string!" }; + } + } + } } namespace OIC { namespace Service { + constexpr RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::INVALID_ID; + constexpr char const* RCSDiscoveryManagerImpl::ALL_RESOURCE_TYPE; + RCSDiscoveryManagerImpl::RCSDiscoveryManagerImpl() { - srand(time(NULL)); - requestMulticastPresence(); - m_timer.post(INTERVALTIME, std::bind(&RCSDiscoveryManagerImpl::onPolling, this)); + subscribePresenceWithMulticast(); + + m_timer.post(POLLING_INTERVAL_TIME, + std::bind(&RCSDiscoveryManagerImpl::onPolling, this)); } RCSDiscoveryManagerImpl* RCSDiscoveryManagerImpl::getInstance() @@ -49,124 +70,158 @@ namespace OIC return &instance; } - void RCSDiscoveryManagerImpl::onResourceFound(std::shared_ptr< PrimitiveResource > resource, - RCSDiscoveryManagerImpl::ID discoveryId, const RCSDiscoveryManager::ResourceDiscoveredCallback& discoverCB) + void RCSDiscoveryManagerImpl::onResourceFound( + std::shared_ptr< PrimitiveResource > resource, ID discoveryId, + const RCSDiscoveryManager::ResourceDiscoveredCallback& discoverCB) { { - std::lock_guard lock(m_mutex); + std::lock_guard < std::mutex > lock(m_mutex); auto it = m_discoveryMap.find(discoveryId); - if(it == m_discoveryMap.end()) return; - if(it->second.isKnownResource(resource)) return; + if (it == m_discoveryMap.end()) return; + if (it->second.isKnownResource(resource)) return; + + it->second.addKnownResource(resource); } - discoverCB(std::make_shared(resource)); + discoverCB(std::make_shared < RCSRemoteResourceObject > (resource)); } - RCSDiscoveryManager::DiscoveryTask::Ptr RCSDiscoveryManagerImpl::startDiscovery - (const RCSAddress& address, const std::string& relativeUri, const std::string& resourceType, - RCSDiscoveryManager::ResourceDiscoveredCallback cb) + RCSDiscoveryManager::DiscoveryTask::Ptr RCSDiscoveryManagerImpl::startDiscovery( + const RCSAddress& address, const std::string& relativeUri, + const std::vector< std::string >& resourceTypes, + RCSDiscoveryManager::ResourceDiscoveredCallback cb) { if (!cb) { - throw RCSInvalidParameterException { "Callback is empty" }; + throw RCSInvalidParameterException{ "Callback is empty" }; } - ID discoveryId = createId(); - auto discoverCb = std::bind(&RCSDiscoveryManagerImpl::onResourceFound, this, - std::placeholders::_1, discoveryId, std::move(cb)); - DiscoverRequestInfo discoveryItem(RCSAddressDetail::getDetail(address)->getAddress(), relativeUri, - resourceType, std::move(discoverCb)); - discoveryItem.discoverRequest(); + validateTypes(resourceTypes); + + const ID discoveryId = createId(); + + DiscoveryRequestInfo discoveryInfo(address, relativeUri, resourceTypes, + std::bind(&RCSDiscoveryManagerImpl::onResourceFound, this, + std::placeholders::_1, discoveryId, std::move(cb))); - m_discoveryMap.insert(std::make_pair(discoveryId, std::move(discoveryItem))); + discoveryInfo.discover(); - return std::unique_ptr( + { + std::lock_guard < std::mutex > lock(m_mutex); + m_discoveryMap.insert(std::make_pair(discoveryId, std::move(discoveryInfo))); + } + + return std::unique_ptr< RCSDiscoveryManager::DiscoveryTask >( new RCSDiscoveryManager::DiscoveryTask(discoveryId)); } - void RCSDiscoveryManagerImpl::requestMulticastPresence() + void RCSDiscoveryManagerImpl::subscribePresenceWithMulticast() { - static constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX; + using namespace std::placeholders; + + constexpr char MULTICAST_PRESENCE_ADDRESS[] = "coap://" OC_MULTICAST_PREFIX; + OCDoHandle presenceHandle; - subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS, OCConnectivityType::CT_DEFAULT, - std::move(std::bind(&RCSDiscoveryManagerImpl::onPresence, this, - std::placeholders::_1, std::placeholders::_2,std::placeholders::_3))); + subscribePresence(presenceHandle, MULTICAST_PRESENCE_ADDRESS, + OCConnectivityType::CT_DEFAULT, + std::bind(&RCSDiscoveryManagerImpl::onPresence, this, _1, _2, _3)); } void RCSDiscoveryManagerImpl::onPolling() { - std::lock_guard lock(m_mutex); - - for(const auto& it : m_discoveryMap) { - it.second.discoverRequest(); + std::lock_guard < std::mutex > lock(m_mutex); + + for (const auto& it : m_discoveryMap) + { + it.second.discover(); + } } - m_timer.post(INTERVALTIME, std::bind(&RCSDiscoveryManagerImpl::onPolling, this)); + m_timer.post(POLLING_INTERVAL_TIME, + std::bind(&RCSDiscoveryManagerImpl::onPolling, this)); } - void RCSDiscoveryManagerImpl::onPresence(OCStackResult ret, - const unsigned int /*seq*/, const std::string& address) + void RCSDiscoveryManagerImpl::onPresence(OCStackResult result, const unsigned int /*seq*/, + const std::string& address) { - if(ret != OC_STACK_OK && ret != OC_STACK_RESOURCE_CREATED) return; + if (result != OC_STACK_OK && result != OC_STACK_RESOURCE_CREATED) return; - std::lock_guard lock(m_mutex); - for(const auto& it : m_discoveryMap) + std::lock_guard < std::mutex > lock(m_mutex); + for (const auto& it : m_discoveryMap) { - if(it.second.isMatchingAddress(address)) + if (it.second.isMatchedAddress(address)) { - it.second.discoverRequest(); + it.second.discover(); } } } - RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId() + RCSDiscoveryManagerImpl::ID RCSDiscoveryManagerImpl::createId() const { - std::lock_guard lock(m_mutex); - static unsigned int s_uniqueId; + static ID s_nextId = INVALID_ID + 1; - if(m_discoveryMap.size() >= LIMITNUMBER) - { - throw RCSException { "Discovery request is full!" }; - } + std::lock_guard < std::mutex > lock(m_mutex); - while(m_discoveryMap.find(s_uniqueId) != m_discoveryMap.end()) + while (s_nextId == INVALID_ID || m_discoveryMap.find(s_nextId) != m_discoveryMap.end()) { - s_uniqueId++; + ++s_nextId; } - return s_uniqueId; + + assert(s_nextId != INVALID_ID && "Invalid ID!"); + + return s_nextId++; } - void RCSDiscoveryManagerImpl::cancel(unsigned int id) + void RCSDiscoveryManagerImpl::cancel(ID id) { - std::lock_guard lock(m_mutex); + std::lock_guard < std::mutex > lock(m_mutex); m_discoveryMap.erase(id); } - DiscoverRequestInfo::DiscoverRequestInfo(const std::string &address, const std::string &relativeUri, - const std::string &resourceType, DiscoverCallback cb) : m_address(address), - m_relativeUri(relativeUri), m_resourceType(resourceType), m_discoverCB(cb) {} - - void DiscoverRequestInfo::discoverRequest() const + DiscoveryRequestInfo::DiscoveryRequestInfo(const RCSAddress& address, + const std::string& relativeUri, const std::vector< std::string >& resourceTypes, + DiscoverCallback cb) : + m_address{ address }, + m_relativeUri{ relativeUri }, + m_resourceTypes{ resourceTypes }, + m_knownResourceIds{ }, + m_discoverCb{ std::move(cb) } { - OIC::Service::discoverResource(m_address, m_relativeUri + "?rt=" + m_resourceType, - OCConnectivityType::CT_DEFAULT, m_discoverCB); + if (m_resourceTypes.empty()) + { + m_resourceTypes.push_back(RCSDiscoveryManagerImpl::ALL_RESOURCE_TYPE); + } } - bool DiscoverRequestInfo::isKnownResource(const std::shared_ptr& resource) + void DiscoveryRequestInfo::discover() const { - std::string resourceId = resource->getSid() + resource->getUri(); + for (const auto& it : m_resourceTypes) + { + std::string uri = std::string(OC_RSRVD_WELL_KNOWN_URI); + if (!it.empty()) + { + uri = std::string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + it; + } + discoverResource(m_address, uri, m_discoverCb); + } + } - auto it = std::find(m_receivedIds.begin(), m_receivedIds.end(), resourceId); + bool DiscoveryRequestInfo::isKnownResource( + const std::shared_ptr< PrimitiveResource >& resource) const + { + return m_knownResourceIds.find(makeResourceId(resource)) != m_knownResourceIds.end(); + } - if(it != m_receivedIds.end()) return true; - m_receivedIds.push_back(resourceId); - return false; + void DiscoveryRequestInfo::addKnownResource( + const std::shared_ptr< PrimitiveResource >& resource) + { + m_knownResourceIds.insert(makeResourceId(resource)); } - bool DiscoverRequestInfo::isMatchingAddress(const std::string& address) const + bool DiscoveryRequestInfo::isMatchedAddress(const std::string& address) const { - return m_address == RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress() - || m_address == address; + return RCSAddressDetail::getDetail(m_address)->isMulticast() + || RCSAddressDetail::getDetail(m_address)->getAddress() == address; } } }