Changes in C++ for vendor specific header options to be sent from client to server...
authorSudarshan Prasad <sudarshan.prasad@intel.com>
Wed, 1 Oct 2014 02:01:06 +0000 (19:01 -0700)
committerSudarshan Prasad <sudarshan.prasad@intel.com>
Tue, 7 Oct 2014 23:49:57 +0000 (16:49 -0700)
Patch 2:
Code clean up
Fixes for sending header options from client to server
Patch 3:
Added additional comments;
Addressed review comments, added more comments.
Added implementation for sending header options from server to client.
Updated related sample files.
Added comments
Rebased with master
Completed additional changes for building.
Patch 4:
Removed unnecessary statements in makefile.

Change-Id: Ie984051615632263a0f653dc5a1347f8b50dae10

19 files changed:
examples/fridgeclient.cpp
examples/fridgeserver.cpp
examples/garageclient.cpp
examples/ocicuc/demo_client.hpp
examples/roomclient.cpp
examples/simpleclient.cpp
examples/simpleclientserver.cpp
include/IClientWrapper.h
include/InProcClientWrapper.h
include/OCApi.h
include/OCHeaderOption.h [new file with mode: 0644]
include/OCResource.h
include/OCResourceRequest.h
include/OCResourceResponse.h
include/OutOfProcClientWrapper.h
src/InProcClientWrapper.cpp
src/InProcServerWrapper.cpp
src/OCPlatform.cpp
src/OCResource.cpp

index 85ced90..f594318 100644 (file)
 using namespace OC;
 namespace PH = std::placeholders;
 
+// Option ID for API version and client token
+const uint16_t API_VERSION = 2048;
+const uint16_t TOKEN = 3000;
+
 class ClientFridge
 {
     public:
@@ -86,21 +90,46 @@ class ClientFridge
         OCResource::Ptr randomdoor = m_platform.constructResourceObject(resource->host(),
                                 "/door/random", false, doorTypes, ifaces);
 
+        // Set header options with API version and token
+        HeaderOptions headerOptions;
+        try
+        {
+            // Set API version and client token
+            HeaderOption::OCHeaderOption apiVersion(API_VERSION, "v.1.0");
+            HeaderOption::OCHeaderOption clientToken(TOKEN, "21ae43gf");
+            headerOptions.push_back(apiVersion);
+            headerOptions.push_back(clientToken);
+        }
+        catch(OCException& e)
+        {
+            std::cout << "Error creating HeaderOption: " << e.what() << std::endl;
+        }
+
+
+        // Setting header options will send above options in all requests
+        // Header options are set per resource.
+        // Below, header options are set only for device resource
+        resource->setHeaderOptions(headerOptions);
+
+        resource->get(QueryParamsMap(), GetCallback(
+                std::bind(&ClientFridge::getResponse, this, "Device", PH::_1,
+                    PH::_2, PH::_3, resource, 0)
+                ));
         light->get(QueryParamsMap(), GetCallback(
                 std::bind(&ClientFridge::getResponse, this, "Fridge Light", PH::_1,
-                    PH::_2, light, 1)
+                    PH::_2, PH::_3, light, 1)
                 ));
         leftdoor->get(QueryParamsMap(), GetCallback(
                 std::bind(&ClientFridge::getResponse, this, "Left Door", PH::_1,
-                    PH::_2, leftdoor, 2)
+                    PH::_2, PH::_3, leftdoor, 2)
                 ));
         rightdoor->get(QueryParamsMap(), GetCallback(
                 std::bind(&ClientFridge::getResponse, this, "Right Door", PH::_1,
-                    PH::_2, rightdoor, 3)
+                    PH::_2, PH::_3, rightdoor, 3)
                 ));
         randomdoor->get(QueryParamsMap(), GetCallback(
                 std::bind(&ClientFridge::getResponse, this, "Random Door", PH::_1,
-                    PH::_2, randomdoor, 4)
+                    PH::_2, PH::_3, randomdoor, 4)
                 ));
     }
 
@@ -108,16 +137,33 @@ class ClientFridge
     // it is possible to attach ANY arbitrary data to do whatever you would like here.  It may,
     // however be a better fit to wrap each call in an object so a fuller context (and additional
     // requests) can be easily made inside of a simple context
