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 // only stop if we are the ones who actually called 'start'. We are counting
102 // on the server to do the stop.
103 if (m_cfg.mode == ModeType::Client)
105 if (m_threadRun && m_listeningThread.joinable())
108 #ifdef WITH_PROCESS_EVENT
111 oc_event_signal(m_processEvent);
114 m_listeningThread.join();
117 #ifdef WITH_PROCESS_EVENT
120 oc_event_free(m_processEvent);
121 m_processEvent = NULL;
124 OCStackResult result = OCStop();
126 if (OC_STACK_OK != result)
128 throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
134 void InProcClientWrapper::listeningFunc()
138 OCStackResult result;
139 #ifdef WITH_PROCESS_EVENT
140 uint32_t nextEventTime;
142 auto cLock = m_csdkLock.lock();
145 std::lock_guard<std::recursive_mutex> lock(*cLock);
146 #ifdef WITH_PROCESS_EVENT
147 result = OCProcessEvent(&nextEventTime);
149 result = OCProcess();
154 result = OC_STACK_ERROR;
157 if (result != OC_STACK_OK)
159 // TODO: do something with result if failed?
162 #ifdef WITH_PROCESS_EVENT
163 oc_event_wait_for(m_processEvent, nextEventTime);
165 // To minimize CPU utilization we may wish to do this with sleep
166 std::this_thread::sleep_for(std::chrono::milliseconds(10));
171 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
173 if (clientResponse->payload == nullptr ||
175 clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
179 return OCRepresentation();
183 oc.setPayload(clientResponse->payload);
185 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
186 if (it == oc.representations().end())
188 return OCRepresentation();
191 // first one is considered the root, everything else is considered a child of this one.
192 OCRepresentation root = *it;
193 root.setDevAddr(clientResponse->devAddr);
194 root.setUri(clientResponse->resourceUri);
197 std::for_each(it, oc.representations().end(),
198 [&root](const OCRepresentation& repItr)
199 {root.addChild(repItr);});
203 OCStackApplicationResult listenCallback(void* ctx, OCDoHandle /*handle*/,
204 OCClientResponse* clientResponse)
206 if (!ctx || !clientResponse)
208 return OC_STACK_KEEP_TRANSACTION;
211 ClientCallbackContext::ListenContext* context =
212 static_cast<ClientCallbackContext::ListenContext*>(ctx);
214 if (clientResponse->result != OC_STACK_OK)
216 oclog() << "listenCallback(): failed to create resource. clientResponse: "
217 << clientResponse->result
220 return OC_STACK_KEEP_TRANSACTION;
223 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
225 oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
227 return OC_STACK_KEEP_TRANSACTION;
230 auto clientWrapper = context->clientWrapper.lock();
234 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
236 return OC_STACK_KEEP_TRANSACTION;
241 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
242 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
243 // loop to ensure valid construction of all resources
245 for(auto resource : container.Resources())
247 std::thread exec(context->callback, resource);
251 catch (std::exception &e)
253 oclog() << "Exception in listCallback, ignoring response: "
254 << e.what() << std::flush;
258 return OC_STACK_KEEP_TRANSACTION;
261 OCStackApplicationResult listenErrorCallback(void* ctx, OCDoHandle /*handle*/,
262 OCClientResponse* clientResponse)
264 if (!ctx || !clientResponse)
266 return OC_STACK_KEEP_TRANSACTION;
269 ClientCallbackContext::ListenErrorContext* context =
270 static_cast<ClientCallbackContext::ListenErrorContext*>(ctx);
272 OCStackResult result = clientResponse->result;
273 if (result == OC_STACK_OK)
275 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
277 OIC_LOG_V(DEBUG, TAG, "%s: clientResponse payload was null or the wrong type",
279 return OC_STACK_KEEP_TRANSACTION;
282 auto clientWrapper = context->clientWrapper.lock();
286 OIC_LOG_V(DEBUG, TAG, "%s: failed to get a shared_ptr to the client wrapper",
288 return OC_STACK_KEEP_TRANSACTION;
291 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
292 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
293 // loop to ensure valid construction of all resources
294 for (auto resource : container.Resources())
296 std::thread exec(context->callback, resource);
299 return OC_STACK_KEEP_TRANSACTION;
302 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
303 std::string resourceURI;
304 if(NULL != clientResponse->resourceUri)
306 resourceURI = clientResponse->resourceUri;
309 std::thread exec(context->errorCallback, resourceURI, result);
311 return OC_STACK_KEEP_TRANSACTION;
314 OCStackResult InProcClientWrapper::ListenForResource(
315 const std::string& serviceUrl,
316 const std::string& resourceType,
317 OCConnectivityType connectivityType,
318 FindCallback& callback, QualityOfService QoS)
322 return OC_STACK_INVALID_PARAM;
325 OCStackResult result;
326 ostringstream resourceUri;
327 resourceUri << serviceUrl << resourceType;
329 ClientCallbackContext::ListenContext* context =
330 new ClientCallbackContext::ListenContext(callback, shared_from_this());
331 OCCallbackData cbdata;
332 cbdata.context = static_cast<void*>(context),
333 cbdata.cb = listenCallback;
334 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;};
336 auto cLock = m_csdkLock.lock();
339 std::lock_guard<std::recursive_mutex> lock(*cLock);
340 result = OCDoResource(nullptr, OC_REST_DISCOVER,
341 resourceUri.str().c_str(),
342 nullptr, nullptr, connectivityType,
343 static_cast<OCQualityOfService>(QoS),
350 result = OC_STACK_ERROR;
355 OCStackResult InProcClientWrapper::ListenErrorForResource(
356 const std::string& serviceUrl,
357 const std::string& resourceType,
358 OCConnectivityType connectivityType,
359 FindCallback& callback, FindErrorCallback& errorCallback,
360 QualityOfService QoS)
364 return OC_STACK_INVALID_PARAM;
367 ostringstream resourceUri;
368 resourceUri << serviceUrl << resourceType;
370 ClientCallbackContext::ListenErrorContext* context =
371 new ClientCallbackContext::ListenErrorContext(callback, errorCallback,
375 return OC_STACK_ERROR;
378 OCCallbackData cbdata(
379 static_cast<void*>(context),
381 [](void* c){delete static_cast<ClientCallbackContext::ListenErrorContext*>(c);}
384 OCStackResult result;
385 auto cLock = m_csdkLock.lock();
388 std::lock_guard<std::recursive_mutex> lock(*cLock);
389 result = OCDoResource(nullptr, OC_REST_DISCOVER,
390 resourceUri.str().c_str(),
391 nullptr, nullptr, connectivityType,
392 static_cast<OCQualityOfService>(QoS),
399 result = OC_STACK_ERROR;
404 OCStackApplicationResult listenResListCallback(void* ctx, OCDoHandle /*handle*/,
405 OCClientResponse* clientResponse)
407 if (!ctx || !clientResponse)
409 return OC_STACK_KEEP_TRANSACTION;
412 ClientCallbackContext::ListenResListContext* context =
413 static_cast<ClientCallbackContext::ListenResListContext*>(ctx);
415 if (clientResponse->result != OC_STACK_OK)
417 oclog() << "listenResListCallback(): failed to create resource. clientResponse: "
418 << clientResponse->result
421 return OC_STACK_KEEP_TRANSACTION;
424 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
426 oclog() << "listenResListCallback(): clientResponse payload was null or the wrong type"
428 return OC_STACK_KEEP_TRANSACTION;
431 auto clientWrapper = context->clientWrapper.lock();
435 oclog() << "listenResListCallback(): failed to get a shared_ptr to the client wrapper"
437 return OC_STACK_KEEP_TRANSACTION;
442 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
443 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
445 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
446 std::thread exec(context->callback, container.Resources());
449 catch (std::exception &e)
451 oclog() << "Exception in listenResListCallback(), ignoring response: "
452 << e.what() << std::flush;
455 return OC_STACK_KEEP_TRANSACTION;
458 OCStackResult InProcClientWrapper::ListenForResourceList(
459 const std::string& serviceUrl,
460 const std::string& resourceType,
461 OCConnectivityType connectivityType,
462 FindResListCallback& callback, QualityOfService QoS)
466 return OC_STACK_INVALID_PARAM;
469 OCStackResult result;
470 ostringstream resourceUri;
471 resourceUri << serviceUrl << resourceType;
473 ClientCallbackContext::ListenResListContext* context =
474 new ClientCallbackContext::ListenResListContext(callback, shared_from_this());
475 OCCallbackData cbdata;
476 cbdata.context = static_cast<void*>(context),
477 cbdata.cb = listenResListCallback;
478 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListContext*)c;};
480 auto cLock = m_csdkLock.lock();
483 std::lock_guard<std::recursive_mutex> lock(*cLock);
484 result = OCDoResource(nullptr, OC_REST_DISCOVER,
485 resourceUri.str().c_str(),
486 nullptr, nullptr, connectivityType,
487 static_cast<OCQualityOfService>(QoS),
494 result = OC_STACK_ERROR;
499 OCStackApplicationResult listenResListWithErrorCallback(void* ctx, OCDoHandle /*handle*/,
500 OCClientResponse* clientResponse)
502 if (!ctx || !clientResponse)
504 return OC_STACK_KEEP_TRANSACTION;
507 ClientCallbackContext::ListenResListWithErrorContext* context =
508 static_cast<ClientCallbackContext::ListenResListWithErrorContext*>(ctx);
510 OCStackResult result = clientResponse->result;
511 if (result != OC_STACK_OK)
513 oclog() << "listenResListWithErrorCallback(): failed to create resource. clientResponse: "
514 << result << std::flush;
516 //send the error callback
518 if(NULL != clientResponse->resourceUri)
520 uri = clientResponse->resourceUri;
522 std::thread exec(context->errorCallback, uri, result);
524 return OC_STACK_KEEP_TRANSACTION;
527 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
529 oclog() << "listenResListWithErrorCallback(): clientResponse payload was null or the wrong type"
531 return OC_STACK_KEEP_TRANSACTION;
534 auto clientWrapper = context->clientWrapper.lock();
538 oclog() << "listenResListWithErrorCallback(): failed to get a shared_ptr to the client wrapper"
540 return OC_STACK_KEEP_TRANSACTION;
545 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
546 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
548 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
549 std::thread exec(context->callback, container.Resources());
552 catch (std::exception &e)
554 oclog() << "Exception in listenResListWithErrorCallback(), ignoring response: "
555 << e.what() << std::flush;
558 return OC_STACK_KEEP_TRANSACTION;
561 OCStackResult InProcClientWrapper::ListenForResourceListWithError(
562 const std::string& serviceUrl,
563 const std::string& resourceType,
564 OCConnectivityType connectivityType,
565 FindResListCallback& callback,
566 FindErrorCallback& errorCallback, QualityOfService QoS)
570 return OC_STACK_INVALID_PARAM;
573 OCStackResult result;
574 ostringstream resourceUri;
575 resourceUri << serviceUrl << resourceType;
577 ClientCallbackContext::ListenResListWithErrorContext* context =
578 new ClientCallbackContext::ListenResListWithErrorContext(callback, errorCallback,
582 return OC_STACK_ERROR;
585 OCCallbackData cbdata;
586 cbdata.context = static_cast<void*>(context),
587 cbdata.cb = listenResListWithErrorCallback;
588 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListWithErrorContext*)c;};
590 auto cLock = m_csdkLock.lock();
593 std::lock_guard<std::recursive_mutex> lock(*cLock);
594 result = OCDoResource(nullptr, OC_REST_DISCOVER,
595 resourceUri.str().c_str(),
596 nullptr, nullptr, connectivityType,
597 static_cast<OCQualityOfService>(QoS),
604 result = OC_STACK_ERROR;
610 OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/,
611 OCClientResponse* clientResponse)
613 ClientCallbackContext::MQTopicContext* context =
614 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
616 if (!clientResponse || !context)
618 return OC_STACK_DELETE_TRANSACTION;
621 std::string resourceURI;
622 if(NULL != clientResponse->resourceUri)
624 resourceURI = clientResponse->resourceUri;
627 if (clientResponse->result != OC_STACK_OK)
629 oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
630 << clientResponse->result
633 std::thread exec(context->callback, clientResponse->result,
634 resourceURI, nullptr);
637 return OC_STACK_DELETE_TRANSACTION;
640 auto clientWrapper = context->clientWrapper.lock();
643 oclog() << "listenMQCallback(): failed to get a shared_ptr to the client wrapper"
645 return OC_STACK_DELETE_TRANSACTION;
650 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
651 (OCRepPayload *) clientResponse->payload);
653 // loop to ensure valid construction of all resources
654 for (auto resource : container.Resources())
656 std::thread exec(context->callback, clientResponse->result,
657 resourceURI, resource);
661 catch (std::exception &e)
663 oclog() << "Exception in listCallback, ignoring response: "
664 << e.what() << std::flush;
667 return OC_STACK_DELETE_TRANSACTION;
670 OCStackResult InProcClientWrapper::ListenForMQTopic(const OCDevAddr& devAddr,
671 const std::string& resourceUri,
672 const QueryParamsMap& queryParams,
673 const HeaderOptions& headerOptions,
674 MQTopicCallback& callback,
675 QualityOfService QoS)
677 oclog() << "ListenForMQTopic()" << std::flush;
681 return OC_STACK_INVALID_PARAM;
684 if (headerOptions.size() > MAX_HEADER_OPTIONS)
686 oclog() << "ListenForMQTopic: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
687 return OC_STACK_INVALID_PARAM;
690 ClientCallbackContext::MQTopicContext* context =
691 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
692 OCCallbackData cbdata;
693 cbdata.context = static_cast<void*>(context),
694 cbdata.cb = listenMQCallback;
695 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
697 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
699 OCStackResult result = OC_STACK_ERROR;
700 auto cLock = m_csdkLock.lock();
703 std::lock_guard<std::recursive_mutex> lock(*cLock);
704 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
705 result = OCDoResource(
706 nullptr, OC_REST_GET,
710 static_cast<OCQualityOfService>(QoS),
713 headerOptions.size());
725 OCStackApplicationResult listenDeviceCallback(void* ctx,
726 OCDoHandle /*handle*/,
727 OCClientResponse* clientResponse)
729 ClientCallbackContext::DeviceListenContext* context =
730 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
734 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
735 OCRepresentation rep = parseGetSetCallback(clientResponse);
736 std::thread exec(context->callback, rep);
739 catch(OC::OCException& e)
741 oclog() <<"Exception in listenDeviceCallback, ignoring response: "
742 <<e.what() <<std::flush;
745 return OC_STACK_KEEP_TRANSACTION;
748 OCStackResult InProcClientWrapper::ListenForDevice(
749 const std::string& serviceUrl,
750 const std::string& deviceURI,
751 OCConnectivityType connectivityType,
752 FindDeviceCallback& callback,
753 QualityOfService QoS)
757 return OC_STACK_INVALID_PARAM;
759 OCStackResult result;
760 ostringstream deviceUri;
761 deviceUri << serviceUrl << deviceURI;
763 ClientCallbackContext::DeviceListenContext* context =
764 new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
765 OCCallbackData cbdata;
767 cbdata.context = static_cast<void*>(context),
768 cbdata.cb = listenDeviceCallback;
769 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeviceListenContext*)c;};
771 auto cLock = m_csdkLock.lock();
774 std::lock_guard<std::recursive_mutex> lock(*cLock);
775 result = OCDoResource(nullptr, OC_REST_DISCOVER,
776 deviceUri.str().c_str(),
777 nullptr, nullptr, connectivityType,
778 static_cast<OCQualityOfService>(QoS),
785 result = OC_STACK_ERROR;
790 void parseServerHeaderOptions(OCClientResponse* clientResponse,
791 HeaderOptions& serverHeaderOptions)
795 // Parse header options from server
797 std::string optionData;
799 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
801 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
802 optionData = reinterpret_cast<const char*>
803 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
804 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
805 serverHeaderOptions.push_back(headerOption);
810 // clientResponse is invalid
811 // TODO check proper logging
812 std::cout << " Invalid response " << std::endl;
817 OCStackApplicationResult createMQTopicCallback(void* ctx, OCDoHandle /*handle*/,
818 OCClientResponse* clientResponse)
820 ClientCallbackContext::MQTopicContext* context =
821 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
822 HeaderOptions serverHeaderOptions;
824 if (!clientResponse || !context)
826 return OC_STACK_DELETE_TRANSACTION;
829 std::string createdUri;
830 bool isLocationOption = false;
831 OCStackResult result = clientResponse->result;
832 if (OC_STACK_OK == result ||
833 OC_STACK_RESOURCE_CREATED == result)
835 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
837 for (auto headerOption : serverHeaderOptions)
839 if (HeaderOption::LOCATION_PATH_OPTION_ID == headerOption.getOptionID())
842 createdUri += headerOption.getOptionData();
843 if (!isLocationOption)
845 isLocationOption = true;
851 if (!isLocationOption && NULL != clientResponse->resourceUri)
853 createdUri = std::string(clientResponse->resourceUri);
856 auto clientWrapper = context->clientWrapper.lock();
860 oclog() << "createMQTopicCallback(): failed to get a shared_ptr to the client wrapper"
862 return OC_STACK_DELETE_TRANSACTION;
867 if (OC_STACK_OK == result ||
868 OC_STACK_RESOURCE_CREATED == result)
870 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
872 for (auto resource : container.Resources())
874 std::thread exec(context->callback, result,
882 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
883 std::thread exec(context->callback, result,
889 catch (std::exception &e)
891 oclog() << "Exception in createMQTopicCallback, ignoring response: "
892 << e.what() << std::flush;
894 return OC_STACK_DELETE_TRANSACTION;
897 OCStackResult InProcClientWrapper::PutMQTopicRepresentation(
898 const OCDevAddr& devAddr,
899 const std::string& uri,
900 const OCRepresentation& rep,
901 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
902 MQTopicCallback& callback, QualityOfService QoS)
906 return OC_STACK_INVALID_PARAM;
909 if (headerOptions.size() > MAX_HEADER_OPTIONS)
911 oclog() << "PutMQTopicRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
912 return OC_STACK_INVALID_PARAM;
915 OCStackResult result;
916 ClientCallbackContext::MQTopicContext* ctx =
917 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
918 OCCallbackData cbdata;
919 cbdata.context = static_cast<void*>(ctx),
920 cbdata.cb = createMQTopicCallback;
921 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
923 std::string url = assembleSetResourceUri(uri, queryParams);
925 auto cLock = m_csdkLock.lock();
929 std::lock_guard<std::recursive_mutex> lock(*cLock);
930 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
932 result = OCDoResource(nullptr, OC_REST_PUT,
933 url.c_str(), &devAddr,
934 assembleSetResourcePayload(rep),
936 static_cast<OCQualityOfService>(QoS),
939 headerOptions.size());
945 result = OC_STACK_ERROR;
951 OCStackApplicationResult getResourceCallback(void* ctx,
952 OCDoHandle /*handle*/,
953 OCClientResponse* clientResponse)
955 ClientCallbackContext::GetContext* context =
956 static_cast<ClientCallbackContext::GetContext*>(ctx);
957 OCRepresentation rep;
958 HeaderOptions serverHeaderOptions;
959 OCStackResult result = clientResponse->result;
961 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
964 rep = parseGetSetCallback(clientResponse);
966 catch(OC::OCException& e)
971 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
972 std::thread exec(context->callback, serverHeaderOptions, rep, result);
974 return OC_STACK_DELETE_TRANSACTION;
977 OCStackResult InProcClientWrapper::GetResourceRepresentation(
978 const OCDevAddr& devAddr,
979 const std::string& resourceUri,
980 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
981 OCConnectivityType connectivityType,
982 GetCallback& callback, QualityOfService QoS)
986 return OC_STACK_INVALID_PARAM;
989 if (headerOptions.size() > MAX_HEADER_OPTIONS)
991 oclog() << "GetResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
992 return OC_STACK_INVALID_PARAM;
995 OCStackResult result;
996 ClientCallbackContext::GetContext* ctx =
997 new ClientCallbackContext::GetContext(callback);
999 OCCallbackData cbdata;
1000 cbdata.context = static_cast<void*>(ctx);
1001 cbdata.cb = getResourceCallback;
1002 cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
1004 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
1006 auto cLock = m_csdkLock.lock();
1010 std::lock_guard<std::recursive_mutex> lock(*cLock);
1011 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1013 result = OCDoResource(
1014 nullptr, OC_REST_GET,
1018 static_cast<OCQualityOfService>(QoS),
1021 headerOptions.size());
1027 result = OC_STACK_ERROR;
1033 OCStackApplicationResult setResourceCallback(void* ctx,
1034 OCDoHandle /*handle*/,
1035 OCClientResponse* clientResponse)
1037 ClientCallbackContext::SetContext* context =
1038 static_cast<ClientCallbackContext::SetContext*>(ctx);
1039 OCRepresentation attrs;
1040 HeaderOptions serverHeaderOptions;
1042 OCStackResult result = clientResponse->result;
1044 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1047 attrs = parseGetSetCallback(clientResponse);
1049 catch(OC::OCException& e)
1054 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1055 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
1057 return OC_STACK_DELETE_TRANSACTION;
1060 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1061 const QueryParamsMap& queryParams)
1065 if (uri.back() == '/')
1067 uri.resize(uri.size() - 1);
1071 ostringstream paramsList;
1072 if (queryParams.size() > 0)
1077 for (auto& param : queryParams)
1079 paramsList << param.first <<'='<<param.second<<';';
1082 std::string queryString = paramsList.str();
1084 if (queryString.empty())
1089 if (queryString.back() == ';')
1091 queryString.resize(queryString.size() - 1);
1094 std::string ret = uri + queryString;
1098 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1099 const QueryParamsList& queryParams)
1103 if (uri.back() == '/')
1105 uri.resize(uri.size() - 1);
1109 ostringstream paramsList;
1110 if (queryParams.size() > 0)
1115 for (auto& param : queryParams)
1117 for (auto& paramList : param.second)
1119 paramsList << param.first << '=' << paramList << ';';
1123 std::string queryString = paramsList.str();
1125 if (queryString.empty())
1130 if (queryString.back() == ';')
1132 queryString.resize(queryString.size() - 1);
1135 std::string ret = uri + queryString;
1139 OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
1141 MessageContainer ocInfo;
1142 ocInfo.addRepresentation(rep);
1143 for(const OCRepresentation& r : rep.getChildren())
1145 ocInfo.addRepresentation(r);
1148 return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
1151 OCStackResult InProcClientWrapper::PostResourceRepresentation(
1152 const OCDevAddr& devAddr,
1153 const std::string& uri,
1154 const OCRepresentation& rep,
1155 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1156 OCConnectivityType connectivityType,
1157 PostCallback& callback, QualityOfService QoS)
1161 return OC_STACK_INVALID_PARAM;
1164 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1166 oclog() << "PostResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1167 return OC_STACK_INVALID_PARAM;
1170 OCStackResult result;
1171 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1172 OCCallbackData cbdata;
1173 cbdata.context = static_cast<void*>(ctx),
1174 cbdata.cb = setResourceCallback;
1175 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1178 std::string url = assembleSetResourceUri(uri, queryParams);
1180 auto cLock = m_csdkLock.lock();
1184 std::lock_guard<std::recursive_mutex> lock(*cLock);
1185 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1187 result = OCDoResource(nullptr, OC_REST_POST,
1188 url.c_str(), &devAddr,
1189 assembleSetResourcePayload(rep),
1191 static_cast<OCQualityOfService>(QoS),
1194 headerOptions.size());
1200 result = OC_STACK_ERROR;
1206 OCStackResult InProcClientWrapper::PutResourceRepresentation(
1207 const OCDevAddr& devAddr,
1208 const std::string& uri,
1209 const OCRepresentation& rep,
1210 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1211 PutCallback& callback, QualityOfService QoS)
1215 return OC_STACK_INVALID_PARAM;
1218 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1220 oclog() << "PutResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1221 return OC_STACK_INVALID_PARAM;
1224 OCStackResult result;
1225 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1226 OCCallbackData cbdata;
1227 cbdata.context = static_cast<void*>(ctx),
1228 cbdata.cb = setResourceCallback;
1229 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1232 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1234 auto cLock = m_csdkLock.lock();
1238 std::lock_guard<std::recursive_mutex> lock(*cLock);
1240 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1242 result = OCDoResource(&handle, OC_REST_PUT,
1243 url.c_str(), &devAddr,
1244 assembleSetResourcePayload(rep),
1246 static_cast<OCQualityOfService>(QoS),
1249 headerOptions.size());
1255 result = OC_STACK_ERROR;
1261 OCStackApplicationResult deleteResourceCallback(void* ctx,
1262 OCDoHandle /*handle*/,
1263 OCClientResponse* clientResponse)
1265 ClientCallbackContext::DeleteContext* context =
1266 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
1267 HeaderOptions serverHeaderOptions;
1269 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1271 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1272 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
1274 return OC_STACK_DELETE_TRANSACTION;
1277 OCStackResult InProcClientWrapper::DeleteResource(
1278 const OCDevAddr& devAddr,
1279 const std::string& uri,
1280 const HeaderOptions& headerOptions,
1281 OCConnectivityType connectivityType,
1282 DeleteCallback& callback,
1283 QualityOfService /*QoS*/)
1287 return OC_STACK_INVALID_PARAM;
1290 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1292 oclog() << "DeleteResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1293 return OC_STACK_INVALID_PARAM;
1296 OCStackResult result;
1297 ClientCallbackContext::DeleteContext* ctx =
1298 new ClientCallbackContext::DeleteContext(callback);
1299 OCCallbackData cbdata;
1300 cbdata.context = static_cast<void*>(ctx),
1301 cbdata.cb = deleteResourceCallback;
1302 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;};
1305 auto cLock = m_csdkLock.lock();
1309 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1311 std::lock_guard<std::recursive_mutex> lock(*cLock);
1313 result = OCDoResource(nullptr, OC_REST_DELETE,
1314 uri.c_str(), &devAddr,
1317 static_cast<OCQualityOfService>(m_cfg.QoS),
1320 headerOptions.size());
1326 result = OC_STACK_ERROR;
1332 OCStackApplicationResult observeResourceCallback(void* ctx,
1333 OCDoHandle /*handle*/,
1334 OCClientResponse* clientResponse)
1336 ClientCallbackContext::ObserveContext* context =
1337 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
1338 OCRepresentation attrs;
1339 HeaderOptions serverHeaderOptions;
1340 uint32_t sequenceNumber = clientResponse->sequenceNumber;
1341 OCStackResult result = clientResponse->result;
1343 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1346 attrs = parseGetSetCallback(clientResponse);
1348 catch(OC::OCException& e)
1353 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1354 std::thread exec(context->callback, serverHeaderOptions, attrs,
1355 result, sequenceNumber);
1357 if (sequenceNumber == MAX_SEQUENCE_NUMBER + 1)
1359 return OC_STACK_DELETE_TRANSACTION;
1362 return OC_STACK_KEEP_TRANSACTION;
1365 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
1366 const OCDevAddr& devAddr,
1367 const std::string& uri,
1368 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1369 ObserveCallback& callback, QualityOfService QoS)
1373 return OC_STACK_INVALID_PARAM;
1376 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1378 oclog() << "ObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1379 return OC_STACK_INVALID_PARAM;
1382 OCStackResult result;
1384 ClientCallbackContext::ObserveContext* ctx =
1385 new ClientCallbackContext::ObserveContext(callback);
1386 OCCallbackData cbdata;
1387 cbdata.context = static_cast<void*>(ctx),
1388 cbdata.cb = observeResourceCallback;
1389 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1393 if (observeType == ObserveType::Observe)
1395 method = OC_REST_OBSERVE;
1397 else if (observeType == ObserveType::ObserveAll)
1399 method = OC_REST_OBSERVE_ALL;
1403 method = OC_REST_OBSERVE_ALL;
1406 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1408 auto cLock = m_csdkLock.lock();
1412 std::lock_guard<std::recursive_mutex> lock(*cLock);
1413 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1415 result = OCDoResource(handle, method,
1416 url.c_str(), &devAddr,
1419 static_cast<OCQualityOfService>(QoS),
1422 headerOptions.size());
1428 return OC_STACK_ERROR;
1434 OCStackResult InProcClientWrapper::CancelObserveResource(
1436 const std::string& /*host*/,
1437 const std::string& /*uri*/,
1438 const HeaderOptions& headerOptions,
1439 QualityOfService QoS)
1441 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1443 oclog() << "CancelObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1444 return OC_STACK_INVALID_PARAM;
1447 OCStackResult result;
1448 auto cLock = m_csdkLock.lock();
1452 std::lock_guard<std::recursive_mutex> lock(*cLock);
1453 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1455 result = OCCancel(handle,
1456 static_cast<OCQualityOfService>(QoS),
1458 headerOptions.size());
1463 result = OC_STACK_ERROR;
1469 #ifdef WITH_PRESENCE
1470 OCStackApplicationResult subscribePresenceCallback(void* ctx,
1471 OCDoHandle /*handle*/,
1472 OCClientResponse* clientResponse)
1474 ClientCallbackContext::SubscribePresenceContext* context =
1475 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
1478 * This a hack while we rethink presence subscription.
1480 std::string url = clientResponse->devAddr.addr;
1482 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1483 std::thread exec(context->callback, clientResponse->result,
1484 clientResponse->sequenceNumber, url);
1488 return OC_STACK_KEEP_TRANSACTION;
1492 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
1493 const std::string& host, const std::string& resourceType,
1494 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
1496 #ifdef WITH_PRESENCE
1497 if (!presenceHandler)
1499 return OC_STACK_INVALID_PARAM;
1502 ClientCallbackContext::SubscribePresenceContext* ctx =
1503 new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
1504 OCCallbackData cbdata;
1505 cbdata.context = static_cast<void*>(ctx),
1506 cbdata.cb = subscribePresenceCallback;
1507 cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;};
1510 auto cLock = m_csdkLock.lock();
1512 std::ostringstream os;
1513 os << host << OC_RSRVD_PRESENCE_URI;
1515 if (!resourceType.empty())
1517 os << "?rt=" << resourceType;
1523 return OC_STACK_ERROR;
1526 return OCDoResource(handle, OC_REST_PRESENCE,
1527 os.str().c_str(), nullptr,
1528 nullptr, connectivityType,
1529 OC_LOW_QOS, &cbdata, NULL, 0);
1531 return OC_STACK_NOT_IMPLEMENTED;
1535 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
1537 #ifdef WITH_PRESENCE
1538 OCStackResult result;
1539 auto cLock = m_csdkLock.lock();
1543 std::lock_guard<std::recursive_mutex> lock(*cLock);
1544 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1548 result = OC_STACK_ERROR;
1553 return OC_STACK_NOT_IMPLEMENTED;
1558 OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
1559 const std::string& host,
1560 const std::vector<std::string>& di,
1561 OCConnectivityType connectivityType,
1562 ObserveCallback& callback)
1566 return OC_STACK_INVALID_PARAM;
1568 OCStackResult result;
1570 ClientCallbackContext::ObserveContext* ctx =
1571 new ClientCallbackContext::ObserveContext(callback);
1572 OCCallbackData cbdata;
1573 cbdata.context = static_cast<void*>(ctx),
1574 cbdata.cb = observeResourceCallback;
1575 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1577 auto cLock = m_csdkLock.lock();
1581 std::lock_guard<std::recursive_mutex> lock(*cLock);
1583 std::ostringstream os;
1584 os << host << OC_RSRVD_DEVICE_PRESENCE_URI;
1585 QueryParamsList queryParams({{OC_RSRVD_DEVICE_ID, di}});
1586 std::string url = assembleSetResourceUri(os.str(), queryParams);
1588 result = OCDoResource(handle, OC_REST_OBSERVE,
1589 url.c_str(), nullptr,
1590 nullptr, connectivityType,
1591 OC_LOW_QOS, &cbdata,
1597 result = OC_STACK_ERROR;
1604 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
1610 OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(const HeaderOptions& headerOptions)
1612 if ( headerOptions.size() == 0)
1617 OCHeaderOption* options = new OCHeaderOption[headerOptions.size()]();
1619 size_t numOptions = 0;
1620 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
1622 OCStackResult ret = OCSetHeaderOption(options, &numOptions, it->getOptionID(),
1623 it->getOptionData().c_str(), it->getOptionData().length());
1624 if (OC_STACK_OK != ret)
1626 OIC_LOG_V(ERROR, TAG, "Failed to convert vnd header options! (error=%d)", ret);
1635 std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
1642 OCDPDev_t* result = new OCDPDev_t(*dev);
1643 result->prm = new OCPrm_t[dev->prmLen];
1644 memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
1645 return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
1648 void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
1652 dpList.push_back(cloneDevice(list));
1657 OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
1658 GetDirectPairedCallback& callback)
1660 if (!callback || 0 == waittime)
1662 return OC_STACK_INVALID_PARAM;
1665 OCStackResult result = OC_STACK_ERROR;
1666 const OCDPDev_t *list = nullptr;
1667 PairedDevices dpDeviceList;
1669 auto cLock = m_csdkLock.lock();
1673 std::lock_guard<std::recursive_mutex> lock(*cLock);
1675 list = OCDiscoverDirectPairingDevices(waittime);
1678 result = OC_STACK_NO_RESOURCE;
1679 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1683 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1684 convert(list, dpDeviceList);
1685 std::thread exec(callback, dpDeviceList);
1687 result = OC_STACK_OK;
1692 result = OC_STACK_ERROR;
1698 OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
1702 return OC_STACK_INVALID_PARAM;
1705 OCStackResult result = OC_STACK_ERROR;
1706 const OCDPDev_t *list = nullptr;
1707 PairedDevices dpDeviceList;
1709 auto cLock = m_csdkLock.lock();
1713 std::lock_guard<std::recursive_mutex> lock(*cLock);
1715 list = OCGetDirectPairedDevices();
1718 result = OC_STACK_NO_RESOURCE;
1719 OIC_LOG_V(DEBUG, TAG, "%s: No device found for direct pairing", __func__);
1722 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1723 convert(list, dpDeviceList);
1724 std::thread exec(callback, dpDeviceList);
1726 result = OC_STACK_OK;
1731 result = OC_STACK_ERROR;
1737 void directPairingCallback(void *ctx, OCDPDev_t *peer,
1738 OCStackResult result)
1741 ClientCallbackContext::DirectPairingContext* context =
1742 static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
1744 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1745 std::thread exec(context->callback, cloneDevice(peer), result);
1749 OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
1750 const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
1752 if (!peer || !callback)
1754 oclog() << "Invalid parameters" << std::flush;
1755 return OC_STACK_INVALID_PARAM;
1758 OCStackResult result = OC_STACK_ERROR;
1759 ClientCallbackContext::DirectPairingContext* context =
1760 new ClientCallbackContext::DirectPairingContext(callback);
1762 auto cLock = m_csdkLock.lock();
1765 std::lock_guard<std::recursive_mutex> lock(*cLock);
1766 result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
1767 pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
1772 result = OC_STACK_ERROR;
1777 OCStackApplicationResult KeepAliveRespCallback(void* ctx,
1778 OCDoHandle /*handle*/,
1779 OCClientResponse* clientResponse)
1781 ClientCallbackContext::KeepAliveContext* context =
1782 static_cast<ClientCallbackContext::KeepAliveContext*>(ctx);
1783 OCRepresentation attrs;
1784 OCStackResult result = clientResponse->result;
1788 attrs = parseGetSetCallback(clientResponse);
1790 catch(OC::OCException& e)
1795 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1796 std::thread exec(context->callback, result, attrs);
1798 return OC_STACK_DELETE_TRANSACTION;
1801 OCStackResult InProcClientWrapper::findKeepAliveResource(std::string host,
1802 KeepAliveCallback resultCallback)
1804 if (host.empty() || !resultCallback)
1806 oclog() << "Invalid parameters" << std::flush;
1807 return OC_STACK_INVALID_PARAM;
1810 OCStackResult result = OC_STACK_ERROR;
1812 ClientCallbackContext::KeepAliveContext* ctx =
1813 new ClientCallbackContext::KeepAliveContext(resultCallback);
1814 OCCallbackData cbdata;
1815 cbdata.context = static_cast<void*>(ctx),
1816 cbdata.cb = KeepAliveRespCallback;
1817 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1819 auto cLock = m_csdkLock.lock();
1823 std::lock_guard<std::recursive_mutex> lock(*cLock);
1824 result = OCFindKeepAliveResource(nullptr, host.c_str(), &cbdata);
1829 result = OC_STACK_ERROR;
1834 OCStackResult InProcClientWrapper::sendKeepAliveRequest(std::string host,
1835 const OCRepresentation& rep,
1836 KeepAliveCallback resultCallback)
1838 if (!resultCallback)
1840 oclog() << "Invalid parameters" << std::flush;
1841 return OC_STACK_INVALID_PARAM;
1844 OCStackResult result = OC_STACK_ERROR;
1846 ClientCallbackContext::KeepAliveContext* ctx = new ClientCallbackContext::KeepAliveContext(resultCallback);
1847 OCCallbackData cbdata;
1848 cbdata.context = static_cast<void*>(ctx),
1849 cbdata.cb = KeepAliveRespCallback;
1850 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1852 auto cLock = m_csdkLock.lock();
1856 std::lock_guard<std::recursive_mutex> lock(*cLock);
1857 OCRepPayload *payload = rep.getPayload();
1858 result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
1863 result = OC_STACK_ERROR;