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 #ifdef WITH_PROCESS_EVENT
68 if (false == m_threadRun)
70 m_processEvent = oc_event_new();
73 OIC_LOG(INFO, TAG, "oc_event_new failed!");
74 return OC_STACK_ERROR;
78 OCTransportFlags serverFlags =
79 static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
80 OCTransportFlags clientFlags =
81 static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
82 OCStackResult result = OCInit2(OC_CLIENT, serverFlags, clientFlags,
85 if (OC_STACK_OK != result)
87 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
90 if (false == m_threadRun)
93 #ifdef WITH_PROCESS_EVENT
94 OCRegisterProcessEvent(m_processEvent);
96 m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
102 OCStackResult InProcClientWrapper::stop()
104 OIC_LOG(INFO, TAG, "stop ocplatform");
106 // only stop if we are the ones who actually called 'start'. We are counting
107 // on the server to do the stop.
108 if (m_cfg.mode == ModeType::Client)
110 if (m_threadRun && m_listeningThread.joinable())
113 #ifdef WITH_PROCESS_EVENT
116 oc_event_signal(m_processEvent);
119 m_listeningThread.join();
121 OCStackResult result = OCStop();
123 if (OC_STACK_OK != result)
125 throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
128 #ifdef WITH_PROCESS_EVENT
131 oc_event_free(m_processEvent);
132 m_processEvent = NULL;
139 void InProcClientWrapper::listeningFunc()
143 OCStackResult result;
144 #ifdef WITH_PROCESS_EVENT
145 uint32_t nextEventTime;
147 auto cLock = m_csdkLock.lock();
150 std::lock_guard<std::recursive_mutex> lock(*cLock);
151 #ifdef WITH_PROCESS_EVENT
152 result = OCProcessEvent(&nextEventTime);
154 result = OCProcess();
159 result = OC_STACK_ERROR;
162 if (result != OC_STACK_OK)
164 // TODO: do something with result if failed?
167 #ifdef WITH_PROCESS_EVENT
168 oc_event_wait_for(m_processEvent, nextEventTime);
170 // To minimize CPU utilization we may wish to do this with sleep
171 std::this_thread::sleep_for(std::chrono::milliseconds(10));
176 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
178 if (clientResponse->payload == nullptr ||
180 clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
184 return OCRepresentation();
188 oc.setPayload(clientResponse->payload);
190 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
191 if (it == oc.representations().end())
193 return OCRepresentation();
196 // first one is considered the root, everything else is considered a child of this one.
197 OCRepresentation root = *it;
198 root.setDevAddr(clientResponse->devAddr);
199 root.setUri(clientResponse->resourceUri);
202 std::for_each(it, oc.representations().end(),
203 [&root](const OCRepresentation& repItr)
204 {root.addChild(repItr);});
208 OCStackApplicationResult listenCallback(void* ctx, OCDoHandle /*handle*/,
209 OCClientResponse* clientResponse)
211 if (!ctx || !clientResponse)
213 return OC_STACK_KEEP_TRANSACTION;
216 ClientCallbackContext::ListenContext* context =
217 static_cast<ClientCallbackContext::ListenContext*>(ctx);
219 if (clientResponse->result != OC_STACK_OK)
221 oclog() << "listenCallback(): failed to create resource. clientResponse: "
222 << clientResponse->result
225 return OC_STACK_KEEP_TRANSACTION;
228 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
230 oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
232 return OC_STACK_KEEP_TRANSACTION;
235 auto clientWrapper = context->clientWrapper.lock();
239 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
241 return OC_STACK_KEEP_TRANSACTION;
246 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
247 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
248 // loop to ensure valid construction of all resources
250 for(auto resource : container.Resources())
252 std::thread exec(context->callback, resource);
256 catch (std::exception &e)
258 oclog() << "Exception in listCallback, ignoring response: "
259 << e.what() << std::flush;
263 return OC_STACK_KEEP_TRANSACTION;
266 OCStackApplicationResult listenErrorCallback(void* ctx, OCDoHandle /*handle*/,
267 OCClientResponse* clientResponse)
269 if (!ctx || !clientResponse)
271 return OC_STACK_KEEP_TRANSACTION;
274 ClientCallbackContext::ListenErrorContext* context =
275 static_cast<ClientCallbackContext::ListenErrorContext*>(ctx);
277 OCStackResult result = clientResponse->result;
278 if (result == OC_STACK_OK)
280 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
282 OIC_LOG_V(DEBUG, TAG, "%s: clientResponse payload was null or the wrong type",
284 return OC_STACK_KEEP_TRANSACTION;
287 auto clientWrapper = context->clientWrapper.lock();
291 OIC_LOG_V(DEBUG, TAG, "%s: failed to get a shared_ptr to the client wrapper",
293 return OC_STACK_KEEP_TRANSACTION;
296 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
297 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
298 // loop to ensure valid construction of all resources
299 for (auto resource : container.Resources())
301 std::thread exec(context->callback, resource);
304 return OC_STACK_KEEP_TRANSACTION;
307 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
308 std::string resourceURI;
309 if(NULL != clientResponse->resourceUri)
311 resourceURI = clientResponse->resourceUri;
314 std::thread exec(context->errorCallback, resourceURI, result);
316 return OC_STACK_KEEP_TRANSACTION;
319 OCStackResult InProcClientWrapper::ListenForResource(
320 const std::string& serviceUrl,
321 const std::string& resourceType,
322 OCConnectivityType connectivityType,
323 FindCallback& callback, QualityOfService QoS)
327 return OC_STACK_INVALID_PARAM;
330 OCStackResult result;
331 ostringstream resourceUri;
332 resourceUri << serviceUrl << resourceType;
334 ClientCallbackContext::ListenContext* context =
335 new ClientCallbackContext::ListenContext(callback, shared_from_this());
336 OCCallbackData cbdata;
337 cbdata.context = static_cast<void*>(context),
338 cbdata.cb = listenCallback;
339 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;};
341 auto cLock = m_csdkLock.lock();
344 std::lock_guard<std::recursive_mutex> lock(*cLock);
345 result = OCDoResource(nullptr, OC_REST_DISCOVER,
346 resourceUri.str().c_str(),
347 nullptr, nullptr, connectivityType,
348 static_cast<OCQualityOfService>(QoS),
355 result = OC_STACK_ERROR;
360 OCStackResult InProcClientWrapper::ListenErrorForResource(
361 const std::string& serviceUrl,
362 const std::string& resourceType,
363 OCConnectivityType connectivityType,
364 FindCallback& callback, FindErrorCallback& errorCallback,
365 QualityOfService QoS)
369 return OC_STACK_INVALID_PARAM;
372 ostringstream resourceUri;
373 resourceUri << serviceUrl << resourceType;
375 ClientCallbackContext::ListenErrorContext* context =
376 new ClientCallbackContext::ListenErrorContext(callback, errorCallback,
380 return OC_STACK_ERROR;
383 OCCallbackData cbdata(
384 static_cast<void*>(context),
386 [](void* c){delete static_cast<ClientCallbackContext::ListenErrorContext*>(c);}
389 OCStackResult result;
390 auto cLock = m_csdkLock.lock();
393 std::lock_guard<std::recursive_mutex> lock(*cLock);
394 result = OCDoResource(nullptr, OC_REST_DISCOVER,
395 resourceUri.str().c_str(),
396 nullptr, nullptr, connectivityType,
397 static_cast<OCQualityOfService>(QoS),
404 result = OC_STACK_ERROR;
409 OCStackApplicationResult listenResListCallback(void* ctx, OCDoHandle /*handle*/,
410 OCClientResponse* clientResponse)
412 if (!ctx || !clientResponse)
414 return OC_STACK_KEEP_TRANSACTION;
417 ClientCallbackContext::ListenResListContext* context =
418 static_cast<ClientCallbackContext::ListenResListContext*>(ctx);
420 if (clientResponse->result != OC_STACK_OK)
422 oclog() << "listenResListCallback(): failed to create resource. clientResponse: "
423 << clientResponse->result
426 return OC_STACK_KEEP_TRANSACTION;
429 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
431 oclog() << "listenResListCallback(): clientResponse payload was null or the wrong type"
433 return OC_STACK_KEEP_TRANSACTION;
436 auto clientWrapper = context->clientWrapper.lock();
440 oclog() << "listenResListCallback(): failed to get a shared_ptr to the client wrapper"
442 return OC_STACK_KEEP_TRANSACTION;
447 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
448 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
450 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
451 std::thread exec(context->callback, container.Resources());
454 catch (std::exception &e)
456 oclog() << "Exception in listenResListCallback(), ignoring response: "
457 << e.what() << std::flush;
460 return OC_STACK_KEEP_TRANSACTION;
463 OCStackResult InProcClientWrapper::ListenForResourceList(
464 const std::string& serviceUrl,
465 const std::string& resourceType,
466 OCConnectivityType connectivityType,
467 FindResListCallback& callback, QualityOfService QoS)
471 return OC_STACK_INVALID_PARAM;
474 OCStackResult result;
475 ostringstream resourceUri;
476 resourceUri << serviceUrl << resourceType;
478 ClientCallbackContext::ListenResListContext* context =
479 new ClientCallbackContext::ListenResListContext(callback, shared_from_this());
480 OCCallbackData cbdata;
481 cbdata.context = static_cast<void*>(context),
482 cbdata.cb = listenResListCallback;
483 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListContext*)c;};
485 auto cLock = m_csdkLock.lock();
488 std::lock_guard<std::recursive_mutex> lock(*cLock);
489 result = OCDoResource(nullptr, OC_REST_DISCOVER,
490 resourceUri.str().c_str(),
491 nullptr, nullptr, connectivityType,
492 static_cast<OCQualityOfService>(QoS),
499 result = OC_STACK_ERROR;
504 OCStackApplicationResult listenResListWithErrorCallback(void* ctx, OCDoHandle /*handle*/,
505 OCClientResponse* clientResponse)
507 if (!ctx || !clientResponse)
509 return OC_STACK_KEEP_TRANSACTION;
512 ClientCallbackContext::ListenResListWithErrorContext* context =
513 static_cast<ClientCallbackContext::ListenResListWithErrorContext*>(ctx);
515 OCStackResult result = clientResponse->result;
516 if (result != OC_STACK_OK)
518 oclog() << "listenResListWithErrorCallback(): failed to create resource. clientResponse: "
519 << result << std::flush;
521 //send the error callback
523 if(NULL != clientResponse->resourceUri)
525 uri = clientResponse->resourceUri;
527 std::thread exec(context->errorCallback, uri, result);
529 return OC_STACK_KEEP_TRANSACTION;
532 if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
534 oclog() << "listenResListWithErrorCallback(): clientResponse payload was null or the wrong type"
536 return OC_STACK_KEEP_TRANSACTION;
539 auto clientWrapper = context->clientWrapper.lock();
543 oclog() << "listenResListWithErrorCallback(): failed to get a shared_ptr to the client wrapper"
545 return OC_STACK_KEEP_TRANSACTION;
550 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
551 reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
553 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
554 std::thread exec(context->callback, container.Resources());
557 catch (std::exception &e)
559 oclog() << "Exception in listenResListWithErrorCallback(), ignoring response: "
560 << e.what() << std::flush;
563 return OC_STACK_KEEP_TRANSACTION;
566 OCStackResult InProcClientWrapper::ListenForResourceListWithError(
567 const std::string& serviceUrl,
568 const std::string& resourceType,
569 OCConnectivityType connectivityType,
570 FindResListCallback& callback,
571 FindErrorCallback& errorCallback, QualityOfService QoS)
575 return OC_STACK_INVALID_PARAM;
578 OCStackResult result;
579 ostringstream resourceUri;
580 resourceUri << serviceUrl << resourceType;
582 ClientCallbackContext::ListenResListWithErrorContext* context =
583 new ClientCallbackContext::ListenResListWithErrorContext(callback, errorCallback,
587 return OC_STACK_ERROR;
590 OCCallbackData cbdata;
591 cbdata.context = static_cast<void*>(context),
592 cbdata.cb = listenResListWithErrorCallback;
593 cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListWithErrorContext*)c;};
595 auto cLock = m_csdkLock.lock();
598 std::lock_guard<std::recursive_mutex> lock(*cLock);
599 result = OCDoResource(nullptr, OC_REST_DISCOVER,
600 resourceUri.str().c_str(),
601 nullptr, nullptr, connectivityType,
602 static_cast<OCQualityOfService>(QoS),
609 result = OC_STACK_ERROR;
615 OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/,
616 OCClientResponse* clientResponse)
618 ClientCallbackContext::MQTopicContext* context =
619 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
621 if (!clientResponse || !context)
623 return OC_STACK_DELETE_TRANSACTION;
626 std::string resourceURI;
627 if(NULL != clientResponse->resourceUri)
629 resourceURI = clientResponse->resourceUri;
632 if (clientResponse->result != OC_STACK_OK)
634 oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
635 << clientResponse->result
638 std::thread exec(context->callback, clientResponse->result,
639 resourceURI, nullptr);
642 return OC_STACK_DELETE_TRANSACTION;
645 auto clientWrapper = context->clientWrapper.lock();
648 oclog() << "listenMQCallback(): failed to get a shared_ptr to the client wrapper"
650 return OC_STACK_DELETE_TRANSACTION;
655 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
656 (OCRepPayload *) clientResponse->payload);
658 // loop to ensure valid construction of all resources
659 for (auto resource : container.Resources())
661 std::thread exec(context->callback, clientResponse->result,
662 resourceURI, resource);
666 catch (std::exception &e)
668 oclog() << "Exception in listCallback, ignoring response: "
669 << e.what() << std::flush;
672 return OC_STACK_DELETE_TRANSACTION;
675 OCStackResult InProcClientWrapper::ListenForMQTopic(const OCDevAddr& devAddr,
676 const std::string& resourceUri,
677 const QueryParamsMap& queryParams,
678 const HeaderOptions& headerOptions,
679 MQTopicCallback& callback,
680 QualityOfService QoS)
682 oclog() << "ListenForMQTopic()" << std::flush;
686 return OC_STACK_INVALID_PARAM;
689 if (headerOptions.size() > MAX_HEADER_OPTIONS)
691 oclog() << "ListenForMQTopic: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
692 return OC_STACK_INVALID_PARAM;
695 ClientCallbackContext::MQTopicContext* context =
696 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
697 OCCallbackData cbdata;
698 cbdata.context = static_cast<void*>(context),
699 cbdata.cb = listenMQCallback;
700 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
702 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
704 OCStackResult result = OC_STACK_ERROR;
705 auto cLock = m_csdkLock.lock();
708 std::lock_guard<std::recursive_mutex> lock(*cLock);
709 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
710 result = OCDoResource(
711 nullptr, OC_REST_GET,
715 static_cast<OCQualityOfService>(QoS),
718 headerOptions.size());
730 OCStackApplicationResult listenDeviceCallback(void* ctx,
731 OCDoHandle /*handle*/,
732 OCClientResponse* clientResponse)
734 ClientCallbackContext::DeviceListenContext* context =
735 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
739 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
740 OCRepresentation rep = parseGetSetCallback(clientResponse);
741 std::thread exec(context->callback, rep);
744 catch(OC::OCException& e)
746 oclog() <<"Exception in listenDeviceCallback, ignoring response: "
747 <<e.what() <<std::flush;
750 return OC_STACK_KEEP_TRANSACTION;
753 OCStackResult InProcClientWrapper::ListenForDevice(
754 const std::string& serviceUrl,
755 const std::string& deviceURI,
756 OCConnectivityType connectivityType,
757 FindDeviceCallback& callback,
758 QualityOfService QoS)
762 return OC_STACK_INVALID_PARAM;
764 OCStackResult result;
765 ostringstream deviceUri;
766 deviceUri << serviceUrl << deviceURI;
768 ClientCallbackContext::DeviceListenContext* context =
769 new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
770 OCCallbackData cbdata;
772 cbdata.context = static_cast<void*>(context),
773 cbdata.cb = listenDeviceCallback;
774 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeviceListenContext*)c;};
776 auto cLock = m_csdkLock.lock();
779 std::lock_guard<std::recursive_mutex> lock(*cLock);
780 result = OCDoResource(nullptr, OC_REST_DISCOVER,
781 deviceUri.str().c_str(),
782 nullptr, nullptr, connectivityType,
783 static_cast<OCQualityOfService>(QoS),
790 result = OC_STACK_ERROR;
795 void parseServerHeaderOptions(OCClientResponse* clientResponse,
796 HeaderOptions& serverHeaderOptions)
800 // Parse header options from server
802 std::string optionData;
804 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
806 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
807 optionData = reinterpret_cast<const char*>
808 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
809 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
810 serverHeaderOptions.push_back(headerOption);
815 // clientResponse is invalid
816 // TODO check proper logging
817 std::cout << " Invalid response " << std::endl;
822 OCStackApplicationResult createMQTopicCallback(void* ctx, OCDoHandle /*handle*/,
823 OCClientResponse* clientResponse)
825 ClientCallbackContext::MQTopicContext* context =
826 static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
827 HeaderOptions serverHeaderOptions;
829 if (!clientResponse || !context)
831 return OC_STACK_DELETE_TRANSACTION;
834 std::string createdUri;
835 bool isLocationOption = false;
836 OCStackResult result = clientResponse->result;
837 if (OC_STACK_OK == result ||
838 OC_STACK_RESOURCE_CREATED == result)
840 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
842 for (auto headerOption : serverHeaderOptions)
844 if (HeaderOption::LOCATION_PATH_OPTION_ID == headerOption.getOptionID())
847 createdUri += headerOption.getOptionData();
848 if (!isLocationOption)
850 isLocationOption = true;
856 if (!isLocationOption && NULL != clientResponse->resourceUri)
858 createdUri = std::string(clientResponse->resourceUri);
861 auto clientWrapper = context->clientWrapper.lock();
865 oclog() << "createMQTopicCallback(): failed to get a shared_ptr to the client wrapper"
867 return OC_STACK_DELETE_TRANSACTION;
872 if (OC_STACK_OK == result ||
873 OC_STACK_RESOURCE_CREATED == result)
875 ListenOCContainer container(clientWrapper, clientResponse->devAddr,
877 for (auto resource : container.Resources())
879 std::thread exec(context->callback, result,
887 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
888 std::thread exec(context->callback, result,
894 catch (std::exception &e)
896 oclog() << "Exception in createMQTopicCallback, ignoring response: "
897 << e.what() << std::flush;
899 return OC_STACK_DELETE_TRANSACTION;
902 OCStackResult InProcClientWrapper::PutMQTopicRepresentation(
903 const OCDevAddr& devAddr,
904 const std::string& uri,
905 const OCRepresentation& rep,
906 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
907 MQTopicCallback& callback, QualityOfService QoS)
911 return OC_STACK_INVALID_PARAM;
914 if (headerOptions.size() > MAX_HEADER_OPTIONS)
916 oclog() << "PutMQTopicRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
917 return OC_STACK_INVALID_PARAM;
920 OCStackResult result;
921 ClientCallbackContext::MQTopicContext* ctx =
922 new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
923 OCCallbackData cbdata;
924 cbdata.context = static_cast<void*>(ctx),
925 cbdata.cb = createMQTopicCallback;
926 cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
928 std::string url = assembleSetResourceUri(uri, queryParams);
930 auto cLock = m_csdkLock.lock();
934 std::lock_guard<std::recursive_mutex> lock(*cLock);
935 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
937 result = OCDoResource(nullptr, OC_REST_PUT,
938 url.c_str(), &devAddr,
939 assembleSetResourcePayload(rep),
941 static_cast<OCQualityOfService>(QoS),
944 headerOptions.size());
950 result = OC_STACK_ERROR;
956 OCStackApplicationResult getResourceCallback(void* ctx,
957 OCDoHandle /*handle*/,
958 OCClientResponse* clientResponse)
960 ClientCallbackContext::GetContext* context =
961 static_cast<ClientCallbackContext::GetContext*>(ctx);
962 OCRepresentation rep;
963 HeaderOptions serverHeaderOptions;
964 OCStackResult result = clientResponse->result;
966 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
969 rep = parseGetSetCallback(clientResponse);
970 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
971 std::thread exec(context->callback, serverHeaderOptions, rep, result);
974 catch(OC::OCException& e)
976 oclog() << "Exception in parseGetSetCallback, ignoring callback: "
977 << e.what() << std::flush;
979 catch(const std::exception& e)
981 oclog() << "Exception in thread execution, ignoring callback: "
982 << e.what() << std::flush;
985 return OC_STACK_DELETE_TRANSACTION;
988 OCStackResult InProcClientWrapper::GetResourceRepresentation(
989 const OCDevAddr& devAddr,
990 const std::string& resourceUri,
991 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
992 OCConnectivityType connectivityType,
993 GetCallback& callback, QualityOfService QoS)
997 return OC_STACK_INVALID_PARAM;
1000 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1002 oclog() << "GetResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1003 return OC_STACK_INVALID_PARAM;
1006 OCStackResult result;
1007 ClientCallbackContext::GetContext* ctx =
1008 new ClientCallbackContext::GetContext(callback);
1010 OCCallbackData cbdata;
1011 cbdata.context = static_cast<void*>(ctx);
1012 cbdata.cb = getResourceCallback;
1013 cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
1015 std::string uri = assembleSetResourceUri(resourceUri, queryParams);
1017 auto cLock = m_csdkLock.lock();
1021 std::lock_guard<std::recursive_mutex> lock(*cLock);
1022 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1024 result = OCDoResource(
1025 nullptr, OC_REST_GET,
1029 static_cast<OCQualityOfService>(QoS),
1032 headerOptions.size());
1038 result = OC_STACK_ERROR;
1044 OCStackApplicationResult setResourceCallback(void* ctx,
1045 OCDoHandle /*handle*/,
1046 OCClientResponse* clientResponse)
1048 ClientCallbackContext::SetContext* context =
1049 static_cast<ClientCallbackContext::SetContext*>(ctx);
1050 OCRepresentation attrs;
1051 HeaderOptions serverHeaderOptions;
1053 OCStackResult result = clientResponse->result;
1055 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1058 attrs = parseGetSetCallback(clientResponse);
1060 catch(OC::OCException& e)
1065 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1066 std::thread exec(context->callback, serverHeaderOptions, attrs, result);
1068 return OC_STACK_DELETE_TRANSACTION;
1071 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1072 const QueryParamsMap& queryParams)
1076 if (uri.back() == '/')
1078 uri.resize(uri.size() - 1);
1082 ostringstream paramsList;
1083 if (queryParams.size() > 0)
1088 for (auto& param : queryParams)
1090 paramsList << param.first <<'='<<param.second<<';';
1093 std::string queryString = paramsList.str();
1095 if (queryString.empty())
1100 if (queryString.back() == ';')
1102 queryString.resize(queryString.size() - 1);
1105 std::string ret = uri + queryString;
1109 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
1110 const QueryParamsList& queryParams)
1114 if (uri.back() == '/')
1116 uri.resize(uri.size() - 1);
1120 ostringstream paramsList;
1121 if (queryParams.size() > 0)
1126 for (auto& param : queryParams)
1128 for (auto& paramList : param.second)
1130 paramsList << param.first << '=' << paramList << ';';
1134 std::string queryString = paramsList.str();
1136 if (queryString.empty())
1141 if (queryString.back() == ';')
1143 queryString.resize(queryString.size() - 1);
1146 std::string ret = uri + queryString;
1150 OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
1152 MessageContainer ocInfo;
1153 ocInfo.addRepresentation(rep);
1154 for(const OCRepresentation& r : rep.getChildren())
1156 ocInfo.addRepresentation(r);
1159 return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
1162 OCStackResult InProcClientWrapper::PostResourceRepresentation(
1163 const OCDevAddr& devAddr,
1164 const std::string& uri,
1165 const OCRepresentation& rep,
1166 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1167 OCConnectivityType connectivityType,
1168 PostCallback& callback, QualityOfService QoS)
1172 return OC_STACK_INVALID_PARAM;
1175 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1177 oclog() << "PostResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1178 return OC_STACK_INVALID_PARAM;
1181 OCStackResult result;
1182 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1183 OCCallbackData cbdata;
1184 cbdata.context = static_cast<void*>(ctx),
1185 cbdata.cb = setResourceCallback;
1186 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1189 std::string url = assembleSetResourceUri(uri, queryParams);
1191 auto cLock = m_csdkLock.lock();
1195 std::lock_guard<std::recursive_mutex> lock(*cLock);
1196 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1198 result = OCDoResource(nullptr, OC_REST_POST,
1199 url.c_str(), &devAddr,
1200 assembleSetResourcePayload(rep),
1202 static_cast<OCQualityOfService>(QoS),
1205 headerOptions.size());
1211 result = OC_STACK_ERROR;
1217 OCStackResult InProcClientWrapper::PutResourceRepresentation(
1218 const OCDevAddr& devAddr,
1219 const std::string& uri,
1220 const OCRepresentation& rep,
1221 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1222 PutCallback& callback, QualityOfService QoS)
1226 return OC_STACK_INVALID_PARAM;
1229 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1231 oclog() << "PutResourceRepresentation: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1232 return OC_STACK_INVALID_PARAM;
1235 OCStackResult result;
1236 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
1237 OCCallbackData cbdata;
1238 cbdata.context = static_cast<void*>(ctx),
1239 cbdata.cb = setResourceCallback;
1240 cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;};
1243 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1245 auto cLock = m_csdkLock.lock();
1249 std::lock_guard<std::recursive_mutex> lock(*cLock);
1251 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1253 result = OCDoResource(&handle, OC_REST_PUT,
1254 url.c_str(), &devAddr,
1255 assembleSetResourcePayload(rep),
1257 static_cast<OCQualityOfService>(QoS),
1260 headerOptions.size());
1266 result = OC_STACK_ERROR;
1272 OCStackApplicationResult deleteResourceCallback(void* ctx,
1273 OCDoHandle /*handle*/,
1274 OCClientResponse* clientResponse)
1276 ClientCallbackContext::DeleteContext* context =
1277 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
1278 HeaderOptions serverHeaderOptions;
1280 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1282 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1283 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
1285 return OC_STACK_DELETE_TRANSACTION;
1288 OCStackResult InProcClientWrapper::DeleteResource(
1289 const OCDevAddr& devAddr,
1290 const std::string& uri,
1291 const HeaderOptions& headerOptions,
1292 OCConnectivityType connectivityType,
1293 DeleteCallback& callback,
1294 QualityOfService /*QoS*/)
1298 return OC_STACK_INVALID_PARAM;
1301 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1303 oclog() << "DeleteResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1304 return OC_STACK_INVALID_PARAM;
1307 OCStackResult result;
1308 ClientCallbackContext::DeleteContext* ctx =
1309 new ClientCallbackContext::DeleteContext(callback);
1310 OCCallbackData cbdata;
1311 cbdata.context = static_cast<void*>(ctx),
1312 cbdata.cb = deleteResourceCallback;
1313 cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;};
1316 auto cLock = m_csdkLock.lock();
1320 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1322 std::lock_guard<std::recursive_mutex> lock(*cLock);
1324 result = OCDoResource(nullptr, OC_REST_DELETE,
1325 uri.c_str(), &devAddr,
1328 static_cast<OCQualityOfService>(m_cfg.QoS),
1331 headerOptions.size());
1337 result = OC_STACK_ERROR;
1343 OCStackApplicationResult observeResourceCallback(void* ctx,
1344 OCDoHandle /*handle*/,
1345 OCClientResponse* clientResponse)
1347 ClientCallbackContext::ObserveContext* context =
1348 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
1349 OCRepresentation attrs;
1350 HeaderOptions serverHeaderOptions;
1351 uint32_t sequenceNumber = clientResponse->sequenceNumber;
1352 OCStackResult result = clientResponse->result;
1354 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
1357 attrs = parseGetSetCallback(clientResponse);
1359 catch(OC::OCException& e)
1364 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1365 std::thread exec(context->callback, serverHeaderOptions, attrs,
1366 result, sequenceNumber);
1368 if (sequenceNumber == MAX_SEQUENCE_NUMBER + 1)
1370 return OC_STACK_DELETE_TRANSACTION;
1373 return OC_STACK_KEEP_TRANSACTION;
1376 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
1377 const OCDevAddr& devAddr,
1378 const std::string& uri,
1379 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
1380 ObserveCallback& callback, QualityOfService QoS)
1384 return OC_STACK_INVALID_PARAM;
1387 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1389 oclog() << "ObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1390 return OC_STACK_INVALID_PARAM;
1393 OCStackResult result;
1395 ClientCallbackContext::ObserveContext* ctx =
1396 new ClientCallbackContext::ObserveContext(callback);
1397 OCCallbackData cbdata;
1398 cbdata.context = static_cast<void*>(ctx),
1399 cbdata.cb = observeResourceCallback;
1400 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1404 if (observeType == ObserveType::Observe)
1406 method = OC_REST_OBSERVE;
1408 else if (observeType == ObserveType::ObserveAll)
1410 method = OC_REST_OBSERVE_ALL;
1414 method = OC_REST_OBSERVE_ALL;
1417 std::string url = assembleSetResourceUri(uri, queryParams).c_str();
1419 auto cLock = m_csdkLock.lock();
1423 std::lock_guard<std::recursive_mutex> lock(*cLock);
1424 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1426 result = OCDoResource(handle, method,
1427 url.c_str(), &devAddr,
1430 static_cast<OCQualityOfService>(QoS),
1433 headerOptions.size());
1439 return OC_STACK_ERROR;
1445 OCStackResult InProcClientWrapper::CancelObserveResource(
1447 const std::string& /*host*/,
1448 const std::string& /*uri*/,
1449 const HeaderOptions& headerOptions,
1450 QualityOfService QoS)
1452 if (headerOptions.size() > MAX_HEADER_OPTIONS)
1454 oclog() << "CancelObserveResource: Header options are more than MAX_HEADER_OPTIONS" << std::flush;
1455 return OC_STACK_INVALID_PARAM;
1458 OCStackResult result;
1459 auto cLock = m_csdkLock.lock();
1463 std::lock_guard<std::recursive_mutex> lock(*cLock);
1464 OCHeaderOption *options = assembleHeaderOptions(headerOptions);
1466 result = OCCancel(handle,
1467 static_cast<OCQualityOfService>(QoS),
1469 headerOptions.size());
1474 result = OC_STACK_ERROR;
1480 #ifdef WITH_PRESENCE
1481 OCStackApplicationResult subscribePresenceCallback(void* ctx,
1482 OCDoHandle /*handle*/,
1483 OCClientResponse* clientResponse)
1485 ClientCallbackContext::SubscribePresenceContext* context =
1486 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
1489 * This a hack while we rethink presence subscription.
1491 std::string url = clientResponse->devAddr.addr;
1493 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1494 std::thread exec(context->callback, clientResponse->result,
1495 clientResponse->sequenceNumber, url);
1499 return OC_STACK_KEEP_TRANSACTION;
1503 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
1504 const std::string& host, const std::string& resourceType,
1505 OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
1507 #ifdef WITH_PRESENCE
1508 if (!presenceHandler)
1510 return OC_STACK_INVALID_PARAM;
1513 ClientCallbackContext::SubscribePresenceContext* ctx =
1514 new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
1515 OCCallbackData cbdata;
1516 cbdata.context = static_cast<void*>(ctx),
1517 cbdata.cb = subscribePresenceCallback;
1518 cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;};
1521 auto cLock = m_csdkLock.lock();
1523 std::ostringstream os;
1524 os << host << OC_RSRVD_PRESENCE_URI;
1526 if (!resourceType.empty())
1528 os << "?rt=" << resourceType;
1534 return OC_STACK_ERROR;
1537 return OCDoResource(handle, OC_REST_PRESENCE,
1538 os.str().c_str(), nullptr,
1539 nullptr, connectivityType,
1540 OC_LOW_QOS, &cbdata, NULL, 0);
1542 return OC_STACK_NOT_IMPLEMENTED;
1546 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
1548 #ifdef WITH_PRESENCE
1549 OCStackResult result;
1550 auto cLock = m_csdkLock.lock();
1554 std::lock_guard<std::recursive_mutex> lock(*cLock);
1555 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1559 result = OC_STACK_ERROR;
1564 return OC_STACK_NOT_IMPLEMENTED;
1569 OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
1570 const std::string& host,
1571 const std::vector<std::string>& di,
1572 OCConnectivityType connectivityType,
1573 ObserveCallback& callback)
1577 return OC_STACK_INVALID_PARAM;
1579 OCStackResult result;
1581 ClientCallbackContext::ObserveContext* ctx =
1582 new ClientCallbackContext::ObserveContext(callback);
1583 OCCallbackData cbdata;
1584 cbdata.context = static_cast<void*>(ctx),
1585 cbdata.cb = observeResourceCallback;
1586 cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
1588 auto cLock = m_csdkLock.lock();
1592 std::lock_guard<std::recursive_mutex> lock(*cLock);
1594 std::ostringstream os;
1595 os << host << OC_RSRVD_DEVICE_PRESENCE_URI;
1596 QueryParamsList queryParams({{OC_RSRVD_DEVICE_ID, di}});
1597 std::string url = assembleSetResourceUri(os.str(), queryParams);
1599 result = OCDoResource(handle, OC_REST_OBSERVE,
1600 url.c_str(), nullptr,
1601 nullptr, connectivityType,
1602 OC_LOW_QOS, &cbdata,
1608 result = OC_STACK_ERROR;
1615 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
1621 OCHeaderOption* InProcClientWrapper::assembleHeaderOptions(const HeaderOptions& headerOptions)
1623 if ( headerOptions.size() == 0)
1628 OCHeaderOption* options = new OCHeaderOption[headerOptions.size()]();
1630 size_t numOptions = 0;
1631 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
1633 OCStackResult ret = OCSetHeaderOption(options, &numOptions, it->getOptionID(),
1634 it->getOptionData().c_str(), it->getOptionData().length());
1635 if (OC_STACK_OK != ret)
1637 OIC_LOG_V(ERROR, TAG, "Failed to convert vnd header options! (error=%d)", ret);
1646 std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
1653 OCDPDev_t* result = new OCDPDev_t(*dev);
1654 result->prm = new OCPrm_t[dev->prmLen];
1655 memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
1656 return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
1659 void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
1663 dpList.push_back(cloneDevice(list));
1668 OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
1669 GetDirectPairedCallback& callback)
1671 if (!callback || 0 == waittime)
1673 return OC_STACK_INVALID_PARAM;
1676 OCStackResult result = OC_STACK_ERROR;
1677 const OCDPDev_t *list = nullptr;
1678 PairedDevices dpDeviceList;
1680 auto cLock = m_csdkLock.lock();
1684 std::lock_guard<std::recursive_mutex> lock(*cLock);
1686 list = OCDiscoverDirectPairingDevices(waittime);
1689 result = OC_STACK_NO_RESOURCE;
1690 oclog() << "findDirectPairingDevices(): No device found for direct pairing"
1694 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1695 convert(list, dpDeviceList);
1696 std::thread exec(callback, dpDeviceList);
1698 result = OC_STACK_OK;
1703 result = OC_STACK_ERROR;
1709 OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
1713 return OC_STACK_INVALID_PARAM;
1716 OCStackResult result = OC_STACK_ERROR;
1717 const OCDPDev_t *list = nullptr;
1718 PairedDevices dpDeviceList;
1720 auto cLock = m_csdkLock.lock();
1724 std::lock_guard<std::recursive_mutex> lock(*cLock);
1726 list = OCGetDirectPairedDevices();
1729 result = OC_STACK_NO_RESOURCE;
1730 OIC_LOG_V(DEBUG, TAG, "%s: No device found for direct pairing", __func__);
1733 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1734 convert(list, dpDeviceList);
1735 std::thread exec(callback, dpDeviceList);
1737 result = OC_STACK_OK;
1742 result = OC_STACK_ERROR;
1748 void directPairingCallback(void *ctx, OCDPDev_t *peer,
1749 OCStackResult result)
1752 ClientCallbackContext::DirectPairingContext* context =
1753 static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
1755 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1756 std::thread exec(context->callback, cloneDevice(peer), result);
1760 OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
1761 const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
1763 if (!peer || !callback)
1765 oclog() << "Invalid parameters" << std::flush;
1766 return OC_STACK_INVALID_PARAM;
1769 OCStackResult result = OC_STACK_ERROR;
1770 ClientCallbackContext::DirectPairingContext* context =
1771 new ClientCallbackContext::DirectPairingContext(callback);
1773 auto cLock = m_csdkLock.lock();
1776 std::lock_guard<std::recursive_mutex> lock(*cLock);
1777 result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
1778 pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
1783 result = OC_STACK_ERROR;
1788 OCStackApplicationResult KeepAliveRespCallback(void* ctx,
1789 OCDoHandle /*handle*/,
1790 OCClientResponse* clientResponse)
1792 ClientCallbackContext::KeepAliveContext* context =
1793 static_cast<ClientCallbackContext::KeepAliveContext*>(ctx);
1794 OCRepresentation attrs;
1795 OCStackResult result = clientResponse->result;
1799 attrs = parseGetSetCallback(clientResponse);
1801 catch(OC::OCException& e)
1806 OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
1807 std::thread exec(context->callback, result, attrs);
1809 return OC_STACK_DELETE_TRANSACTION;
1812 OCStackResult InProcClientWrapper::findKeepAliveResource(std::string host,
1813 KeepAliveCallback resultCallback)
1815 if (host.empty() || !resultCallback)
1817 oclog() << "Invalid parameters" << std::flush;
1818 return OC_STACK_INVALID_PARAM;
1821 OCStackResult result = OC_STACK_ERROR;
1823 ClientCallbackContext::KeepAliveContext* ctx =
1824 new ClientCallbackContext::KeepAliveContext(resultCallback);
1825 OCCallbackData cbdata;
1826 cbdata.context = static_cast<void*>(ctx),
1827 cbdata.cb = KeepAliveRespCallback;
1828 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1830 auto cLock = m_csdkLock.lock();
1834 std::lock_guard<std::recursive_mutex> lock(*cLock);
1835 result = OCFindKeepAliveResource(nullptr, host.c_str(), &cbdata);
1840 result = OC_STACK_ERROR;
1845 OCStackResult InProcClientWrapper::sendKeepAliveRequest(std::string host,
1846 const OCRepresentation& rep,
1847 KeepAliveCallback resultCallback)
1849 if (!resultCallback)
1851 oclog() << "Invalid parameters" << std::flush;
1852 return OC_STACK_INVALID_PARAM;
1855 OCStackResult result = OC_STACK_ERROR;
1857 ClientCallbackContext::KeepAliveContext* ctx = new ClientCallbackContext::KeepAliveContext(resultCallback);
1858 OCCallbackData cbdata;
1859 cbdata.context = static_cast<void*>(ctx),
1860 cbdata.cb = KeepAliveRespCallback;
1861 cbdata.cd = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
1863 auto cLock = m_csdkLock.lock();
1867 std::lock_guard<std::recursive_mutex> lock(*cLock);
1868 OCRepPayload *payload = rep.getPayload();
1869 result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
1874 result = OC_STACK_ERROR;