-    void getResponse(const std::string& resourceName, const OCRepresentation rep, const int eCode,
-            OCResource::Ptr resource, int getId)
+    void getResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
+                const OCRepresentation rep, const int eCode, OCResource::Ptr resource, int getId)
     {
         std::cout << "Got a response from get from the "<<resourceName<< std::endl;
         std::cout << "Get ID is "<<getId<<" and resource URI is "<<resource->uri()<<std::endl;
 
         std::cout << "The Attribute Data is: "<<std::endl;
 
+        for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
+        {
+            if(it->getOptionID() == API_VERSION)
+            {
+                std::cout << "Server API version in GET response: " <<
+                        it->getOptionData() << std::endl;
+            }
+        }
+
         switch(getId)
         {
+            case 0:
+                {
+                    // Get on device
+                    std::string name;
+                    rep.getValue("device_name", name);
+                    std::cout << "Name of device: "<< name << std::endl;
+                    break;
+                }
             case 1:
                 {
                     bool isOn;
index 2f400fd..dcc575f 100644 (file)
 using namespace OC;
 namespace PH = std::placeholders;
 
+// Option ID for API version and client token
+const uint16_t API_VERSION = 2048;
+const uint16_t TOKEN = 3000;
+
+// Setting API version and token (shared out of band with client)
+// This assumes the fact that this server responds
+// only with a server with below version and token
+const std::string FRIDGE_CLIENT_API_VERSION = "v.1.0";
+const std::string FRIDGE_CLIENT_TOKEN = "21ae43gf";
+
 class Resource
 {
     protected:
@@ -88,26 +98,73 @@ class DeviceResource : public Resource
     {
         if(request)
         {
-            if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+            // Get the header options from the request
+            HeaderOptions headerOptions = request->getHeaderOptions();
+            std::string clientAPIVersion;
+            std::string clientToken;
+
+            // Search the header options map and look for API version and Client token
+            for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
             {
-                if(request->getRequestType() == "GET")
+                uint16_t optionID = it->getOptionID();
+                if(optionID == API_VERSION)
                 {
-                    if(response)
+                    clientAPIVersion = it->getOptionData();
+                    std::cout << " Client API version: " << clientAPIVersion << std::endl;
+                }
+                else if(optionID == TOKEN)
+                {
+                    clientToken = it->getOptionData();
+                    std::cout << " Client token: " << clientToken << std::endl;
+                }
+                else
+                {
+                    std::cout << " Invalid header option " << std::endl;
+                }
+            }
+
+            // In this case Server entity handler verifies API version
+            // and client token. If they are valid, client requests are handled.
+            if(clientAPIVersion == FRIDGE_CLIENT_API_VERSION && clientToken == FRIDGE_CLIENT_TOKEN)
+            {
+                HeaderOptions serverHeaderOptions;
+                try
+                {
+                    // Set API version from server side
+                    HeaderOption::OCHeaderOption apiVersion(API_VERSION, FRIDGE_CLIENT_API_VERSION);
+                    serverHeaderOptions.push_back(apiVersion);
+                }
+                catch(OCException& e)
+                {
+                    std::cout << "Error creating HeaderOption in server: " << e.what() << std::endl;
+                }
+
+                if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+                {
+                    if(request->getRequestType() == "GET")
                     {
-                        std::cout<<"DeviceResource Get Request"<<std::endl;
-                        response->setErrorCode(200);
-                        response->setResourceRepresentation(get(), "");
+                        if(response)
+                        {
+                            std::cout<<"DeviceResource Get Request"<<std::endl;
+                            response->setErrorCode(200);
+                            response->setHeaderOptions(serverHeaderOptions);
+                            response->setResourceRepresentation(get(), "");
+                        }
+                    }
+                    else
+                    {
+                        std::cout <<"DeviceResource unsupported request type "
+                        << request->getRequestType() << std::endl;
                     }
                 }
                 else
                 {
-                    std::cout <<"DeviceResource unsupported request type "
-                    << request->getRequestType() << std::endl;
+                    std::cout << "DeviceResource unsupported request flag" <<std::endl;
                 }
             }
             else
             {
-                std::cout << "DeviceResource unsupported request flag" <<std::endl;
+                std::cout << "Unsupported/invalid header options/values" << std::endl;
             }
         }
     }
@@ -215,7 +272,7 @@ class LightResource : public Resource
                 }
                 else
                 {
-                    std::cout <<"Light unsupported request type "
+                    std::cout << "Light unsupported request type"
                     << request->getRequestType() << std::endl;
                 }
             }
@@ -272,6 +329,7 @@ class DoorResource : public Resource
     virtual void entityHandler(std::shared_ptr<OCResourceRequest> request,
             std::shared_ptr<OCResourceResponse> response)
     {
+        std::cout << "EH of door invoked " << std::endl;
         if(request)
         {
             std::cout << "In entity handler for Door, URI is : "
index 17cf0cf..9edd08e 100644 (file)
@@ -131,7 +131,7 @@ void printRepresentation(const OCRepresentation& rep)
 
 }
 // callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -168,7 +168,7 @@ void putLightRepresentation(std::shared_ptr<OCResource> resource)
 }
 
 // Callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
index d6aad00..d82b530 100644 (file)
@@ -8,7 +8,7 @@ namespace Intel { namespace OCDemo { namespace client {
 class resource_handle
 {
  friend class resource_handler;
+
  private:
  const std::string                     URI;
  std::shared_ptr<OC::OCResource>       resource;
@@ -26,9 +26,12 @@ class resource_handle
  // Callbacks (note that the signature after binding will match exactly:
  private:
  void onFoundResource(std::shared_ptr<OC::OCResource> in_resource);
- void onResourceGet(OC::OCRepresentation rep, const int error_code);
- void onResourcePut(const OC::OCRepresentation rep, const int error_code);
- void onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number);
+ void onResourceGet(const OC::HeaderOptions& headerOptions,
+                OC::OCRepresentation rep, const int error_code);
+ void onResourcePut(const OC::HeaderOptions& headerOptions, const OC::OCRepresentation rep,
+                const int error_code);
+ void onObserve(const OC::HeaderOptions& headerOptions, const OC::OCRepresentation rep,
+                const int error_code, const int& sequence_number);
 };
 
 class resource_handler
@@ -67,9 +70,9 @@ class resource_handler
 
                 call_timer.mark("find_resources");
 
-                platform.findResource("", resource->URI, 
+                platform.findResource("", resource->URI,
                                       std::bind(&resource_handle::onFoundResource, resource, std::placeholders::_1));
-         } 
+         }
  }
 };
 
@@ -79,7 +82,7 @@ resource_handler::resource_handler(OC::OCPlatform& platform_, const std::vector<
  : platform(platform_)
 {
  for(const auto& URI : resource_URIs)
-  add(URI); 
+  add(URI);
 }
 
 resource_handler::resource_handler(OC::OCPlatform& platform_)
@@ -112,8 +115,8 @@ void resource_handle::onFoundResource(std::shared_ptr<OC::OCResource> in_resourc
 
        OC::QueryParamsMap qpm;
 
-       resource->get(qpm, std::bind(&resource_handle::onResourceGet, this, 
-                                    std::placeholders::_1, std::placeholders::_2));
+       resource->get(qpm, std::bind(&resource_handle::onResourceGet, this,
+            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
   }
  catch(OC::OCException& e)
   {
@@ -125,7 +128,8 @@ void resource_handle::onFoundResource(std::shared_ptr<OC::OCResource> in_resourc
   }
 }
 
-void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int error_code)
+void resource_handle::onResourceGet(const OC::HeaderOptions& headerOptions,
+                const OC::OCRepresentation rep, const int error_code)
 {
  using std::cout;
 
@@ -147,7 +151,7 @@ void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int er
 
  std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
 
- // Now, make a change to the light representation (replacing, rather than parsing): 
+ // Now, make a change to the light representation (replacing, rather than parsing):
  OC::AttributeMap attrs {
                          { "state", { "true" } },
                          { "power", { "10" } }
@@ -158,13 +162,15 @@ void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int er
  call_timer.mark("put_resource");
 
  OC::OCRepresentation out_rep;
- out_rep.setAttributeMap(attrs); 
- resource->put(out_rep, OC::QueryParamsMap(), 
-               std::bind(&resource_handle::onResourcePut, this, std::placeholders::_1, std::placeholders::_2));
+ out_rep.setAttributeMap(attrs);
+
+ resource->put(out_rep, OC::QueryParamsMap(),
+               std::bind(&resource_handle::onResourcePut, this, std::placeholders::_1,
+               std::placeholders::_2, std::placeholders::_3));
 }
 
-void resource_handle::onResourcePut(const OC::OCRepresentation rep, const int error_code)
+void resource_handle::onResourcePut(const OC::HeaderOptions& headerOptions,
+            const OC::OCRepresentation rep, const int error_code)
 {
  std::cout << "onResourcePut():\n";
 
@@ -185,10 +191,13 @@ void resource_handle::onResourcePut(const OC::OCRepresentation rep, const int er
 
  // Start an observer:
  resource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
-                    std::bind(&resource_handle::onObserve, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+                std::bind(&resource_handle::onObserve, this,
+                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                std::placeholders::_4));
 }
 
-void resource_handle::onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
+void resource_handle::onObserve(const OC::HeaderOptions& headerOptions,
+            const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
 {
  if(0 != error_code)
   {
@@ -215,7 +224,7 @@ void resource_handle::onObserve(const OC::OCRepresentation rep, const int error_
     const auto result = resource->cancelObserve();
 
     std::cout << "onObserve(): result of cancellation: " << result << ".\n";
-    
+
     this_thread::sleep_for(chrono::seconds(10));
   }
 }
index 735a630..e39cafe 100644 (file)
@@ -39,10 +39,10 @@ int observe_count()
 
 // Forward declaration
 void putRoomRepresentation(std::shared_ptr<OCResource> resource);
-void onPut(const OCRepresentation& rep, const int eCode);
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
 
 // callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -105,7 +105,7 @@ void putRoomRepresentation(std::shared_ptr<OCResource> resource)
 }
 
 // callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
index b692201..8c4cb1a 100644 (file)
@@ -53,7 +53,8 @@ int observe_count()
     return ++oc;
 }
 
-void onObserve(const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
+void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep,
+                    const int& eCode, const int& sequenceNumber)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -86,7 +87,7 @@ void onObserve(const OCRepresentation& rep, const int& eCode, const int& sequenc
     }
 }
 
-void onPost2(const OCRepresentation& rep, const int eCode)
+void onPost2(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -123,7 +124,7 @@ void onPost2(const OCRepresentation& rep, const int eCode)
     }
 }
 
-void onPost(const OCRepresentation& rep, const int eCode)
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -185,7 +186,7 @@ void postLightRepresentation(std::shared_ptr<OCResource> resource)
 }
 
 // callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
@@ -229,7 +230,7 @@ void putLightRepresentation(std::shared_ptr<OCResource> resource)
 }
 
 // Callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
index 77d719a..f25806e 100644 (file)
@@ -38,7 +38,8 @@ class ClientWorker
 private:
     bool m_isFoo;
     int m_barCount;
-    void putResourceInfo(const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
+    void putResourceInfo(const HeaderOptions& headerOptions,
+            const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
     {
        std::cout << "In PutResourceInfo" << std::endl;
 
@@ -67,7 +68,8 @@ private:
        }
     }
 
-    void getResourceInfo(const OCRepresentation rep, const int eCode)
+    void getResourceInfo(const HeaderOptions& headerOptions, const OCRepresentation rep,
+                const int eCode)
     {
         std::cout << "In getResourceInfo" << std::endl;
 
@@ -92,7 +94,9 @@ private:
             rep2.setValue("isFoo", m_isFoo);
             rep2.setValue("barCount", m_barCount);
 
-            m_resource->put(rep2, QueryParamsMap(), PutCallback(std::bind(&ClientWorker::putResourceInfo, this, rep2, std::placeholders::_1, std::placeholders::_2)));
+            m_resource->put(rep2, QueryParamsMap(),
+                PutCallback(std::bind(&ClientWorker::putResourceInfo, this, std::placeholders::_1,
+                     rep2, std::placeholders::_2, std::placeholders::_3)));
         }
     }
 
@@ -131,7 +135,9 @@ private:
 
             std::cout<<"Doing a get on q/foo."<<std::endl;
 
-            resource->get(QueryParamsMap(), GetCallback(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
+            resource->get(QueryParamsMap(),
+                GetCallback(std::bind(&ClientWorker::getResourceInfo, this,
+                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
         }
     }
 
index 4cf9979..dc3f545 100644 (file)
@@ -47,25 +47,26 @@ namespace OC
 
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
                         const std::string& uri, const QueryParamsMap& queryParams,
+                        const HeaderOptions& headerOptions,
                         GetCallback& callback)=0;
 
         virtual OCStackResult PutResourceRepresentation(const std::string& host,
                         const std::string& uri, const OCRepresentation& rep,
-                        const QueryParamsMap& queryParams,
+                        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
                         PutCallback& callback) = 0;
 
         virtual OCStackResult PostResourceRepresentation(const std::string& host,
                         const std::string& uri, const OCRepresentation& rep,
-                        const QueryParamsMap& queryParams,
-                        PutCallback& callback) = 0;
+                        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+                        PostCallback& callback) = 0;
 
         virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
                         const std::string& host, const std::string& uri,
-                        const QueryParamsMap& queryParams,
+                        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
                         ObserveCallback& callback)=0;
 
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
-                        const std::string& uri)=0;
+            const std::string& uri, const HeaderOptions& headerOptions)=0;
 
         virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
                         SubscribeCallback& presenceHandler)=0;
