Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / src / InProcClientWrapper.cpp
index 84a8f93..987c0f5 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "OCPlatform.h"
 #include "OCResource.h"
+#include "ocpayload.h"
 #include <OCSerialization.h>
 using namespace std;
 
@@ -38,7 +39,11 @@ namespace OC
 
         if(m_cfg.mode == ModeType::Client)
         {
-            OCStackResult result = OCInit(m_cfg.ipAddress.c_str(), m_cfg.port, OC_CLIENT);
+            OCTransportFlags serverFlags =
+                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
+            OCTransportFlags clientFlags =
+                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
+            OCStackResult result = OCInit1(OC_CLIENT, serverFlags, clientFlags);
 
             if(OC_STACK_OK != result)
             {
@@ -94,28 +99,21 @@ namespace OC
 
     OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
     {
-        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
-        {
+        if(clientResponse->payload == nullptr ||
+                (
+                    clientResponse->payload->type != PAYLOAD_TYPE_DEVICE &&
+                    clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM &&
+                    clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION
+                )
+          )
+        {
+            //OCPayloadDestroy(clientResponse->payload);
             return OCRepresentation();
         }
 
         MessageContainer oc;
-        try
-        {
-            oc.setJSONRepresentation(clientResponse->resJSONPayload);
-        }
-        catch (cereal::RapidJSONException& ex)
-        {
-            oclog() <<"RapidJSON Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
-                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
-            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
-        }
-        catch (cereal::Exception& ex)
-        {
-            oclog() <<"Cereal Exception in parseGetSetCallback: "<<ex.what() <<std::endl<<
-                "Data was:"<< clientResponse->resJSONPayload<< ":" << std::flush;
-            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_INVALID_JSON);
-        }
+        oc.setPayload(clientResponse->payload);
+        //OCPayloadDestroy(clientResponse->payload);
 
         std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
         if(it == oc.representations().end())
@@ -149,6 +147,13 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
+        if(!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+        {
+            oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
+                << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         auto clientWrapper = context->clientWrapper.lock();
 
         if(!clientWrapper)
@@ -158,40 +163,24 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
-        std::stringstream requestStream;
-        requestStream << clientResponse->resJSONPayload;
-
-        try
+        ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+                                reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+        // loop to ensure valid construction of all resources
+        for(auto resource : container.Resources())
         {
-
-            ListenOCContainer container(clientWrapper, *clientResponse->addr,
-                    clientResponse->connType, requestStream);
-            // loop to ensure valid construction of all resources
-            for(auto resource : container.Resources())
-            {
-                std::thread exec(context->callback, resource);
-                exec.detach();
-            }
-
-        }
-        catch(const std::exception& e)
-        {
-            oclog() << "listenCallback failed to parse a malformed message: "
-                    << e.what()
-                    << std::endl
-                    << clientResponse->resJSONPayload
-                    << std::endl
-                    << clientResponse->result
-                    << std::flush;
-            return OC_STACK_KEEP_TRANSACTION;
+            std::thread exec(context->callback, resource);
+            exec.detach();
         }
 
+
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
-        const std::string& resourceType, OCConnectivityType connectivityType,
-        FindCallback& callback, QualityOfService QoS)
+    OCStackResult InProcClientWrapper::ListenForResource(
+            const std::string& serviceUrl,
+            const std::string& resourceType,
+            OCConnectivityType connectivityType,
+            FindCallback& callback, QualityOfService QoS)
     {
         if(!callback)
         {
@@ -199,23 +188,23 @@ namespace OC
         }
 
         OCStackResult result;
+        ostringstream resourceUri;
+        resourceUri << serviceUrl << resourceType;
 
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext();
-        context->callback = callback;
-        context->clientWrapper = shared_from_this();
-
-        cbdata.context =  static_cast<void*>(context);
-        cbdata.cb = listenCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);};
+        ClientCallbackContext::ListenContext* context =
+            new ClientCallbackContext::ListenContext(callback, shared_from_this());
+        OCCallbackData cbdata(
+                static_cast<void*>(context),
+                listenCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::ListenContext*>(c);}
+            );
 
         auto cLock = m_csdkLock.lock();
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDoResource(nullptr, OC_REST_GET,
-                                  resourceType.c_str(),
+            result = OCDoResource(nullptr, OC_REST_DISCOVER,
+                                  resourceUri.str().c_str(),
                                   nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
@@ -250,31 +239,35 @@ namespace OC
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
-        const std::string& deviceURI, OCConnectivityType connectivityType,
-        FindDeviceCallback& callback, QualityOfService QoS)
+    OCStackResult InProcClientWrapper::ListenForDevice(
+            const std::string& serviceUrl,
+            const std::string& deviceURI,
+            OCConnectivityType connectivityType,
+            FindDeviceCallback& callback,
+            QualityOfService QoS)
     {
         if(!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
+        ostringstream deviceUri;
+        deviceUri << serviceUrl << deviceURI;
 
-        OCCallbackData cbdata = {0};
         ClientCallbackContext::DeviceListenContext* context =
-            new ClientCallbackContext::DeviceListenContext();
-        context->callback = callback;
-        context->clientWrapper = shared_from_this();
-        cbdata.context =  static_cast<void*>(context);
-        cbdata.cb = listenDeviceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
+            new ClientCallbackContext::DeviceListenContext(callback, shared_from_this());
+        OCCallbackData cbdata(
+                static_cast<void*>(context),
+                listenDeviceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);}
+                );
 
         auto cLock = m_csdkLock.lock();
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDoResource(nullptr, OC_REST_GET,
-                                  deviceURI.c_str(),
+            result = OCDoResource(nullptr, OC_REST_DISCOVER,
+                                  deviceUri.str().c_str(),
                                   nullptr, nullptr, connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
@@ -341,8 +334,9 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType,
+    OCStackResult InProcClientWrapper::GetResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& resourceUri,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         GetCallback& callback, QualityOfService QoS)
     {
@@ -351,26 +345,28 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
+        ClientCallbackContext::GetContext* ctx =
+            new ClientCallbackContext::GetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                getResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);}
+                );
 
-        ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext();
-        ctx->callback = callback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cb = &getResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::GetContext*>(c);};
+        std::string uri = assembleSetResourceUri(resourceUri, queryParams);
 
         auto cLock = m_csdkLock.lock();
 
         if(cLock)
         {
-            std::ostringstream os;
-            os << host << assembleSetResourceUri(uri, queryParams).c_str();
-
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
-            result = OCDoResource(nullptr, OC_REST_GET, os.str().c_str(),
-                                  nullptr, nullptr, connectivityType,
+            result = OCDoResource(
+                                  nullptr, OC_REST_GET,
+                                  uri.c_str(),
+                                  &devAddr, nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -430,11 +426,11 @@ namespace OC
 
         for(auto& param : queryParams)
         {
-            paramsList << param.first <<'='<<param.second<<'&';
+            paramsList << param.first <<'='<<param.second<<';';
         }
 
         std::string queryString = paramsList.str();
-        if(queryString.back() == '&')
+        if(queryString.back() == ';')
         {
             queryString.resize(queryString.size() - 1);
         }
@@ -443,15 +439,17 @@ namespace OC
         return ret;
     }
 
-    std::string InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
+    OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
     {
         MessageContainer ocInfo;
         ocInfo.addRepresentation(rep);
-        return ocInfo.getJSONRepresentation(OCInfoFormat::IncludeOC);
+        return reinterpret_cast<OCPayload*>(ocInfo.getPayload());
     }
 
-    OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
+    OCStackResult InProcClientWrapper::PostResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
+        const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PostCallback& callback, QualityOfService QoS)
     {
@@ -460,18 +458,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
-        ctx->callback = callback;
-        cbdata.cb = &setResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
+        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                setResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);}
+                );
 
