36c2bc6e95cb1bd1faf61888b8e55560b41086c4
[platform/upstream/iotivity.git] / service / resource-container / src / DiscoverResourceUnit.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "RCSRemoteResourceObject.h"
22 #include "DiscoverResourceUnit.h"
23 #include "RCSAddress.h"
24
25 using namespace OIC::Service;
26
27 DiscoverResourceUnit::DiscoverResourceUnit(const std::string &bundleId)
28     : m_bundleId(bundleId)
29 {
30     pUpdatedCB = nullptr;
31     isStartedDiscovery = false;
32     discoveryTask = nullptr;
33
34     pUpdatedCBFromServer = std::bind(&DiscoverResourceUnit::onUpdate, this,
35                                      std::placeholders::_1, std::placeholders::_2);
36 }
37
38 DiscoverResourceUnit::~DiscoverResourceUnit()
39 {
40     pUpdatedCB = nullptr;
41     discoveryTask = nullptr;
42     pUpdatedCBFromServer = nullptr;
43
44     m_vecRemoteResource.clear();
45 }
46
47 void DiscoverResourceUnit::startDiscover(DiscoverResourceInfo info, UpdatedCB updatedCB)
48 {
49     if (isStartedDiscovery)
50     {
51         // Already start Discovery
52         return;
53     }
54
55     OIC_LOG_V(DEBUG, DISCOVER_TAG, "Start discover %s", info.resourceUri.c_str());
56
57     m_Uri = info.resourceUri;
58     m_ResourceType = info.resourceType;
59     m_AttrubuteName = info.attributeName;
60     pUpdatedCB = updatedCB;
61
62     try
63     {
64         // TODO may be will changed active discovery
65         if (m_Uri.empty())
66         {
67             pDiscoveredCB = std::bind(&DiscoverResourceUnit::discoverdCB, this, std::placeholders::_1,
68                                       std::string(""));
69         }
70         else
71         {
72             pDiscoveredCB = std::bind(&DiscoverResourceUnit::discoverdCB, this, std::placeholders::_1, m_Uri);
73         }
74
75         discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
76                             RCSAddress::multicast(), m_ResourceType, pDiscoveredCB);
77     }
78     catch (RCSInvalidParameterException &e)
79     {
80         // TODO Handle Exception
81         return;
82     }
83
84     isStartedDiscovery = true;
85 }
86
87 void DiscoverResourceUnit::discoverdCB(RCSRemoteResourceObject::Ptr remoteObject, std::string uri)
88 {
89     if (remoteObject && !isAlreadyDiscoveredResource(remoteObject))
90     {
91         OIC_LOG_V(DEBUG, DISCOVER_TAG, "Discovered - uri: %s", uri.c_str());
92         if (uri.empty() || uri.compare(remoteObject->getUri()) == 0){
93             RemoteResourceUnit::Ptr newDiscoveredResource =
94                        RemoteResourceUnit::createRemoteResourceInfo(remoteObject,
95                                pUpdatedCBFromServer);
96                 m_vecRemoteResource.push_back(newDiscoveredResource);
97                 newDiscoveredResource->startMonitoring();
98                 newDiscoveredResource->startCaching();
99
100             OIC_LOG_V(DEBUG, DISCOVER_TAG, "Created remote resource unit");
101         }
102         else{
103             OIC_LOG_V(DEBUG, DISCOVER_TAG, "URI is not matching - uri: %s", uri.c_str());
104         }
105     }
106     else
107     {
108         // Already Discovered Resource
109     }
110 }
111
112 void DiscoverResourceUnit::onUpdate(REMOTE_MSG msg, RCSRemoteResourceObject::Ptr updatedResource)
113 {
114     if (msg == REMOTE_MSG::DATA_UPDATED)
115     {
116         if (updatedResource == nullptr)
117         {
118             return;
119         }
120         try
121         {
122             updatedResource->getCachedAttribute(m_AttrubuteName);
123         }
124         catch (RCSInvalidKeyException &e)
125         {
126             // TODO Handle Exception
127             return;
128         }
129         catch (std::exception &e)
130         {
131             return;
132         }
133
134         std::vector<RCSResourceAttributes::Value> retVector
135             = buildInputResourceData(updatedResource);
136         if (!retVector.empty() && pUpdatedCB != nullptr)
137         {
138             pUpdatedCB(m_AttrubuteName, retVector);
139         }
140     }
141     else
142     {
143         // TODO find & delete
144     }
145 }
146
147 std::vector<RCSResourceAttributes::Value> DiscoverResourceUnit::buildInputResourceData(
148     RCSRemoteResourceObject::Ptr updatedResource)
149 {
150     (void)updatedResource;
151     std::vector<RCSResourceAttributes::Value> retVector = {};
152     for (auto iter : m_vecRemoteResource)
153     {
154         if (iter->getRemoteResourceObject()->getCacheState() != CacheState::READY)
155         {
156             continue;
157         }
158
159         try
160         {
161             RCSResourceAttributes::Value value =
162                 iter->getRemoteResourceObject()->getCachedAttribute(m_AttrubuteName);
163             retVector.push_back(value);
164
165         }
166         catch (RCSInvalidKeyException &e)
167         {
168             // TODO Handle Exception
169         }
170     }
171
172     return retVector;
173 }
174
175 bool DiscoverResourceUnit::isAlreadyDiscoveredResource(
176     RCSRemoteResourceObject::Ptr discoveredResource)
177 {
178     for (auto iter : m_vecRemoteResource)
179     {
180         if (discoveredResource->getUri().compare(iter->getRemoteResourceUri()) == 0 &&
181             discoveredResource->getAddress().compare(iter->getRemoteResourceObject()->getAddress()) == 0 )
182         {
183             return true;
184         }
185     }
186     return false;
187 }