index 333b1e6..431ba1d 100644 (file)
@@ -49,22 +49,25 @@ namespace OC
 
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
             const std::string& uri, const QueryParamsMap& queryParams,
+            const HeaderOptions& headerOptions,
             GetCallback& callback);
 
         virtual OCStackResult PutResourceRepresentation(const std::string& host,
             const std::string& uri, const OCRepresentation& attributes,
-            const QueryParamsMap& queryParams, PutCallback& callback);
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            PutCallback& callback);
 
         virtual OCStackResult PostResourceRepresentation(const std::string& host,
             const std::string& uri, const OCRepresentation& attributes,
-            const QueryParamsMap& queryParams, PostCallback& callback);
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            PostCallback& callback);
 
         virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
             const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
-            ObserveCallback& callback);
+            const HeaderOptions& headerOptions, ObserveCallback& callback);
 
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
-            const std::string& uri);
+            const std::string& uri, const HeaderOptions& headerOptions);
 
         virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
             SubscribeCallback& presenceHandler);
@@ -78,6 +81,8 @@ namespace OC
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
         std::string assembleSetResourcePayload(const OCRepresentation& attributes);
+        void assembleHeaderOptions(OCHeaderOption options[],
+            const HeaderOptions& headerOptions);
         std::thread m_listeningThread;
         bool m_threadRun;
         std::weak_ptr<std::recursive_mutex> m_csdkLock;
