Change the header install path for c_common and logger
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceClient / RCSRemoteResourceObject.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
23 #include "OCPlatform.h"
24
25 #include "ResourceBroker.h"
26 #include "ResourceCacheManager.h"
27
28 #include "ScopeLogger.h"
29
30 #define TAG PCF("RCSRemoteResourceObject")
31
32 namespace
33 {
34     using namespace OIC::Service;
35
36     ResourceState convertBrokerState(BROKER_STATE state)
37     {
38         SCOPE_LOG_F(DEBUG, TAG);
39
40         switch (state)
41         {
42             case BROKER_STATE::ALIVE:
43                 return ResourceState::ALIVE;
44
45             case BROKER_STATE::REQUESTED:
46                 return ResourceState::REQUESTED;
47
48             case BROKER_STATE::LOST_SIGNAL:
49                 return ResourceState::LOST_SIGNAL;
50
51             case BROKER_STATE::DESTROYED:
52                 return ResourceState::DESTROYED;
53
54             case BROKER_STATE::NONE:
55                 return ResourceState::NONE;
56         }
57
58         return ResourceState::NONE;
59     }
60
61     CacheState convertCacheState(CACHE_STATE state)
62     {
63         SCOPE_LOG_F(DEBUG, TAG);
64
65         switch (state)
66         {
67             case CACHE_STATE::READY:
68                 return CacheState::READY;
69
70             case CACHE_STATE::READY_YET:
71             case CACHE_STATE::UPDATING:
72                 return CacheState::UNREADY;
73
74             case CACHE_STATE::LOST_SIGNAL:
75                 return CacheState::LOST_SIGNAL;
76
77             case CACHE_STATE::DESTROYED:
78             case CACHE_STATE::NONE:
79                 return CacheState::NONE;
80         }
81
82         return CacheState::NONE;
83     }
84
85     OCStackResult hostingCallback(BROKER_STATE state,
86             RCSRemoteResourceObject::StateChangedCallback onResourceStateChanged)
87     {
88         SCOPE_LOG_F(DEBUG, TAG);
89
90         onResourceStateChanged(convertBrokerState(state));
91         return OC_STACK_OK;
92     }
93
94     OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >,
95             const RCSResourceAttributes& data, int eCode,
96             RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated,
97             std::weak_ptr<RCSRemoteResourceObject> resourcePtr)
98     {
99         SCOPE_LOG_F(DEBUG, TAG);
100
101         //If error code is failure then RE Cache module should
102         //do clean up for caching flags, maps etc.
103         if(eCode > 4)
104         {
105             OIC_LOG_V(ERROR, TAG, "Error code: %d",eCode);
106             try
107             {
108                 std::shared_ptr<RCSRemoteResourceObject> resource = resourcePtr.lock();
109                 if(resource)
110                 {
111                     resource->stopCaching();
112                 }
113                 else
114                 {
115                     OIC_LOG(ERROR, TAG, "Resource object is null");
116                 }
117             }
118             catch(...)
119             {
120                 //Exception will be thrown: stack will return OC_STACK_ERROR
121                 // if it already stopped observe. This call is reqired for clearing
122                 //Cache manager.
123                 OIC_LOG(DEBUG, TAG, "Cleared Cache");
124             }
125         }
126
127         //Calling application callback
128         onCacheUpdated(data, eCode);
129         return OC_STACK_OK;
130     }
131
132     void setRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
133             RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
134     {
135         SCOPE_LOG_F(DEBUG, TAG);
136
137         onRemoteAttributesSet(response.getAttributes(), eCode);
138     }
139
140     void getRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
141             RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
142     {
143         SCOPE_LOG_F(DEBUG, TAG);
144
145         onRemoteAttributesReceived(response.getAttributes(), eCode);
146     }
147 }
148
149 namespace OIC
150 {
151     namespace Service
152     {
153
154         RCSQueryParams& RCSQueryParams::setResourceInterface(std::string resourceInterface)
155         {
156             m_resourceInterface = std::move(resourceInterface);
157             return *this;
158         }
159
160         RCSQueryParams& RCSQueryParams::setResourceType(std::string resourceType)
161         {
162             m_resourceType = std::move(resourceType);
163             return *this;
164         }
165
166         RCSQueryParams& RCSQueryParams::put(std::string key, std::string value)
167         {
168             m_map[std::move(key)] = std::move(value);
169             return *this;
170         }
171
172         std::string RCSQueryParams::getResourceInterface() const
173         {
174             return m_resourceInterface;
175         }
176
177         std::string RCSQueryParams::getResourceType() const
178         {
179             return m_resourceType;
180         }
181
182         std::string RCSQueryParams::get(const std::string& key) const
183         {
184             try
185             {
186                 return m_map.at(key);
187             }
188             catch (const std::out_of_range&)
189             {
190                 throw RCSInvalidKeyException(key + " is an invalid key");
191             }
192         }
193
194         const RCSQueryParams::Map& RCSQueryParams::getAll() const
195         {
196             return m_map;
197         }
198
199         RCSRemoteResourceObject::RCSRemoteResourceObject(
200                 std::shared_ptr< PrimitiveResource > primtiveResource) :
201                 m_primitiveResource{ primtiveResource },
202                 m_cacheId{ },
203                 m_brokerId{ }
204         {
205         }
206
207         RCSRemoteResourceObject::~RCSRemoteResourceObject()
208         {
209             SCOPE_LOG_F(DEBUG, TAG);
210
211             try{
212                 stopCaching();
213                 stopMonitoring();
214             }
215             catch(std::exception &e){
216                 OIC_LOG_V(ERROR, TAG, "%s", e.what());
217             }
218         }
219
220         RCSRemoteResourceObject::Ptr RCSRemoteResourceObject::fromOCResource(
221                 std::shared_ptr< OC::OCResource > ocResource)
222         {
223             if (!ocResource)
224             {
225                 throw RCSInvalidParameterException("the oc resource must not be nullptr.");
226             }
227
228             return std::make_shared< RCSRemoteResourceObject >(
229                     PrimitiveResource::create(ocResource));
230         }
231
232         std::shared_ptr< OC::OCResource > RCSRemoteResourceObject::toOCResource(
233         RCSRemoteResourceObject::Ptr rcsResource)
234         {
235             if (!rcsResource)
236             {
237                 throw RCSInvalidParameterException("the rcs resource must not be nullptr.");
238             }
239
240             OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
241                 rcsResource->getUri(),
242                 rcsResource->m_primitiveResource->getConnectivityType(),
243                 rcsResource->isObservable(),
244                 rcsResource->getTypes(),
245                 rcsResource->getInterfaces());
246
247             return ocResource;
248         }
249
250         bool RCSRemoteResourceObject::isMonitoring() const
251         {
252             return m_brokerId != 0;
253         }
254
255         bool RCSRemoteResourceObject::isCaching() const
256         {
257             return m_cacheId != 0;
258         }
259
260         bool RCSRemoteResourceObject::isObservable() const
261         {
262             return m_primitiveResource->isObservable();
263         }
264
265         void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb)
266         {
267             SCOPE_LOG_F(DEBUG, TAG);
268
269             if (!cb)
270             {
271                 throw RCSInvalidParameterException{ "startMonitoring : Callback is NULL" };
272             }
273
274             if (isMonitoring())
275             {
276                 OIC_LOG(DEBUG, TAG, "startMonitoring : already started");
277                 throw RCSBadRequestException{ "Monitoring already started." };
278             }
279
280             m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
281                     std::bind(hostingCallback, std::placeholders::_1, std::move(cb)));
282         }
283
284         void RCSRemoteResourceObject::stopMonitoring()
285         {
286             SCOPE_LOG_F(DEBUG, TAG);
287
288             if (!isMonitoring())
289             {
290                 OIC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
291                 return;
292             }
293
294             ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
295             m_brokerId = 0;
296         }
297
298         ResourceState RCSRemoteResourceObject::getState() const
299         {
300             SCOPE_LOG_F(DEBUG, TAG);
301
302             if (!isMonitoring())
303             {
304                 return ResourceState::NONE;
305             }
306
307             return convertBrokerState(
308                     ResourceBroker::getInstance()->getResourceState(m_primitiveResource));
309         }
310
311         void RCSRemoteResourceObject::startCaching()
312         {
313             startCaching({ });
314         }
315
316         void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb,
317             CacheMode mode, CacheReport reportType)
318         {
319             SCOPE_LOG_F(DEBUG, TAG);
320
321             if (isCaching())
322             {
323                 OIC_LOG(DEBUG, TAG, "startCaching : already Started");
324                 throw RCSBadRequestException{ "Caching already started." };
325             }
326
327             REPORT_FREQUENCY freq;
328             if (reportType == CacheReport::REPORT_CHANGES)
329             {
330                 freq = REPORT_FREQUENCY::UPTODATE;
331             }
332             else if(reportType == CacheReport::REPORT_ALL)
333             {
334                 freq = REPORT_FREQUENCY::WHENEVER_NOTIFIED;
335             }
336
337             if (mode == CacheMode::OBSERVE_ONLY)
338             {
339                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
340                         m_primitiveResource,
341                         std::bind(cachingCallback, std::placeholders::_1,
342                                   std::placeholders::_2, std::placeholders::_3,
343                                   std::move(cb), shared_from_this()), CACHE_METHOD::OBSERVE_ONLY,
344                                   freq, 0);
345             }
346
347             else if (cb)
348             {
349                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
350                         m_primitiveResource,
351                         std::bind(cachingCallback, std::placeholders::_1,
352                                 std::placeholders::_2, std::placeholders::_3,
353                                 std::move(cb), shared_from_this()), CACHE_METHOD::ITERATED_GET,
354                                 freq, 0);
355             }
356             else
357             {
358                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
359                         m_primitiveResource, { }, CACHE_METHOD::ITERATED_GET,
360                         REPORT_FREQUENCY::NONE, 0);
361             }
362
363             OIC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
364         }
365
366         void RCSRemoteResourceObject::stopCaching()
367         {
368             SCOPE_LOG_F(DEBUG, TAG);
369
370             if (!isCaching())
371             {
372                 OIC_LOG(DEBUG, TAG, "Caching already terminated");
373                 return;
374             }
375
376             try
377             {
378                 ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
379             }
380             catch (const RCSInvalidParameterException &)
381             {
382                 throw;
383             }
384             catch (...)
385             {
386                 m_cacheId = 0;
387                 throw;
388             }
389             m_cacheId = 0;
390         }
391
392         CacheState RCSRemoteResourceObject::getCacheState() const
393         {
394             SCOPE_LOG_F(DEBUG, TAG);
395
396             if (!isCaching())
397             {
398                 return CacheState::NONE;
399             }
400
401             return convertCacheState(
402                     ResourceCacheManager::getInstance()->getResourceCacheState(m_cacheId));
403         }
404
405         bool RCSRemoteResourceObject::isCachedAvailable() const
406         {
407             if (!isCaching())
408             {
409                 return false;
410             }
411
412             return ResourceCacheManager::getInstance()->isCachedData(m_cacheId);
413         }
414
415         RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const
416         {
417             SCOPE_LOG_F(DEBUG, TAG);
418
419             if (!isCaching())
420             {
421                 throw RCSBadRequestException{ "Caching not started." };
422             }
423
424             if (!isCachedAvailable())
425             {
426                 throw RCSBadRequestException{ "Cache data is not available." };
427             }
428
429             return ResourceCacheManager::getInstance()->getCachedData(m_cacheId);
430         }
431
432         RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
433                 const std::string& key) const
434         {
435             SCOPE_LOG_F(DEBUG, TAG);
436
437             return getCachedAttributes().at(key);
438         }
439
440         std::string RCSRemoteResourceObject::getUri() const
441         {
442             return m_primitiveResource->getUri();
443         }
444
445         std::string RCSRemoteResourceObject::getAddress() const
446         {
447             return m_primitiveResource->getHost();
448         }
449
450         std::vector< std::string > RCSRemoteResourceObject::getTypes() const
451         {
452             return m_primitiveResource->getTypes();
453         }
454
455         std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const
456         {
457             return m_primitiveResource->getInterfaces();
458         }
459
460         void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb)
461         {
462             SCOPE_LOG_F(DEBUG, TAG);
463
464             if (!cb)
465             {
466                 throw RCSInvalidParameterException{ "getRemoteAttributes : Callback is empty" };
467             }
468
469             m_primitiveResource->requestGet(
470                     std::bind(getRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
471                             std::placeholders::_3, std::move(cb)));
472         }
473
474         void RCSRemoteResourceObject::get(GetCallback cb)
475         {
476             SCOPE_LOG_F(DEBUG, TAG);
477
478             if (!cb)
479             {
480                 throw RCSInvalidParameterException{ "get : Callback is empty" };
481             }
482
483             m_primitiveResource->requestGet(std::move(cb));
484         }
485
486         void RCSRemoteResourceObject::get(const RCSQueryParams& queryParams, GetCallback cb)
487         {
488             SCOPE_LOG_F(DEBUG, TAG);
489
490             if (!cb)
491             {
492                 throw RCSInvalidParameterException{ "get : Callback is empty" };
493             }
494
495             const auto& paramMap = queryParams.getAll();
496
497             m_primitiveResource->requestGetWith(
498                     queryParams.getResourceType(), queryParams.getResourceInterface(),
499                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() },
500                     std::move(cb));
501         }
502
503         void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
504                 RemoteAttributesSetCallback cb)
505         {
506             SCOPE_LOG_F(DEBUG, TAG);
507
508             if (!cb)
509             {
510                 throw RCSInvalidParameterException{ "setRemoteAttributes : Callback is empty" };
511             }
512
513             m_primitiveResource->requestSet(attribute,
514                     std::bind(setRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
515                             std::placeholders::_3, cb));
516         }
517
518         void RCSRemoteResourceObject::set(const RCSResourceAttributes& attributes, SetCallback cb)
519         {
520             SCOPE_LOG_F(DEBUG, TAG);
521
522             if (!cb)
523             {
524                 throw RCSInvalidParameterException{ "set : Callback is empty" };
525             }
526
527             m_primitiveResource->requestSet(attributes, std::move(cb));
528         }
529
530         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
531                 const RCSResourceAttributes& attributes, SetCallback cb)
532         {
533             SCOPE_LOG_F(DEBUG, TAG);
534
535             if (!cb)
536             {
537                 throw RCSInvalidParameterException{ "set : Callback is empty" };
538             }
539
540             const auto& paramMap = queryParams.getAll();
541
542             m_primitiveResource->requestSetWith(
543                     queryParams.getResourceType(), queryParams.getResourceInterface(),
544                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, attributes,
545                     std::move(cb));
546         }
547
548         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
549                 const RCSRepresentation& rep, SetCallback cb)
550         {
551             SCOPE_LOG_F(DEBUG, TAG);
552
553             if (!cb)
554             {
555                 throw RCSInvalidParameterException{ "set : Callback is empty" };
556             }
557
558             const auto& paramMap = queryParams.getAll();
559
560             m_primitiveResource->requestSetWith(
561                     queryParams.getResourceType(), queryParams.getResourceInterface(),
562                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, rep,
563                     std::move(cb));
564         }
565
566     }
567 }