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);
965 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
966 std::thread exec(context->callback, serverHeaderOptions, rep, result);
969 catch(OC::OCException& e)
971 oclog() << "Exception in parseGetSetCallback, ignoring callback: "
972 << e.what() << std::flush;
974 catch(const std::exception& e)
976 oclog() << "Exception in thread execution, ignoring callback: "
977 << e.what() << std::flush;
980 return OC_STACK_DELETE_TRANSACTION;
983 OCStackResult InProcClientWrapper::GetResourceRepresentation(
984 const OCDevAddr& devAddr,
985 const std::string& resourceUri,
986 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
987 OCConnectivityType connectivityType,
988 GetCallback& callback, QualityOfService QoS)
992 return OC_STACK_INVALID_PARAM;
995 if (headerOptions.size() > MAX_HEADER_OPTIONS)
997 oclog() << "GetResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
998 return OC_STACK_INVALID_PARAM;
1001 OCStackResult result;
1002 ClientCallbackContext::GetContext* ctx =
1003 new ClientCallbackContext::GetContext(callback);
1005 OCCallbackData cbdata;
1006 cbdata.context = static_cast<void*>(ctx);
1007 cbdata.cb = getResourceCallback;
1008 cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
1010 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
1012 auto cLock = m_csdkLock.lock();
1016 std::lock_guard<std::recursive_mutex> lock(*cLock);
1017 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1019 result = OCDoResource(
1020 nullptr, OC_REST_GET,
1024 static_cast<OCQualityOfService>(QoS),
1027 headerOptions.size());
1033 result = OC_STACK_ERROR;
1039 OCStackApplicationResult setResourceCallback(void* ctx,
1040 OCDoHandle /*handle*/,
1041 OCClientResponse* clientResponse)
1043 ClientCallbackContext::SetContext* context =
1044 static_cast<ClientCallbackContext::SetContext*>(ctx);
1045 OCRepresentation attrs;
1046 HeaderOptions serverHeaderOptions;
1048 OCStackResult result = clientResponse->result;
1050 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1053 attrs = parseGetSetCallback(clientResponse);
1055 catch(OC::OCException& e)
1060 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1061 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
1063 return OC_STACK_DELETE_TRANSACTION;
1066 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1067 const QueryParamsMap& queryParams)
1071 if (uri.back() == '/')
1073 uri.resize(uri.size() - 1);
1077 ostringstream paramsList;
1078 if (queryParams.size() > 0)
1083 for (auto& param : queryParams)
1085 paramsList << param.first <<'='<<param.second<<';';
1088 std::string queryString = paramsList.str();
1090 if (queryString.empty())
1095 if (queryString.back() == ';')
1097 queryString.resize(queryString.size() - 1);
1100 std::string ret = uri + queryString;
1104 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1105 const QueryParamsList& queryParams)
1109 if (uri.back() == '/')
1111 uri.resize(uri.size() - 1);
1115 ostringstream paramsList;
1116 if (queryParams.size() > 0)
1121 for (auto& param : queryParams)
1123 for (auto& paramList : param.second)
1125 paramsList << param.first << '=' << paramList << ';';
1129 std::string queryString = paramsList.str();
1131 if (queryString.empty())
1136 if (queryString.back() == ';')
1138 queryString.resize(queryString.size() - 1);
1141 std::string ret = uri + queryString;
1145 OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
1147 MessageContainer ocInfo;
1148 ocInfo.addRepresentation(rep);
1149 for(const OCRepresentation& r : rep.getChildren())
1151 ocInfo.addRepresentation(r);
1154 return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
1157 OCStackResult InProcClientWrapper::PostResourceRepresentation(
1158 const OCDevAddr& devAddr,
1159 const std::string& uri,
1160 const OCRepresentation& rep,
1161 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1162 OCConnectivityType connectivityType,
1163 PostCallback& callback, QualityOfService QoS)
1167 return OC_STACK_INVALID_PARAM;
1170 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1172 oclog() << "PostResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1173 return OC_STACK_INVALID_PARAM;
1176 OCStackResult result;
1177 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1178 OCCallbackData cbdata;
1179 cbdata.context = static_cast<void*>(ctx),
1180 cbdata.cb = setResourceCallback;
1181 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1184 std::string url = assembleSetResourceUri(uri, queryParams);
1186 auto cLock = m_csdkLock.lock();
1190 std::lock_guard<std::recursive_mutex> lock(*cLock);
1191 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1193 result = OCDoResource(nullptr, OC_REST_POST,
1194 url.c_str(), &devAddr,
1195 assembleSetResourcePayload(rep),
1197 static_cast<OCQualityOfService>(QoS),
1200 headerOptions.size());
1206 result = OC_STACK_ERROR;
1212 OCStackResult InProcClientWrapper::PutResourceRepresentation(
1213 const OCDevAddr& devAddr,
1214 const std::string& uri,
1215 const OCRepresentation& rep,
1216 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1217 PutCallback& callback, QualityOfService QoS)
1221 return OC_STACK_INVALID_PARAM;
1224 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1226 oclog() << "PutResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1227 return OC_STACK_INVALID_PARAM;
1230 OCStackResult result;
1231 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1232 OCCallbackData cbdata;
1233 cbdata.context = static_cast<void*>(ctx),
1234 cbdata.cb = setResourceCallback;
1235 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1238 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1240 auto cLock = m_csdkLock.lock();
1244 std::lock_guard<std::recursive_mutex> lock(*cLock);
1246 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1248 result = OCDoResource(&handle, OC_REST_PUT,
1249 url.c_str(), &devAddr,
1250 assembleSetResourcePayload(rep),
1252 static_cast<OCQualityOfService>(QoS),
1255 headerOptions.size());
1261 result = OC_STACK_ERROR;
1267 OCStackApplicationResult deleteResourceCallback(void* ctx,
1268 OCDoHandle /*handle*/,
1269 OCClientResponse* clientResponse)
1271 ClientCallbackContext::DeleteContext* context =
1272 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
1273 HeaderOptions serverHeaderOptions;
1275 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1277 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1278 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
1280 return OC_STACK_DELETE_TRANSACTION;
1283 OCStackResult InProcClientWrapper::DeleteResource(
1284 const OCDevAddr& devAddr,
1285 const std::string& uri,
1286 const HeaderOptions& headerOptions,
1287 OCConnectivityType connectivityType,
1288 DeleteCallback& callback,
1289 QualityOfService /*QoS*/)
1293 return OC_STACK_INVALID_PARAM;
1296 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1298 oclog() << "DeleteResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1299 return OC_STACK_INVALID_PARAM;
1302 OCStackResult result;
1303 ClientCallbackContext::DeleteContext* ctx =
1304 new ClientCallbackContext::DeleteContext(callback);
1305 OCCallbackData cbdata;
1306 cbdata.context = static_cast<void*>(ctx),
1307 cbdata.cb = deleteResourceCallback;
1308 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;};
1311 auto cLock = m_csdkLock.lock();
1315 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1317 std::lock_guard<std::recursive_mutex> lock(*cLock);
1319 result = OCDoResource(nullptr, OC_REST_DELETE,
1320 uri.c_str(), &devAddr,
1323 static_cast<OCQualityOfService>(m_cfg.QoS),
1326 headerOptions.size());
1332 result = OC_STACK_ERROR;
1338 OCStackApplicationResult observeResourceCallback(void* ctx,
1339 OCDoHandle /*handle*/,
1340 OCClientResponse* clientResponse)
1342 ClientCallbackContext::ObserveContext* context =
1343 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
1344 OCRepresentation attrs;
1345 HeaderOptions serverHeaderOptions;
1346 uint32_t sequenceNumber = clientResponse->sequenceNumber;
1347 OCStackResult result = clientResponse->result;
1349 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1352 attrs = parseGetSetCallback(clientResponse);
1354 catch(OC::OCException& e)
1359 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1360 std::thread exec(context->callback, serverHeaderOptions, attrs,
1361 result, sequenceNumber);
1363 if (sequenceNumber == MAX_SEQUENCE_NUMBER + 1)
1365 return OC_STACK_DELETE_TRANSACTION;
1368 return OC_STACK_KEEP_TRANSACTION;
1371 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
1372 const OCDevAddr& devAddr,
1373 const std::string& uri,
1374 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1375 ObserveCallback& callback, QualityOfService QoS)
1379 return OC_STACK_INVALID_PARAM;
1382 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1384 oclog() << "ObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1385 return OC_STACK_INVALID_PARAM;
1388 OCStackResult result;
1390 ClientCallbackContext::ObserveContext* ctx =
1391 new ClientCallbackContext::ObserveContext(callback);
1392 OCCallbackData cbdata;
1393 cbdata.context = static_cast<void*>(ctx),
1394 cbdata.cb = observeResourceCallback;
1395 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1399 if (observeType == ObserveType::Observe)
1401 method = OC_REST_OBSERVE;
1403 else if (observeType == ObserveType::ObserveAll)
1405 method = OC_REST_OBSERVE_ALL;
1409 method = OC_REST_OBSERVE_ALL;
1412 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1414 auto cLock = m_csdkLock.lock();
1418 std::lock_guard<std::recursive_mutex> lock(*cLock);
1419 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1421 result = OCDoResource(handle, method,
1422 url.c_str(), &devAddr,
1425 static_cast<OCQualityOfService>(QoS),
1428 headerOptions.size());
1434 return OC_STACK_ERROR;
1440 OCStackResult InProcClientWrapper::CancelObserveResource(
1442 const std::string& /*host*/,
1443 const std::string& /*uri*/,
1444 const HeaderOptions& headerOptions,
1445 QualityOfService QoS)
1447 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1449 oclog() << "CancelObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1450 return OC_STACK_INVALID_PARAM;
1453 OCStackResult result;
1454 auto cLock = m_csdkLock.lock();
1458 std::lock_guard<std::recursive_mutex> lock(*cLock);
1459 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1461 result = OCCancel(handle,
1462 static_cast<OCQualityOfService>(QoS),
1464 headerOptions.size());
1469 result = OC_STACK_ERROR;
1475 #ifdef WITH_PRESENCE
1476 OCStackApplicationResult subscribePresenceCallback(void* ctx,
1477 OCDoHandle /*handle*/,
1478 OCClientResponse* clientResponse)
1480 ClientCallbackContext::SubscribePresenceContext* context =
1481 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
1484 * This a hack while we rethink presence subscription.
1486 std::string url = clientResponse->devAddr.addr;
1488 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1489 std::thread exec(context->callback, clientResponse->result,
1490 clientResponse->sequenceNumber, url);
1494 return OC_STACK_KEEP_TRANSACTION;
1498 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
1499 const std::string& host, const std::string& resourceType,
1500 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
1502 #ifdef WITH_PRESENCE
1503 if (!presenceHandler)
1505 return OC_STACK_INVALID_PARAM;
1508 ClientCallbackContext::SubscribePresenceContext* ctx =
1509 new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
1510 OCCallbackData cbdata;
1511 cbdata.context = static_cast<void*>(ctx),
1512 cbdata.cb = subscribePresenceCallback;
1513 cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;};
1516 auto cLock = m_csdkLock.lock();
1518 std::ostringstream os;
1519 os << host << OC_RSRVD_PRESENCE_URI;
1521 if (!resourceType.empty())
1523 os << "?rt=" << resourceType;
1529 return OC_STACK_ERROR;
1532 return OCDoResource(handle, OC_REST_PRESENCE,
1533 os.str().c_str(), nullptr,
1534 nullptr, connectivityType,
1535 OC_LOW_QOS, &cbdata, NULL, 0);
1537 return OC_STACK_NOT_IMPLEMENTED;
1541 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
1543 #ifdef WITH_PRESENCE
1544 OCStackResult result;
1545 auto cLock = m_csdkLock.lock();
1549 std::lock_guard<std::recursive_mutex> lock(*cLock);
1550 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1554 result = OC_STACK_ERROR;
1559 return OC_STACK_NOT_IMPLEMENTED;
1564 OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
1565 const std::string& host,
1566 const std::vector<std::string>& di,
1567 OCConnectivityType connectivityType,
1568 ObserveCallback& callback)
1572 return OC_STACK_INVALID_PARAM;
1574 OCStackResult result;
1576 ClientCallbackContext::ObserveContext* ctx =
1577 new ClientCallbackContext::ObserveContext(callback);
1578 OCCallbackData cbdata;
1579 cbdata.context = static_cast<void*>(ctx),
1580 cbdata.cb = observeResourceCallback;
1581 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1583 auto cLock = m_csdkLock.lock();
1587 std::lock_guard<std::recursive_mutex> lock(*cLock);
1589 std::ostringstream os;
1590 os << host << OC_RSRVD_DEVICE_PRESENCE_URI;
1591 QueryParamsList queryParams({{OC_RSRVD_DEVICE_ID, di}});
1592 std::string url = assembleSetResourceUri(os.str(), queryParams);
1594 result = OCDoResource(handle, OC_REST_OBSERVE,
1595 url.c_str(), nullptr,
1596 nullptr, connectivityType,
1597 OC_LOW_QOS, &cbdata,
1603 result = OC_STACK_ERROR;
1610 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
1616 OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(const HeaderOptions& headerOptions)
1618 if ( headerOptions.size() == 0)
1623 OCHeaderOption* options = new OCHeaderOption[headerOptions.size()]();
1625 size_t numOptions = 0;
1626 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
1628 OCStackResult ret = OCSetHeaderOption(options, &numOptions, it->getOptionID(),
1629 it->getOptionData().c_str(), it->getOptionData().length());
1630 if (OC_STACK_OK != ret)
1632 OIC_LOG_V(ERROR, TAG, "Failed to convert vnd header options! (error=%d)", ret);
1641 std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
1648 OCDPDev_t* result = new OCDPDev_t(*dev);
1649 result->prm = new OCPrm_t[dev->prmLen];
1650 memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
1651 return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
1654 void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
1658 dpList.push_back(cloneDevice(list));
1663 OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
1664 GetDirectPairedCallback& callback)
1666 if (!callback || 0 == waittime)
1668 return OC_STACK_INVALID_PARAM;
1671 OCStackResult result = OC_STACK_ERROR;
1672 const OCDPDev_t *list = nullptr;
1673 PairedDevices dpDeviceList;
1675 auto cLock = m_csdkLock.lock();
1679 std::lock_guard<std::recursive_mutex> lock(*cLock);
1681 list = OCDiscoverDirectPairingDevices(waittime);
1684 result = OC_STACK_NO_RESOURCE;
1685 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1689 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1690 convert(list, dpDeviceList);
1691 std::thread exec(callback, dpDeviceList);
1693 result = OC_STACK_OK;
1698 result = OC_STACK_ERROR;
1704 OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
1708 return OC_STACK_INVALID_PARAM;
1711 OCStackResult result = OC_STACK_ERROR;
1712 const OCDPDev_t *list = nullptr;
1713 PairedDevices dpDeviceList;
1715 auto cLock = m_csdkLock.lock();
1719 std::lock_guard<std::recursive_mutex> lock(*cLock);
1721 list = OCGetDirectPairedDevices();
1724 result = OC_STACK_NO_RESOURCE;
1725 OIC_LOG_V(DEBUG, TAG, "%s: No device found for direct pairing", __func__);
1728 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1729 convert(list, dpDeviceList);
1730 std::thread exec(callback, dpDeviceList);
1732 result = OC_STACK_OK;
1737 result = OC_STACK_ERROR;
1743 void directPairingCallback(void *ctx, OCDPDev_t *peer,
1744 OCStackResult result)
1747 ClientCallbackContext::DirectPairingContext* context =
1748 static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
1750 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1751 std::thread exec(context->callback, cloneDevice(peer), result);
1755 OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
1756 const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
1758 if (!peer || !callback)
1760 oclog() << "Invalid parameters" << std::flush;
1761 return OC_STACK_INVALID_PARAM;
1764 OCStackResult result = OC_STACK_ERROR;
1765 ClientCallbackContext::DirectPairingContext* context =
1766 new ClientCallbackContext::DirectPairingContext(callback);
1768 auto cLock = m_csdkLock.lock();
1771 std::lock_guard<std::recursive_mutex> lock(*cLock);
1772 result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
1773 pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
1778 result = OC_STACK_ERROR;
1783 OCStackApplicationResult KeepAliveRespCallback(void* ctx,
1784 OCDoHandle /*handle*/,
1785 OCClientResponse* clientResponse)
1787 ClientCallbackContext::KeepAliveContext* context =
1788 static_cast<ClientCallbackContext::KeepAliveContext*>(ctx);
1789 OCRepresentation attrs;
1790 OCStackResult result = clientResponse->result;
1794 attrs = parseGetSetCallback(clientResponse);
1796 catch(OC::OCException& e)
1801 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1802 std::thread exec(context->callback, result, attrs);
1804 return OC_STACK_DELETE_TRANSACTION;
1807 OCStackResult InProcClientWrapper::findKeepAliveResource(std::string host,
1808 KeepAliveCallback resultCallback)
1810 if (host.empty() || !resultCallback)
1812 oclog() << "Invalid parameters" << std::flush;
1813 return OC_STACK_INVALID_PARAM;
1816 OCStackResult result = OC_STACK_ERROR;
1818 ClientCallbackContext::KeepAliveContext* ctx =
1819 new ClientCallbackContext::KeepAliveContext(resultCallback);
1820 OCCallbackData cbdata;
1821 cbdata.context = static_cast<void*>(ctx),
1822 cbdata.cb = KeepAliveRespCallback;
1823 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1825 auto cLock = m_csdkLock.lock();
1829 std::lock_guard<std::recursive_mutex> lock(*cLock);
1830 result = OCFindKeepAliveResource(nullptr, host.c_str(), &cbdata);
1835 result = OC_STACK_ERROR;
1840 OCStackResult InProcClientWrapper::sendKeepAliveRequest(std::string host,
1841 const OCRepresentation& rep,
1842 KeepAliveCallback resultCallback)
1844 if (!resultCallback)
1846 oclog() << "Invalid parameters" << std::flush;
1847 return OC_STACK_INVALID_PARAM;
1850 OCStackResult result = OC_STACK_ERROR;
1852 ClientCallbackContext::KeepAliveContext* ctx = new ClientCallbackContext::KeepAliveContext(resultCallback);
1853 OCCallbackData cbdata;
1854 cbdata.context = static_cast<void*>(ctx),
1855 cbdata.cb = KeepAliveRespCallback;
1856 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1858 auto cLock = m_csdkLock.lock();
1862 std::lock_guard<std::recursive_mutex> lock(*cLock);
1863 OCRepPayload *payload = rep.getPayload();
1864 result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
1869 result = OC_STACK_ERROR;