index 7219c6a..7c0eedc 100644 (file)
@@ -33,6 +33,7 @@
 #include <boost/variant.hpp>
 
 #include "ocstack.h"
+#include "OCHeaderOption.h"
 #include <OCException.h>
 
 namespace OC
@@ -596,6 +597,9 @@ namespace OC
         }
     }
 
+    // Typedef for header option vector
+    // OCHeaderOption class is in HeaderOption namespace
+    typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions;
 
     // Typedef for query parameter map
     typedef std::map<std::string, std::string> QueryParamsMap;
@@ -629,13 +633,23 @@ namespace OC
     const std::string BATCH_INTERFACE = "oc.mi.b";
 
     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
+
     typedef std::function<void(const std::shared_ptr<OCResourceRequest>,
                                 const std::shared_ptr<OCResourceResponse>)> EntityHandler;
+
     typedef std::function<void(OCStackResult, const unsigned int)> SubscribeCallback;
-    typedef std::function<void(const OCRepresentation&, const int)> GetCallback;
-    typedef std::function<void(const OCRepresentation&, const int)> PutCallback;
-    typedef std::function<void(const OCRepresentation&, const int)> PostCallback;
-    typedef std::function<void(const OCRepresentation&, const int, const int)> ObserveCallback;
+
+    typedef std::function<void(const HeaderOptions&,
+                                const OCRepresentation&, const int)> GetCallback;
+
+    typedef std::function<void(const HeaderOptions&,
+                                const OCRepresentation&, const int)> PostCallback;
+
+    typedef std::function<void(const HeaderOptions&,
+                                const OCRepresentation&, const int)> PutCallback;
+
+    typedef std::function<void(const HeaderOptions&,
+                                const OCRepresentation&, const int, const int)> ObserveCallback;
 } // namespace OC
 
 #endif
diff --git a/include/OCHeaderOption.h b/include/OCHeaderOption.h
new file mode 100644 (file)
index 0000000..73993f3
--- /dev/null
@@ -0,0 +1,88 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/// @file OCHeaderOption.h
+
+/// @brief  This file contains the declaration of classes and its members related to
+///         OCHeaderOption.
+
+#ifndef __OCHEADEROPTION_H
+#define __OCHEADEROPTION_H
+
+#include <OCException.h>
+
+namespace OC
+{
+    namespace HeaderOption
+    {
+        /**
+        *     @brief OCHeaderOption class allows to create instances which comprises optionID
+        *            and optionData as members. These are used in setting Header options.
+        *            After creating instances of OCHeaderOptions, use setHeaderOptions API
+        *            (in OCResource.h) to set header Options.
+        *            NOTE: HeaderOptionID  is an unsigned integer value which MUST be within
+        *            range of 2048 to 3000 inclusive of lower and upper bound.
+        *            HeaderOptions instance creation fails if above condition is not satisfied.
+        */
+        const uint16_t MIN_HEADER_OPTIONID = 2048;
+        const uint16_t MAX_HEADER_OPTIONID = 3000;
+
+        class OCHeaderOption
+        {
+        private:
+            uint16_t m_optionID;
+            std::string m_optionData;
+
+        public:
+            /**
+            * OCHeaderOption constructor
+            */
+            OCHeaderOption(uint16_t optionID, std::string optionData):
+                m_optionID(optionID),
+                m_optionData(optionData)
+            {
+                if(!(optionID >= MIN_HEADER_OPTIONID && optionID <= MAX_HEADER_OPTIONID))
+                {
+                    throw OCException("Error:OptionID valid only from 2048 to 3000 inclusive");
+                }
+            }
+
+            /**
+            * API to get Option ID
+            * @return unsigned integer option ID
+            */
+            uint16_t getOptionID() const
+            {
+                return m_optionID;
+            }
+
+            /*
+            * API to get Option data
+            * @return std::string of option data
+            */
+            std::string getOptionData() const
+            {
+                return m_optionData;
+            }
+        };
+    } // namespace HeaderOption
+} // namespace OC
+
+#endif //__OCHEADEROPTION_H
index 3cc765f..8e98693 100644 (file)
@@ -81,22 +81,30 @@ namespace OC
         * @param queryParametersMap map which can have the query parameter name and value
         * @param attributeHandler handles callback
         *        The callback function will be invoked with a map of attribute name and values.
