Various fixes for the Android resource container extension
[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     OC_LOG_V(DEBUG, CONTAINER_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         OC_LOG_V(DEBUG, CONTAINER_TAG, "Discovered%s", uri.c_str());
92         RemoteResourceUnit::Ptr newDiscoveredResource =
93             RemoteResourceUnit::createRemoteResourceInfo(remoteObject, pUpdatedCBFromServer);
94
95         if (uri.empty() || uri.compare(remoteObject->getUri()) == 0)
96         {
97             m_vecRemoteResource.push_back(newDiscoveredResource);
98             newDiscoveredResource->startMonitoring();
99             newDiscoveredResource->startCaching();
100         }
101     }
102     else
103     {
104         // Already Discovered Resource
105     }
106 }
107
108 void DiscoverResourceUnit::onUpdate(REMOTE_MSG msg, RCSRemoteResourceObject::Ptr updatedResource)
109 {
110     if (msg == REMOTE_MSG::DATA_UPDATED)
111     {
112         if (updatedResource == nullptr)
113         {
114             return;
115         }
116         try
117         {
118             updatedResource->getCachedAttribute(m_AttrubuteName);
119         }
120         catch (RCSInvalidKeyException &e)
121         {
122             // TODO Handle Exception
123             return;
124         }
125         catch (std::exception &e)
126         {
127             return;
128         }
129
130         std::vector<RCSResourceAttributes::Value> retVector
131             = buildInputResourceData(updatedResource);
132         if (!retVector.empty() && pUpdatedCB != nullptr)
133         {
134             pUpdatedCB(m_AttrubuteName, retVector);
135         }
136     }
137     else
138     {
139         // TODO find & delete
140     }
141 }
142
143 std::vector<RCSResourceAttributes::Value> DiscoverResourceUnit::buildInputResourceData(
144     RCSRemoteResourceObject::Ptr updatedResource)
145 {
146     (void)updatedResource;
147     std::vector<RCSResourceAttributes::Value> retVector = {};
148     for (auto iter : m_vecRemoteResource)
149     {
150         if (iter->getRemoteResourceObject()->getCacheState() != CacheState::READY)
151         {
152             continue;
153         }
154
155         try
156         {
157             RCSResourceAttributes::Value value =
158                 iter->getRemoteResourceObject()->getCachedAttribute(m_AttrubuteName);
159             retVector.push_back(value);
160
161         }
162         catch (RCSInvalidKeyException &e)
163         {
164             // TODO Handle Exception
165         }
166     }
167
168     return retVector;
169 }
170
171 bool DiscoverResourceUnit::isAlreadyDiscoveredResource(
172     RCSRemoteResourceObject::Ptr discoveredResource)
173 {
174     for (auto iter : m_vecRemoteResource)
175     {
176         if (discoveredResource->getUri().compare(iter->getRemoteResourceUri()) == 0 &&
177             discoveredResource->getAddress().compare(iter->getRemoteResourceObject()->getAddress()) == 0 )
178         {
179             return true;
180         }
181     }
182     return false;
183 }