b83061f5227612a0dcbf91e880cfe281eb3a6587
[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 #ifdef HAVE_ARPA_INET_H
27 #include <arpa/inet.h>
28 #endif
29 #ifdef HAVE_WS2TCPIP_H
30 #include <ws2tcpip.h>
31 #endif
32 #ifdef HAVE_IN6ADDR_H
33 #include <in6addr.h>
34 #endif
35
36 namespace OC {
37
38 static const char COAP[] = "coap://";
39 static const char COAPS[] = "coaps://";
40 static const char COAP_TCP[] = "coap+tcp://";
41 static const char COAP_GATT[] = "coap+gatt://";
42 static const char COAP_RFCOMM[] = "coap+rfcomm://";
43
44 using OC::nil_guard;
45 using OC::result_guard;
46 using OC::checked_guard;
47
48 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
49                         const OCDevAddr& devAddr, const std::string& uri,
50                         const std::string& serverId, uint8_t property,
51                         const std::vector<std::string>& resourceTypes,
52                         const std::vector<std::string>& interfaces)
53  :  m_clientWrapper(clientWrapper), m_uri(uri),
54     m_resourceId(serverId, m_uri), m_devAddr(devAddr),
55     m_isCollection(false), m_property(property),
56     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
57     m_observeHandle(nullptr)
58 {
59     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
60                         != m_interfaces.end();
61
62     if (m_uri.empty() ||
63         resourceTypes.empty() ||
64         interfaces.empty()||
65         m_clientWrapper.expired())
66     {
67         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
68                 interfaces.empty(), m_clientWrapper.expired(), false, false);
69     }
70 }
71
72 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
73                         const std::string& host, const std::string& uri,
74                         const std::string& serverId,
75                         OCConnectivityType connectivityType, uint8_t property,
76                         const std::vector<std::string>& resourceTypes,
77                         const std::vector<std::string>& interfaces)
78  :  m_clientWrapper(clientWrapper), m_uri(uri),
79     m_resourceId(serverId, m_uri),
80     m_isCollection(false), m_property(property),
81     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
82     m_observeHandle(nullptr)
83 {
84     m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
85 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
86                           {0}
87 #endif
88                         };
89     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
90                         != m_interfaces.end();
91
92     if (m_uri.empty() ||
93         resourceTypes.empty() ||
94         interfaces.empty()||
95         m_clientWrapper.expired())
96     {
97         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
98                 interfaces.empty(), m_clientWrapper.expired(), false, false);
99     }
100
101     if (uri.length() == 1 && uri[0] == '/')
102     {
103         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
104                 interfaces.empty(), m_clientWrapper.expired(), false, false);
105     }
106
107     if (uri[0] != '/')
108     {
109         throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
110                 interfaces.empty(), m_clientWrapper.expired(), false, false);
111     }
112
113     // construct the devAddr from the pieces we have
114     m_devAddr.adapter = static_cast<OCTransportAdapter>(connectivityType >> CT_ADAPTER_SHIFT);
115     m_devAddr.flags = static_cast<OCTransportFlags>(connectivityType & CT_MASK_FLAGS);
116
117     this->setHost(host);
118 }
119
120 OCResource::~OCResource()
121 {
122 }
123
124 void OCResource::setHost(const std::string& host)
125 {
126     size_t prefix_len;
127
128     if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
129     {
130         prefix_len = sizeof(COAP) - 1;
131     }
132     else if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
133     {
134         prefix_len = sizeof(COAPS) - 1;
135         m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
136     }
137     else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
138     {
139         prefix_len = sizeof(COAP_TCP) - 1;
140     }
141     else if (host.compare(0, sizeof(COAP_GATT) - 1, COAP_GATT) == 0)
142     {
143         prefix_len = sizeof(COAP_GATT) - 1;
144     }
145     else if (host.compare(0, sizeof(COAP_RFCOMM) - 1, COAP_RFCOMM) == 0)
146     {
147         prefix_len = sizeof(COAP_RFCOMM) - 1;
148     }
149     else
150     {
151         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
152             m_interfaces.empty(), m_clientWrapper.expired(), false, false);
153     }
154
155     // remove 'coap://' or 'coaps://' or 'coap+tcp://' or 'coap+gatt://' or 'coap+rfcomm://'
156     std::string host_token = host.substr(prefix_len);
157
158     if (host_token[0] == '[') // IPv6
159     {
160         size_t bracket = host_token.find(']');
161
162         if (std::string::npos == bracket || 0 == bracket)
163         {
164             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
165                 m_interfaces.empty(), m_clientWrapper.expired(), false, false);
166         }
167         // extract the ipv6 address
168         std::string ip6Addr = host_token.substr(1, bracket - 1);
169
170         // address validity check
171         std::string ip6AddrToValidityCheck(ip6Addr);
172         size_t percent = ip6AddrToValidityCheck.find('%');
173         if (std::string::npos != percent)
174         {
175             ip6AddrToValidityCheck.resize(percent);
176         }
177         struct in6_addr buf;
178         const char *cAddr = ip6AddrToValidityCheck.c_str();
179         if (0 == inet_pton(AF_INET6, cAddr, &buf))
180         {
181             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
182                 m_interfaces.empty(), m_clientWrapper.expired(), false, false);
183         }
184
185         //skip ']' and ':' characters in host string
186         host_token = host_token.substr(bracket + 2);
187         int port = std::stoi(host_token);
188
189         if (0 > port || UINT16_MAX < port)
190         {
191             throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
192                 m_interfaces.empty(), m_clientWrapper.expired(), false, false);
193         }
194
195         ip6Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
196         m_devAddr.addr[ip6Addr.length()] = '\0';
197         m_devAddr.port = static_cast<uint16_t>(port);
198         m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_IP_USE_V6);
199     }
200     else if (host_token[0] == ':')
201     {
202         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
203             m_interfaces.empty(), m_clientWrapper.expired(), false, false);
204     }
205     else
206     {
207         size_t dot = host_token.find('.');
208         if (std::string::npos == dot) // MAC
209         {
210             std::string macAddr = host_token;
211
212             // address validity check
213             if (MAC_ADDR_STR_SIZE != macAddr.length())
214             {
215                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
216                     m_interfaces.empty(), m_clientWrapper.expired(), false, false);
217             }
218
219             for (size_t blockCnt = 0; blockCnt < MAC_ADDR_BLOCKS; blockCnt++)
220             {
221                 std::string block = macAddr.substr(blockCnt * 3, 2);
222
223                 if (std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef"))
224                 {
225                     throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
226                         m_interfaces.empty(), m_clientWrapper.expired(), false, false);
227                 }
228
229                 if (MAC_ADDR_BLOCKS - 1 > blockCnt)
230                 {
231                     char delimiter = macAddr[blockCnt * 3 + 2];
232
233                     if (':' != delimiter)
234                     {
235                         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
236                             m_interfaces.empty(), m_clientWrapper.expired(), false, false);
237                     }
238                 }
239             }
240
241             macAddr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
242             m_devAddr.addr[MAC_ADDR_STR_SIZE] = '\0';
243         }
244         else // IPv4
245         {
246             size_t colon = host_token.find(':');
247
248             if (colon == std::string::npos || colon == 0)
249             {
250                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
251                     m_interfaces.empty(), m_clientWrapper.expired(), false, false);
252             }
253
254             // extract the ipv4 address
255             std::string ip4Addr = host_token.substr(0, colon);
256
257             // address validity check
258             struct in_addr buf;
259             const char *cAddr = ip4Addr.c_str();
260             if (0 == inet_pton(AF_INET, cAddr, &buf))
261             {
262                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
263                     m_interfaces.empty(), m_clientWrapper.expired(), false, false);
264             }
265
266             //skip ':' characters in host string
267             host_token = host_token.substr(colon + 1);
268             int port = std::stoi(host_token);
269
270             if (0 > port || UINT16_MAX < port)
271             {
272                 throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
273                     m_interfaces.empty(), m_clientWrapper.expired(), false, false);
274             }
275
276             ip4Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
277             m_devAddr.addr[ip4Addr.length()] = '\0';
278             m_devAddr.port = static_cast<uint16_t>(port);
279         }
280     }
281 }
282
283 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
284                               GetCallback attributeHandler, QualityOfService QoS)
285 {
286     return checked_guard(m_clientWrapper.lock(),
287                             &IClientWrapper::GetResourceRepresentation,
288                             m_devAddr, m_uri,
289                             queryParametersMap, m_headerOptions, CT_DEFAULT,
290                             attributeHandler, QoS);
291 }
292
293 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
294                               GetCallback attributeHandler)
295 {
296     QualityOfService defaultQos = OC::QualityOfService::NaQos;
297     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
298     return result_guard(get(queryParametersMap, attributeHandler, defaultQos));
299 }
300
301 OCStackResult OCResource::get(const std::string& resourceType,
302                      const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
303                      GetCallback attributeHandler)
304 {
305     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
306     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
307
308     return result_guard(get(resourceType, resourceInterface, queryParametersMap, attributeHandler, defaultQoS));
309 }
310
311 OCStackResult OCResource::get(const std::string& resourceType, const std::string& resourceInterface, const QueryParamsMap& queryParametersMap, GetCallback attributeHandler,
312         QualityOfService QoS)
313 {
314     QueryParamsMap mapCpy(queryParametersMap);
315
316     if (!resourceType.empty())
317     {
318         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
319     }
320
321     if (!resourceInterface.empty())
322     {
323         mapCpy[OC::Key::INTERFACESKEY]= resourceInterface;
324     }
325
326     return result_guard(get(mapCpy, attributeHandler, QoS));
327 }
328
329 OCStackResult OCResource::put(const OCRepresentation& rep,
330                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler,
331                               QualityOfService QoS)
332 {
333     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
334                          m_devAddr, m_uri, rep, queryParametersMap,
335                          m_headerOptions, attributeHandler, QoS);
336 }
337
338 OCStackResult OCResource::put(const OCRepresentation& rep,
339                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
340 {
341     QualityOfService defaultQos = OC::QualityOfService::NaQos;
342     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
343     return result_guard(put(rep, queryParametersMap, attributeHandler, defaultQos));
344 }
345
346 OCStackResult OCResource::put(const std::string& resourceType,
347                               const std::string& resourceInterface, const OCRepresentation& rep,
348                               const QueryParamsMap& queryParametersMap,
349                               PutCallback attributeHandler)
350 {
351     QualityOfService defaultQos = OC::QualityOfService::NaQos;
352     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
353
354     return result_guard(put(resourceType, resourceInterface, rep, queryParametersMap,
355             attributeHandler, defaultQos));
356 }
357
358 OCStackResult OCResource::put(const std::string& resourceType,
359                               const std::string& resourceInterface, const OCRepresentation& rep,
360                               const QueryParamsMap& queryParametersMap,
361                               PutCallback attributeHandler,
362                               QualityOfService QoS)
363 {
364     QueryParamsMap mapCpy(queryParametersMap);
365
366     if (!resourceType.empty())
367     {
368         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
369     }
370
371     if (!resourceInterface.empty())
372     {
373         mapCpy[OC::Key::INTERFACESKEY]=resourceInterface;
374     }
375
376     return result_guard(put(rep, mapCpy, attributeHandler, QoS));
377 }
378
379 OCStackResult OCResource::post(const OCRepresentation& rep,
380                                const QueryParamsMap& queryParametersMap, PostCallback attributeHandler,
381                                QualityOfService QoS)
382 {
383     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
384                          m_devAddr, m_uri, rep, queryParametersMap,
385                          m_headerOptions, CT_DEFAULT, attributeHandler, QoS);
386 }
387
388 OCStackResult OCResource::post(const OCRepresentation& rep,
389                               const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
390 {
391     QualityOfService defaultQos = OC::QualityOfService::NaQos;
392     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
393     return result_guard(post(rep, queryParametersMap, attributeHandler, defaultQos));
394 }
395
396 OCStackResult OCResource::post(const std::string& resourceType,
397                                const std::string& resourceInterface, const OCRepresentation& rep,
398                                const QueryParamsMap& queryParametersMap,
399                                PostCallback attributeHandler)
400 {
401     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
402     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
403
404     return result_guard(post(resourceType, resourceInterface, rep, queryParametersMap, attributeHandler,
405             defaultQoS));
406 }
407
408 OCStackResult OCResource::post(const std::string& resourceType,
409                                const std::string& resourceInterface, const OCRepresentation& rep,
410                                const QueryParamsMap& queryParametersMap,
411                                PostCallback attributeHandler,
412                                QualityOfService QoS)
413 {
414     QueryParamsMap mapCpy(queryParametersMap);
415
416     if (!resourceType.empty())
417     {
418         mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType;
419     }
420
421     if (!resourceInterface.empty())
422     {
423         mapCpy[OC::Key::INTERFACESKEY]=resourceInterface;
424     }
425
426     return result_guard(post(rep, mapCpy, attributeHandler, QoS));
427 }
428
429 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler, QualityOfService QoS)
430 {
431     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource,
432                          m_devAddr, m_uri, m_headerOptions, CT_DEFAULT, deleteHandler, QoS);
433 }
434
435 OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler)
436 {
437     QualityOfService defaultQos = OC::QualityOfService::NaQos;
438     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
439
440     return result_guard(deleteResource(deleteHandler, defaultQos));
441 }
442
443 OCStackResult OCResource::observe(ObserveType observeType,
444         const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler,
445         QualityOfService QoS)
446 {
447     if (m_observeHandle != nullptr)
448     {
449         return result_guard(OC_STACK_INVALID_PARAM);
450     }
451
452     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
453                          observeType, &m_observeHandle, m_devAddr,
454                          m_uri, queryParametersMap, m_headerOptions,
455                          observeHandler, QoS);
456 }
457
458 OCStackResult OCResource::observe(ObserveType observeType,
459         const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
460 {
461     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
462     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
463
464     return result_guard(observe(observeType, queryParametersMap, observeHandler, defaultQoS));
465 }
466
467 OCStackResult OCResource::cancelObserve()
468 {
469     QualityOfService defaultQoS = OC::QualityOfService::NaQos;
470     checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
471     return result_guard(cancelObserve(defaultQoS));
472 }
473
474 OCStackResult OCResource::cancelObserve(QualityOfService QoS)
475 {
476     if (m_observeHandle == nullptr)
477     {
478         return result_guard(OC_STACK_INVALID_PARAM);
479     }
480
481     OCStackResult result =  checked_guard(m_clientWrapper.lock(),
482             &IClientWrapper::CancelObserveResource,
483             m_observeHandle, (const char*)"", m_uri, m_headerOptions, QoS);
484
485     if (result == OC_STACK_OK)
486     {
487         m_observeHandle = nullptr;
488     }
489
490     return result;
491 }
492
493 void OCResource::setHeaderOptions(const HeaderOptions& headerOptions)
494 {
495     m_headerOptions = headerOptions;
496 }
497
498 void OCResource::unsetHeaderOptions()
499 {
500     m_headerOptions.clear();
501 }
502
503 std::string OCResource::host() const
504 {
505     std::ostringstream ss;
506
507     if (m_devAddr.adapter & OC_ADAPTER_TCP)
508     {
509         ss << COAP_TCP;
510     }
511     else if (m_devAddr.adapter & OC_ADAPTER_GATT_BTLE)
512     {
513         ss << COAP_GATT;
514     }
515     else if (m_devAddr.adapter & OC_ADAPTER_RFCOMM_BTEDR)
516     {
517         ss << COAP_RFCOMM;
518     }
519     else
520     {
521         if (m_devAddr.flags & OC_SECURE)
522         {
523             ss << COAPS;
524         }
525         else
526         {
527             ss << COAP;
528         }
529     }
530
531     if (m_devAddr.flags & OC_IP_USE_V6)
532     {
533         ss << '[' << m_devAddr.addr << ']';
534     }
535     else
536     {
537         ss << m_devAddr.addr;
538     }
539     if (m_devAddr.port)
540     {
541         ss << ':' << m_devAddr.port;
542     }
543     return ss.str();
544 }
545
546 std::string OCResource::uri() const
547 {
548     return m_uri;
549 }
550
551 OCConnectivityType OCResource::connectivityType() const
552 {
553     return static_cast<OCConnectivityType>(
554            (m_devAddr.adapter << CT_ADAPTER_SHIFT) | (m_devAddr.flags & CT_MASK_FLAGS));
555 }
556
557 bool OCResource::isObservable() const
558 {
559     return (m_property & OC_OBSERVABLE) == OC_OBSERVABLE;
560 }
561
562 #ifdef WITH_MQ
563 bool OCResource::isPublish() const
564 {
565     return (m_property & OC_MQ_PUBLISHER) == OC_MQ_PUBLISHER;
566 }
567 #endif
568
569 std::vector<std::string> OCResource::getResourceTypes() const
570 {
571     return m_resourceTypes;
572 }
573
574 std::vector<std::string> OCResource::getResourceInterfaces(void) const
575 {
576     return m_interfaces;
577 }
578
579 OCResourceIdentifier OCResource::uniqueIdentifier() const
580 {
581     return m_resourceId;
582 }
583
584 std::string OCResource::sid() const
585 {
586     return this->uniqueIdentifier().m_representation;
587 }
588
589 #ifdef WITH_MQ
590 OCStackResult OCResource::discoveryMQTopics(const QueryParamsMap& queryParametersMap,
591                                             MQTopicCallback attributeHandler,
592                                             QualityOfService qos)
593 {
594     return checked_guard(m_clientWrapper.lock(),
595                             &IClientWrapper::ListenForMQTopic,
596                             m_devAddr, m_uri,
597                             queryParametersMap, m_headerOptions,
598                             attributeHandler, qos);
599 }
600
601 OCStackResult OCResource::createMQTopic(const OCRepresentation& rep,
602                                         const std::string& topicUri,
603                                         const QueryParamsMap& queryParametersMap,
604                                         MQTopicCallback attributeHandler,
605                                         QualityOfService qos)
606 {
607     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutMQTopicRepresentation,
608                          m_devAddr, topicUri, rep, queryParametersMap,
609                          m_headerOptions, attributeHandler, qos);
610 }
611 #endif
612 #ifdef MQ_SUBSCRIBER
613 OCStackResult OCResource::subscribeMQTopic(ObserveType observeType,
614                                            const QueryParamsMap& queryParametersMap,
615                                            ObserveCallback observeHandler,
616                                            QualityOfService qos)
617 {
618     return result_guard(observe(observeType, queryParametersMap, observeHandler, qos));
619 }
620
621 OCStackResult OCResource::unsubscribeMQTopic(QualityOfService qos)
622 {
623     return result_guard(cancelObserve(qos));
624 }
625
626 OCStackResult OCResource::requestMQPublish(const QueryParamsMap& queryParametersMap,
627                                            PostCallback attributeHandler,
628                                            QualityOfService qos)
629 {
630     OCRepresentation rep;
631     rep.setValue(std::string("req_pub"), std::string("true"));
632     return result_guard(post(rep, queryParametersMap, attributeHandler, qos));
633 }
634 #endif
635 #ifdef MQ_PUBLISHER
636 OCStackResult OCResource::publishMQTopic(const OCRepresentation& rep,
637                                          const QueryParamsMap& queryParametersMap,
638                                          PostCallback attributeHandler,
639                                          QualityOfService qos)
640 {
641     return result_guard(post(rep, queryParametersMap, attributeHandler, qos));
642 }
643 #endif
644
645 bool OCResource::operator==(const OCResource &other) const
646 {
647     return m_resourceId == other.m_resourceId;
648 }
649
650 bool OCResource::operator!=(const OCResource &other) const
651 {
652     return m_resourceId != other.m_resourceId;
653 }
654
655 bool OCResource::operator<(const OCResource &other) const
656 {
657     return m_resourceId < other.m_resourceId;
658 }
659
660 bool OCResource::operator>(const OCResource &other) const
661 {
662     return m_resourceId > other.m_resourceId;
663 }
664
665 bool OCResource::operator<=(const OCResource &other) const
666 {
667     return m_resourceId <= other.m_resourceId;
668 }
669
670 bool OCResource::operator>=(const OCResource &other) const
671 {
672     return m_resourceId >= other.m_resourceId;
673 }
674
675 OCResourceIdentifier::OCResourceIdentifier(const std::string& wireServerIdentifier,
676         const std::string& resourceUri)
677     :m_representation(wireServerIdentifier), m_resourceUri(resourceUri)
678 {
679 }
680
681 std::ostream& operator <<(std::ostream& os, const OCResourceIdentifier& ri)
682 {
683     os << ri.m_representation<<ri.m_resourceUri;
684
685     return os;
686 }
687
688 bool OCResourceIdentifier::operator==(const OCResourceIdentifier &other) const
689 {
690     return m_representation == other.m_representation
691         && m_resourceUri == other.m_resourceUri;
692 }
693
694 bool OCResourceIdentifier::operator!=(const OCResourceIdentifier &other) const
695 {
696     return !(*this == other);
697 }
698
699 bool OCResourceIdentifier::operator<(const OCResourceIdentifier &other) const
700 {
701     return m_resourceUri < other.m_resourceUri
702         || (m_resourceUri == other.m_resourceUri &&
703                 m_representation < other.m_representation);
704 }
705
706 bool OCResourceIdentifier::operator>(const OCResourceIdentifier &other) const
707 {
708     return *this != other && !(*this<other);
709 }
710
711 bool OCResourceIdentifier::operator<=(const OCResourceIdentifier &other) const
712 {
713     return !(*this > other);
714 }
715
716 bool OCResourceIdentifier::operator>=(const OCResourceIdentifier &other) const
717 {
718     return !(*this < other);
719 }
720
721 } // namespace OC