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