-        *        The callback function will be invoked with a list of URIs if 'get' is invoked on a resource container
-        *        (list will be empty if not a container)
-        *        The callback function will also have the result from this Get operation. This will have error codes
+        *        The callback function will be invoked with a list of URIs if 'get' is invoked on a
+        *        resource container (list will be empty if not a container)
+        *        The callback function will also have the result from this Get operation. This will
+        *        have error codes
         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
         * NOTE: OCStackResult is defined in ocstack.h.<br>
         * <b>Example:</b><br>
-        * Consider resource "a/home" (with link interface and resource type as home) contains links to "a/kitchen" and "a/room".
+        * Consider resource "a/home" (with link interface and resource type as home) contains links
+        *  to "a/kitchen" and "a/room".
         * Step 1: get("home", Link_Interface, &onGet)<br>
-        * Callback onGet will receive a) Empty attribute map because there are no attributes for a/home b) list with
-        * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET operation<br>
-        * NOTE: A resource may contain single or multiple resource types. Also, a resource may contain single or multiple interfaces.<br>
-        * Currently, single GET request is allowed to do operate on single resource type or resource interface. In future, a single GET <br>
+        * Callback onGet will receive a) Empty attribute map because there are no attributes for
+        * a/home b) list with
+        * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET
+        * operation<br>
+        * NOTE: A resource may contain single or multiple resource types. Also, a resource may
+        * contain single or multiple interfaces.<br>
+        * Currently, single GET request is allowed to do operate on single resource type or resource
+        * interface. In future, a single GET <br>
         * can operate on multiple resource types and interfaces. <br>
-        * NOTE: A client can traverse a tree or graph by doing successive GETs on the returned resources at a node.<br>
+        * NOTE: A client can traverse a tree or graph by doing successive GETs on the returned
+        * resources at a node.<br>
         */
-        OCStackResult get(const std::string& resourceType, const std::string& resourceInterface, const QueryParamsMap& queryParametersMap, GetCallback attributeHandler);
+        OCStackResult get(const std::string& resourceType, const std::string& resourceInterface,
+            const QueryParamsMap& queryParametersMap, GetCallback attributeHandler);
 
         /**
         * Function to set the representation of a resource (via PUT)
@@ -126,7 +134,6 @@ namespace OC
         *        This will have error codes.
         *        The Representation parameter maps which can either have all the attribute names
         *        and values
-        *        (which will represent entire state of the resource) or a
         *        set of attribute names and values which needs to be modified
         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
         * NOTE: OCStackResult is defined in ocstack.h. <br>
@@ -194,6 +201,32 @@ namespace OC
         OCStackResult cancelObserve();
 
         /**
+        * Function to set header information.
+        * @param headerOptions std::vector where header information(header optionID and optionData
+        * is passed
+        *
+        * NOTE: Once the headers information is set, it will be applicable to GET, PUT and observe
+        * request. <br>
+        * setHeaderOptions can be used multiple times if headers need to be modifed by the client.
+        * Latest headers will be used to send in the request. <br>
+        * NOTE: Initial support is only for two headers. If headerMap consists of more than two
+        * header options, they will be ignored. <br>
+        * Use unsetHeaderOptions API to clear the header information.
+        */
+        void setHeaderOptions(const HeaderOptions& headerOptions)
+        {
+            m_headerOptions = headerOptions;
+        }
+
+        /**
+        * Function to unset header options.
+        */
+        void unsetHeaderOptions()
+        {
+            m_headerOptions.clear();
+        }
+
+        /**
         * Function to get the host address of this resource
         * @return std::string host address
         * NOTE: This might or might not be exposed in future due to security concerns
@@ -241,10 +274,12 @@ namespace OC
         std::vector<std::string> m_interfaces;
         std::vector<std::string> m_children;
         OCDoHandle m_observeHandle;
+        HeaderOptions m_headerOptions;
 
     private:
-        OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host, const std::string& uri,
-            bool observable, const std::vector<std::string>& resourceTypes, const std::vector<std::string>& interfaces);
+        OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
+            const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
+            const std::vector<std::string>& interfaces);
     };
 
 } // namespace OC
index f556246..dffcfd0 100644 (file)
@@ -104,6 +104,10 @@ namespace OC
             return m_resourceUri;
         }
 
+        /** This API retrieves headerOptions which was sent from a client
+        * @return std::map HeaderOptions with the header options
+        */
+        const HeaderOptions& getHeaderOptions() const {return m_headerOptions;}
 
     private:
         std::string m_requestType;
@@ -112,6 +116,7 @@ namespace OC
         int m_requestHandlerFlag;
         OCRepresentation m_representation;
         ObservationInfo m_observationInfo;
+        HeaderOptions m_headerOptions;
 
     public:
         // TODO: This is not a public API for app developers.
@@ -179,8 +184,13 @@ namespace OC
             m_observationInfo = observationInfo;
         }
 
