Continue improving libcoap build script
[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     {
98         SCOPE_LOG_F(DEBUG, TAG);
99
100         onCacheUpdated(data, eCode);
101         return OC_STACK_OK;
102     }
103
104     void setRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
105             RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
106     {
107         SCOPE_LOG_F(DEBUG, TAG);
108
109         onRemoteAttributesSet(response.getAttributes(), eCode);
110     }
111
112     void getRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
113             RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
114     {
115         SCOPE_LOG_F(DEBUG, TAG);
116
117         onRemoteAttributesReceived(response.getAttributes(), eCode);
118     }
119 }
120
121 namespace OIC
122 {
123     namespace Service
124     {
125
126         RCSQueryParams& RCSQueryParams::setResourceInterface(std::string resourceInterface)
127         {
128             m_resourceInterface = std::move(resourceInterface);
129             return *this;
130         }
131
132         RCSQueryParams& RCSQueryParams::setResourceType(std::string resourceType)
133         {
134             m_resourceType = std::move(resourceType);
135             return *this;
136         }
137
138         RCSQueryParams& RCSQueryParams::put(std::string key, std::string value)
139         {
140             m_map[std::move(key)] = std::move(value);
141             return *this;
142         }
143
144         std::string RCSQueryParams::getResourceInterface() const
145         {
146             return m_resourceInterface;
147         }
148
149         std::string RCSQueryParams::getResourceType() const
150         {
151             return m_resourceType;
152         }
153
154         std::string RCSQueryParams::get(const std::string& key) const
155         {
156             try
157             {
158                 return m_map.at(key);
159             }
160             catch (const std::out_of_range&)
161             {
162                 throw RCSInvalidKeyException(key + " is an invalid key");
163             }
164         }
165
166         const RCSQueryParams::Map& RCSQueryParams::getAll() const
167         {
168             return m_map;
169         }
170
171         RCSRemoteResourceObject::RCSRemoteResourceObject(
172                 std::shared_ptr< PrimitiveResource > primtiveResource) :
173                 m_primitiveResource{ primtiveResource },
174                 m_cacheId{ },
175                 m_brokerId{ }
176         {
177         }
178
179         RCSRemoteResourceObject::~RCSRemoteResourceObject()
180         {
181             SCOPE_LOG_F(DEBUG, TAG);
182
183             try{
184                 stopCaching();
185                 stopMonitoring();
186             }
187             catch(std::exception &e){
188                 OIC_LOG_V(ERROR, TAG, "%s", e.what());
189             }
190         }
191
192         RCSRemoteResourceObject::Ptr RCSRemoteResourceObject::fromOCResource(
193                 std::shared_ptr< OC::OCResource > ocResource)
194         {
195             if (!ocResource)
196             {
197                 throw RCSInvalidParameterException("the oc resource must not be nullptr.");
198             }
199
200             return std::make_shared< RCSRemoteResourceObject >(
201                     PrimitiveResource::create(ocResource));
202         }
203
204         std::shared_ptr< OC::OCResource > RCSRemoteResourceObject::toOCResource(
205         RCSRemoteResourceObject::Ptr rcsResource)
206         {
207             if (!rcsResource)
208             {
209                 throw RCSInvalidParameterException("the rcs resource must not be nullptr.");
210             }
211
212             OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
213                 rcsResource->getUri(),
214                 rcsResource->m_primitiveResource->getConnectivityType(),
215                 rcsResource->isObservable(),
216                 rcsResource->getTypes(),
217                 rcsResource->getInterfaces());
218
219             return ocResource;
220         }
221
222         bool RCSRemoteResourceObject::isMonitoring() const
223         {
224             return m_brokerId != 0;
225         }
226
227         bool RCSRemoteResourceObject::isCaching() const
228         {
229             return m_cacheId != 0;
230         }
231
232         bool RCSRemoteResourceObject::isObservable() const
233         {
234             return m_primitiveResource->isObservable();
235         }
236
237         void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb)
238         {
239             SCOPE_LOG_F(DEBUG, TAG);
240
241             if (!cb)
242             {
243                 throw RCSInvalidParameterException{ "startMonitoring : Callback is NULL" };
244             }
245
246             if (isMonitoring())
247             {
248                 OIC_LOG(DEBUG, TAG, "startMonitoring : already started");
249                 throw RCSBadRequestException{ "Monitoring already started." };
250             }
251
252             m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
253                     std::bind(hostingCallback, std::placeholders::_1, std::move(cb)));
254         }
255
256         void RCSRemoteResourceObject::stopMonitoring()
257         {
258             SCOPE_LOG_F(DEBUG, TAG);
259
260             if (!isMonitoring())
261             {
262                 OIC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
263                 return;
264             }
265
266             ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
267             m_brokerId = 0;
268         }
269
270         ResourceState RCSRemoteResourceObject::getState() const
271         {
272             SCOPE_LOG_F(DEBUG, TAG);
273
274             if (!isMonitoring())
275             {
276                 return ResourceState::NONE;
277             }
278
279             return convertBrokerState(
280                     ResourceBroker::getInstance()->getResourceState(m_primitiveResource));
281         }
282
283         void RCSRemoteResourceObject::startCaching()
284         {
285             startCaching({ });
286         }
287
288         void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb, CacheMode mode)
289         {
290             SCOPE_LOG_F(DEBUG, TAG);
291
292             if (isCaching())
293             {
294                 OIC_LOG(DEBUG, TAG, "startCaching : already Started");
295                 throw RCSBadRequestException{ "Caching already started." };
296             }
297
298             if (mode == CacheMode::OBSERVE_ONLY)
299             {
300                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
301                         m_primitiveResource,
302                         std::bind(cachingCallback, std::placeholders::_1,
303                                   std::placeholders::_2, std::placeholders::_3,
304                                   std::move(cb)), CACHE_METHOD::OBSERVE_ONLY,
305                                   REPORT_FREQUENCY::UPTODATE, 0);
306             }
307
308             else if (cb)
309             {
310                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
311                         m_primitiveResource,
312                         std::bind(cachingCallback, std::placeholders::_1,
313                                 std::placeholders::_2, std::placeholders::_3,
314                                 std::move(cb)), CACHE_METHOD::ITERATED_GET,
315                                 REPORT_FREQUENCY::UPTODATE, 0);
316             }
317             else
318             {
319                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
320                         m_primitiveResource, { }, CACHE_METHOD::ITERATED_GET,
321                         REPORT_FREQUENCY::NONE, 0);
322             }
323
324             OIC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
325         }
326
327         void RCSRemoteResourceObject::stopCaching()
328         {
329             SCOPE_LOG_F(DEBUG, TAG);
330
331             if (!isCaching())
332             {
333                 OIC_LOG(DEBUG, TAG, "Caching already terminated");
334                 return;
335             }
336
337             try
338             {
339                 ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
340             }
341             catch (const RCSInvalidParameterException &)
342             {
343                 throw;
344             }
345             catch (...)
346             {
347                 m_cacheId = 0;
348                 throw;
349             }
350             m_cacheId = 0;
351         }
352
353         CacheState RCSRemoteResourceObject::getCacheState() const
354         {
355             SCOPE_LOG_F(DEBUG, TAG);
356
357             if (!isCaching())
358             {
359                 return CacheState::NONE;
360             }
361
362             return convertCacheState(
363                     ResourceCacheManager::getInstance()->getResourceCacheState(m_cacheId));
364         }
365
366         bool RCSRemoteResourceObject::isCachedAvailable() const
367         {
368             if (!isCaching())
369             {
370                 return false;
371             }
372
373             return ResourceCacheManager::getInstance()->isCachedData(m_cacheId);
374         }
375
376         RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const
377         {
378             SCOPE_LOG_F(DEBUG, TAG);
379
380             if (!isCaching())
381             {
382                 throw RCSBadRequestException{ "Caching not started." };
383             }
384
385             if (!isCachedAvailable())
386             {
387                 throw RCSBadRequestException{ "Cache data is not available." };
388             }
389
390             return ResourceCacheManager::getInstance()->getCachedData(m_cacheId);
391         }
392
393         RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
394                 const std::string& key) const
395         {
396             SCOPE_LOG_F(DEBUG, TAG);
397
398             return getCachedAttributes().at(key);
399         }
400
401         std::string RCSRemoteResourceObject::getUri() const
402         {
403             return m_primitiveResource->getUri();
404         }
405
406         std::string RCSRemoteResourceObject::getAddress() const
407         {
408             return m_primitiveResource->getHost();
409         }
410
411         std::vector< std::string > RCSRemoteResourceObject::getTypes() const
412         {
413             return m_primitiveResource->getTypes();
414         }
415
416         std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const
417         {
418             return m_primitiveResource->getInterfaces();
419         }
420
421         void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb)
422         {
423             SCOPE_LOG_F(DEBUG, TAG);
424
425             if (!cb)
426             {
427                 throw RCSInvalidParameterException{ "getRemoteAttributes : Callback is empty" };
428             }
429
430             m_primitiveResource->requestGet(
431                     std::bind(getRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
432                             std::placeholders::_3, std::move(cb)));
433         }
434
435         void RCSRemoteResourceObject::get(GetCallback cb)
436         {
437             SCOPE_LOG_F(DEBUG, TAG);
438
439             if (!cb)
440             {
441                 throw RCSInvalidParameterException{ "get : Callback is empty" };
442             }
443
444             m_primitiveResource->requestGet(std::move(cb));
445         }
446
447         void RCSRemoteResourceObject::get(const RCSQueryParams& queryParams, GetCallback cb)
448         {
449             SCOPE_LOG_F(DEBUG, TAG);
450
451             if (!cb)
452             {
453                 throw RCSInvalidParameterException{ "get : Callback is empty" };
454             }
455
456             const auto& paramMap = queryParams.getAll();
457
458             m_primitiveResource->requestGetWith(
459                     queryParams.getResourceType(), queryParams.getResourceInterface(),
460                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() },
461                     std::move(cb));
462         }
463
464         void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
465                 RemoteAttributesSetCallback cb)
466         {
467             SCOPE_LOG_F(DEBUG, TAG);
468
469             if (!cb)
470             {
471                 throw RCSInvalidParameterException{ "setRemoteAttributes : Callback is empty" };
472             }
473
474             m_primitiveResource->requestSet(attribute,
475                     std::bind(setRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
476                             std::placeholders::_3, cb));
477         }
478
479         void RCSRemoteResourceObject::set(const RCSResourceAttributes& attributes, SetCallback cb)
480         {
481             SCOPE_LOG_F(DEBUG, TAG);
482
483             if (!cb)
484             {
485                 throw RCSInvalidParameterException{ "set : Callback is empty" };
486             }
487
488             m_primitiveResource->requestSet(attributes, std::move(cb));
489         }
490
491         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
492                 const RCSResourceAttributes& attributes, SetCallback cb)
493         {
494             SCOPE_LOG_F(DEBUG, TAG);
495
496             if (!cb)
497             {
498                 throw RCSInvalidParameterException{ "set : Callback is empty" };
499             }
500
501             const auto& paramMap = queryParams.getAll();
502
503             m_primitiveResource->requestSetWith(
504                     queryParams.getResourceType(), queryParams.getResourceInterface(),
505                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, attributes,
506                     std::move(cb));
507         }
508
509         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
510                 const RCSRepresentation& rep, SetCallback cb)
511         {
512             SCOPE_LOG_F(DEBUG, TAG);
513
514             if (!cb)
515             {
516                 throw RCSInvalidParameterException{ "set : Callback is empty" };
517             }
518
519             const auto& paramMap = queryParams.getAll();
520
521             m_primitiveResource->requestSetWith(
522                     queryParams.getResourceType(), queryParams.getResourceInterface(),
523                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, rep,
524                     std::move(cb));
525         }
526
527     }
528 }