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>
30 #include "oickeepalive.h"
33 #define TAG "OIC_CLIENT_WRAPPER"
39 InProcClientWrapper::InProcClientWrapper(
40 std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
41 : m_threadRun(false), m_csdkLock(csdkLock),
44 // if the config type is server, we ought to never get called. If the config type
45 // is both, we count on the server to run the thread and do the initialize
49 InProcClientWrapper::~InProcClientWrapper()
55 catch (InitializeException &e)
57 oclog() << "Exception in stop"<< e.what() << std::flush;
61 OCStackResult InProcClientWrapper::start()
63 OIC_LOG_V(INFO, TAG, "start ocplatform for client : %d", m_cfg.transportType);
65 if (m_cfg.mode == ModeType::Client)
67 OCTransportFlags serverFlags =
68 static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
69 OCTransportFlags clientFlags =
70 static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
71 OCStackResult result = OCInit2(OC_CLIENT, serverFlags, clientFlags,
74 if (OC_STACK_OK != result)
76 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
79 if (false == m_threadRun)
82 #ifdef WITH_PROCESS_EVENT
83 m_processEvent = oc_event_new();
86 OIC_LOG(INFO, TAG, "oc_event_new failed!");
87 return OC_STACK_ERROR;
89 OCRegisterProcessEvent(m_processEvent);
91 m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
97 OCStackResult InProcClientWrapper::stop()
99 OIC_LOG(INFO, TAG, "stop ocplatform");
101 if (m_threadRun && m_listeningThread.joinable())
104 #ifdef WITH_PROCESS_EVENT
107 oc_event_signal(m_processEvent);
110 m_listeningThread.join();
113 #ifdef WITH_PROCESS_EVENT
116 oc_event_free(m_processEvent);
117 m_processEvent = NULL;
121 // only stop if we are the ones who actually called 'start'. We are counting
122 // on the server to do the stop.
123 if (m_cfg.mode == ModeType::Client)
125 OCStackResult result = OCStop();
127 if (OC_STACK_OK != result)
129 throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
135 void InProcClientWrapper::listeningFunc()
139 OCStackResult result;
140 #ifdef WITH_PROCESS_EVENT
141 uint32_t nextEventTime;
143 auto cLock = m_csdkLock.lock();
146 std::lock_guard<std::recursive_mutex> lock(*cLock);
147 #ifdef WITH_PROCESS_EVENT
148 result = OCProcessEvent(&nextEventTime);
150 result = OCProcess();
155 result = OC_STACK_ERROR;
158 if (result != OC_STACK_OK)
160 // TODO: do something with result if failed?
163 #ifdef WITH_PROCESS_EVENT
164 oc_event_wait_for(m_processEvent, nextEventTime);
166 // To minimize CPU utilization we may wish to do this with sleep
167 std::this_thread::sleep_for(std::chrono::milliseconds(10));
172 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
174 if (clientResponse->payload == nullptr ||
176 clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
180 return OCRepresentation();
184 oc.setPayload(clientResponse->payload);
186 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
187 if (it == oc.representations().end())
189 return OCRepresentation();
192 // first one is considered the root, everything else is considered a child of this one.
193 OCRepresentation root = *it;
194 root.setDevAddr(clientResponse->devAddr);
195 root.setUri(clientResponse->resourceUri);
198 std::for_each(it, oc.representations().end(),
199 [&root](const OCRepresentation& repItr)
200 {root.addChild(repItr);});
204 OCStackApplicationResult listenCallback(void* ctx, OCDoHandle /*handle*/,
205 OCClientResponse* clientResponse)
207 if (!ctx || !clientResponse)
209 return OC_STACK_KEEP_TRANSACTION;
212 ClientCallbackContext::ListenContext* context =
213 static_cast<ClientCallbackContext::ListenContext*>(ctx);
215 if (clientResponse->result != OC_STACK_OK)
217 oclog() << "listenCallback(): failed to create resource. clientResponse: "
218 << clientResponse->result
221 return OC_STACK_KEEP_TRANSACTION;
224 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
226 oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
228 return OC_STACK_KEEP_TRANSACTION;
231 auto clientWrapper = context->clientWrapper.lock();
235 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
237 return OC_STACK_KEEP_TRANSACTION;
242 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
243 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
244 // loop to ensure valid construction of all resources
246 for(auto resource : container.Resources())
248 std::thread exec(context->callback, resource);
252 catch (std::exception &e)
254 oclog() << "Exception in listCallback, ignoring response: "
255 << e.what() << std::flush;
259 return OC_STACK_KEEP_TRANSACTION;
262 OCStackApplicationResult listenErrorCallback(void* ctx, OCDoHandle /*handle*/,
263 OCClientResponse* clientResponse)
265 if (!ctx || !clientResponse)
267 return OC_STACK_KEEP_TRANSACTION;
270 ClientCallbackContext::ListenErrorContext* context =
271 static_cast<ClientCallbackContext::ListenErrorContext*>(ctx);
273 OCStackResult result = clientResponse->result;
274 if (result == OC_STACK_OK)
276 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
278 OIC_LOG_V(DEBUG, TAG, "%s: clientResponse payload was null or the wrong type",
280 return OC_STACK_KEEP_TRANSACTION;
283 auto clientWrapper = context->clientWrapper.lock();
287 OIC_LOG_V(DEBUG, TAG, "%s: failed to get a shared_ptr to the client wrapper",
289 return OC_STACK_KEEP_TRANSACTION;
292 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
293 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
294 // loop to ensure valid construction of all resources
295 for (auto resource : container.Resources())
297 std::thread exec(context->callback, resource);
300 return OC_STACK_KEEP_TRANSACTION;
303 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
304 std::string resourceURI;
305 if(NULL != clientResponse->resourceUri)
307 resourceURI = clientResponse->resourceUri;
310 std::thread exec(context->errorCallback, resourceURI, result);
312 return OC_STACK_KEEP_TRANSACTION;
315 OCStackResult InProcClientWrapper::ListenForResource(
316 const std::string& serviceUrl,
317 const std::string& resourceType,
318 OCConnectivityType connectivityType,
319 FindCallback& callback, QualityOfService QoS)
323 return OC_STACK_INVALID_PARAM;
326 OCStackResult result;
327 ostringstream resourceUri;
328 resourceUri << serviceUrl << resourceType;
330 ClientCallbackContext::ListenContext* context =
331 new ClientCallbackContext::ListenContext(callback, shared_from_this());
332 OCCallbackData cbdata;
333 cbdata.context = static_cast<void*>(context),
334 cbdata.cb = listenCallback;
335 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;};
337 auto cLock = m_csdkLock.lock();
340 std::lock_guard<std::recursive_mutex> lock(*cLock);
341 result = OCDoResource(nullptr, OC_REST_DISCOVER,
342 resourceUri.str().c_str(),
343 nullptr, nullptr, connectivityType,
344 static_cast<OCQualityOfService>(QoS),
351 result = OC_STACK_ERROR;
356 OCStackResult InProcClientWrapper::ListenErrorForResource(
357 const std::string& serviceUrl,
358 const std::string& resourceType,
359 OCConnectivityType connectivityType,
360 FindCallback& callback, FindErrorCallback& errorCallback,
361 QualityOfService QoS)
365 return OC_STACK_INVALID_PARAM;
368 ostringstream resourceUri;
369 resourceUri << serviceUrl << resourceType;
371 ClientCallbackContext::ListenErrorContext* context =
372 new ClientCallbackContext::ListenErrorContext(callback, errorCallback,
376 return OC_STACK_ERROR;
379 OCCallbackData cbdata(
380 static_cast<void*>(context),
382 [](void* c){delete static_cast<ClientCallbackContext::ListenErrorContext*>(c);}
385 OCStackResult result;
386 auto cLock = m_csdkLock.lock();
389 std::lock_guard<std::recursive_mutex> lock(*cLock);
390 result = OCDoResource(nullptr, OC_REST_DISCOVER,
391 resourceUri.str().c_str(),
392 nullptr, nullptr, connectivityType,
393 static_cast<OCQualityOfService>(QoS),
400 result = OC_STACK_ERROR;
405 OCStackApplicationResult listenResListCallback(void* ctx, OCDoHandle /*handle*/,
406 OCClientResponse* clientResponse)
408 if (!ctx || !clientResponse)
410 return OC_STACK_KEEP_TRANSACTION;
413 ClientCallbackContext::ListenResListContext* context =
414 static_cast<ClientCallbackContext::ListenResListContext*>(ctx);
416 if (clientResponse->result != OC_STACK_OK)
418 oclog() << "listenResListCallback(): failed to create resource. clientResponse: "
419 << clientResponse->result
422 return OC_STACK_KEEP_TRANSACTION;
425 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
427 oclog() << "listenResListCallback(): clientResponse payload was null or the wrong type"
429 return OC_STACK_KEEP_TRANSACTION;
432 auto clientWrapper = context->clientWrapper.lock();
436 oclog() << "listenResListCallback(): failed to get a shared_ptr to the client wrapper"
438 return OC_STACK_KEEP_TRANSACTION;
443 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
444 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
446 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
447 std::thread exec(context->callback, container.Resources());
450 catch (std::exception &e)
452 oclog() << "Exception in listenResListCallback(), ignoring response: "
453 << e.what() << std::flush;
456 return OC_STACK_KEEP_TRANSACTION;
459 OCStackResult InProcClientWrapper::ListenForResourceList(
460 const std::string& serviceUrl,
461 const std::string& resourceType,
462 OCConnectivityType connectivityType,
463 FindResListCallback& callback, QualityOfService QoS)
467 return OC_STACK_INVALID_PARAM;
470 OCStackResult result;
471 ostringstream resourceUri;
472 resourceUri << serviceUrl << resourceType;
474 ClientCallbackContext::ListenResListContext* context =
475 new ClientCallbackContext::ListenResListContext(callback, shared_from_this());
476 OCCallbackData cbdata;
477 cbdata.context = static_cast<void*>(context),
478 cbdata.cb = listenResListCallback;
479 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListContext*)c;};
481 auto cLock = m_csdkLock.lock();
484 std::lock_guard<std::recursive_mutex> lock(*cLock);
485 result = OCDoResource(nullptr, OC_REST_DISCOVER,
486 resourceUri.str().c_str(),
487 nullptr, nullptr, connectivityType,
488 static_cast<OCQualityOfService>(QoS),
495 result = OC_STACK_ERROR;
500 OCStackApplicationResult listenResListWithErrorCallback(void* ctx, OCDoHandle /*handle*/,
501 OCClientResponse* clientResponse)
503 if (!ctx || !clientResponse)
505 return OC_STACK_KEEP_TRANSACTION;
508 ClientCallbackContext::ListenResListWithErrorContext* context =
509 static_cast<ClientCallbackContext::ListenResListWithErrorContext*>(ctx);
511 OCStackResult result = clientResponse->result;
512 if (result != OC_STACK_OK)
514 oclog() << "listenResListWithErrorCallback(): failed to create resource. clientResponse: "
515 << result << std::flush;
517 //send the error callback
519 if(NULL != clientResponse->resourceUri)
521 uri = clientResponse->resourceUri;
523 std::thread exec(context->errorCallback, uri, result);
525 return OC_STACK_KEEP_TRANSACTION;
528 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
530 oclog() << "listenResListWithErrorCallback(): clientResponse payload was null or the wrong type"
532 return OC_STACK_KEEP_TRANSACTION;
535 auto clientWrapper = context->clientWrapper.lock();
539 oclog() << "listenResListWithErrorCallback(): failed to get a shared_ptr to the client wrapper"
541 return OC_STACK_KEEP_TRANSACTION;
546 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
547 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
549 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
550 std::thread exec(context->callback, container.Resources());
553 catch (std::exception &e)
555 oclog() << "Exception in listenResListWithErrorCallback(), ignoring response: "
556 << e.what() << std::flush;
559 return OC_STACK_KEEP_TRANSACTION;
562 OCStackResult InProcClientWrapper::ListenForResourceListWithError(
563 const std::string& serviceUrl,
564 const std::string& resourceType,
565 OCConnectivityType connectivityType,
566 FindResListCallback& callback,
567 FindErrorCallback& errorCallback, QualityOfService QoS)
571 return OC_STACK_INVALID_PARAM;
574 OCStackResult result;
575 ostringstream resourceUri;
576 resourceUri << serviceUrl << resourceType;
578 ClientCallbackContext::ListenResListWithErrorContext* context =
579 new ClientCallbackContext::ListenResListWithErrorContext(callback, errorCallback,
583 return OC_STACK_ERROR;
586 OCCallbackData cbdata;
587 cbdata.context = static_cast<void*>(context),
588 cbdata.cb = listenResListWithErrorCallback;
589 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListWithErrorContext*)c;};
591 auto cLock = m_csdkLock.lock();
594 std::lock_guard<std::recursive_mutex> lock(*cLock);
595 result = OCDoResource(nullptr, OC_REST_DISCOVER,
596 resourceUri.str().c_str(),
597 nullptr, nullptr, connectivityType,
598 static_cast<OCQualityOfService>(QoS),
605 result = OC_STACK_ERROR;
611 OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/,
612 OCClientResponse* clientResponse)
614 ClientCallbackContext::MQTopicContext* context =
615 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
617 if (!clientResponse || !context)
619 return OC_STACK_DELETE_TRANSACTION;
622 std::string resourceURI;
623 if(NULL != clientResponse->resourceUri)
625 resourceURI = clientResponse->resourceUri;
628 if (clientResponse->result != OC_STACK_OK)
630 oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
631 << clientResponse->result
634 std::thread exec(context->callback, clientResponse->result,
635 resourceURI, nullptr);
638 return OC_STACK_DELETE_TRANSACTION;
641 auto clientWrapper = context->clientWrapper.lock();
644 oclog() << "listenMQCallback(): failed to get a shared_ptr to the client wrapper"
646 return OC_STACK_DELETE_TRANSACTION;
651 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
652 (OCRepPayload *) clientResponse->payload);
654 // loop to ensure valid construction of all resources
655 for (auto resource : container.Resources())
657 std::thread exec(context->callback, clientResponse->result,
658 resourceURI, resource);
662 catch (std::exception &e)
664 oclog() << "Exception in listCallback, ignoring response: "
665 << e.what() << std::flush;
668 return OC_STACK_DELETE_TRANSACTION;
671 OCStackResult InProcClientWrapper::ListenForMQTopic(const OCDevAddr& devAddr,
672 const std::string& resourceUri,
673 const QueryParamsMap& queryParams,
674 const HeaderOptions& headerOptions,
675 MQTopicCallback& callback,
676 QualityOfService QoS)
678 oclog() << "ListenForMQTopic()" << std::flush;
682 return OC_STACK_INVALID_PARAM;
685 if (headerOptions.size() > MAX_HEADER_OPTIONS)
687 oclog() << "ListenForMQTopic: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
688 return OC_STACK_INVALID_PARAM;
691 ClientCallbackContext::MQTopicContext* context =
692 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
693 OCCallbackData cbdata;
694 cbdata.context = static_cast<void*>(context),
695 cbdata.cb = listenMQCallback;
696 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
698 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
700 OCStackResult result = OC_STACK_ERROR;
701 auto cLock = m_csdkLock.lock();
704 std::lock_guard<std::recursive_mutex> lock(*cLock);
705 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
706 result = OCDoResource(
707 nullptr, OC_REST_GET,
711 static_cast<OCQualityOfService>(QoS),
714 headerOptions.size());
726 OCStackApplicationResult listenDeviceCallback(void* ctx,
727 OCDoHandle /*handle*/,
728 OCClientResponse* clientResponse)
730 ClientCallbackContext::DeviceListenContext* context =
731 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
735 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
736 OCRepresentation rep = parseGetSetCallback(clientResponse);
737 std::thread exec(context->callback, rep);
740 catch(OC::OCException& e)
742 oclog() <<"Exception in listenDeviceCallback, ignoring response: "
743 <<e.what() <<std::flush;
746 return OC_STACK_KEEP_TRANSACTION;
749 OCStackResult InProcClientWrapper::ListenForDevice(
750 const std::string& serviceUrl,
751 const std::string& deviceURI,
752 OCConnectivityType connectivityType,
753 FindDeviceCallback& callback,
754 QualityOfService QoS)
758 return OC_STACK_INVALID_PARAM;
760 OCStackResult result;
761 ostringstream deviceUri;
762 deviceUri << serviceUrl << deviceURI;
764 ClientCallbackContext::DeviceListenContext* context =
765 new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
766 OCCallbackData cbdata;
768 cbdata.context = static_cast<void*>(context),
769 cbdata.cb = listenDeviceCallback;
770 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeviceListenContext*)c;};
772 auto cLock = m_csdkLock.lock();
775 std::lock_guard<std::recursive_mutex> lock(*cLock);
776 result = OCDoResource(nullptr, OC_REST_DISCOVER,
777 deviceUri.str().c_str(),
778 nullptr, nullptr, connectivityType,
779 static_cast<OCQualityOfService>(QoS),
786 result = OC_STACK_ERROR;
791 void parseServerHeaderOptions(OCClientResponse* clientResponse,
792 HeaderOptions& serverHeaderOptions)
796 // Parse header options from server
798 std::string optionData;
800 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
802 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
803 optionData = reinterpret_cast<const char*>
804 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
805 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
806 serverHeaderOptions.push_back(headerOption);
811 // clientResponse is invalid
812 // TODO check proper logging
813 std::cout << " Invalid response " << std::endl;
818 OCStackApplicationResult createMQTopicCallback(void* ctx, OCDoHandle /*handle*/,
819 OCClientResponse* clientResponse)
821 ClientCallbackContext::MQTopicContext* context =
822 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
823 HeaderOptions serverHeaderOptions;
825 if (!clientResponse || !context)
827 return OC_STACK_DELETE_TRANSACTION;
830 std::string createdUri;
831 bool isLocationOption = false;
832 OCStackResult result = clientResponse->result;
833 if (OC_STACK_OK == result ||
834 OC_STACK_RESOURCE_CREATED == result)
836 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
838 for (auto headerOption : serverHeaderOptions)
840 if (HeaderOption::LOCATION_PATH_OPTION_ID == headerOption.getOptionID())
843 createdUri += headerOption.getOptionData();
844 if (!isLocationOption)
846 isLocationOption = true;
852 if (!isLocationOption && NULL != clientResponse->resourceUri)
854 createdUri = std::string(clientResponse->resourceUri);
857 auto clientWrapper = context->clientWrapper.lock();
861 oclog() << "createMQTopicCallback(): failed to get a shared_ptr to the client wrapper"
863 return OC_STACK_DELETE_TRANSACTION;
868 if (OC_STACK_OK == result ||
869 OC_STACK_RESOURCE_CREATED == result)
871 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
873 for (auto resource : container.Resources())
875 std::thread exec(context->callback, result,
883 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
884 std::thread exec(context->callback, result,
890 catch (std::exception &e)
892 oclog() << "Exception in createMQTopicCallback, ignoring response: "
893 << e.what() << std::flush;
895 return OC_STACK_DELETE_TRANSACTION;
898 OCStackResult InProcClientWrapper::PutMQTopicRepresentation(
899 const OCDevAddr& devAddr,
900 const std::string& uri,
901 const OCRepresentation& rep,
902 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
903 MQTopicCallback& callback, QualityOfService QoS)
907 return OC_STACK_INVALID_PARAM;
910 if (headerOptions.size() > MAX_HEADER_OPTIONS)
912 oclog() << "PutMQTopicRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
913 return OC_STACK_INVALID_PARAM;
916 OCStackResult result;
917 ClientCallbackContext::MQTopicContext* ctx =
918 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
919 OCCallbackData cbdata;
920 cbdata.context = static_cast<void*>(ctx),
921 cbdata.cb = createMQTopicCallback;
922 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
924 std::string url = assembleSetResourceUri(uri, queryParams);
926 auto cLock = m_csdkLock.lock();
930 std::lock_guard<std::recursive_mutex> lock(*cLock);
931 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
933 result = OCDoResource(nullptr, OC_REST_PUT,
934 url.c_str(), &devAddr,
935 assembleSetResourcePayload(rep),
937 static_cast<OCQualityOfService>(QoS),
940 headerOptions.size());
946 result = OC_STACK_ERROR;
952 OCStackApplicationResult getResourceCallback(void* ctx,
953 OCDoHandle /*handle*/,
954 OCClientResponse* clientResponse)
956 ClientCallbackContext::GetContext* context =
957 static_cast<ClientCallbackContext::GetContext*>(ctx);
958 OCRepresentation rep;
959 HeaderOptions serverHeaderOptions;
960 OCStackResult result = clientResponse->result;
962 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
965 rep = parseGetSetCallback(clientResponse);
967 catch(OC::OCException& e)
972 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
973 std::thread exec(context->callback, serverHeaderOptions, rep, result);
975 return OC_STACK_DELETE_TRANSACTION;
978 OCStackResult InProcClientWrapper::GetResourceRepresentation(
979 const OCDevAddr& devAddr,
980 const std::string& resourceUri,
981 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
982 OCConnectivityType connectivityType,
983 GetCallback& callback, QualityOfService QoS)
987 return OC_STACK_INVALID_PARAM;
990 if (headerOptions.size() > MAX_HEADER_OPTIONS)
992 oclog() << "GetResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
993 return OC_STACK_INVALID_PARAM;
996 OCStackResult result;
997 ClientCallbackContext::GetContext* ctx =
998 new ClientCallbackContext::GetContext(callback);
1000 OCCallbackData cbdata;
1001 cbdata.context = static_cast<void*>(ctx);
1002 cbdata.cb = getResourceCallback;
1003 cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
1005 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
1007 auto cLock = m_csdkLock.lock();
1011 std::lock_guard<std::recursive_mutex> lock(*cLock);
1012 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1014 result = OCDoResource(
1015 nullptr, OC_REST_GET,
1019 static_cast<OCQualityOfService>(QoS),
1022 headerOptions.size());
1028 result = OC_STACK_ERROR;
1034 OCStackApplicationResult setResourceCallback(void* ctx,
1035 OCDoHandle /*handle*/,
1036 OCClientResponse* clientResponse)
1038 ClientCallbackContext::SetContext* context =
1039 static_cast<ClientCallbackContext::SetContext*>(ctx);
1040 OCRepresentation attrs;
1041 HeaderOptions serverHeaderOptions;
1043 OCStackResult result = clientResponse->result;
1045 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1048 attrs = parseGetSetCallback(clientResponse);
1050 catch(OC::OCException& e)
1055 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1056 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
1058 return OC_STACK_DELETE_TRANSACTION;
1061 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1062 const QueryParamsMap& queryParams)
1066 if (uri.back() == '/')
1068 uri.resize(uri.size() - 1);
1072 ostringstream paramsList;
1073 if (queryParams.size() > 0)
1078 for (auto& param : queryParams)
1080 paramsList << param.first <<'='<<param.second<<';';
1083 std::string queryString = paramsList.str();
1085 if (queryString.empty())
1090 if (queryString.back() == ';')
1092 queryString.resize(queryString.size() - 1);
1095 std::string ret = uri + queryString;
1099 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1100 const QueryParamsList& queryParams)
1104 if (uri.back() == '/')
1106 uri.resize(uri.size() - 1);
1110 ostringstream paramsList;
1111 if (queryParams.size() > 0)
1116 for (auto& param : queryParams)
1118 for (auto& paramList : param.second)
1120 paramsList << param.first << '=' << paramList << ';';
1124 std::string queryString = paramsList.str();
1126 if (queryString.empty())
1131 if (queryString.back() == ';')
1133 queryString.resize(queryString.size() - 1);
1136 std::string ret = uri + queryString;
1140 OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
1142 MessageContainer ocInfo;
1143 ocInfo.addRepresentation(rep);
1144 for(const OCRepresentation& r : rep.getChildren())
1146 ocInfo.addRepresentation(r);
1149 return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
1152 OCStackResult InProcClientWrapper::PostResourceRepresentation(
1153 const OCDevAddr& devAddr,
1154 const std::string& uri,
1155 const OCRepresentation& rep,
1156 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1157 OCConnectivityType connectivityType,
1158 PostCallback& callback, QualityOfService QoS)
1162 return OC_STACK_INVALID_PARAM;
1165 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1167 oclog() << "PostResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1168 return OC_STACK_INVALID_PARAM;
1171 OCStackResult result;
1172 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1173 OCCallbackData cbdata;
1174 cbdata.context = static_cast<void*>(ctx),
1175 cbdata.cb = setResourceCallback;
1176 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1179 std::string url = assembleSetResourceUri(uri, queryParams);
1181 auto cLock = m_csdkLock.lock();
1185 std::lock_guard<std::recursive_mutex> lock(*cLock);
1186 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1188 result = OCDoResource(nullptr, OC_REST_POST,
1189 url.c_str(), &devAddr,
1190 assembleSetResourcePayload(rep),
1192 static_cast<OCQualityOfService>(QoS),
1195 headerOptions.size());
1201 result = OC_STACK_ERROR;
1207 OCStackResult InProcClientWrapper::PutResourceRepresentation(
1208 const OCDevAddr& devAddr,
1209 const std::string& uri,
1210 const OCRepresentation& rep,
1211 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1212 PutCallback& callback, QualityOfService QoS)
1216 return OC_STACK_INVALID_PARAM;
1219 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1221 oclog() << "PutResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1222 return OC_STACK_INVALID_PARAM;
1225 OCStackResult result;
1226 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1227 OCCallbackData cbdata;
1228 cbdata.context = static_cast<void*>(ctx),
1229 cbdata.cb = setResourceCallback;
1230 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1233 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1235 auto cLock = m_csdkLock.lock();
1239 std::lock_guard<std::recursive_mutex> lock(*cLock);
1241 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1243 result = OCDoResource(&handle, OC_REST_PUT,
1244 url.c_str(), &devAddr,
1245 assembleSetResourcePayload(rep),
1247 static_cast<OCQualityOfService>(QoS),
1250 headerOptions.size());
1256 result = OC_STACK_ERROR;
1262 OCStackApplicationResult deleteResourceCallback(void* ctx,
1263 OCDoHandle /*handle*/,
1264 OCClientResponse* clientResponse)
1266 ClientCallbackContext::DeleteContext* context =
1267 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
1268 HeaderOptions serverHeaderOptions;
1270 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1272 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1273 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
1275 return OC_STACK_DELETE_TRANSACTION;
1278 OCStackResult InProcClientWrapper::DeleteResource(
1279 const OCDevAddr& devAddr,
1280 const std::string& uri,
1281 const HeaderOptions& headerOptions,
1282 OCConnectivityType connectivityType,
1283 DeleteCallback& callback,
1284 QualityOfService /*QoS*/)
1288 return OC_STACK_INVALID_PARAM;
1291 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1293 oclog() << "DeleteResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1294 return OC_STACK_INVALID_PARAM;
1297 OCStackResult result;
1298 ClientCallbackContext::DeleteContext* ctx =
1299 new ClientCallbackContext::DeleteContext(callback);
1300 OCCallbackData cbdata;
1301 cbdata.context = static_cast<void*>(ctx),
1302 cbdata.cb = deleteResourceCallback;
1303 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;};
1306 auto cLock = m_csdkLock.lock();
1310 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1312 std::lock_guard<std::recursive_mutex> lock(*cLock);
1314 result = OCDoResource(nullptr, OC_REST_DELETE,
1315 uri.c_str(), &devAddr,
1318 static_cast<OCQualityOfService>(m_cfg.QoS),
1321 headerOptions.size());
1327 result = OC_STACK_ERROR;
1333 OCStackApplicationResult observeResourceCallback(void* ctx,
1334 OCDoHandle /*handle*/,
1335 OCClientResponse* clientResponse)
1337 ClientCallbackContext::ObserveContext* context =
1338 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
1339 OCRepresentation attrs;
1340 HeaderOptions serverHeaderOptions;
1341 uint32_t sequenceNumber = clientResponse->sequenceNumber;
1342 OCStackResult result = clientResponse->result;
1344 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1347 attrs = parseGetSetCallback(clientResponse);
1349 catch(OC::OCException& e)
1354 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1355 std::thread exec(context->callback, serverHeaderOptions, attrs,
1356 result, sequenceNumber);
1358 if (sequenceNumber == MAX_SEQUENCE_NUMBER + 1)
1360 return OC_STACK_DELETE_TRANSACTION;
1363 return OC_STACK_KEEP_TRANSACTION;
1366 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
1367 const OCDevAddr& devAddr,
1368 const std::string& uri,
1369 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1370 ObserveCallback& callback, QualityOfService QoS)
1374 return OC_STACK_INVALID_PARAM;
1377 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1379 oclog() << "ObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1380 return OC_STACK_INVALID_PARAM;
1383 OCStackResult result;
1385 ClientCallbackContext::ObserveContext* ctx =
1386 new ClientCallbackContext::ObserveContext(callback);
1387 OCCallbackData cbdata;
1388 cbdata.context = static_cast<void*>(ctx),
1389 cbdata.cb = observeResourceCallback;
1390 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1394 if (observeType == ObserveType::Observe)
1396 method = OC_REST_OBSERVE;
1398 else if (observeType == ObserveType::ObserveAll)
1400 method = OC_REST_OBSERVE_ALL;
1404 method = OC_REST_OBSERVE_ALL;
1407 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1409 auto cLock = m_csdkLock.lock();
1413 std::lock_guard<std::recursive_mutex> lock(*cLock);
1414 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1416 result = OCDoResource(handle, method,
1417 url.c_str(), &devAddr,
1420 static_cast<OCQualityOfService>(QoS),
1423 headerOptions.size());
1429 return OC_STACK_ERROR;
1435 OCStackResult InProcClientWrapper::CancelObserveResource(
1437 const std::string& /*host*/,
1438 const std::string& /*uri*/,
1439 const HeaderOptions& headerOptions,
1440 QualityOfService QoS)
1442 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1444 oclog() << "CancelObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1445 return OC_STACK_INVALID_PARAM;
1448 OCStackResult result;
1449 auto cLock = m_csdkLock.lock();
1453 std::lock_guard<std::recursive_mutex> lock(*cLock);
1454 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1456 result = OCCancel(handle,
1457 static_cast<OCQualityOfService>(QoS),
1459 headerOptions.size());
1464 result = OC_STACK_ERROR;
1470 #ifdef WITH_PRESENCE
1471 OCStackApplicationResult subscribePresenceCallback(void* ctx,
1472 OCDoHandle /*handle*/,
1473 OCClientResponse* clientResponse)
1475 ClientCallbackContext::SubscribePresenceContext* context =
1476 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
1479 * This a hack while we rethink presence subscription.
1481 std::string url = clientResponse->devAddr.addr;
1483 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1484 std::thread exec(context->callback, clientResponse->result,
1485 clientResponse->sequenceNumber, url);
1489 return OC_STACK_KEEP_TRANSACTION;
1493 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
1494 const std::string& host, const std::string& resourceType,
1495 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
1497 #ifdef WITH_PRESENCE
1498 if (!presenceHandler)
1500 return OC_STACK_INVALID_PARAM;
1503 ClientCallbackContext::SubscribePresenceContext* ctx =
1504 new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
1505 OCCallbackData cbdata;
1506 cbdata.context = static_cast<void*>(ctx),
1507 cbdata.cb = subscribePresenceCallback;
1508 cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;};
1511 auto cLock = m_csdkLock.lock();
1513 std::ostringstream os;
1514 os << host << OC_RSRVD_PRESENCE_URI;
1516 if (!resourceType.empty())
1518 os << "?rt=" << resourceType;
1524 return OC_STACK_ERROR;
1527 return OCDoResource(handle, OC_REST_PRESENCE,
1528 os.str().c_str(), nullptr,
1529 nullptr, connectivityType,
1530 OC_LOW_QOS, &cbdata, NULL, 0);
1532 return OC_STACK_NOT_IMPLEMENTED;
1536 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
1538 #ifdef WITH_PRESENCE
1539 OCStackResult result;
1540 auto cLock = m_csdkLock.lock();
1544 std::lock_guard<std::recursive_mutex> lock(*cLock);
1545 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1549 result = OC_STACK_ERROR;
1554 return OC_STACK_NOT_IMPLEMENTED;
1559 OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
1560 const std::string& host,
1561 const std::vector<std::string>& di,
1562 OCConnectivityType connectivityType,
1563 ObserveCallback& callback)
1567 return OC_STACK_INVALID_PARAM;
1569 OCStackResult result;
1571 ClientCallbackContext::ObserveContext* ctx =
1572 new ClientCallbackContext::ObserveContext(callback);
1573 OCCallbackData cbdata;
1574 cbdata.context = static_cast<void*>(ctx),
1575 cbdata.cb = observeResourceCallback;
1576 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1578 auto cLock = m_csdkLock.lock();
1582 std::lock_guard<std::recursive_mutex> lock(*cLock);
1584 std::ostringstream os;
1585 os << host << OC_RSRVD_DEVICE_PRESENCE_URI;
1586 QueryParamsList queryParams({{OC_RSRVD_DEVICE_ID, di}});
1587 std::string url = assembleSetResourceUri(os.str(), queryParams);
1589 result = OCDoResource(handle, OC_REST_OBSERVE,
1590 url.c_str(), nullptr,
1591 nullptr, connectivityType,
1592 OC_LOW_QOS, &cbdata,
1598 result = OC_STACK_ERROR;
1605 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
1611 OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(const HeaderOptions& headerOptions)
1613 if ( headerOptions.size() == 0)
1618 OCHeaderOption* options = new OCHeaderOption[headerOptions.size()]();
1620 size_t numOptions = 0;
1621 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
1623 OCStackResult ret = OCSetHeaderOption(options, &numOptions, it->getOptionID(),
1624 it->getOptionData().c_str(), it->getOptionData().length());
1625 if (OC_STACK_OK != ret)
1627 OIC_LOG_V(ERROR, TAG, "Failed to convert vnd header options! (error=%d)", ret);
1636 std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
1643 OCDPDev_t* result = new OCDPDev_t(*dev);
1644 result->prm = new OCPrm_t[dev->prmLen];
1645 memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
1646 return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
1649 void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
1653 dpList.push_back(cloneDevice(list));
1658 OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
1659 GetDirectPairedCallback& callback)
1661 if (!callback || 0 == waittime)
1663 return OC_STACK_INVALID_PARAM;
1666 OCStackResult result = OC_STACK_ERROR;
1667 const OCDPDev_t *list = nullptr;
1668 PairedDevices dpDeviceList;
1670 auto cLock = m_csdkLock.lock();
1674 std::lock_guard<std::recursive_mutex> lock(*cLock);
1676 list = OCDiscoverDirectPairingDevices(waittime);
1679 result = OC_STACK_NO_RESOURCE;
1680 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1684 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1685 convert(list, dpDeviceList);
1686 std::thread exec(callback, dpDeviceList);
1688 result = OC_STACK_OK;
1693 result = OC_STACK_ERROR;
1699 OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
1703 return OC_STACK_INVALID_PARAM;
1706 OCStackResult result = OC_STACK_ERROR;
1707 const OCDPDev_t *list = nullptr;
1708 PairedDevices dpDeviceList;
1710 auto cLock = m_csdkLock.lock();
1714 std::lock_guard<std::recursive_mutex> lock(*cLock);
1716 list = OCGetDirectPairedDevices();
1719 result = OC_STACK_NO_RESOURCE;
1720 OIC_LOG_V(DEBUG, TAG, "%s: No device found for direct pairing", __func__);
1723 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1724 convert(list, dpDeviceList);
1725 std::thread exec(callback, dpDeviceList);
1727 result = OC_STACK_OK;
1732 result = OC_STACK_ERROR;
1738 void directPairingCallback(void *ctx, OCDPDev_t *peer,
1739 OCStackResult result)
1742 ClientCallbackContext::DirectPairingContext* context =
1743 static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
1745 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1746 std::thread exec(context->callback, cloneDevice(peer), result);
1750 OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
1751 const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
1753 if (!peer || !callback)
1755 oclog() << "Invalid parameters" << std::flush;
1756 return OC_STACK_INVALID_PARAM;
1759 OCStackResult result = OC_STACK_ERROR;
1760 ClientCallbackContext::DirectPairingContext* context =
1761 new ClientCallbackContext::DirectPairingContext(callback);
1763 auto cLock = m_csdkLock.lock();
1766 std::lock_guard<std::recursive_mutex> lock(*cLock);
1767 result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
1768 pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
1773 result = OC_STACK_ERROR;
1778 OCStackApplicationResult KeepAliveRespCallback(void* ctx,
1779 OCDoHandle /*handle*/,
1780 OCClientResponse* clientResponse)
1782 ClientCallbackContext::KeepAliveContext* context =
1783 static_cast<ClientCallbackContext::KeepAliveContext*>(ctx);
1784 OCRepresentation attrs;
1785 OCStackResult result = clientResponse->result;
1789 attrs = parseGetSetCallback(clientResponse);
1791 catch(OC::OCException& e)
1796 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1797 std::thread exec(context->callback, result, attrs);
1799 return OC_STACK_DELETE_TRANSACTION;
1802 OCStackResult InProcClientWrapper::findKeepAliveResource(std::string host,
1803 KeepAliveCallback resultCallback)
1805 if (host.empty() || !resultCallback)
1807 oclog() << "Invalid parameters" << std::flush;
1808 return OC_STACK_INVALID_PARAM;
1811 OCStackResult result = OC_STACK_ERROR;
1813 ClientCallbackContext::KeepAliveContext* ctx =
1814 new ClientCallbackContext::KeepAliveContext(resultCallback);
1815 OCCallbackData cbdata;
1816 cbdata.context = static_cast<void*>(ctx),
1817 cbdata.cb = KeepAliveRespCallback;
1818 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1820 auto cLock = m_csdkLock.lock();
1824 std::lock_guard<std::recursive_mutex> lock(*cLock);
1825 result = OCFindKeepAliveResource(nullptr, host.c_str(), &cbdata);
1830 result = OC_STACK_ERROR;
1835 OCStackResult InProcClientWrapper::sendKeepAliveRequest(std::string host,
1836 const OCRepresentation& rep,
1837 KeepAliveCallback resultCallback)
1839 if (!resultCallback)
1841 oclog() << "Invalid parameters" << std::flush;
1842 return OC_STACK_INVALID_PARAM;
1845 OCStackResult result = OC_STACK_ERROR;
1847 ClientCallbackContext::KeepAliveContext* ctx = new ClientCallbackContext::KeepAliveContext(resultCallback);
1848 OCCallbackData cbdata;
1849 cbdata.context = static_cast<void*>(ctx),
1850 cbdata.cb = KeepAliveRespCallback;
1851 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1853 auto cLock = m_csdkLock.lock();
1857 std::lock_guard<std::recursive_mutex> lock(*cLock);
1858 OCRepPayload *payload = rep.getPayload();
1859 result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
1864 result = OC_STACK_ERROR;