+        // TODO: This is not a public API for app developers.
+        // This function will not be exposed in future
+        void setHeaderOptions(const HeaderOptions& headerOptions)
+        {
+            m_headerOptions = headerOptions;
+        }
     };
-
-} // namespace OC
+ }// namespace OC
 
 #endif //__OCRESOURCEREQUEST_H
index 2bed33e..56250fa 100644 (file)
@@ -18,9 +18,9 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-/// @file OCResourceResponse.h 
+/// @file OCResourceResponse.h
 
-/// @brief  This file contains the declaration of classes and its members related to 
+/// @brief  This file contains the declaration of classes and its members related to
 ///         ResourceResponse.
 
 #ifndef __OCRESOURCERESPONSE_H
@@ -60,6 +60,15 @@ namespace OC
         void setErrorCode(const int eCode) { m_errorCode = eCode; }
 
         /**
+        * This API allows to set headerOptions in the response
+        * @param headerOptions HeaderOptions vector consisting of OCHeaderOption objects
+        */
+        void setHeaderOptions(const HeaderOptions& headerOptions)
+        {
+            m_headerOptions = headerOptions;
+        }
+
+        /**
         *  API to set the entire resource attribute representation
         *  @param attributeMap reference containing the name value pairs representing
         *         the resource's attributes
@@ -93,7 +102,8 @@ namespace OC
 
         /**
         *  API to set the entire resource attribute representation
-        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap reference containing the name value pairs representing the resource's
+        *  attributes
         */
         void setResourceRepresentation(OCRepresentation& rep) {
             // Call the default
@@ -102,7 +112,8 @@ namespace OC
 
         /**
         *  API to set the entire resource attribute representation
-        *  @param attributeMap rvalue reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap rvalue reference containing the name value pairs representing the
+        *  resource's attributes
         */
         void setResourceRepresentation(OCRepresentation&& rep) {
             // Call the above function
@@ -111,7 +122,8 @@ namespace OC
 
         /**
         *  API to set the entire resource attribute representation (Linked List Interface))
-        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap reference containing the name value pairs representing the resource's
+        *  attributes
         */
         void setResourceRepresentationLL(OCRepresentation& rep) {
 
@@ -174,7 +186,8 @@ namespace OC
 
         /**
         *  API to set the entire resource attribute representation (Default))
-        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap reference containing the name value pairs representing the resource's
+        *  attributes
         */
         void setResourceRepresentationDefault(OCRepresentation& rep) {
 
@@ -242,7 +255,8 @@ namespace OC
 
         /**
         *  API to set the entire resource attribute representation (BATCH)
-        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap reference containing the name value pairs representing the resource's
+        *  attributes
         */
         void setResourceRepresentationBatch(OCRepresentation& rep) {
             ostringstream payload;
@@ -282,15 +296,16 @@ namespace OC
 
         /** TODO remove this once after above function stabilize.
         *  API to set the entire resource attribute representation
-        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        *  @param attributeMap reference containing the name value pairs representing the
+        *  resource's attributes
         */
-        void setResourceRepresentation(AttributeMap& attributes) { 
+        void setResourceRepresentation(AttributeMap& attributes) {
 
             // TODO To be refactored
             ostringstream payload;
 
             payload << "{";
-            
+
             // TODO fix this (do this programmatically)
             payload << "\"href\":\"/a/room\"";
 
@@ -315,19 +330,28 @@ namespace OC
     private:
         std::string m_payload;
         int m_errorCode;
+        HeaderOptions m_headerOptions;
 
     // TODO only stack should have visibility and apps should not
     public:
 
-        /** 
-        * Get error code 
+        /**
+        * Get error code
+        */
+        int getErrorCode() const;
+
+        /**
+        * This API allows to retrieve headerOptions from a response
         */
-        int getErrorCode() const; 
+        const HeaderOptions& getHeaderOptions() const
+        {
+            return m_headerOptions;
+        }
 
         /**
         * Get the resource attribute representation
         */
-        AttributeMap& getResourceRepresentation() const; 
+        AttributeMap& getResourceRepresentation() const;
 
         // TODO This should go away & just use getResourceRepresentation
         std::string getPayload()
index 18c3c04..df8e1cb 100644 (file)
@@ -37,25 +37,30 @@ namespace OC
             const std::string& resourceType, FindCallback& callback) {return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
-            const std::string& uri, const QueryParamsMap& queryParams, GetCallback& callback)
+            const std::string& uri, const QueryParamsMap& queryParams,
+            const HeaderOptions& headerOptions, GetCallback& callback)
             {return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult PutResourceRepresentation(const std::string& host,
             const std::string& uri, const OCRepresentation& attributes,
-            const QueryParamsMap& queryParams, PutCallback& callback)
+            const QueryParamsMap& queryParams,
+            const HeaderOptions& headerOptions, PutCallback& callback)
             {return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult PostResourceRepresentation(const std::string& host,
             const std::string& uri, const OCRepresentation& attributes,
-            const QueryParamsMap& queryParams, PostCallback& callback)
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            PostCallback& callback)
             {return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
             const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
+            const HeaderOptions& headerOptions,
             ObserveCallback& callback){return OC_STACK_NOTIMPL;}
 
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
-            const std::string& uri){return OC_STACK_NOTIMPL;}
+            const std::string& uri,
+            const HeaderOptions& headerOptions){return OC_STACK_NOTIMPL;}
 
         virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper,
             const std::string& host, const boost::property_tree::ptree resourceNode)
index 44a3525..eb6197f 100644 (file)
@@ -260,6 +260,7 @@ namespace OC
     OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
     {
         std::stringstream requestStream;
+
         requestStream<<clientResponse->resJSONPayload;
         if(strlen((char*)clientResponse->resJSONPayload) == 0)
         {
@@ -365,24 +366,53 @@ namespace OC
         return root_resource;
     }
 
+    void parseServerHeaderOptions(OCClientResponse* clientResponse,
+                    HeaderOptions& serverHeaderOptions)
+    {
+        if(clientResponse)
+        {
+            // Parse header options from server
+            uint16_t optionID;
+            std::string optionData;
+
+            for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
+            {
+                optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
+                optionData = reinterpret_cast<const char*>
+                                (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
+                HeaderOption::OCHeaderOption headerOption(optionID, optionData);
+                serverHeaderOptions.push_back(headerOption);
+            }
+        }
+        else
+        {
+            // clientResponse is invalid
+            // TODO check proper logging
+            std::cout << " Invalid response " << std::endl;
+        }
+    }
+
     OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle,
         OCClientResponse* clientResponse)
     {
         GetContext* context = static_cast<GetContext*>(ctx);
 
         OCRepresentation rep;
-
+        HeaderOptions serverHeaderOptions;
         if(clientResponse->result == OC_STACK_OK)
         {
+            parseServerHeaderOptions(clientResponse, serverHeaderOptions);
             rep = parseGetSetCallback(clientResponse);
         }
 
-        std::thread exec(context->callback, rep, clientResponse->result);
+        std::thread exec(context->callback, serverHeaderOptions, rep, clientResponse->result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
     }
+
     OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
-        const std::string& uri, const QueryParamsMap& queryParams, GetCallback& callback)
+        const std::string& uri, const QueryParamsMap& queryParams,
+        const HeaderOptions& headerOptions, GetCallback& callback)
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -402,11 +432,14 @@ namespace OC
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCDoHandle handle;
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
                                   nullptr, nullptr,
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata,
-                                  NULL, 0);
+                                  options, headerOptions.size());
         }
         else
         {
@@ -421,12 +454,14 @@ namespace OC
     {
         SetContext* context = static_cast<SetContext*>(ctx);
         OCRepresentation attrs;
+        HeaderOptions serverHeaderOptions;
 
         if(clientResponse->result == OC_STACK_OK)
         {
+            parseServerHeaderOptions(clientResponse, serverHeaderOptions);
             attrs = parseGetSetCallback(clientResponse);
         }
-        std::thread exec(context->callback, attrs, clientResponse->result);
+        std::thread exec(context->callback, serverHeaderOptions, attrs, clientResponse->result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
     }
@@ -474,7 +509,8 @@ namespace OC
 
     OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
         const std::string& uri, const OCRepresentation& rep,
-        const QueryParamsMap& queryParams, PostCallback& callback)
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+         PostCallback& callback)
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -495,12 +531,15 @@ namespace OC
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
             OCDoHandle handle;
