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 "ocpayload.h"
27 #include <OCSerialization.h>
32 InProcClientWrapper::InProcClientWrapper(
33 std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
34 : m_threadRun(false), m_csdkLock(csdkLock),
37 // if the config type is server, we ought to never get called. If the config type
38 // is both, we count on the server to run the thread and do the initialize
40 if (m_cfg.mode == ModeType::Client)
42 OCTransportFlags serverFlags =
43 static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
44 OCTransportFlags clientFlags =
45 static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
46 OCStackResult result = OCInit1(OC_CLIENT, serverFlags, clientFlags);
48 if (OC_STACK_OK != result)
50 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
54 m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
58 InProcClientWrapper::~InProcClientWrapper()
60 if (m_threadRun && m_listeningThread.joinable())
63 m_listeningThread.join();
66 // only stop if we are the ones who actually called 'init'. We are counting
67 // on the server to do the stop.
68 if (m_cfg.mode == ModeType::Client)
74 void InProcClientWrapper::listeningFunc()
79 auto cLock = m_csdkLock.lock();
82 std::lock_guard<std::recursive_mutex> lock(*cLock);
87 result = OC_STACK_ERROR;
90 if (result != OC_STACK_OK)
92 // TODO: do something with result if failed?
95 // To minimize CPU utilization we may wish to do this with sleep
96 std::this_thread::sleep_for(std::chrono::milliseconds(10));
100 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
102 if (clientResponse->payload == nullptr ||
104 clientResponse->payload->type != PAYLOAD_TYPE_DEVICE &&
105 clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM &&
106 clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
110 //OCPayloadDestroy(clientResponse->payload);
111 return OCRepresentation();
115 oc.setPayload(clientResponse->payload);
116 //OCPayloadDestroy(clientResponse->payload);
118 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
119 if (it == oc.representations().end())
121 return OCRepresentation();
124 // first one is considered the root, everything else is considered a child of this one.
125 OCRepresentation root = *it;
126 root.setDevAddr(clientResponse->devAddr);
127 root.setUri(clientResponse->resourceUri);
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 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
154 oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
156 return OC_STACK_KEEP_TRANSACTION;
159 auto clientWrapper = context->clientWrapper.lock();
163 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
165 return OC_STACK_KEEP_TRANSACTION;
169 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
170 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
171 // loop to ensure valid construction of all resources
172 for(auto resource : container.Resources())
174 std::thread exec(context->callback, resource);
178 catch (std::exception &e){
179 oclog() << "Exception in listCallback, ignoring response: "
180 << e.what() << std::flush;
184 return OC_STACK_KEEP_TRANSACTION;
187 OCStackApplicationResult listenErrorCallback(void* ctx, OCDoHandle /*handle*/,
188 OCClientResponse* clientResponse)
190 if (!ctx || !clientResponse)
192 return OC_STACK_KEEP_TRANSACTION;
195 ClientCallbackContext::ListenErrorContext* context =
196 static_cast<ClientCallbackContext::ListenErrorContext*>(ctx);
199 return OC_STACK_KEEP_TRANSACTION;
202 OCStackResult result = clientResponse->result;
203 if (result == OC_STACK_OK)
205 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
207 oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
209 return OC_STACK_KEEP_TRANSACTION;
212 auto clientWrapper = context->clientWrapper.lock();
216 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
218 return OC_STACK_KEEP_TRANSACTION;
221 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
222 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
223 // loop to ensure valid construction of all resources
224 for (auto resource : container.Resources())
226 std::thread exec(context->callback, resource);
229 return OC_STACK_KEEP_TRANSACTION;
232 std::string resourceURI = clientResponse->resourceUri;
233 std::thread exec(context->errorCallback, resourceURI, result);
235 return OC_STACK_DELETE_TRANSACTION;
238 OCStackResult InProcClientWrapper::ListenForResource(
239 const std::string& serviceUrl,
240 const std::string& resourceType,
241 OCConnectivityType connectivityType,
242 FindCallback& callback, QualityOfService QoS)
246 return OC_STACK_INVALID_PARAM;
249 OCStackResult result;
250 ostringstream resourceUri;
251 resourceUri << serviceUrl << resourceType;
253 ClientCallbackContext::ListenContext* context =
254 new ClientCallbackContext::ListenContext(callback, shared_from_this());
255 OCCallbackData cbdata;
256 cbdata.context = static_cast<void*>(context),
257 cbdata.cb = listenCallback;
258 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;};
260 auto cLock = m_csdkLock.lock();
263 std::lock_guard<std::recursive_mutex> lock(*cLock);
264 result = OCDoResource(nullptr, OC_REST_DISCOVER,
265 resourceUri.str().c_str(),
266 nullptr, nullptr, connectivityType,
267 static_cast<OCQualityOfService>(QoS),
274 result = OC_STACK_ERROR;
279 OCStackResult InProcClientWrapper::ListenErrorForResource(
280 const std::string& serviceUrl,
281 const std::string& resourceType,
282 OCConnectivityType connectivityType,
283 FindCallback& callback, FindErrorCallback& errorCallback,
284 QualityOfService QoS)
288 return OC_STACK_INVALID_PARAM;
291 ostringstream resourceUri;
292 resourceUri << serviceUrl << resourceType;
294 ClientCallbackContext::ListenErrorContext* context =
295 new ClientCallbackContext::ListenErrorContext(callback, errorCallback,
299 return OC_STACK_ERROR;
302 OCCallbackData cbdata(
303 static_cast<void*>(context),
305 [](void* c){delete static_cast<ClientCallbackContext::ListenErrorContext*>(c);}
308 OCStackResult result;
309 auto cLock = m_csdkLock.lock();
312 std::lock_guard<std::recursive_mutex> lock(*cLock);
313 result = OCDoResource(nullptr, OC_REST_DISCOVER,
314 resourceUri.str().c_str(),
315 nullptr, nullptr, connectivityType,
316 static_cast<OCQualityOfService>(QoS),
323 result = OC_STACK_ERROR;
328 OCStackApplicationResult listenDeviceCallback(void* ctx,
329 OCDoHandle /*handle*/,
330 OCClientResponse* clientResponse)
332 ClientCallbackContext::DeviceListenContext* context =
333 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
337 OCRepresentation rep = parseGetSetCallback(clientResponse);
338 std::thread exec(context->callback, rep);
341 catch(OC::OCException& e)
343 oclog() <<"Exception in listenDeviceCallback, ignoring response: "
344 <<e.what() <<std::flush;
347 return OC_STACK_KEEP_TRANSACTION;
350 OCStackResult InProcClientWrapper::ListenForDevice(
351 const std::string& serviceUrl,
352 const std::string& deviceURI,
353 OCConnectivityType connectivityType,
354 FindDeviceCallback& callback,
355 QualityOfService QoS)
359 return OC_STACK_INVALID_PARAM;
361 OCStackResult result;
362 ostringstream deviceUri;
363 deviceUri << serviceUrl << deviceURI;
365 ClientCallbackContext::DeviceListenContext* context =
366 new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
367 OCCallbackData cbdata;
369 cbdata.context = static_cast<void*>(context),
370 cbdata.cb = listenDeviceCallback;
371 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeviceListenContext*)c;};
373 auto cLock = m_csdkLock.lock();
376 std::lock_guard<std::recursive_mutex> lock(*cLock);
377 result = OCDoResource(nullptr, OC_REST_DISCOVER,
378 deviceUri.str().c_str(),
379 nullptr, nullptr, connectivityType,
380 static_cast<OCQualityOfService>(QoS),
387 result = OC_STACK_ERROR;
392 void parseServerHeaderOptions(OCClientResponse* clientResponse,
393 HeaderOptions& serverHeaderOptions)
397 // Parse header options from server
399 std::string optionData;
401 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
403 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
404 optionData = reinterpret_cast<const char*>
405 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
406 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
407 serverHeaderOptions.push_back(headerOption);
412 // clientResponse is invalid
413 // TODO check proper logging
414 std::cout << " Invalid response " << std::endl;
418 OCStackApplicationResult getResourceCallback(void* ctx,
419 OCDoHandle /*handle*/,
420 OCClientResponse* clientResponse)
422 ClientCallbackContext::GetContext* context =
423 static_cast<ClientCallbackContext::GetContext*>(ctx);
425 OCRepresentation rep;
426 HeaderOptions serverHeaderOptions;
427 OCStackResult result = clientResponse->result;
428 if (result == OC_STACK_OK)
430 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
433 rep = parseGetSetCallback(clientResponse);
435 catch(OC::OCException& e)
441 std::thread exec(context->callback, serverHeaderOptions, rep, result);
443 return OC_STACK_DELETE_TRANSACTION;
446 OCStackResult InProcClientWrapper::GetResourceRepresentation(
447 const OCDevAddr& devAddr,
448 const std::string& resourceUri,
449 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
450 GetCallback& callback, QualityOfService QoS)
454 return OC_STACK_INVALID_PARAM;
456 OCStackResult result;
457 ClientCallbackContext::GetContext* ctx =
458 new ClientCallbackContext::GetContext(callback);
459 OCCallbackData cbdata;
460 cbdata.context = static_cast<void*>(ctx),
461 cbdata.cb = getResourceCallback;
462 cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
465 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
467 auto cLock = m_csdkLock.lock();
471 std::lock_guard<std::recursive_mutex> lock(*cLock);
472 OCHeaderOption options[MAX_HEADER_OPTIONS];
474 result = OCDoResource(
475 nullptr, OC_REST_GET,
479 static_cast<OCQualityOfService>(QoS),
481 assembleHeaderOptions(options, headerOptions),
482 headerOptions.size());
487 result = OC_STACK_ERROR;
493 OCStackApplicationResult setResourceCallback(void* ctx,
494 OCDoHandle /*handle*/,
495 OCClientResponse* clientResponse)
497 ClientCallbackContext::SetContext* context =
498 static_cast<ClientCallbackContext::SetContext*>(ctx);
499 OCRepresentation attrs;
500 HeaderOptions serverHeaderOptions;
502 OCStackResult result = clientResponse->result;
503 if (OC_STACK_OK == result ||
504 OC_STACK_RESOURCE_CREATED == result ||
505 OC_STACK_RESOURCE_DELETED == result ||
506 OC_STACK_RESOURCE_CHANGED == result)
508 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
511 attrs = parseGetSetCallback(clientResponse);
513 catch(OC::OCException& e)
519 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
521 return OC_STACK_DELETE_TRANSACTION;
524 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
525 const QueryParamsMap& queryParams)
529 if (uri.back() == '/')
531 uri.resize(uri.size() - 1);
535 ostringstream paramsList;
536 if (queryParams.size() > 0)
541 for (auto& param : queryParams)
543 paramsList << param.first <<'='<<param.second<<';';
546 std::string queryString = paramsList.str();
548 if (queryString.empty())
553 if (queryString.back() == ';')
555 queryString.resize(queryString.size() - 1);
558 std::string ret = uri + queryString;
562 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
563 const QueryParamsList& queryParams)
567 if (uri.back() == '/')
569 uri.resize(uri.size() - 1);
573 ostringstream paramsList;
574 if (queryParams.size() > 0)
579 for (auto& param : queryParams)
581 for (auto& paramList : param.second)
583 paramsList << param.first << '=' << paramList;
584 if (paramList != param.second.back())
592 std::string queryString = paramsList.str();
594 if (queryString.empty())
599 if (queryString.back() == ';')
601 queryString.resize(queryString.size() - 1);
604 std::string ret = uri + queryString;
608 OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
610 MessageContainer ocInfo;
611 ocInfo.addRepresentation(rep);
612 for(const OCRepresentation& r : rep.getChildren())
614 ocInfo.addRepresentation(r);
617 return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
620 OCStackResult InProcClientWrapper::PostResourceRepresentation(
621 const OCDevAddr& devAddr,
622 const std::string& uri,
623 const OCRepresentation& rep,
624 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
625 OCConnectivityType connectivityType,
626 PostCallback& callback, QualityOfService QoS)
630 return OC_STACK_INVALID_PARAM;
632 OCStackResult result;
633 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
634 OCCallbackData cbdata;
635 cbdata.context = static_cast<void*>(ctx),
636 cbdata.cb = setResourceCallback;
637 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
640 std::string url = assembleSetResourceUri(uri, queryParams);
642 auto cLock = m_csdkLock.lock();
646 std::lock_guard<std::recursive_mutex> lock(*cLock);
647 OCHeaderOption options[MAX_HEADER_OPTIONS];
649 result = OCDoResource(nullptr, OC_REST_POST,
650 url.c_str(), &devAddr,
651 assembleSetResourcePayload(rep),
653 static_cast<OCQualityOfService>(QoS),
655 assembleHeaderOptions(options, headerOptions),
656 headerOptions.size());
661 result = OC_STACK_ERROR;
667 OCStackResult InProcClientWrapper::PutResourceRepresentation(
668 const OCDevAddr& devAddr,
669 const std::string& uri,
670 const OCRepresentation& rep,
671 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
672 PutCallback& callback, QualityOfService QoS)
676 return OC_STACK_INVALID_PARAM;
678 OCStackResult result;
679 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
680 OCCallbackData cbdata;
681 cbdata.context = static_cast<void*>(ctx),
682 cbdata.cb = setResourceCallback;
683 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
686 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
688 auto cLock = m_csdkLock.lock();
692 std::lock_guard<std::recursive_mutex> lock(*cLock);
694 OCHeaderOption options[MAX_HEADER_OPTIONS];
696 result = OCDoResource(&handle, OC_REST_PUT,
697 url.c_str(), &devAddr,
698 assembleSetResourcePayload(rep),
700 static_cast<OCQualityOfService>(QoS),
702 assembleHeaderOptions(options, headerOptions),
703 headerOptions.size());
708 result = OC_STACK_ERROR;
714 OCStackApplicationResult deleteResourceCallback(void* ctx,
715 OCDoHandle /*handle*/,
716 OCClientResponse* clientResponse)
718 ClientCallbackContext::DeleteContext* context =
719 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
720 HeaderOptions serverHeaderOptions;
722 if (clientResponse->result == OC_STACK_OK)
724 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
726 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
728 return OC_STACK_DELETE_TRANSACTION;
731 OCStackResult InProcClientWrapper::DeleteResource(
732 const OCDevAddr& devAddr,
733 const std::string& uri,
734 const HeaderOptions& headerOptions,
735 DeleteCallback& callback,
736 QualityOfService /*QoS*/)
740 return OC_STACK_INVALID_PARAM;
742 OCStackResult result;
743 ClientCallbackContext::DeleteContext* ctx =
744 new ClientCallbackContext::DeleteContext(callback);
745 OCCallbackData cbdata;
746 cbdata.context = static_cast<void*>(ctx),
747 cbdata.cb = deleteResourceCallback;
748 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;};
751 auto cLock = m_csdkLock.lock();
755 OCHeaderOption options[MAX_HEADER_OPTIONS];
757 std::lock_guard<std::recursive_mutex> lock(*cLock);
759 result = OCDoResource(nullptr, OC_REST_DELETE,
760 uri.c_str(), &devAddr,
763 static_cast<OCQualityOfService>(m_cfg.QoS),
765 assembleHeaderOptions(options, headerOptions),
766 headerOptions.size());
771 result = OC_STACK_ERROR;
777 OCStackApplicationResult observeResourceCallback(void* ctx,
778 OCDoHandle /*handle*/,
779 OCClientResponse* clientResponse)
781 ClientCallbackContext::ObserveContext* context =
782 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
783 OCRepresentation attrs;
784 HeaderOptions serverHeaderOptions;
785 uint32_t sequenceNumber = clientResponse->sequenceNumber;
786 OCStackResult result = clientResponse->result;
787 if (clientResponse->result == OC_STACK_OK)
789 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
792 attrs = parseGetSetCallback(clientResponse);
794 catch(OC::OCException& e)
799 std::thread exec(context->callback, serverHeaderOptions, attrs,
800 result, sequenceNumber);
802 if (sequenceNumber == OC_OBSERVE_DEREGISTER)
804 return OC_STACK_DELETE_TRANSACTION;
806 return OC_STACK_KEEP_TRANSACTION;
809 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
810 const OCDevAddr& devAddr,
811 const std::string& uri,
812 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
813 ObserveCallback& callback, QualityOfService QoS)
817 return OC_STACK_INVALID_PARAM;
819 OCStackResult result;
821 ClientCallbackContext::ObserveContext* ctx =
822 new ClientCallbackContext::ObserveContext(callback);
823 OCCallbackData cbdata;
824 cbdata.context = static_cast<void*>(ctx),
825 cbdata.cb = observeResourceCallback;
826 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
830 if (observeType == ObserveType::Observe)
832 method = OC_REST_OBSERVE;
834 else if (observeType == ObserveType::ObserveAll)
836 method = OC_REST_OBSERVE_ALL;
840 method = OC_REST_OBSERVE_ALL;
843 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
845 auto cLock = m_csdkLock.lock();
849 std::lock_guard<std::recursive_mutex> lock(*cLock);
850 OCHeaderOption options[MAX_HEADER_OPTIONS];
852 result = OCDoResource(handle, method,
853 url.c_str(), &devAddr,
856 static_cast<OCQualityOfService>(QoS),
858 assembleHeaderOptions(options, headerOptions),
859 headerOptions.size());
864 return OC_STACK_ERROR;
870 OCStackResult InProcClientWrapper::CancelObserveResource(
872 const std::string& /*host*/,
873 const std::string& /*uri*/,
874 const HeaderOptions& headerOptions,
875 QualityOfService QoS)
877 OCStackResult result;
878 auto cLock = m_csdkLock.lock();
882 std::lock_guard<std::recursive_mutex> lock(*cLock);
883 OCHeaderOption options[MAX_HEADER_OPTIONS];
885 result = OCCancel(handle,
886 static_cast<OCQualityOfService>(QoS),
887 assembleHeaderOptions(options, headerOptions),
888 headerOptions.size());
892 result = OC_STACK_ERROR;
898 OCStackApplicationResult subscribePresenceCallback(void* ctx,
899 OCDoHandle /*handle*/,
900 OCClientResponse* clientResponse)
902 ClientCallbackContext::SubscribePresenceContext* context =
903 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
906 * This a hack while we rethink presence subscription.
908 std::string url = clientResponse->devAddr.addr;
910 std::thread exec(context->callback, clientResponse->result,
911 clientResponse->sequenceNumber, url);
915 return OC_STACK_KEEP_TRANSACTION;
918 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
919 const std::string& host, const std::string& resourceType,
920 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
922 if (!presenceHandler)
924 return OC_STACK_INVALID_PARAM;
927 ClientCallbackContext::SubscribePresenceContext* ctx =
928 new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
929 OCCallbackData cbdata;
930 cbdata.context = static_cast<void*>(ctx),
931 cbdata.cb = subscribePresenceCallback;
932 cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;};
935 auto cLock = m_csdkLock.lock();
937 std::ostringstream os;
938 os << host << OC_RSRVD_PRESENCE_URI;
940 if (!resourceType.empty())
942 os << "?rt=" << resourceType;
948 return OC_STACK_ERROR;
951 return OCDoResource(handle, OC_REST_PRESENCE,
952 os.str().c_str(), nullptr,
953 nullptr, connectivityType,
954 OC_LOW_QOS, &cbdata, NULL, 0);
957 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
959 OCStackResult result;
960 auto cLock = m_csdkLock.lock();
964 std::lock_guard<std::recursive_mutex> lock(*cLock);
965 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
969 result = OC_STACK_ERROR;
975 OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
976 const std::string& host,
977 const QueryParamsList& queryParams,
978 OCConnectivityType connectivityType,
979 ObserveCallback& callback)
983 return OC_STACK_INVALID_PARAM;
985 OCStackResult result;
987 ClientCallbackContext::ObserveContext* ctx =
988 new ClientCallbackContext::ObserveContext(callback);
989 OCCallbackData cbdata;
990 cbdata.context = static_cast<void*>(ctx),
991 cbdata.cb = observeResourceCallback;
992 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
994 auto cLock = m_csdkLock.lock();
998 std::lock_guard<std::recursive_mutex> lock(*cLock);
1000 std::ostringstream os;
1001 os << host << OCF_RSRVD_DEVICE_PRESENCE_URI;
1002 std::string url = assembleSetResourceUri(os.str(), queryParams);
1004 result = OCDoResource(handle, OC_REST_OBSERVE,
1005 url.c_str(), nullptr,
1006 nullptr, connectivityType,
1007 OC_LOW_QOS, &cbdata,
1013 result = OC_STACK_ERROR;
1019 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
1025 OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
1026 const HeaderOptions& headerOptions)
1030 if ( headerOptions.size() == 0)
1035 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
1037 options[i] = OCHeaderOption();
1038 options[i].protocolID = OC_COAP_ID;
1039 options[i].optionID = it->getOptionID();
1040 options[i].optionLength = it->getOptionData().length() + 1;
1041 strcpy((char*)options[i].optionData, (it->getOptionData().c_str()));
1048 std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
1055 OCDPDev_t* result = new OCDPDev_t(*dev);
1056 result->prm = new OCPrm_t[dev->prmLen];
1057 memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
1058 return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
1061 void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
1065 dpList.push_back(cloneDevice(list));
1070 OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
1071 GetDirectPairedCallback& callback)
1073 if (!callback || 0 == waittime)
1075 return OC_STACK_INVALID_PARAM;
1078 OCStackResult result = OC_STACK_ERROR;
1079 const OCDPDev_t *list = nullptr;
1080 PairedDevices dpDeviceList;
1082 auto cLock = m_csdkLock.lock();
1086 std::lock_guard<std::recursive_mutex> lock(*cLock);
1088 list = OCDiscoverDirectPairingDevices(waittime);
1091 result = OC_STACK_NO_RESOURCE;
1092 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1096 convert(list, dpDeviceList);
1097 std::thread exec(callback, dpDeviceList);
1099 result = OC_STACK_OK;
1104 result = OC_STACK_ERROR;
1110 OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
1114 return OC_STACK_INVALID_PARAM;
1117 OCStackResult result = OC_STACK_ERROR;
1118 const OCDPDev_t *list = nullptr;
1119 PairedDevices dpDeviceList;
1121 auto cLock = m_csdkLock.lock();
1125 std::lock_guard<std::recursive_mutex> lock(*cLock);
1127 list = OCGetDirectPairedDevices();
1130 result = OC_STACK_NO_RESOURCE;
1131 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1135 convert(list, dpDeviceList);
1136 std::thread exec(callback, dpDeviceList);
1138 result = OC_STACK_OK;
1143 result = OC_STACK_ERROR;
1149 void directPairingCallback(void *ctx, OCDPDev_t *peer,
1150 OCStackResult result)
1153 ClientCallbackContext::DirectPairingContext* context =
1154 static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
1156 std::thread exec(context->callback, cloneDevice(peer), result);
1160 OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
1161 const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
1163 if (!peer || !callback)
1165 oclog() << "Invalid parameters" << std::flush;
1166 return OC_STACK_INVALID_PARAM;
1169 OCStackResult result = OC_STACK_ERROR;
1170 ClientCallbackContext::DirectPairingContext* context =
1171 new ClientCallbackContext::DirectPairingContext(callback);
1173 auto cLock = m_csdkLock.lock();
1176 std::lock_guard<std::recursive_mutex> lock(*cLock);
1177 result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
1178 pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
1183 result = OC_STACK_ERROR;