22d4b5cdf81d352c41388aaaf961894b59e4f17b
[platform/upstream/iotivity.git] / service / notification-manager / NotificationManager / src / HostingObject.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 "HostingObject.h"
22
23 namespace OIC
24 {
25 namespace Service
26 {
27 #define HOSTING_LOG_TAG  PCF("Hosting")
28 #define OIC_HOSTING_LOG(level, tag, ...)  OCLogv((level), (HOSTING_LOG_TAG), __VA_ARGS__)
29
30 HostingObject::HostingObject()
31 : remoteObject(nullptr), mirroredServer(nullptr),
32   remoteState(ResourceState::NOT_MONITORING),
33   pStateChangedCB(nullptr), pDataUpdateCB(nullptr),
34   pDestroyCB(nullptr), pSetRequestHandler(nullptr)
35 {
36 }
37
38 HostingObject::RemoteObjectPtr HostingObject::getRemoteResource() const
39 {
40     return remoteObject;
41 }
42
43 void HostingObject::initializeHostingObject(RemoteObjectPtr rResource, DestroyedCallback destroyCB)
44 {
45
46     remoteObject = rResource;
47
48     pStateChangedCB = std::bind(&HostingObject::stateChangedCB, this,
49             std::placeholders::_1, remoteObject);
50     pDataUpdateCB = std::bind(&HostingObject::dataChangedCB, this,
51             std::placeholders::_1, remoteObject);
52     pDestroyCB = destroyCB;
53
54     pSetRequestHandler = std::bind(&HostingObject::setRequestHandler, this,
55             std::placeholders::_1, std::placeholders::_2);
56
57     try
58     {
59         remoteObject->startMonitoring(pStateChangedCB);
60         remoteObject->startCaching(pDataUpdateCB);
61     }catch(...)
62     {
63         throw;
64     }
65 }
66
67 void HostingObject::destroyHostingObject()
68 {
69     pDestroyCB();
70 }
71
72 void HostingObject::stateChangedCB(ResourceState state, RemoteObjectPtr rObject)
73 {
74     remoteState = state;
75
76     switch (state)
77     {
78     case ResourceState::ALIVE:
79     {
80         if(rObject->isCaching() == false)
81         {
82             try
83             {
84                 rObject->startCaching(pDataUpdateCB);
85             }catch(InvalidParameterException &e)
86             {
87                 OIC_HOSTING_LOG(DEBUG,
88                         "[HostingObject::stateChangedCB]startCaching InvalidParameterException:%s",
89                         e.what());
90             }
91         }
92         break;
93     }
94     case ResourceState::LOST_SIGNAL:
95     case ResourceState::DESTROYED:
96     {
97         if(rObject->isCaching() == true)
98         {
99             try
100             {
101                 rObject->stopCaching();
102             }catch(InvalidParameterException &e)
103             {
104                 OIC_HOSTING_LOG(DEBUG,
105                         "[HostingObject::stateChangedCB]stopCaching InvalidParameterException:%s",
106                         e.what());
107             }
108         }
109         if(rObject->isMonitoring() == true)
110         {
111             try
112             {
113                 rObject->stopMonitoring();
114             }catch(InvalidParameterException &e)
115             {
116                 OIC_HOSTING_LOG(DEBUG,
117                         "[HostingObject::stateChangedCB]stopWatching InvalidParameterException:%s",
118                         e.what());
119             }
120         }
121         mirroredServer = nullptr;
122         destroyHostingObject();
123         break;
124     }
125     default:
126         // not support of state
127         break;
128     }
129 }
130
131 void HostingObject::dataChangedCB(const ResourceAttributes & attributes, RemoteObjectPtr rObject)
132 {
133     if(attributes.empty())
134     {
135         return;
136     }
137
138     if(mirroredServer == nullptr)
139     {
140         try
141         {
142             mirroredServer = createMirroredServer(rObject);
143         }catch(PlatformException &e)
144         {
145             OIC_HOSTING_LOG(DEBUG,
146                         "[HostingObject::dataChangedCB]createMirroredServer PlatformException:%s",
147                         e.what());
148             mirroredServer = nullptr;
149             return;
150         }
151     }
152
153     ResourceAttributes rData;
154     {
155         ResourceObject::LockGuard guard(mirroredServer);
156         rData = mirroredServer->getAttributes();
157     }
158     if(rData.empty() || rData != attributes)
159     {
160         {
161             ResourceObject::LockGuard guard(mirroredServer);
162             for(auto it = rData.begin(); ; ++it)
163             {
164                 if(it == rData.end())
165                 {
166                     break;
167                 }
168                 mirroredServer->removeAttribute(it->key());
169             }
170
171             for(auto it = attributes.begin();; ++it)
172             {
173                 if(it == attributes.end())
174                 {
175                     break;
176                 }
177                 mirroredServer->setAttribute(it->key(), it->value());
178             }
179         }
180     }
181 }
182
183 HostingObject::ResourceObjectPtr HostingObject::createMirroredServer(RemoteObjectPtr rObject)
184 {
185     ResourceObjectPtr retResource = nullptr;
186     if(rObject != nullptr)
187     {
188         std::string fulluri = rObject->getUri();
189         std::string uri = fulluri.substr(0, fulluri.size()-8);
190         std::vector<std::string> types = rObject->getTypes();
191         std::vector<std::string> interfaces = rObject->getInterfaces();
192         try
193         {
194             std::string type = types.begin()->c_str();
195             std::string interface = interfaces.begin()->c_str();
196             retResource = ResourceObject::Builder(uri, type, interface).
197                     setDiscoverable(true).setObservable(true).build();
198
199             // TODO need to bind types and interfaces
200             retResource->setAutoNotifyPolicy(ResourceObject::AutoNotifyPolicy::UPDATED);
201             retResource->setSetRequestHandler(pSetRequestHandler);
202         }catch(...)
203         {
204             OIC_HOSTING_LOG(DEBUG, "[HostingObject::createMirroredServer] %s", "PlatformException");
205             throw;
206         }
207     }
208     else
209     {
210         throw PlatformException(OC_STACK_ERROR);
211     }
212
213     return retResource;
214 }
215
216 RCSSetResponse HostingObject::setRequestHandler(const RCSRequest & primitiveRequest,
217             ResourceAttributes & resourceAttibutes)
218 {
219     try
220     {
221         RequestObject newRequest = { };
222         newRequest.invokeRequest(remoteObject, RequestObject::RequestMethod::Setter,
223                 primitiveRequest, resourceAttibutes);
224     }catch(PlatformException &e)
225     {
226         OIC_HOSTING_LOG(DEBUG,
227                 "[HostingObject::setRequestHandler] PlatformException:%s",
228                 e.what());
229         throw;
230     }
231
232     return RCSSetResponse::create(resourceAttibutes);
233 }
234
235 } /* namespace Service */
236 } /* namespace OIC */