+
+            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(&handle, OC_REST_POST,
                                   os.str().c_str(), nullptr,
                                   assembleSetResourcePayload(rep).c_str(),
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
-                                  &cbdata, NULL, 0);
+                                  &cbdata, options, headerOptions.size());
         }
         else
         {
@@ -513,7 +552,8 @@ namespace OC
 
     OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
         const std::string& uri, const OCRepresentation& rep,
-        const QueryParamsMap& queryParams, PutCallback& callback)
+        const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        PutCallback& callback)
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -535,12 +575,15 @@ namespace OC
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCDoHandle handle;
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(&handle, OC_REST_PUT,
                                   os.str().c_str(), nullptr,
                                   assembleSetResourcePayload(rep).c_str(),
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata,
-                                  NULL, 0);
+                                  options, headerOptions.size());
         }
         else
         {
@@ -560,19 +603,23 @@ namespace OC
     {
         ObserveContext* context = static_cast<ObserveContext*>(ctx);
         OCRepresentation attrs;
+        HeaderOptions serverHeaderOptions;
         uint32_t sequenceNumber = clientResponse->sequenceNumber;
+
         if(clientResponse->result == OC_STACK_OK)
         {
+            parseServerHeaderOptions(clientResponse, serverHeaderOptions);
             attrs = parseGetSetCallback(clientResponse);
         }
-        std::thread exec(context->callback, attrs, clientResponse->result, sequenceNumber);
+        std::thread exec(context->callback, serverHeaderOptions, attrs,
+                    clientResponse->result, sequenceNumber);
         exec.detach();
         return OC_STACK_KEEP_TRANSACTION;
     }
 
     OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
         const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
-        ObserveCallback& callback)
+        const HeaderOptions& headerOptions, ObserveCallback& callback)
     {
         OCStackResult result;
         OCCallbackData cbdata = {0};
@@ -605,12 +652,15 @@ namespace OC
             os << host << assembleSetResourceUri(uri, queryParams).c_str();
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+            assembleHeaderOptions(options, headerOptions);
             result = OCDoResource(handle, method,
                                   os.str().c_str(), nullptr,
                                   nullptr,
                                   static_cast<OCQualityOfService>(m_cfg.QoS),
                                   &cbdata,
-                                  NULL, 0);
+                                  options, headerOptions.size());
         }
         else
         {
@@ -621,7 +671,7 @@ namespace OC
     }
 
     OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
-        const std::string& host, const std::string& uri)
+        const std::string& host, const std::string& uri, const HeaderOptions& headerOptions)
     {
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
@@ -629,7 +679,10 @@ namespace OC
         if(cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCCancel(handle, OC_NON_CONFIRMABLE, NULL, 0);
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+            assembleHeaderOptions(options, headerOptions);
+            result = OCCancel(handle, OC_NON_CONFIRMABLE, options, headerOptions.size());
         }
         else
         {
@@ -694,4 +747,20 @@ namespace OC
 
         return result;
     }
+
+    void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
+           const HeaderOptions& headerOptions)
+    {
+        int i = 0;
+
+        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);
+            i++;
+        }
+    }
 }