-        // TODO: in the future the cstack should be combining these two strings!
-        ostringstream os;
-        os << host << assembleSetResourceUri(uri, queryParams).c_str();
-        // TODO: end of above
+        std::string url = assembleSetResourceUri(uri, queryParams);
 
         auto cLock = m_csdkLock.lock();
 
@@ -481,8 +475,9 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(nullptr, OC_REST_POST,
-                                  os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  url.c_str(), &devAddr,
+                                  assembleSetResourcePayload(rep),
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -497,8 +492,10 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType, const OCRepresentation& rep,
+    OCStackResult InProcClientWrapper::PutResourceRepresentation(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
+        const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PutCallback& callback, QualityOfService QoS)
     {
@@ -507,18 +504,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
+        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                setResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);}
+                );
 
-        ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext();
-        ctx->callback = callback;
-        cbdata.cb = &setResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::SetContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
-
-        // TODO: in the future the cstack should be combining these two strings!
-        ostringstream os;
-        os << host << assembleSetResourceUri(uri, queryParams).c_str();
-        // TODO: end of above
+        std::string url = assembleSetResourceUri(uri, queryParams).c_str();
 
         auto cLock = m_csdkLock.lock();
 
@@ -529,8 +522,9 @@ namespace OC
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(&handle, OC_REST_PUT,
-                                  os.str().c_str(), nullptr,
-                                  assembleSetResourcePayload(rep).c_str(), connectivityType,
+                                  url.c_str(), &devAddr,
+                                  assembleSetResourcePayload(rep),
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -561,8 +555,9 @@ namespace OC
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::DeleteResource(const std::string& host,
-        const std::string& uri, OCConnectivityType connectivityType,
+    OCStackResult InProcClientWrapper::DeleteResource(
+        const OCDevAddr& devAddr,
+        const std::string& uri,
         const HeaderOptions& headerOptions, DeleteCallback& callback, QualityOfService QoS)
     {
         if(!callback)
@@ -570,16 +565,13 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
-
-        ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext();
-        ctx->callback = callback;
-        cbdata.cb = &deleteResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);};
-        cbdata.context = static_cast<void*>(ctx);
-
-        ostringstream os;
-        os << host << uri;
+        ClientCallbackContext::DeleteContext* ctx =
+            new ClientCallbackContext::DeleteContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                deleteResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::DeleteContext*>(c);}
+                );
 
         auto cLock = m_csdkLock.lock();
 
