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;
152 ListenOCContainer container(clientWrapper, *clientResponse->addr,
153 clientResponse->connType, requestStream);
155 ListenOCContainer container(clientWrapper, *clientResponse->addr,
158 // loop to ensure valid construction of all resources
159 for(auto resource : container.Resources())
161 std::thread exec(context->callback, resource);
166 catch(const std::exception& e)
168 oclog() << "listenCallback failed to parse a malformed message: "
171 << clientResponse->resJSONPayload
173 << clientResponse->result
175 return OC_STACK_KEEP_TRANSACTION;
178 return OC_STACK_KEEP_TRANSACTION;
182 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
183 const std::string& resourceType, uint8_t connectivityType,
184 FindCallback& callback, QualityOfService QoS)
186 OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
187 const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
190 OCStackResult result;
192 OCCallbackData cbdata = {0};
194 ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext();
195 context->callback = callback;
196 context->clientWrapper = shared_from_this();
198 cbdata.context = static_cast<void*>(context);
199 cbdata.cb = listenCallback;
200 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);};
202 auto cLock = m_csdkLock.lock();
205 std::lock_guard<std::recursive_mutex> lock(*cLock);
208 result = OCDoResource(&handle, OC_REST_GET,
209 resourceType.c_str(),
210 nullptr, nullptr, connectivityType,
211 static_cast<OCQualityOfService>(QoS),
215 result = OCDoResource(&handle, OC_REST_GET,
216 resourceType.c_str(),
218 static_cast<OCQualityOfService>(QoS),
226 result = OC_STACK_ERROR;
231 OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
232 OCClientResponse* clientResponse)
234 ClientCallbackContext::DeviceListenContext* context =
235 static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
237 OCRepresentation rep = parseGetSetCallback(clientResponse);
238 std::thread exec(context->callback, rep);
241 return OC_STACK_KEEP_TRANSACTION;
245 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
246 const std::string& deviceURI, uint8_t connectivityType,
247 FindDeviceCallback& callback, QualityOfService QoS)
249 OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
250 const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
253 OCStackResult result;
255 OCCallbackData cbdata = {0};
257 ClientCallbackContext::DeviceListenContext* context =
258 new ClientCallbackContext::DeviceListenContext();
259 context->callback = callback;
260 context->clientWrapper = shared_from_this();
262 cbdata.context = static_cast<void*>(context);
263 cbdata.cb = listenDeviceCallback;
264 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
266 auto cLock = m_csdkLock.lock();
269 std::lock_guard<std::recursive_mutex> lock(*cLock);
272 result = OCDoResource(&handle, OC_REST_GET,
274 nullptr, nullptr, connectivityType,
275 static_cast<OCQualityOfService>(QoS),
279 result = OCDoResource(&handle, OC_REST_GET,
282 static_cast<OCQualityOfService>(QoS),
289 result = OC_STACK_ERROR;
294 void parseServerHeaderOptions(OCClientResponse* clientResponse,
295 HeaderOptions& serverHeaderOptions)
299 // Parse header options from server
301 std::string optionData;
303 for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
305 optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
306 optionData = reinterpret_cast<const char*>
307 (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
308 HeaderOption::OCHeaderOption headerOption(optionID, optionData);
309 serverHeaderOptions.push_back(headerOption);
314 // clientResponse is invalid
315 // TODO check proper logging
316 std::cout << " Invalid response " << std::endl;
320 OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle,
321 OCClientResponse* clientResponse)
323 ClientCallbackContext::GetContext* context =
324 static_cast<ClientCallbackContext::GetContext*>(ctx);
326 OCRepresentation rep;
327 HeaderOptions serverHeaderOptions;
328 if(clientResponse->result == OC_STACK_OK)
330 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
331 rep = parseGetSetCallback(clientResponse);
334 std::thread exec(context->callback, serverHeaderOptions, rep, clientResponse->result);
336 return OC_STACK_DELETE_TRANSACTION;
340 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
341 const std::string& uri, uint8_t connectivityType, const QueryParamsMap& queryParams,
342 const HeaderOptions& headerOptions, GetCallback& callback,
343 QualityOfService QoS)
345 OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
346 const std::string& uri, const QueryParamsMap& queryParams,
347 const HeaderOptions& headerOptions, GetCallback& callback,
348 QualityOfService QoS)
351 OCStackResult result;
352 OCCallbackData cbdata = {0};
354 ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext();
355 ctx->callback = callback;
356 cbdata.context = static_cast<void*>(ctx);
357 cbdata.cb = &getResourceCallback;
358 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);};
360 auto cLock = m_csdkLock.lock();
364 std::ostringstream os;
365 os << host << assembleSetResourceUri(uri, queryParams).c_str();
367 std::lock_guard<std::recursive_mutex> lock(*cLock);
369 OCHeaderOption options[MAX_HEADER_OPTIONS];
371 assembleHeaderOptions(options, headerOptions);
373 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
374 nullptr, nullptr, connectivityType,
375 static_cast<OCQualityOfService>(QoS),
377 options, headerOptions.size());
379 result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
381 static_cast<OCQualityOfService>(QoS),
383 options, headerOptions.size());
389 result = OC_STACK_ERROR;
395 OCStackApplicationResult setResourceCallback(void* ctx, OCDoHandle handle,
396 OCClientResponse* clientResponse)
398 ClientCallbackContext::SetContext* context =
399 static_cast<ClientCallbackContext::SetContext*>(ctx);
400 OCRepresentation attrs;
401 HeaderOptions serverHeaderOptions;
403 if (OC_STACK_OK == clientResponse->result ||
404 OC_STACK_RESOURCE_CREATED == clientResponse->result ||
405 OC_STACK_RESOURCE_DELETED == clientResponse->result)
407 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
408 attrs = parseGetSetCallback(clientResponse);
411 std::thread exec(context->callback, serverHeaderOptions, attrs, clientResponse->result);
413 return OC_STACK_DELETE_TRANSACTION;
416 std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
417 const QueryParamsMap& queryParams)
419 if(uri.back() == '/')
421 uri.resize(uri.size()-1);
424 ostringstream paramsList;
425 if(queryParams.size() > 0)
430 for(auto& param : queryParams)
432 paramsList << param.first <<'='<<param.second<<'&';
435 std::string queryString = paramsList.str();
436 if(queryString.back() == '&')
438 queryString.resize(queryString.size() - 1);
441 std::string ret = uri + queryString;
445 std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
447 MessageContainer ocInfo;
448 ocInfo.addRepresentation(rep);
449 return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
453 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
454 const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
455 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
456 PostCallback& callback, QualityOfService QoS)
458 OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
459 const std::string& uri, const OCRepresentation& rep,
460 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
461 PostCallback& callback, QualityOfService QoS)
464 OCStackResult result;
465 OCCallbackData cbdata = {0};
467 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
468 ctx->callback = callback;
469 cbdata.cb = &setResourceCallback;
470 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
471 cbdata.context = static_cast<void*>(ctx);
473 // TODO: in the future the cstack should be combining these two strings!
475 os << host << assembleSetResourceUri(uri, queryParams).c_str();
476 // TODO: end of above
478 auto cLock = m_csdkLock.lock();
482 std::lock_guard<std::recursive_mutex> lock(*cLock);
483 OCHeaderOption options[MAX_HEADER_OPTIONS];
486 assembleHeaderOptions(options, headerOptions);
488 result = OCDoResource(&handle, OC_REST_POST,
489 os.str().c_str(), nullptr,
490 assembleSetResourcePayload(rep).c_str(), connectivityType,
491 static_cast<OCQualityOfService>(QoS),
492 &cbdata, options, headerOptions.size());
494 result = OCDoResource(&handle, OC_REST_POST,
495 os.str().c_str(), nullptr,
496 assembleSetResourcePayload(rep).c_str(),
497 static_cast<OCQualityOfService>(QoS),
498 &cbdata, options, headerOptions.size());
504 result = OC_STACK_ERROR;
511 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
512 const std::string& uri, uint8_t connectivityType, const OCRepresentation& rep,
513 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
514 PutCallback& callback, QualityOfService QoS)
516 OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
517 const std::string& uri, const OCRepresentation& rep,
518 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
519 PutCallback& callback, QualityOfService QoS)
522 OCStackResult result;
523 OCCallbackData cbdata = {0};
525 ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
526 ctx->callback = callback;
527 cbdata.cb = &setResourceCallback;
528 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
529 cbdata.context = static_cast<void*>(ctx);
531 // TODO: in the future the cstack should be combining these two strings!
533 os << host << assembleSetResourceUri(uri, queryParams).c_str();
534 // TODO: end of above
536 auto cLock = m_csdkLock.lock();
540 std::lock_guard<std::recursive_mutex> lock(*cLock);
542 OCHeaderOption options[MAX_HEADER_OPTIONS];
544 assembleHeaderOptions(options, headerOptions);
546 result = OCDoResource(&handle, OC_REST_PUT,
547 os.str().c_str(), nullptr,
548 assembleSetResourcePayload(rep).c_str(), connectivityType,
549 static_cast<OCQualityOfService>(QoS),
551 options, headerOptions.size());
553 result = OCDoResource(&handle, OC_REST_PUT,
554 os.str().c_str(), nullptr,
555 assembleSetResourcePayload(rep).c_str(),
556 static_cast<OCQualityOfService>(QoS),
558 options, headerOptions.size());
564 result = OC_STACK_ERROR;
570 OCStackApplicationResult deleteResourceCallback(void* ctx, OCDoHandle handle,
571 OCClientResponse* clientResponse)
573 ClientCallbackContext::DeleteContext* context =
574 static_cast<ClientCallbackContext::DeleteContext*>(ctx);
575 HeaderOptions serverHeaderOptions;
577 if(clientResponse->result == OC_STACK_OK)
579 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
581 std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
583 return OC_STACK_DELETE_TRANSACTION;
587 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
588 const std::string& uri, uint8_t connectivityType, const HeaderOptions& headerOptions,
589 DeleteCallback& callback, QualityOfService QoS)
591 OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
592 const std::string& uri, const HeaderOptions& headerOptions,
593 DeleteCallback& callback, QualityOfService QoS)
596 OCStackResult result;
597 OCCallbackData cbdata = {0};
599 ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext();
600 ctx->callback = callback;
601 cbdata.cb = &deleteResourceCallback;
602 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);};
603 cbdata.context = static_cast<void*>(ctx);
608 auto cLock = m_csdkLock.lock();
612 OCHeaderOption options[MAX_HEADER_OPTIONS];
615 assembleHeaderOptions(options, headerOptions);
617 std::lock_guard<std::recursive_mutex> lock(*cLock);
619 result = OCDoResource(&handle, OC_REST_DELETE,
620 os.str().c_str(), nullptr,
621 nullptr, connectivityType,
622 static_cast<OCQualityOfService>(m_cfg.QoS),
623 &cbdata, options, headerOptions.size());
625 result = OCDoResource(&handle, OC_REST_DELETE,
626 os.str().c_str(), nullptr,
627 nullptr, static_cast<OCQualityOfService>(m_cfg.QoS),
628 &cbdata, options, headerOptions.size());
634 result = OC_STACK_ERROR;
640 OCStackApplicationResult observeResourceCallback(void* ctx, OCDoHandle handle,
641 OCClientResponse* clientResponse)
643 ClientCallbackContext::ObserveContext* context =
644 static_cast<ClientCallbackContext::ObserveContext*>(ctx);
645 OCRepresentation attrs;
646 HeaderOptions serverHeaderOptions;
647 uint32_t sequenceNumber = clientResponse->sequenceNumber;
649 if(clientResponse->result == OC_STACK_OK)
651 parseServerHeaderOptions(clientResponse, serverHeaderOptions);
652 attrs = parseGetSetCallback(clientResponse);
654 std::thread exec(context->callback, serverHeaderOptions, attrs,
655 clientResponse->result, sequenceNumber);
657 return OC_STACK_KEEP_TRANSACTION;
661 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
662 const std::string& host, const std::string& uri, uint8_t connectivityType,
663 const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
664 ObserveCallback& callback, QualityOfService QoS)
666 OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
667 const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
668 const HeaderOptions& headerOptions, ObserveCallback& callback, QualityOfService QoS)
671 OCStackResult result;
672 OCCallbackData cbdata = {0};
674 ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext();
675 ctx->callback = callback;
676 cbdata.context = static_cast<void*>(ctx);
677 cbdata.cb = &observeResourceCallback;
678 cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);};
681 if (observeType == ObserveType::Observe)
683 method = OC_REST_OBSERVE;
685 else if (observeType == ObserveType::ObserveAll)
687 method = OC_REST_OBSERVE_ALL;
691 method = OC_REST_OBSERVE_ALL;
694 auto cLock = m_csdkLock.lock();
698 std::ostringstream os;
699 os << host << assembleSetResourceUri(uri, queryParams).c_str();
701 std::lock_guard<std::recursive_mutex> lock(*cLock);
702 OCHeaderOption options[MAX_HEADER_OPTIONS];
704 assembleHeaderOptions(options, headerOptions);
706 result = OCDoResource(handle, method,
707 os.str().c_str(), nullptr,
708 nullptr, connectivityType,
709 static_cast<OCQualityOfService>(QoS),
711 options, headerOptions.size());
713 result = OCDoResource(handle, method,
714 os.str().c_str(), nullptr,
716 static_cast<OCQualityOfService>(QoS),
718 options, headerOptions.size());
724 return OC_STACK_ERROR;
730 OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
731 const std::string& host, const std::string& uri, const HeaderOptions& headerOptions,
732 QualityOfService QoS)
734 OCStackResult result;
735 auto cLock = m_csdkLock.lock();
739 std::lock_guard<std::recursive_mutex> lock(*cLock);
740 OCHeaderOption options[MAX_HEADER_OPTIONS];
742 assembleHeaderOptions(options, headerOptions);
743 result = OCCancel(handle, static_cast<OCQualityOfService>(QoS), options,
744 headerOptions.size());
748 result = OC_STACK_ERROR;
754 OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
755 OCClientResponse* clientResponse)
757 char stringAddress[DEV_ADDR_SIZE_MAX];
761 if(OCDevAddrToString(clientResponse->addr, stringAddress) == 0 &&
762 OCDevAddrToPort(clientResponse->addr, &port) == 0)
764 os<<stringAddress<<":"<<port;
766 ClientCallbackContext::SubscribePresenceContext* context =
767 static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
769 std::thread exec(context->callback, clientResponse->result,
770 clientResponse->sequenceNumber, os.str());
776 oclog() << "subscribePresenceCallback(): OCDevAddrToString() or OCDevAddrToPort() "
777 <<"failed"<< std::flush;
779 return OC_STACK_KEEP_TRANSACTION;
783 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
784 const std::string& host, const std::string& resourceType, uint8_t connectivityType,
785 SubscribeCallback& presenceHandler)
787 OCStackResult InProcClientWrapper::SubscribePresence(OCDoHandle* handle,
788 const std::string& host, const std::string& resourceType,
789 SubscribeCallback& presenceHandler)
792 OCCallbackData cbdata = {0};
794 ClientCallbackContext::SubscribePresenceContext* ctx =
795 new ClientCallbackContext::SubscribePresenceContext();
796 ctx->callback = presenceHandler;
797 cbdata.cb = &subscribePresenceCallback;
798 cbdata.context = static_cast<void*>(ctx);
799 cbdata.cd = [](void* c)
800 {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);};
801 auto cLock = m_csdkLock.lock();
803 std::ostringstream os;
804 os << host << "/oc/presence";
806 if(!resourceType.empty())
808 os << "?rt=" << resourceType;
814 return OC_STACK_ERROR;
818 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
819 connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
821 return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
822 OC_LOW_QOS, &cbdata, NULL, 0);
826 OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
828 OCStackResult result;
829 auto cLock = m_csdkLock.lock();
833 std::lock_guard<std::recursive_mutex> lock(*cLock);
834 result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
838 result = OC_STACK_ERROR;
844 OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
850 void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
851 const HeaderOptions& headerOptions)
855 for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
857 options[i].protocolID = OC_COAP_ID;
858 options[i].optionID = static_cast<uint16_t>(it->getOptionID());
859 options[i].optionLength = (it->getOptionData()).length() + 1;
860 memcpy(options[i].optionData, (it->getOptionData()).c_str(),
861 (it->getOptionData()).length() + 1);