1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "InProcClientWrapper.h"
24 #include "OCPlatform.h"
25 #include "OCResource.h"
26 #include <OCSerialization.h>
31 InProcClientWrapper::InProcClientWrapper(
32 std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
33 : m_threadRun(false), m_csdkLock(csdkLock),
36 // if the config type is server, we ought to never get called. If the config type
37 // is both, we count on the server to run the thread and do the initialize
39 if(m_cfg.mode == ModeType::Client)
41 OCStackResult result = OCInit(m_cfg.ipAddress.c_str(), m_cfg.port, OC_CLIENT);
43 if(OC_STACK_OK != result)
45 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
49 m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
53 InProcClientWrapper::~InProcClientWrapper()
55 if(m_threadRun && m_listeningThread.joinable())
58 m_listeningThread.join();
61 // only stop if we are the ones who actually called 'init'. We are counting
62 // on the server to do the stop.
63 if(m_cfg.mode == ModeType::Client)
69 void InProcClientWrapper::listeningFunc()
74 auto cLock = m_csdkLock.lock();
77 std::lock_guard<std::recursive_mutex> lock(*cLock);
82 result = OC_STACK_ERROR;
85 if(result != OC_STACK_OK)
87 // TODO: do something with result if failed?
90 // To minimize CPU utilization we may wish to do this with sleep
91 std::this_thread::sleep_for(std::chrono::milliseconds(10));
95 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
97 if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
99 return OCRepresentation();
105 oc.setJSONRepresentation(clientResponse->resJSONPayload);
107 catch (cereal::RapidJSONException& ex)
109 oclog() <<"RapidJSON Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
110 "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
111 throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
113 catch (cereal::Exception& ex)
115 oclog() <<"Cereal Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
116 "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
117 throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
120 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
121 if(it == oc.representations().end())
123 return OCRepresentation();
126 // first one is considered the root, everything else is considered a child of this one.
127 OCRepresentation root = *it;
130 std::for_each(it, oc.representations().end(),
131 [&root](const OCRepresentation& repItr)
132 {root.addChild(repItr);});
137 OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
138 OCClientResponse* clientResponse)
140 ClientCallbackContext::ListenContext* context =
141 static_cast<ClientCallbackContext::ListenContext*>(ctx);
143 if(clientResponse->result != OC_STACK_OK)
145 oclog() << "listenCallback(): failed to create resource. clientResponse: "
146 << clientResponse->result
149 return OC_STACK_KEEP_TRANSACTION;
152 auto clientWrapper = context->clientWrapper.lock();
156 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
158 return OC_STACK_KEEP_TRANSACTION;
161 std::stringstream requestStream;
162 requestStream << clientResponse->resJSONPayload;
168 ListenOCContainer container(clientWrapper, *clientResponse->addr,
169 clientResponse->connType, requestStream);
171 ListenOCContainer container(clientWrapper, *clientResponse->addr,
174 // loop to ensure valid construction of all resources
175 for(auto resource : container.Resources())
177 std::thread exec(context->callback, resource);
182 catch(const std::exception& e)
184 oclog() << "listenCallback failed to parse a malformed message: "
187 << clientResponse->resJSONPayload
189 << clientResponse->result
191 return OC_STACK_KEEP_TRANSACTION;
194 return OC_STACK_KEEP_TRANSACTION;
198 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
199 const std::string& resourceType, OCConnectivityType connectivityType,
200 FindCallback& callback, QualityOfService QoS)
202 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
203 const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
206 OCStackResult result;
208 OCCallbackData cbdata = {0};
210 ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext();
211 context->callback = callback;
212 context->clientWrapper = shared_from_this();
214 cbdata.context = static_cast<void*>(context);
215 cbdata.cb = listenCallback;
216 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);};
218 auto cLock = m_csdkLock.lock();
221 std::lock_guard<std::recursive_mutex> lock(*cLock);
224 result = OCDoResource(&handle, OC_REST_GET,
225 resourceType.c_str(),
226 nullptr, nullptr, connectivityType,
227 static_cast<OCQualityOfService>(QoS),
231 result = OCDoResource(&handle, OC_REST_GET,
232 resourceType.c_str(),
234 static_cast<OCQualityOfService>(QoS),
242 result = OC_STACK_ERROR;
247 OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
248 OCClientResponse* clientResponse)
250 ClientCallbackContext::DeviceListenContext* context =
251 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
255 OCRepresentation rep = parseGetSetCallback(clientResponse);
256 std::thread exec(context->callback, rep);
259 catch(OC::OCException& e)
261 oclog() <<"Exception in listenDeviceCallback, ignoring response: "
262 <<e.what() <<std::flush;
265 return OC_STACK_KEEP_TRANSACTION;
269 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
270 const std::string& deviceURI, OCConnectivityType connectivityType,
271 FindDeviceCallback& callback, QualityOfService QoS)
273 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
274 const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
277 OCStackResult result;
279 OCCallbackData cbdata = {0};
280 ClientCallbackContext::DeviceListenContext* context =
281 new ClientCallbackContext::DeviceListenContext();
282 context->callback = callback;
283 context->clientWrapper = shared_from_this();
284 cbdata.context = static_cast<void*>(context);
285 cbdata.cb = listenDeviceCallback;
286 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
288 auto cLock = m_csdkLock.lock();
291 std::lock_guard<std::recursive_mutex> lock(*cLock);
294 result = OCDoResource(&handle, OC_REST_GET,
296 nullptr, nullptr, connectivityType,
297 static_cast<OCQualityOfService>(QoS),
301 result = OCDoResource(&handle, OC_REST_GET,
304 static_cast<OCQualityOfService>(QoS),
311 result = OC_STACK_ERROR;
316 void parseServerHeaderOptions(OCClientResponse* clientResponse,
317 HeaderOptions& serverHeaderOptions)
321 // Parse header options from server
323 std::string optionData;
325 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
327 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
328 optionData = reinterpret_cast<const char*>
329 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
330 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
331 serverHeaderOptions.push_back(headerOption);
336 // clientResponse is invalid
337 // TODO check proper logging
338 std::cout << " Invalid response " << std::endl;
342 OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle,
343 OCClientResponse* clientResponse)
345 ClientCallbackContext::GetContext* context =
346 static_cast<ClientCallbackContext::GetContext*>(ctx);
348 OCRepresentation rep;
349 HeaderOptions serverHeaderOptions;
350 OCStackResult result = clientResponse->result;
351 if(result == OC_STACK_OK)
353 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
356 rep = parseGetSetCallback(clientResponse);
358 catch(OC::OCException& e)
364 std::thread exec(context->callback, serverHeaderOptions, rep, result);
366 return OC_STACK_DELETE_TRANSACTION;
370 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
371 const std::string& uri, OCConnectivityType connectivityType,
372 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
373 GetCallback& callback, QualityOfService QoS)
375 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
376 const std::string& uri, const QueryParamsMap& queryParams,
377 const HeaderOptions& headerOptions, GetCallback& callback,
378 QualityOfService QoS)
381 OCStackResult result;
382 OCCallbackData cbdata = {0};
384 ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext();
385 ctx->callback = callback;
386 cbdata.context = static_cast<void*>(ctx);
387 cbdata.cb = &getResourceCallback;
388 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);};
390 auto cLock = m_csdkLock.lock();
394 std::ostringstream os;
395 os << host << assembleSetResourceUri(uri, queryParams).c_str();
397 std::lock_guard<std::recursive_mutex> lock(*cLock);
399 OCHeaderOption options[MAX_HEADER_OPTIONS];
401 assembleHeaderOptions(options, headerOptions);
403 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
404 nullptr, nullptr, connectivityType,
405 static_cast<OCQualityOfService>(QoS),
407 options, headerOptions.size());
409 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
411 static_cast<OCQualityOfService>(QoS),
413 options, headerOptions.size());
419 result = OC_STACK_ERROR;
425 OCStackApplicationResult setResourceCallback(void* ctx, OCDoHandle handle,
426 OCClientResponse* clientResponse)
428 ClientCallbackContext::SetContext* context =
429 static_cast<ClientCallbackContext::SetContext*>(ctx);
430 OCRepresentation attrs;
431 HeaderOptions serverHeaderOptions;
433 OCStackResult result = clientResponse->result;
434 if (OC_STACK_OK == result ||
435 OC_STACK_RESOURCE_CREATED == result ||
436 OC_STACK_RESOURCE_DELETED == result)
438 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
441 attrs = parseGetSetCallback(clientResponse);
443 catch(OC::OCException& e)
449 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
451 return OC_STACK_DELETE_TRANSACTION;
454 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
455 const QueryParamsMap& queryParams)
457 if(uri.back() == '/')
459 uri.resize(uri.size()-1);
462 ostringstream paramsList;
463 if(queryParams.size() > 0)
468 for(auto& param : queryParams)
470 paramsList << param.first <<'='<<param.second<<'&';
473 std::string queryString = paramsList.str();
474 if(queryString.back() == '&')
476 queryString.resize(queryString.size() - 1);
479 std::string ret = uri + queryString;
483 std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
485 MessageContainer ocInfo;
486 ocInfo.addRepresentation(rep);
487 return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
491 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
492 const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
493 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
494 PostCallback& callback, QualityOfService QoS)
496 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
497 const std::string& uri, const OCRepresentation& rep,
498 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
499 PostCallback& callback, QualityOfService QoS)
502 OCStackResult result;
503 OCCallbackData cbdata = {0};
505 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
506 ctx->callback = callback;
507 cbdata.cb = &setResourceCallback;
508 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
509 cbdata.context = static_cast<void*>(ctx);
511 // TODO: in the future the cstack should be combining these two strings!
513 os << host << assembleSetResourceUri(uri, queryParams).c_str();
514 // TODO: end of above
516 auto cLock = m_csdkLock.lock();
520 std::lock_guard<std::recursive_mutex> lock(*cLock);
521 OCHeaderOption options[MAX_HEADER_OPTIONS];
524 assembleHeaderOptions(options, headerOptions);
526 result = OCDoResource(&handle, OC_REST_POST,
527 os.str().c_str(), nullptr,
528 assembleSetResourcePayload(rep).c_str(), connectivityType,
529 static_cast<OCQualityOfService>(QoS),
530 &cbdata, options, headerOptions.size());
532 result = OCDoResource(&handle, OC_REST_POST,
533 os.str().c_str(), nullptr,
534 assembleSetResourcePayload(rep).c_str(),
535 static_cast<OCQualityOfService>(QoS),
536 &cbdata, options, headerOptions.size());
542 result = OC_STACK_ERROR;
549 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
550 const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
551 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
552 PutCallback& callback, QualityOfService QoS)
554 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
555 const std::string& uri, const OCRepresentation& rep,
556 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
557 PutCallback& callback, QualityOfService QoS)
560 OCStackResult result;
561 OCCallbackData cbdata = {0};
563 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
564 ctx->callback = callback;
565 cbdata.cb = &setResourceCallback;
566 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
567 cbdata.context = static_cast<void*>(ctx);
569 // TODO: in the future the cstack should be combining these two strings!
571 os << host << assembleSetResourceUri(uri, queryParams).c_str();
572 // TODO: end of above
574 auto cLock = m_csdkLock.lock();
578 std::lock_guard<std::recursive_mutex> lock(*cLock);
580 OCHeaderOption options[MAX_HEADER_OPTIONS];
582 assembleHeaderOptions(options, headerOptions);
584 result = OCDoResource(&handle, OC_REST_PUT,
585 os.str().c_str(), nullptr,
586 assembleSetResourcePayload(rep).c_str(), connectivityType,
587 static_cast<OCQualityOfService>(QoS),
589 options, headerOptions.size());
591 result = OCDoResource(&handle, OC_REST_PUT,
592 os.str().c_str(), nullptr,
593 assembleSetResourcePayload(rep).c_str(),
594 static_cast<OCQualityOfService>(QoS),
596 options, headerOptions.size());
602 result = OC_STACK_ERROR;
608 OCStackApplicationResult deleteResourceCallback(void* ctx, OCDoHandle handle,
609 OCClientResponse* clientResponse)
611 ClientCallbackContext::DeleteContext* context =
612 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
613 HeaderOptions serverHeaderOptions;
615 if(clientResponse->result == OC_STACK_OK)
617 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
619 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
621 return OC_STACK_DELETE_TRANSACTION;
625 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
626 const std::string& uri, OCConnectivityType connectivityType,
627 const HeaderOptions& headerOptions, DeleteCallback& callback, QualityOfService QoS)
629 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
630 const std::string& uri, const HeaderOptions& headerOptions,
631 DeleteCallback& callback, QualityOfService QoS)
634 OCStackResult result;
635 OCCallbackData cbdata = {0};
637 ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext();
638 ctx->callback = callback;
639 cbdata.cb = &deleteResourceCallback;
640 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);};
641 cbdata.context = static_cast<void*>(ctx);
646 auto cLock = m_csdkLock.lock();
650 OCHeaderOption options[MAX_HEADER_OPTIONS];
653 assembleHeaderOptions(options, headerOptions);
655 std::lock_guard<std::recursive_mutex> lock(*cLock);
657 result = OCDoResource(&handle, OC_REST_DELETE,
658 os.str().c_str(), nullptr,
659 nullptr, connectivityType,
660 static_cast<OCQualityOfService>(m_cfg.QoS),
661 &cbdata, options, headerOptions.size());
663 result = OCDoResource(&handle, OC_REST_DELETE,
664 os.str().c_str(), nullptr,
665 nullptr, static_cast<OCQualityOfService>(m_cfg.QoS),
666 &cbdata, options, headerOptions.size());
672 result = OC_STACK_ERROR;
678 OCStackApplicationResult observeResourceCallback(void* ctx, OCDoHandle handle,
679 OCClientResponse* clientResponse)
681 ClientCallbackContext::ObserveContext* context =
682 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
683 OCRepresentation attrs;
684 HeaderOptions serverHeaderOptions;
685 uint32_t sequenceNumber = clientResponse->sequenceNumber;
686 OCStackResult result = clientResponse->result;
687 if(clientResponse->result == OC_STACK_OK)
689 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
692 attrs = parseGetSetCallback(clientResponse);
694 catch(OC::OCException& e)
699 std::thread exec(context->callback, serverHeaderOptions, attrs,
700 result, sequenceNumber);
702 if(sequenceNumber == OC_OBSERVE_DEREGISTER)
704 return OC_STACK_DELETE_TRANSACTION;
706 return OC_STACK_KEEP_TRANSACTION;
710 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
711 const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
712 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
713 ObserveCallback& callback, QualityOfService QoS)
715 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
716 const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
717 const HeaderOptions& headerOptions, ObserveCallback& callback, QualityOfService QoS)
720 OCStackResult result;
721 OCCallbackData cbdata = {0};
723 ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext();
724 ctx->callback = callback;
725 cbdata.context = static_cast<void*>(ctx);
726 cbdata.cb = &observeResourceCallback;
727 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);};
730 if (observeType == ObserveType::Observe)
732 method = OC_REST_OBSERVE;
734 else if (observeType == ObserveType::ObserveAll)
736 method = OC_REST_OBSERVE_ALL;
740 method = OC_REST_OBSERVE_ALL;
743 auto cLock = m_csdkLock.lock();
747 std::ostringstream os;
748 os << host << assembleSetResourceUri(uri, queryParams).c_str();
750 std::lock_guard<std::recursive_mutex> lock(*cLock);
751 OCHeaderOption options[MAX_HEADER_OPTIONS];
753 assembleHeaderOptions(options, headerOptions);
755 result = OCDoResource(handle, method,
756 os.str().c_str(), nullptr,
757 nullptr, connectivityType,
758 static_cast<OCQualityOfService>(QoS),
760 options, headerOptions.size());
762 result = OCDoResource(handle, method,
763 os.str().c_str(), nullptr,
765 static_cast<OCQualityOfService>(QoS),
767 options, headerOptions.size());
773 return OC_STACK_ERROR;
779 OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
780 const std::string& host, const std::string& uri, const HeaderOptions& headerOptions,
781 QualityOfService QoS)
783 OCStackResult result;
784 auto cLock = m_csdkLock.lock();
788 std::lock_guard<std::recursive_mutex> lock(*cLock);
789 OCHeaderOption options[MAX_HEADER_OPTIONS];
791 assembleHeaderOptions(options, headerOptions);
792 result = OCCancel(handle, static_cast<OCQualityOfService>(QoS), options,
793 headerOptions.size());
797 result = OC_STACK_ERROR;
803 OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
804 OCClientResponse* clientResponse)
806 char stringAddress[DEV_ADDR_SIZE_MAX];
810 if(OCDevAddrToString(clientResponse->addr, stringAddress) == 0 &&
811 OCDevAddrToPort(clientResponse->addr, &port) == 0)
813 os<<stringAddress<<":"<<port;
815 ClientCallbackContext::SubscribePresenceContext* context =
816 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
818 std::thread exec(context->callback, clientResponse->result,
819 clientResponse->sequenceNumber, os.str());
825 oclog() << "subscribePresenceCallback(): OCDevAddrToString() or OCDevAddrToPort() "
826 <<"failed"<< std::flush;
828 return OC_STACK_KEEP_TRANSACTION;
832 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
833 const std::string& host, const std::string& resourceType,
834 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
836 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
837 const std::string& host, const std::string& resourceType,
838 SubscribeCallback& presenceHandler)
841 OCCallbackData cbdata = {0};
843 ClientCallbackContext::SubscribePresenceContext* ctx =
844 new ClientCallbackContext::SubscribePresenceContext();
845 ctx->callback = presenceHandler;
846 cbdata.cb = &subscribePresenceCallback;
847 cbdata.context = static_cast<void*>(ctx);
848 cbdata.cd = [](void* c)
849 {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);};
850 auto cLock = m_csdkLock.lock();
852 std::ostringstream os;
853 os << host << "/oc/presence";
855 if(!resourceType.empty())
857 os << "?rt=" << resourceType;
863 return OC_STACK_ERROR;
867 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
868 connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
870 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
871 OC_LOW_QOS, &cbdata, NULL, 0);
875 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
877 OCStackResult result;
878 auto cLock = m_csdkLock.lock();
882 std::lock_guard<std::recursive_mutex> lock(*cLock);
883 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
887 result = OC_STACK_ERROR;
893 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
899 void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
900 const HeaderOptions& headerOptions)
904 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
906 options[i].protocolID = OC_COAP_ID;
907 options[i].optionID = static_cast<uint16_t>(it->getOptionID());
908 options[i].optionLength = (it->getOptionData()).length() + 1;
909 memcpy(options[i].optionData, (it->getOptionData()).c_str(),
910 (it->getOptionData()).length() + 1);