@@ -590,8 +582,9 @@ namespace OC
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
             result = OCDoResource(nullptr, OC_REST_DELETE,
-                                  os.str().c_str(), nullptr,
-                                  nullptr, connectivityType,
+                                  uri.c_str(), &devAddr,
+                                  nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -638,7 +631,8 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
-        const std::string& host, const std::string& uri, OCConnectivityType connectivityType,
+        const OCDevAddr& devAddr,
+        const std::string& uri,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         ObserveCallback& callback, QualityOfService QoS)
     {
@@ -647,13 +641,14 @@ namespace OC
             return OC_STACK_INVALID_PARAM;
         }
         OCStackResult result;
-        OCCallbackData cbdata = {0};
 
-        ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext();
-        ctx->callback = callback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cb = &observeResourceCallback;
-        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);};
+        ClientCallbackContext::ObserveContext* ctx =
+            new ClientCallbackContext::ObserveContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                observeResourceCallback,
+                [](void* c){delete static_cast<ClientCallbackContext::ObserveContext*>(c);}
+                );
 
         OCMethod method;
         if (observeType == ObserveType::Observe)
@@ -669,19 +664,19 @@ namespace OC
             method = OC_REST_OBSERVE_ALL;
         }
 
+        std::string url = assembleSetResourceUri(uri, queryParams).c_str();
+
         auto cLock = m_csdkLock.lock();
 
         if(cLock)
         {
-            std::ostringstream os;
-            os << host << assembleSetResourceUri(uri, queryParams).c_str();
-
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
             result = OCDoResource(handle, method,
-                                  os.str().c_str(), nullptr,
-                                  nullptr, connectivityType,
+                                  url.c_str(), &devAddr,
+                                  nullptr,
+                                  CT_DEFAULT,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -696,9 +691,12 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
-        const std::string& host, const std::string& uri, const HeaderOptions& headerOptions,
-        QualityOfService QoS)
+    OCStackResult InProcClientWrapper::CancelObserveResource(
+            OCDoHandle handle,
+            const std::string& host, // unused
+            const std::string& uri,  // unused
+            const HeaderOptions& headerOptions,
+            QualityOfService QoS)
     {
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
@@ -724,32 +722,19 @@ namespace OC
     OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle,
             OCClientResponse* clientResponse)
     {
-        ostringstream os;
-        uint16_t port;
-        uint8_t a;
-        uint8_t b;
-        uint8_t c;
-        uint8_t d;
+        ClientCallbackContext::SubscribePresenceContext* context =
+        static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
 
-        if(OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) == 0 &&
-                OCDevAddrToPort(clientResponse->addr, &port) == 0)
-        {
-            os<<static_cast<int>(a)<<"."<<static_cast<int>(b)<<"."<<static_cast<int>(c)
-                    <<"."<<static_cast<int>(d)<<":"<<static_cast<int>(port);
+        /*
+         * This a hack while we rethink presence subscription.
+         */
+        std::string url = clientResponse->devAddr.addr;
 
-            ClientCallbackContext::SubscribePresenceContext* context =
-                static_cast<ClientCallbackContext::SubscribePresenceContext*>(ctx);
+        std::thread exec(context->callback, clientResponse->result,
+                    clientResponse->sequenceNumber, url);
 
-            std::thread exec(context->callback, clientResponse->result,
-                    clientResponse->sequenceNumber, os.str());
+        exec.detach();
 
-            exec.detach();
-        }
-        else
-        {
-            oclog() << "subscribePresenceCallback(): OCDevAddrToIPv4Addr() or OCDevAddrToPort() "
-                    <<"failed"<< std::flush;
-        }
         return OC_STACK_KEEP_TRANSACTION;
     }
 