index 71def86..904c24f 100644 (file)
@@ -69,6 +69,23 @@ void formResourceRequest(OCEntityHandlerFlag flag,
                     pRequest->setQueryParams(qp);
                 }
             }
+            if(entityHandlerRequest->numRcvdVendorSpecificHeaderOptions != 0)
+            {
+                //Set the header options here.
+                uint16_t optionID;
+                std::string optionData;
+                HeaderOptions headerOptions;
+
+                for(int i = 0; i < MAX_HEADER_OPTIONS; i++)
+                {
+                    optionID = entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionID;
+                    optionData = reinterpret_cast<const char*>
+                             (entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData);
+                    HeaderOption::OCHeaderOption headerOption(optionID, optionData);
+                    headerOptions.push_back(headerOption);
+                }
+                pRequest->setHeaderOptions(headerOptions);
+            }
 
             if(OC_REST_GET == entityHandlerRequest->method)
             {
@@ -112,10 +129,12 @@ void processResourceResponse(OCEntityHandlerFlag flag,
     {
         // TODO we could use const reference
         std::string payLoad;
+        HeaderOptions serverHeaderOptions;
 
         if(pResponse)
         {
             payLoad = pResponse->getPayload();
+            serverHeaderOptions = pResponse->getHeaderOptions();
         }
         else
         {
@@ -125,6 +144,22 @@ void processResourceResponse(OCEntityHandlerFlag flag,
 
         if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
         {
+            int i = 0;
+            entityHandlerRequest->numSendVendorSpecificHeaderOptions =
+                        serverHeaderOptions.size();
+            for (auto it=serverHeaderOptions.begin(); it != serverHeaderOptions.end(); ++it)
+            {
+                entityHandlerRequest->sendVendorSpecificHeaderOptions[i].protocolID = OC_COAP_ID;
+                entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionID =
+                        static_cast<uint16_t>(it->getOptionID());
+                entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionLength =
+                        (it->getOptionData()).length() + 1;
+                memcpy(entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionData,
+                        (it->getOptionData()).c_str(),
+                        (it->getOptionData()).length() + 1);
+                i++;
+            }
+
             strncpy((char*)entityHandlerRequest->resJSONPayload,
                         payLoad.c_str(),
                         entityHandlerRequest->resJSONPayloadLen);
index d05faa7..df54f60 100644 (file)
@@ -140,7 +140,8 @@ OCStackResult OCPlatform::registerResource(OCResourceHandle& resourceHandle,
                                            uint8_t resourceProperty)
 {
     return checked_guard(m_server, &IServerWrapper::registerResource,
-                         ref(resourceHandle), resourceURI, resourceTypeName, resourceInterface, entityHandler, resourceProperty);
+                         ref(resourceHandle), resourceURI, resourceTypeName,
+                                resourceInterface, entityHandler, resourceProperty);
 }
 
 OCStackResult OCPlatform::unregisterResource(const OCResourceHandle& resourceHandle) const
index e9b2730..ebe653b 100644 (file)
@@ -28,8 +28,9 @@ using OC::result_guard;
 using OC::checked_guard;
 
 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
-                       const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
-                       const std::vector<std::string>& interfaces) 
+                       const std::string& uri, bool observable,
+                       const std::vector<std::string>& resourceTypes,
+                       const std::vector<std::string>& interfaces)
  :  m_clientWrapper(clientWrapper), m_uri(uri), m_host(host), m_isObservable(observable),
     m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
@@ -55,12 +56,12 @@ OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
                               GetCallback attributeHandler)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
-                         m_host, m_uri, queryParametersMap, attributeHandler);
+                         m_host, m_uri, queryParametersMap, m_headerOptions, attributeHandler);
 }
 
 OCStackResult OCResource::get(const std::string& resourceType,
-                              const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
-                              GetCallback attributeHandler)
+                     const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
+                     GetCallback attributeHandler)
 {
     QueryParamsMap mapCpy(queryParametersMap);
 
@@ -78,10 +79,10 @@ OCStackResult OCResource::get(const std::string& resourceType,
 }
 
 OCStackResult OCResource::put(const OCRepresentation& rep,
-                              const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
+                     const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
-                         m_host, m_uri, rep, queryParametersMap, attributeHandler);
+                         m_host, m_uri, rep, queryParametersMap, m_headerOptions, attributeHandler);
 }
 
 OCStackResult OCResource::put(const std::string& resourceType,
@@ -105,10 +106,10 @@ OCStackResult OCResource::put(const std::string& resourceType,
 }
 
 OCStackResult OCResource::post(const OCRepresentation& rep,
-                               const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
+                     const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
-                         m_host, m_uri, rep, queryParametersMap, attributeHandler);
+                         m_host, m_uri, rep, queryParametersMap, m_headerOptions, attributeHandler);
 }
 
 OCStackResult OCResource::post(const std::string& resourceType,
@@ -132,7 +133,7 @@ OCStackResult OCResource::post(const std::string& resourceType,
 }
 
 OCStackResult OCResource::observe(ObserveType observeType,
-                                  const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
+                           const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
 {
     if(m_observeHandle != nullptr)
     {
@@ -141,7 +142,7 @@ OCStackResult OCResource::observe(ObserveType observeType,
 
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
                          observeType, &m_observeHandle, m_host,
-                         m_uri, queryParametersMap, observeHandler);
+                         m_uri, queryParametersMap, m_headerOptions, observeHandler);
 }
 
 OCStackResult OCResource::cancelObserve()
@@ -152,7 +153,7 @@ OCStackResult OCResource::cancelObserve()
     }
 
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::CancelObserveResource,
-                         m_observeHandle, m_host, m_uri);
+                         m_observeHandle, m_host, m_uri, m_headerOptions);
 }
 
 std::string OCResource::host() const