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 <OCSerialization.h>
31 InProcClientWrapper::InProcClientWrapper(
32 std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
33 : m_threadRun(false), m_csdkLock(csdkLock),
36 // if the config type is server, we ought to never get called. If the config type
37 // is both, we count on the server to run the thread and do the initialize
39 if(m_cfg.mode == ModeType::Client)
41 OCStackResult result = OCInit(m_cfg.ipAddress.c_str(), m_cfg.port, OC_CLIENT);
43 if(OC_STACK_OK != result)
45 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
49 m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
53 InProcClientWrapper::~InProcClientWrapper()
55 if(m_threadRun && m_listeningThread.joinable())
58 m_listeningThread.join();
61 // only stop if we are the ones who actually called 'init'. We are counting
62 // on the server to do the stop.
63 if(m_cfg.mode == ModeType::Client)
69 void InProcClientWrapper::listeningFunc()
74 auto cLock = m_csdkLock.lock();
77 std::lock_guard<std::recursive_mutex> lock(*cLock);
82 result = OC_STACK_ERROR;
85 if(result != OC_STACK_OK)
87 // TODO: do something with result if failed?
90 // To minimize CPU utilization we may wish to do this with sleep
91 std::this_thread::sleep_for(std::chrono::milliseconds(10));
95 OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
97 if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
99 throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_ERROR);
103 oc.setJSONRepresentation(clientResponse->resJSONPayload);
105 std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
106 if(it == oc.representations().end())
108 throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_ERROR);
111 // first one is considered the root, everything else is considered a child of this one.
112 OCRepresentation root = *it;
115 std::for_each(it, oc.representations().end(),
116 [&root](const OCRepresentation& repItr)
117 {root.addChild(repItr);});
122 OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
123 OCClientResponse* clientResponse)
125 ClientCallbackContext::ListenContext* context =
126 static_cast<ClientCallbackContext::ListenContext*>(ctx);
128 if(clientResponse->result != OC_STACK_OK)
130 oclog() << "listenCallback(): failed to create resource. clientResponse: "
131 << clientResponse->result
134 return OC_STACK_KEEP_TRANSACTION;
137 auto clientWrapper = context->clientWrapper.lock();
141 oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
143 return OC_STACK_KEEP_TRANSACTION;
146 std::stringstream requestStream;
147 requestStream << clientResponse->resJSONPayload;
153 ListenOCContainer container(clientWrapper, *clientResponse->addr,
154 clientResponse->connType, requestStream);
156 ListenOCContainer container(clientWrapper, *clientResponse->addr,
159 // loop to ensure valid construction of all resources
160 for(auto resource : container.Resources())
162 std::thread exec(context->callback, resource);
167 catch(const std::exception& e)
169 oclog() << "listenCallback failed to parse a malformed message: "
172 << clientResponse->resJSONPayload
174 << clientResponse->result
176 return OC_STACK_KEEP_TRANSACTION;
179 return OC_STACK_KEEP_TRANSACTION;
183 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
184 const std::string& resourceType, uint8_t connectivityType,
185 FindCallback& callback, QualityOfService QoS)
187 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
188 const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
191 OCStackResult result;
193 OCCallbackData cbdata = {0};
195 ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext();
196 context->callback = callback;
197 context->clientWrapper = shared_from_this();
199 cbdata.context = static_cast<void*>(context);
200 cbdata.cb = listenCallback;
201 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);};
203 auto cLock = m_csdkLock.lock();
206 std::lock_guard<std::recursive_mutex> lock(*cLock);
209 result = OCDoResource(&handle, OC_REST_GET,
210 resourceType.c_str(),
211 nullptr, nullptr, connectivityType,
212 static_cast<OCQualityOfService>(QoS),
216 result = OCDoResource(&handle, OC_REST_GET,
217 resourceType.c_str(),
219 static_cast<OCQualityOfService>(QoS),
227 result = OC_STACK_ERROR;
232 OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
233 OCClientResponse* clientResponse)
235 ClientCallbackContext::DeviceListenContext* context =
236 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
238 OCRepresentation rep = parseGetSetCallback(clientResponse);
239 std::thread exec(context->callback, rep);
242 return OC_STACK_KEEP_TRANSACTION;
246 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
247 const std::string& deviceURI, uint8_t connectivityType,
248 FindDeviceCallback& callback, QualityOfService QoS)
250 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
251 const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
254 OCStackResult result;
256 OCCallbackData cbdata = {0};
257 ClientCallbackContext::DeviceListenContext* context =
258 new ClientCallbackContext::DeviceListenContext();
259 context->callback = callback;
260 context->clientWrapper = shared_from_this();
261 cbdata.context = static_cast<void*>(context);
262 cbdata.cb = listenDeviceCallback;
263 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
265 auto cLock = m_csdkLock.lock();
268 std::lock_guard<std::recursive_mutex> lock(*cLock);
271 result = OCDoResource(&handle, OC_REST_GET,
273 nullptr, nullptr, connectivityType,
274 static_cast<OCQualityOfService>(QoS),
278 result = OCDoResource(&handle, OC_REST_GET,
281 static_cast<OCQualityOfService>(QoS),
288 result = OC_STACK_ERROR;
293 void parseServerHeaderOptions(OCClientResponse* clientResponse,
294 HeaderOptions& serverHeaderOptions)
298 // Parse header options from server
300 std::string optionData;
302 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
304 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
305 optionData = reinterpret_cast<const char*>
306 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
307 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
308 serverHeaderOptions.push_back(headerOption);
313 // clientResponse is invalid
314 // TODO check proper logging
315 std::cout << " Invalid response " << std::endl;
319 OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle,
320 OCClientResponse* clientResponse)
322 ClientCallbackContext::GetContext* context =
323 static_cast<ClientCallbackContext::GetContext*>(ctx);
325 OCRepresentation rep;
326 HeaderOptions serverHeaderOptions;
327 if(clientResponse->result == OC_STACK_OK)
329 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
330 rep = parseGetSetCallback(clientResponse);
333 std::thread exec(context->callback, serverHeaderOptions, rep, clientResponse->result);
335 return OC_STACK_DELETE_TRANSACTION;
339 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
340 const std::string& uri, uint8_t connectivityType, const QueryParamsMap& queryParams,
341 const HeaderOptions& headerOptions, GetCallback& callback,
342 QualityOfService QoS)
344 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
345 const std::string& uri, const QueryParamsMap& queryParams,
346 const HeaderOptions& headerOptions, GetCallback& callback,
347 QualityOfService QoS)
350 OCStackResult result;
351 OCCallbackData cbdata = {0};
353 ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext();
354 ctx->callback = callback;
355 cbdata.context = static_cast<void*>(ctx);
356 cbdata.cb = &getResourceCallback;
357 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);};
359 auto cLock = m_csdkLock.lock();
363 std::ostringstream os;
364 os << host << assembleSetResourceUri(uri, queryParams).c_str();
366 std::lock_guard<std::recursive_mutex> lock(*cLock);
368 OCHeaderOption options[MAX_HEADER_OPTIONS];
370 assembleHeaderOptions(options, headerOptions);
372 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
373 nullptr, nullptr, connectivityType,
374 static_cast<OCQualityOfService>(QoS),
376 options, headerOptions.size());
378 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
380 static_cast<OCQualityOfService>(QoS),
382 options, headerOptions.size());
388 result = OC_STACK_ERROR;
394 OCStackApplicationResult setResourceCallback(void* ctx, OCDoHandle handle,
395 OCClientResponse* clientResponse)
397 ClientCallbackContext::SetContext* context =
398 static_cast<ClientCallbackContext::SetContext*>(ctx);
399 OCRepresentation attrs;
400 HeaderOptions serverHeaderOptions;
402 if (OC_STACK_OK == clientResponse->result ||
403 OC_STACK_RESOURCE_CREATED == clientResponse->result ||
404 OC_STACK_RESOURCE_DELETED == clientResponse->result)
406 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
407 attrs = parseGetSetCallback(clientResponse);
410 std::thread exec(context->callback, serverHeaderOptions, attrs, clientResponse->result);
412 return OC_STACK_DELETE_TRANSACTION;
415 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
416 const QueryParamsMap& queryParams)
418 if(uri.back() == '/')
420 uri.resize(uri.size()-1);
423 ostringstream paramsList;
424 if(queryParams.size() > 0)
429 for(auto& param : queryParams)
431 paramsList << param.first <<'='<<param.second<<'&';
434 std::string queryString = paramsList.str();
435 if(queryString.back() == '&')
437 queryString.resize(queryString.size() - 1);
440 std::string ret = uri + queryString;
444 std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
446 MessageContainer ocInfo;
447 ocInfo.addRepresentation(rep);
448 return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
452 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
453 const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
454 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
455 PostCallback& callback, QualityOfService QoS)
457 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
458 const std::string& uri, const OCRepresentation& rep,
459 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
460 PostCallback& callback, QualityOfService QoS)
463 OCStackResult result;
464 OCCallbackData cbdata = {0};
466 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
467 ctx->callback = callback;
468 cbdata.cb = &setResourceCallback;
469 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
470 cbdata.context = static_cast<void*>(ctx);
472 // TODO: in the future the cstack should be combining these two strings!
474 os << host << assembleSetResourceUri(uri, queryParams).c_str();
475 // TODO: end of above
477 auto cLock = m_csdkLock.lock();
481 std::lock_guard<std::recursive_mutex> lock(*cLock);
482 OCHeaderOption options[MAX_HEADER_OPTIONS];
485 assembleHeaderOptions(options, headerOptions);
487 result = OCDoResource(&handle, OC_REST_POST,
488 os.str().c_str(), nullptr,
489 assembleSetResourcePayload(rep).c_str(), connectivityType,
490 static_cast<OCQualityOfService>(QoS),
491 &cbdata, options, headerOptions.size());
493 result = OCDoResource(&handle, OC_REST_POST,
494 os.str().c_str(), nullptr,
495 assembleSetResourcePayload(rep).c_str(),
496 static_cast<OCQualityOfService>(QoS),
497 &cbdata, options, headerOptions.size());
503 result = OC_STACK_ERROR;
510 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
511 const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
512 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
513 PutCallback& callback, QualityOfService QoS)
515 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
516 const std::string& uri, const OCRepresentation& rep,
517 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
518 PutCallback& callback, QualityOfService QoS)
521 OCStackResult result;
522 OCCallbackData cbdata = {0};
524 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
525 ctx->callback = callback;
526 cbdata.cb = &setResourceCallback;
527 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
528 cbdata.context = static_cast<void*>(ctx);
530 // TODO: in the future the cstack should be combining these two strings!
532 os << host << assembleSetResourceUri(uri, queryParams).c_str();
533 // TODO: end of above
535 auto cLock = m_csdkLock.lock();
539 std::lock_guard<std::recursive_mutex> lock(*cLock);
541 OCHeaderOption options[MAX_HEADER_OPTIONS];
543 assembleHeaderOptions(options, headerOptions);
545 result = OCDoResource(&handle, OC_REST_PUT,
546 os.str().c_str(), nullptr,
547 assembleSetResourcePayload(rep).c_str(), connectivityType,
548 static_cast<OCQualityOfService>(QoS),
550 options, headerOptions.size());
552 result = OCDoResource(&handle, OC_REST_PUT,
553 os.str().c_str(), nullptr,
554 assembleSetResourcePayload(rep).c_str(),
555 static_cast<OCQualityOfService>(QoS),
557 options, headerOptions.size());
563 result = OC_STACK_ERROR;
569 OCStackApplicationResult deleteResourceCallback(void* ctx, OCDoHandle handle,
570 OCClientResponse* clientResponse)
572 ClientCallbackContext::DeleteContext* context =
573 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
574 HeaderOptions serverHeaderOptions;
576 if(clientResponse->result == OC_STACK_OK)
578 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
580 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
582 return OC_STACK_DELETE_TRANSACTION;
586 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
587 const std::string& uri, uint8_t connectivityType, const HeaderOptions& headerOptions,
588 DeleteCallback& callback, QualityOfService QoS)
590 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
591 const std::string& uri, const HeaderOptions& headerOptions,
592 DeleteCallback& callback, QualityOfService QoS)
595 OCStackResult result;
596 OCCallbackData cbdata = {0};
598 ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext();
599 ctx->callback = callback;
600 cbdata.cb = &deleteResourceCallback;
601 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);};
602 cbdata.context = static_cast<void*>(ctx);
607 auto cLock = m_csdkLock.lock();
611 OCHeaderOption options[MAX_HEADER_OPTIONS];
614 assembleHeaderOptions(options, headerOptions);
616 std::lock_guard<std::recursive_mutex> lock(*cLock);
618 result = OCDoResource(&handle, OC_REST_DELETE,
619 os.str().c_str(), nullptr,
620 nullptr, connectivityType,
621 static_cast<OCQualityOfService>(m_cfg.QoS),
622 &cbdata, options, headerOptions.size());
624 result = OCDoResource(&handle, OC_REST_DELETE,
625 os.str().c_str(), nullptr,
626 nullptr, static_cast<OCQualityOfService>(m_cfg.QoS),
627 &cbdata, options, headerOptions.size());
633 result = OC_STACK_ERROR;
639 OCStackApplicationResult observeResourceCallback(void* ctx, OCDoHandle handle,
640 OCClientResponse* clientResponse)
642 ClientCallbackContext::ObserveContext* context =
643 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
644 OCRepresentation attrs;
645 HeaderOptions serverHeaderOptions;
646 uint32_t sequenceNumber = clientResponse->sequenceNumber;
648 if(clientResponse->result == OC_STACK_OK)
650 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
651 attrs = parseGetSetCallback(clientResponse);
653 std::thread exec(context->callback, serverHeaderOptions, attrs,
654 clientResponse->result, sequenceNumber);
656 return OC_STACK_KEEP_TRANSACTION;
660 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
661 const std::string& host, const std::string& uri, uint8_t connectivityType,
662 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
663 ObserveCallback& callback, QualityOfService QoS)
665 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
666 const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
667 const HeaderOptions& headerOptions, ObserveCallback& callback, QualityOfService QoS)
670 OCStackResult result;
671 OCCallbackData cbdata = {0};
673 ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext();
674 ctx->callback = callback;
675 cbdata.context = static_cast<void*>(ctx);
676 cbdata.cb = &observeResourceCallback;
677 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);};
680 if (observeType == ObserveType::Observe)
682 method = OC_REST_OBSERVE;
684 else if (observeType == ObserveType::ObserveAll)
686 method = OC_REST_OBSERVE_ALL;
690 method = OC_REST_OBSERVE_ALL;
693 auto cLock = m_csdkLock.lock();
697 std::ostringstream os;
698 os << host << assembleSetResourceUri(uri, queryParams).c_str();
700 std::lock_guard<std::recursive_mutex> lock(*cLock);
701 OCHeaderOption options[MAX_HEADER_OPTIONS];
703 assembleHeaderOptions(options, headerOptions);
705 result = OCDoResource(handle, method,
706 os.str().c_str(), nullptr,
707 nullptr, connectivityType,
708 static_cast<OCQualityOfService>(QoS),
710 options, headerOptions.size());
712 result = OCDoResource(handle, method,
713 os.str().c_str(), nullptr,
715 static_cast<OCQualityOfService>(QoS),
717 options, headerOptions.size());
723 return OC_STACK_ERROR;
729 OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
730 const std::string& host, const std::string& uri, const HeaderOptions& headerOptions,
731 QualityOfService QoS)
733 OCStackResult result;
734 auto cLock = m_csdkLock.lock();
738 std::lock_guard<std::recursive_mutex> lock(*cLock);
739 OCHeaderOption options[MAX_HEADER_OPTIONS];
741 assembleHeaderOptions(options, headerOptions);
742 result = OCCancel(handle, static_cast<OCQualityOfService>(QoS), options,
743 headerOptions.size());
747 result = OC_STACK_ERROR;
753 OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
754 OCClientResponse* clientResponse)
756 char stringAddress[DEV_ADDR_SIZE_MAX];
760 if(OCDevAddrToString(clientResponse->addr, stringAddress) == 0 &&
761 OCDevAddrToPort(clientResponse->addr, &port) == 0)
763 os<<stringAddress<<":"<<port;
765 ClientCallbackContext::SubscribePresenceContext* context =
766 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
768 std::thread exec(context->callback, clientResponse->result,
769 clientResponse->sequenceNumber, os.str());
775 oclog() << "subscribePresenceCallback(): OCDevAddrToString() or OCDevAddrToPort() "
776 <<"failed"<< std::flush;
778 return OC_STACK_KEEP_TRANSACTION;
782 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
783 const std::string& host, const std::string& resourceType, uint8_t connectivityType,
784 SubscribeCallback& presenceHandler)
786 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
787 const std::string& host, const std::string& resourceType,
788 SubscribeCallback& presenceHandler)
791 OCCallbackData cbdata = {0};
793 ClientCallbackContext::SubscribePresenceContext* ctx =
794 new ClientCallbackContext::SubscribePresenceContext();
795 ctx->callback = presenceHandler;
796 cbdata.cb = &subscribePresenceCallback;
797 cbdata.context = static_cast<void*>(ctx);
798 cbdata.cd = [](void* c)
799 {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);};
800 auto cLock = m_csdkLock.lock();
802 std::ostringstream os;
803 os << host << "/oc/presence";
805 if(!resourceType.empty())
807 os << "?rt=" << resourceType;
813 return OC_STACK_ERROR;
817 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
818 connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
820 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
821 OC_LOW_QOS, &cbdata, NULL, 0);
825 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
827 OCStackResult result;
828 auto cLock = m_csdkLock.lock();
832 std::lock_guard<std::recursive_mutex> lock(*cLock);
833 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
837 result = OC_STACK_ERROR;
843 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
849 void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
850 const HeaderOptions& headerOptions)
854 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
856 options[i].protocolID = OC_COAP_ID;
857 options[i].optionID = static_cast<uint16_t>(it->getOptionID());
858 options[i].optionLength = (it->getOptionData()).length() + 1;
859 memcpy(options[i].optionData, (it->getOptionData()).c_str(),
860 (it->getOptionData()).length() + 1);