@@ -761,19 +746,20 @@ namespace OC
         {
             return OC_STACK_INVALID_PARAM;
         }
-        OCCallbackData cbdata = {0};
 
         ClientCallbackContext::SubscribePresenceContext* ctx =
-            new ClientCallbackContext::SubscribePresenceContext();
-        ctx->callback = presenceHandler;
-        cbdata.cb = &subscribePresenceCallback;
-        cbdata.context = static_cast<void*>(ctx);
-        cbdata.cd = [](void* c)
-            {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);};
+            new ClientCallbackContext::SubscribePresenceContext(presenceHandler);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                subscribePresenceCallback,
+                [](void* c)
+                {delete static_cast<ClientCallbackContext::SubscribePresenceContext*>(c);}
+                );
+
         auto cLock = m_csdkLock.lock();
 
         std::ostringstream os;
-        os << host << OC_PRESENCE_URI;
+        os << host << OC_RSRVD_PRESENCE_URI;
 
         if(!resourceType.empty())
         {
@@ -786,8 +772,10 @@ namespace OC
             return OC_STACK_ERROR;
         }
 
-        return OCDoResource(handle, OC_REST_PRESENCE, os.str().c_str(), nullptr, nullptr,
-                            connectivityType, OC_LOW_QOS, &cbdata, NULL, 0);
+        return OCDoResource(handle, OC_REST_PRESENCE,
+                            os.str().c_str(), nullptr,
+                            nullptr, connectivityType,
+                            OC_LOW_QOS, &cbdata, NULL, 0);
     }
 
     OCStackResult InProcClientWrapper::UnsubscribePresence(OCDoHandle handle)
@@ -826,11 +814,10 @@ namespace OC
 
         for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
         {
-            options[i].protocolID = OC_COAP_ID;
-            options[i].optionID = static_cast<uint16_t>(it->getOptionID());
-            options[i].optionLength = (it->getOptionData()).length() + 1;
-            memcpy(options[i].optionData, (it->getOptionData()).c_str(),
-                    (it->getOptionData()).length() + 1);
+            options[i] = OCHeaderOption(OC_COAP_ID,
+                    it->getOptionID(),
+                    it->getOptionData().length() + 1,
+                    reinterpret_cast<const uint8_t*>(it->getOptionData().c_str()));
             i++;
         }