Merge branch 'master' into resource-manipulation
[platform/upstream/iotivity.git] / resource / src / OCResource.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 "OCResource.h"
22 #include "OCUtilities.h"
23
24 #include <boost/lexical_cast.hpp>
25 #include <sstream>
26
27 namespace OC {
28
29 using OC::nil_guard;
30 using OC::result_guard;
31 using OC::checked_guard;
32
33 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
34                         const OCDevAddr& devAddr, const std::string& uri,
35                         const std::string& serverId, bool observable,
36                         const std::vector<std::string>& resourceTypes,
37                         const std::vector<std::string>& interfaces)
38  :  m_clientWrapper(clientWrapper), m_uri(uri),
39     m_resourceId(serverId, m_uri), m_devAddr(devAddr), m_useHostString(false),
40     m_isObservable(observable), m_isCollection(false),
41     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
42     m_observeHandle(nullptr)
43 {
44     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
45                         != m_interfaces.end();
46
47     if (m_uri.empty() ||
48         resourceTypes.empty() ||
49         interfaces.empty()||
50         m_clientWrapper.expired())
51     {
52         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
53                 interfaces.empty(), m_clientWrapper.expired(), false, false);
54     }
55 }
56
57 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
58                         const std::string& host, const std::string& uri,
59                         const std::string& serverId,
60                         OCConnectivityType connectivityType, bool observable,
61                         const std::vector<std::string>& resourceTypes,
62                         const std::vector<std::string>& interfaces)
63  :  m_clientWrapper(clientWrapper), m_uri(uri),
64     m_resourceId(serverId, m_uri),
65     m_devAddr{ OC_DEFAULT_ADAPTER },
66     m_useHostString(true),
67     m_isObservable(observable), m_isCollection(false),
68     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
69     m_observeHandle(nullptr)
70 {
71     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
72                         != m_interfaces.end();
73
74     if (m_uri.empty() ||
75         resourceTypes.empty() ||
76         interfaces.empty()||
77         m_clientWrapper.expired())
78     {
79         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
80                 interfaces.empty(), m_clientWrapper.expired(), false, false);
81     }
82
83     // construct the devAddr from the pieces we have
84     m_devAddr.adapter = static_cast<OCTransportAdapter>(connectivityType >> CT_ADAPTER_SHIFT);
85     m_devAddr.flags = static_cast<OCTransportFlags>(connectivityType & CT_MASK_FLAGS);
86     size_t len = host.length();
87     if (len >= MAX_ADDR_STR_SIZE)
88     {
89         throw std::length_error("host address is too long.");
90     }
91     host.copy(m_devAddr.addr, len);
92     m_devAddr.addr[len] = '\0';
93 }
94
95 OCResource::~OCResource()
96 {
97 }
98
99 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
100                               GetCallback attributeHandler, QualityOfService QoS)
101 {
102     return checked_guard(m_clientWrapper.lock(),
103                             &IClientWrapper::GetResourceRepresentation,
104                             m_devAddr, m_useHostString, m_uri,
105                             queryParametersMap, m_headerOptions,
106                             attributeHandler, QoS);
107 }
108
109 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
110                               GetCallback attributeHandler)
111 {
112     QualityOfService defaultQos = OC::QualityOfService::NaQos;
113     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
114     return result_guard(get(queryParametersMap, attributeHandler, defaultQos));
115 }
116
117 OCStackResult OCResource::get(const std::string& resourceType,
118                      const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
119                      GetCallback attributeHandler)
120 {
121     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
122     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
123
124     return result_guard(get(resourceType, resourceInterface, queryParametersMap, attributeHandler, defaultQoS));
125 }
126
127 OCStackResult OCResource::get(const std::string& resourceType, const std::string& resourceInterface, const QueryParamsMap& queryParametersMap, GetCallback attributeHandler,
128         QualityOfService QoS)
129 {
130     QueryParamsMap mapCpy(queryParametersMap);
131
132     if(!resourceType.empty())
133     {
134         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
135     }
136
137     if(!resourceInterface.empty())
138     {
139         mapCpy[OC::Key::INTERFACESKEY]= resourceInterface;
140     }
141
142     return result_guard(get(mapCpy, attributeHandler, QoS));
143 }
144
145 OCStackResult OCResource::put(const OCRepresentation& rep,
146                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler,
147                               QualityOfService QoS)
148 {
149     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
150                          m_devAddr, m_useHostString, m_uri, rep, queryParametersMap,
151                          m_headerOptions, attributeHandler, QoS);
152 }
153
154 OCStackResult OCResource::put(const OCRepresentation& rep,
155                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
156 {
157     QualityOfService defaultQos = OC::QualityOfService::NaQos;
158     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
159     return result_guard(put(rep, queryParametersMap, attributeHandler, defaultQos));
160 }
161
162 OCStackResult OCResource::put(const std::string& resourceType,
163                               const std::string& resourceInterface, const OCRepresentation& rep,
164                               const QueryParamsMap& queryParametersMap,
165                               PutCallback attributeHandler)
166 {
167     QualityOfService defaultQos = OC::QualityOfService::NaQos;
168     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
169
170     return result_guard(put(resourceType, resourceInterface, rep, queryParametersMap,
171             attributeHandler, defaultQos));
172 }
173
174 OCStackResult OCResource::put(const std::string& resourceType,
175                               const std::string& resourceInterface, const OCRepresentation& rep,
176                               const QueryParamsMap& queryParametersMap,
177                               PutCallback attributeHandler,
178                               QualityOfService QoS)
179 {
180     QueryParamsMap mapCpy(queryParametersMap);
181
182     if(!resourceType.empty())
183     {
184         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
185     }
186
187     if(!resourceInterface.empty())
188     {
189         mapCpy[OC::Key::INTERFACESKEY]=resourceInterface;
190     }
191
192     return result_guard(put(rep, mapCpy, attributeHandler, QoS));
193 }
194
195 OCStackResult OCResource::post(const OCRepresentation& rep,
196                                const QueryParamsMap& queryParametersMap, PostCallback attributeHandler,
197                                QualityOfService QoS)
198 {
199     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
200                          m_devAddr, m_useHostString, m_uri, rep, queryParametersMap,
201                          m_headerOptions, attributeHandler, QoS);
202 }
203
204 OCStackResult OCResource::post(const OCRepresentation& rep,
205                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
206 {
207     QualityOfService defaultQos = OC::QualityOfService::NaQos;
208     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
209     return result_guard(post(rep, queryParametersMap, attributeHandler, defaultQos));
210 }
211
212 OCStackResult OCResource::post(const std::string& resourceType,
213                                const std::string& resourceInterface, const OCRepresentation& rep,
214                                const QueryParamsMap& queryParametersMap,
215                                PostCallback attributeHandler)
216 {
217     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
218     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
219
220     return result_guard(post(resourceType, resourceInterface, rep, queryParametersMap, attributeHandler,
221             defaultQoS));
222 }
223
224 OCStackResult OCResource::post(const std::string& resourceType,
225                                const std::string& resourceInterface, const OCRepresentation& rep,
226                                const QueryParamsMap& queryParametersMap,
227                                PostCallback attributeHandler,
228                                QualityOfService QoS)
229 {
230     QueryParamsMap mapCpy(queryParametersMap);
231
232     if(!resourceType.empty())
233     {
234         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
235     }
236
237     if(!resourceInterface.empty())
238     {
239         mapCpy[OC::Key::INTERFACESKEY]=resourceInterface;
240     }
241
242     return result_guard(post(rep, mapCpy, attributeHandler, QoS));
243 }
244
245 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler, QualityOfService QoS)
246 {
247     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
248                          m_devAddr, m_useHostString, m_uri, m_headerOptions, deleteHandler, QoS);
249 }
250
251 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler)
252 {
253     QualityOfService defaultQos = OC::QualityOfService::NaQos;
254     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
255
256     return result_guard(deleteResource(deleteHandler, defaultQos));
257 }
258
259 OCStackResult OCResource::observe(ObserveType observeType,
260         const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler,
261         QualityOfService QoS)
262 {
263     if(m_observeHandle != nullptr)
264     {
265         return result_guard(OC_STACK_INVALID_PARAM);
266     }
267
268     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
269                          observeType, &m_observeHandle, m_devAddr,
270                          m_useHostString, m_uri, queryParametersMap, m_headerOptions,
271                          observeHandler, QoS);
272 }
273
274 OCStackResult OCResource::observe(ObserveType observeType,
275         const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
276 {
277     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
278     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
279
280     return result_guard(observe(observeType, queryParametersMap, observeHandler, defaultQoS));
281 }
282
283 OCStackResult OCResource::cancelObserve()
284 {
285     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
286     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
287     return result_guard(cancelObserve(defaultQoS));
288 }
289
290 OCStackResult OCResource::cancelObserve(QualityOfService QoS)
291 {
292     if(m_observeHandle == nullptr)
293     {
294         return result_guard(OC_STACK_INVALID_PARAM);
295     }
296
297     OCStackResult result =  checked_guard(m_clientWrapper.lock(),
298             &IClientWrapper::CancelObserveResource,
299             m_observeHandle, "", m_uri, m_headerOptions, QoS);
300
301     if(result == OC_STACK_OK)
302     {
303         m_observeHandle = nullptr;
304     }
305
306     return result;
307 }
308
309 std::string OCResource::host() const
310 {
311     if (m_useHostString)
312     {
313         return std::string(m_devAddr.addr);
314     }
315
316     std::ostringstream ss;
317     if (m_devAddr.flags & OC_SECURE)
318     {
319         ss << "coaps://";
320     }
321     else
322     {
323         ss << "coap://";
324     }
325     if (m_devAddr.flags & OC_IP_USE_V6)
326     {
327         ss << '[' << m_devAddr.addr << ']';
328     }
329     else
330     {
331         ss << m_devAddr.addr;
332     }
333     if (m_devAddr.port)
334     {
335         ss << ':' << m_devAddr.port;
336     }
337     return ss.str();
338 }
339
340 std::string OCResource::uri() const
341 {
342     return m_uri;
343 }
344
345 OCConnectivityType OCResource::connectivityType() const
346 {
347     return static_cast<OCConnectivityType>(
348            (m_devAddr.adapter << CT_ADAPTER_SHIFT) | (m_devAddr.flags & CT_MASK_FLAGS));
349 }
350
351 bool OCResource::isObservable() const
352 {
353     return m_isObservable;
354 }
355
356 OCResourceIdentifier OCResource::uniqueIdentifier() const
357 {
358     return m_resourceId;
359 }
360
361 std::string OCResource::sid() const
362 {
363     return this->uniqueIdentifier().m_representation;
364 }
365
366 bool OCResource::operator==(const OCResource &other) const
367 {
368     return m_resourceId == other.m_resourceId;
369 }
370
371 bool OCResource::operator!=(const OCResource &other) const
372 {
373     return m_resourceId != other.m_resourceId;
374 }
375
376 bool OCResource::operator<(const OCResource &other) const
377 {
378     return m_resourceId < other.m_resourceId;
379 }
380
381 bool OCResource::operator>(const OCResource &other) const
382 {
383     return m_resourceId > other.m_resourceId;
384 }
385
386 bool OCResource::operator<=(const OCResource &other) const
387 {
388     return m_resourceId <= other.m_resourceId;
389 }
390
391 bool OCResource::operator>=(const OCResource &other) const
392 {
393     return m_resourceId >= other.m_resourceId;
394 }
395
396 OCResourceIdentifier::OCResourceIdentifier(const std::string& wireServerIdentifier,
397         const std::string& resourceUri)
398     :m_representation(wireServerIdentifier), m_resourceUri(resourceUri)
399 {
400 }
401
402 std::ostream& operator <<(std::ostream& os, const OCResourceIdentifier& ri)
403 {
404     os << ri.m_representation<<ri.m_resourceUri;
405
406     return os;
407 }
408
409 bool OCResourceIdentifier::operator==(const OCResourceIdentifier &other) const
410 {
411     return m_representation == other.m_representation
412         && m_resourceUri == other.m_resourceUri;
413 }
414
415 bool OCResourceIdentifier::operator!=(const OCResourceIdentifier &other) const
416 {
417     return !(*this == other);
418 }
419
420 bool OCResourceIdentifier::operator<(const OCResourceIdentifier &other) const
421 {
422     return m_resourceUri < other.m_resourceUri
423         || (m_resourceUri == other.m_resourceUri &&
424                 m_representation < other.m_representation);
425 }
426
427 bool OCResourceIdentifier::operator>(const OCResourceIdentifier &other) const
428 {
429     return *this != other && !(*this<other);
430 }
431
432 bool OCResourceIdentifier::operator<=(const OCResourceIdentifier &other) const
433 {
434     return !(*this > other);
435 }
436
437 bool OCResourceIdentifier::operator>=(const OCResourceIdentifier &other) const
438 {
439     return !(*this < other);
440 }
441
442 } // namespace OC
443