CPP Collection
authorSashi Penta <sashi.kumar.penta@intel.com>
Tue, 19 Aug 2014 06:02:54 +0000 (23:02 -0700)
committerSashi Penta <sashi.kumar.penta@intel.com>
Tue, 19 Aug 2014 22:05:22 +0000 (15:05 -0700)
Patch 1:
Server side CPP collection interfaces implementation.
Includes new class OCRepresentation for collection resources and simple resource.
Includes Sudarshan's changes related to Query Params.

Patch 2:
Client side CPP Put on collection

Patch 3:
Addresses Jesse's comments

Change-Id: Ia1b8fa32a7d80d13519f456aaa6817466ffdfa60

17 files changed:
OCLib/InProcClientWrapper.cpp
OCLib/InProcServerWrapper.cpp
OCLib/OCResource.cpp
examples/roomclient.cpp [new file with mode: 0644]
examples/roomserver.cpp [new file with mode: 0644]
examples/simpleclient.cpp
examples/simpleclientserver.cpp
examples/simpleserver.cpp
include/IClientWrapper.h
include/InProcClientWrapper.h
include/OCPlatform.h
include/OCRepresentation.h [new file with mode: 0644]
include/OCResource.h
include/OCResourceRequest.h
include/OCResourceResponse.h
include/OutOfProcClientWrapper.h
makefile

index 1fffd35..305294a 100644 (file)
@@ -116,6 +116,7 @@ namespace OC
     const std::string OBSERVABLEKEY = "obs";
     const std::string RESOURCETYPESKEY= "rt";
     const std::string INTERFACESKEY = "if";
+    const std::string PROPERTYKEY = "prop";
 
     std::shared_ptr<OCResource> InProcClientWrapper::parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const boost::property_tree::ptree resourceNode)
     {
@@ -124,17 +125,20 @@ namespace OC
         std::vector<std::string> rTs;
         std::vector<std::string> ifaces;
 
-        boost::property_tree::ptree resourceTypes = resourceNode.get_child(RESOURCETYPESKEY, boost::property_tree::ptree());
-        for(auto itr : resourceTypes)
+        boost::property_tree::ptree properties = resourceNode.get_child(PROPERTYKEY, boost::property_tree::ptree());
+
+        boost::property_tree::ptree rT = properties.get_child(RESOURCETYPESKEY, boost::property_tree::ptree());
+        for(auto itr : rT)
         {
             rTs.push_back(itr.second.data());
         }
 
-        boost::property_tree::ptree interfaces = resourceNode.get_child(INTERFACESKEY, boost::property_tree::ptree());
-        for(auto itr : interfaces)
+        boost::property_tree::ptree iF = properties.get_child(INTERFACESKEY, boost::property_tree::ptree());
+        for(auto itr : iF)
         {
             ifaces.push_back(itr.second.data());
         }
+
         return std::shared_ptr<OCResource>(new OCResource(clientWrapper, host, uri, obs, rTs, ifaces));
     }
     
@@ -149,7 +153,7 @@ namespace OC
             boost::property_tree::ptree root;
             boost::property_tree::read_json(requestStream, root);
             
-            boost::property_tree::ptree payload = root.get_child("oc.payload", boost::property_tree::ptree());
+            boost::property_tree::ptree payload = root.get_child("oc", boost::property_tree::ptree());
             
             for(auto payloadItr : payload)
             {
@@ -171,7 +175,9 @@ namespace OC
                     std::cout << "Failed to create resource: "<< e.what() <<std::endl;
                     // TODO: Do we want to handle this somehow?  Perhaps we need to log this?
                 }
-            
+          
+                // TODO break after first found resource; something wrong in collection should be fixed first 
+                break; 
             }
             return OC_STACK_KEEP_TRANSACTION;
 
@@ -247,6 +253,8 @@ namespace OC
     OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
     {
         GetSetContext* context = static_cast<GetSetContext*>(ctx);
+
+        std::cout << "GET JSON: " << (char*) clientResponse->resJSONPayload << endl;
         
         AttributeMap attrs;
 
@@ -259,7 +267,8 @@ namespace OC
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
     }
-    OCStackResult InProcClientWrapper::GetResourceAttributes(const std::string& host, const std::string& uri, std::function<void(const AttributeMap, const int)>& callback)
+    OCStackResult InProcClientWrapper::GetResourceAttributes(const std::string& host, const std::string& uri, 
+        const QueryParamsMap& queryParams, std::function<void(const AttributeMap, const int)>& callback)
     {
         OCStackResult result;
         OCCallbackData* cbdata = new OCCallbackData();
@@ -270,9 +279,10 @@ namespace OC
 
         // TODO: in the future the cstack should be combining these two strings!
         ostringstream os;
-        os << host << uri;
-
+        os << host << assembleSetResourceUri(uri, queryParams).c_str();
+        //std::cout << "GET URI: " << os.str() << std::endl;
         // TODO: end of above
+
         auto cLock = m_csdkLock.lock();
         if(cLock)
         {
@@ -321,14 +331,21 @@ namespace OC
             paramsList << param.first <<'='<<param.second<<'&';
         }
 
-        std::string ret = uri + paramsList.str();
+        std::string queryString = paramsList.str();
+        if(queryString.back() == '&')
+        {
+            queryString.resize(queryString.size() - 1);
+        }
+
+        std::string ret = uri + queryString;
         return ret;
     }
     
     std::string InProcClientWrapper::assembleSetResourcePayload(const AttributeMap& attributes)
     {
         ostringstream payload;
-        payload << "{\"oc\":{\"payload\":{";
+        // TODO need to change the format to "{"oc":[]}"
+        payload << "{\"oc\":{";
 
         for(AttributeMap::const_iterator itr = attributes.begin(); itr!= attributes.end(); ++ itr)
         {
@@ -339,7 +356,7 @@ namespace OC
             
             payload << "\""<<itr->first<<"\":\""<< itr->second.front()<<"\"";
         }
-        payload << "}}}";
+        payload << "}}";
         return payload.str();
     }
 
@@ -354,7 +371,6 @@ namespace OC
         // 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
 
         cbdata->context = static_cast<void*>(ctx);
@@ -395,7 +411,8 @@ namespace OC
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&, const int&)>& callback)
+    OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, 
+       const std::string& uri, const QueryParamsMap& queryParams, std::function<void(const AttributeMap&, const int&, const int&)>& callback)
     {
         OCStackResult result;
         OCCallbackData* cbdata = new OCCallbackData();
@@ -418,8 +435,11 @@ namespace OC
             method = OC_REST_OBSERVE_ALL;
         }
 
+        // TODO: in the future the cstack should be combining these two strings!
         ostringstream os;
-        os << host<< uri;
+        os << host << assembleSetResourceUri(uri, queryParams).c_str();
+        // std::cout << "OBSERVE URI: " << os.str() << std::endl;
+        // TODO: end of above
         
         auto cLock = m_csdkLock.lock();
         if(cLock)
index fb7119c..90eb46c 100644 (file)
@@ -72,7 +72,9 @@ OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerReq
                 if(entityHandlerRequest->query)
                 {
                     std::string querystr(reinterpret_cast<char*>(entityHandlerRequest->query));
+
                     OC::Utilities::QueryParamsKeyVal qp = OC::Utilities::getQueryParams(querystr);
+
                     if(qp.size() > 0)
                         pRequest->setQueryParams(qp);
                 }
@@ -100,10 +102,11 @@ OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerReq
 
     if(entityHandlerEntry != entityHandlerMap.end()) {
         // Call CPP Application Entity Handler
+        // TODO CPP Application also should return OC_EH_OK or OC_EH_ERROR
         entityHandlerEntry->second(pRequest, pResponse);
     }
     else {
-        std::cout << "No eintity handler found."  << endl;
+        std::cout << "No entity handler found."  << endl;
         return OC_EH_ERROR;
     }
 
@@ -115,24 +118,26 @@ OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerReq
 
         if(OC_REST_GET == entityHandlerRequest->method)
         {
-            cout << "\t\t\tGoing from stack for GET: " << payLoad << endl;
+            cout << "\t\t\tGoing from stack for GET: ";
         }
         else if (OC_REST_PUT == entityHandlerRequest->method)
         {
-            cout << "\t\t\tGoing from stack for PUT: " << payLoad << endl;
+            cout << "\t\t\tGoing from stack for PUT: ";
         }
-
         else
         {
-            cout << "\t\t\t Unknown method...!!!" << endl;
+            cout << "\t\t\tUnknown method...!!!" << endl;
         }
-        // TODO @SASHI Now there is memory that needs to be freed.
-        entityHandlerRequest->resJSONPayload = reinterpret_cast<unsigned char *>(OC::OCReflect::OCStack::strdup(payLoad.c_str()));
 
-        if(nullptr == entityHandlerRequest->resJSONPayload)
+        if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
+        {
+            strncpy((char*)entityHandlerRequest->resJSONPayload, payLoad.c_str(), entityHandlerRequest->resJSONPayloadLen);
+            cout << (char*)entityHandlerRequest->resJSONPayload << endl;
+        }
+        else
         {
-            // TODO @SASHI throw std::runtime_error("out of memory");
-            cout << "Out of memory in copying to resJSONPayload" << endl;
+            // TODO throw appropriate runtime error
+            cout << "Payload is larger than the PayloadLen" << endl;
         }
     }
 
index 46c1cf8..2221839 100644 (file)
@@ -37,13 +37,13 @@ namespace OC {
     {
     }
 
-    OCStackResult OCResource::get(std::function<void(const AttributeMap, const int)> attributeHandler)
+    OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap, std::function<void(const AttributeMap, const int)> attributeHandler)
     {
         auto cw = m_clientWrapper.lock();
 
         if(cw)
         {
-            return cw->GetResourceAttributes(m_host, m_uri, attributeHandler);
+            return cw->GetResourceAttributes(m_host, m_uri, queryParametersMap, attributeHandler);
         }
         else
         {
@@ -51,7 +51,8 @@ namespace OC {
         }
     }
 
-    OCStackResult OCResource::put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function<void(const AttributeMap, const int)> attributeHandler)
+    OCStackResult OCResource::put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, 
+        std::function<void(const AttributeMap, const int)> attributeHandler)
     {
         auto cw = m_clientWrapper.lock();
 
@@ -65,7 +66,8 @@ namespace OC {
         }
     }
 
-    OCStackResult OCResource::observe(ObserveType observeType, std::function<void(const AttributeMap&, const int&, const int&)> observeHandler)
+    OCStackResult OCResource::observe(ObserveType observeType, const QueryParamsMap& queryParametersMap, 
+        std::function<void(const AttributeMap&, const int&, const int&)> observeHandler)
     {
         if(m_observeHandle != nullptr)
         {
@@ -77,7 +79,7 @@ namespace OC {
 
             if(cw)
             {
-                return cw->ObserveResource(observeType, &m_observeHandle, m_host, m_uri, observeHandler);
+                return cw->ObserveResource(observeType, &m_observeHandle, m_host, m_uri, queryParametersMap, observeHandler);
             }
             else
             {
diff --git a/examples/roomclient.cpp b/examples/roomclient.cpp
new file mode 100644 (file)
index 0000000..8f527ac
--- /dev/null
@@ -0,0 +1,336 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// OCClient.cpp : Defines the entry point for the console application.
+//
+#include <string>
+#include <cstdlib>
+#include <pthread.h>
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+const int SUCCESS_RESPONSE = 0;
+std::shared_ptr<OCResource> curResource;
+
+int observe_count()
+{
+    static int oc = 0;
+    return ++oc;
+}
+
+void onObserve(const AttributeMap& attributeMap, const int& eCode, const int& sequenceNumber)
+{
+    if(eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "OBSERVE RESULT:"<<std::endl;
+        std::cout << "\tSequenceNumber: "<< sequenceNumber << endl;
+        for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+        {
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
+            for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+            {
+                std::cout <<"\t"<< *valueItr << " ";
+            }
+
+            std::cout << std::endl;
+        }
+        
+        if(observe_count() > 30)
+        {
+            std::cout<<"Cancelling Observe..."<<std::endl;
+            OCStackResult result = curResource->cancelObserve();
+
+            std::cout << "Cancel result: "<< result <<std::endl;
+            sleep(10);
+            std::cout << "DONE"<<std::endl;
+            std::exit(0);
+        }
+    }
+    else
+    {
+        std::cout << "onObserve Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+// callback handler on PUT request
+void onGetRep(OCRepresentation& rep, const int eCode)
+{
+    if(eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "GET request was successful" << std::endl;
+
+        AttributeMap attributeMap = rep.getAttributeMap();
+
+        for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+        {
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
+            for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+            {
+                std::cout <<"\t"<< *valueItr << " ";
+            }
+
+            std::cout << std::endl;
+        }
+
+        std::vector<OCRepresentation> children = rep.getChildren();
+
+        for(auto oit = children.begin(); oit != children.end(); ++oit)
+        {
+            attributeMap = oit->getAttributeMap();
+
+            for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+            {
+                std::cout << "\tAttribute name: "<< it->first << " value: ";
+                for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+                {
+                    std::cout <<"\t"<< *valueItr << " ";
+                }
+
+                std::cout << std::endl;
+            }
+        }
+
+    }
+    else
+    {
+        std::cout << "onGET Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+
+// callback handler on PUT request
+void onPutRep(OCRepresentation& rep, const int eCode)
+{
+    if(eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "PUT request was successful" << std::endl;
+
+        AttributeMap attributeMap = rep.getAttributeMap();
+
+        for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+        {
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
+            for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+            {
+                std::cout <<"\t"<< *valueItr << " ";
+            }
+
+            std::cout << std::endl;
+        }
+
+        std::vector<OCRepresentation> children = rep.getChildren();
+
+        for(auto oit = children.begin(); oit != children.end(); ++oit)
+        {
+            attributeMap = oit->getAttributeMap();
+
+            for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+            {
+                std::cout << "\tAttribute name: "<< it->first << " value: ";
+                for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+                {
+                    std::cout <<"\t"<< *valueItr << " ";
+                }
+
+                std::cout << std::endl;
+            }
+        }
+
+    }
+    else
+    {
+        std::cout << "onPut Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+
+// callback handler on PUT request
+void onPut(const AttributeMap attributeMap, const int eCode)
+{
+    if(eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "PUT request was successful" << std::endl;
+
+        for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+        {
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
+            for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+            {
+                std::cout <<"\t"<< *valueItr << " ";
+            }
+
+            std::cout << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "onPut Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+
+// Local function to put a different state for this resource
+void putRoomRepresentation(std::shared_ptr<OCResource> resource)
+{
+    if(resource)
+    {
+        std::cout << "Putting room representation..."<<std::endl;
+        // Create AttributeMap
+        AttributeMap attributeMap;
+        // Add the attribute name and values in the attribute map
+        AttributeValues stateVal;
+        stateVal.push_back("true");
+
+        AttributeValues powerVal;
+        powerVal.push_back("8");
+
+        attributeMap["state"] = stateVal;
+        attributeMap["speed"] = powerVal;
+
+        // Create QueryParameters Map and add query params (if any)
+        QueryParamsMap qp;
+        qp["if"] = BATCH_INTERFACE;
+
+        // Invoke resource's pit API with attribute map, query map and the callback parameter
+        resource->put(attributeMap, qp, &onPut);
+    }
+}
+
+// callback handler on GET request
+void onGet(const AttributeMap attributeMap, const int eCode)
+{
+    if(eCode == SUCCESS_RESPONSE)
+    {
+        std::cout << "GET Succeeded:"<<std::endl;
+        for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
+        {
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
+            for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
+            {
+                std::cout <<"\t"<< *valueItr << " ";
+            }
+
+            std::cout << std::endl;
+        }
+
+        putRoomRepresentation(curResource);
+    }
+    else
+    {
+        std::cout << "onGet Response error: " << eCode << std::endl;
+        std::exit(-1);
+    }
+}
+// Local function to get representation of light resource
+void getRoomRepresentation(std::shared_ptr<OCResource> resource)
+{
+    if(resource)
+    {
+        std::cout << "Getting Room Representation..."<<std::endl;
+        // Invoke resource's get API with the callback parameter
+
+        QueryParamsMap qp;
+        qp["if"] = BATCH_INTERFACE; // LINK_INTERFACE; 
+        resource->get(qp, &onGet);
+    }
+}
+
+// Callback to found resources
+void foundResource(std::shared_ptr<OCResource> resource)
+{
+
+    if(curResource)
+    {
+        std::cout << "Found another resource, ignoring"<<std::endl;
+    }
+
+    std::string resourceURI;
+    std::string hostAddress;
+    try
+    {
+        // Do some operations with resource object.
+        if(resource)
+        {
+            std::cout<<"DISCOVERED Resource:"<<std::endl;
+            // Get the resource URI
+            resourceURI = resource->uri();
+            std::cout << "\tURI of the resource: " << resourceURI << std::endl;
+
+            // Get the resource host address
+            hostAddress = resource->host();
+            std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
+
+            if(resourceURI == "/a/room")
+            {
+                curResource = resource;
+                // Call a local function which will internally invoke get API on the resource pointer
+                // TODO change this back when getRoomRepresentation works
+                getRoomRepresentation(resource);
+                 //putRoomRepresentation(resource);
+            }
+        }
+        else
+        {
+            // Resource is invalid
+            std::cout << "Resource is invalid" << std::endl;
+        }
+
+    }
+    catch(std::exception& e)
+    {
+        //log(e.what());
+    }
+}
+
+int main(int argc, char* argv[]) {
+
+    // Create PlatformConfig object
+    PlatformConfig cfg;
+    cfg.ipAddress = "192.168.1.10";
+    cfg.port = 5683;
+    cfg.mode = ModeType::Client;
+    cfg.serviceType = ServiceType::InProc;
+
+    // Create a OCPlatform instance.
+    // Note: Platform creation is synchronous call.
+
+    try
+    {
+        OCPlatform platform(cfg);
+        std::cout << "Created Platform..."<<std::endl;
+        // Find all resources
+        platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.room", &foundResource);
+        //platform.findResource("", "coap://224.0.1.187/oc/core", &foundResource);
+        std::cout<< "Finding Resource... " <<std::endl;
+        while(true)
+        {
+            // some operations
+        }
+
+    }catch(OCException& e)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/examples/roomserver.cpp b/examples/roomserver.cpp
new file mode 100644 (file)
index 0000000..8c88aa3
--- /dev/null
@@ -0,0 +1,651 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample shows how one could create a resource (collection) with children.
+///
+
+#include <functional>
+
+#include <pthread.h>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+using namespace std;
+
+
+// Forward declaring the entityHandler (room)
+void entityHandlerRoom(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+void entityHandlerLight(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+void entityHandlerFan(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+
+class RoomResource
+{
+public:
+
+    // Room members
+    std::string m_roomUri;
+    std::string m_roomType;
+    std::string m_roomInterface1;
+    std::string m_roomInterface2;
+    std::string m_roomInterface3;
+    OCResourceHandle m_roomHandle;
+
+    // light members
+    bool m_lightState;
+    int m_lightColor;
+    std::string m_lightInterface;
+    std::string m_lightUri;
+    std::string m_lightType;
+    OCResourceHandle m_lightHandle;
+
+    // fan members
+    bool m_fanState;
+    int m_fanSpeed;
+    std::string m_fanInterface;
+    std::string m_fanUri;
+    std::string m_fanType;
+    OCResourceHandle m_fanHandle;
+
+public:
+    /// Constructor
+    RoomResource(): m_lightState(false), m_lightColor(0), m_fanState(false), m_fanSpeed(0) 
+    {
+        m_roomUri = "/a/room"; // URI of the resource
+        m_roomType = "core.room"; // resource type name. In this case, it is light
+        m_roomInterface1 = DEFAULT_INTERFACE; // resource interface.
+        m_roomInterface2 = BATCH_INTERFACE; // resource interface.
+        m_roomInterface3 = LINK_INTERFACE; // resource interface.
+
+        m_lightUri = "/a/light"; // URI of the resource
+        m_lightType = "core.light"; // resource type name. In this case, it is light
+        m_lightInterface = DEFAULT_INTERFACE; // resource interface.
+
+        m_fanUri = "/a/fan"; // URI of the resource
+        m_fanType = "core.fan"; // resource type name. In this case, it is light
+        m_fanInterface = DEFAULT_INTERFACE; // resource interface.
+    }
+
+    /// This function internally calls registerResource API.
+    void createResources(OC::OCPlatform& platform)
+    {
+        // This will internally create and register the resource.
+        OCStackResult result = platform.registerResource(
+                                    m_roomHandle, m_roomUri, m_roomType,
+                                    m_roomInterface1, &entityHandlerRoom, 
+                                    OC_DISCOVERABLE | OC_OBSERVABLE
+                                  );
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation (room) was unsuccessful\n";
+        }
+
+        result = platform.bindInterfaceToResource(m_roomHandle, m_roomInterface2);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+
+        result = platform.bindInterfaceToResource(m_roomHandle, m_roomInterface3);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding TypeName to Resource was unsuccessful\n";
+        }
+
+        result = platform.registerResource(
+                                    m_lightHandle, m_lightUri, m_lightType,
+                                    m_lightInterface, &entityHandlerLight, 
+                                    OC_DISCOVERABLE | OC_OBSERVABLE
+                                   );
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation (light) was unsuccessful\n";
+        }
+
+        result = platform.registerResource(
+                                    m_fanHandle, m_fanUri, m_fanType,
+                                    m_fanInterface, &entityHandlerFan, 
+                                    OC_DISCOVERABLE | OC_OBSERVABLE
+                                   );
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation (fan) was unsuccessful\n";
+        }
+
+    }
+
+    void setRoomRepresentation(OCRepresentation& rep)
+    {
+        setLightRepresentation(rep);
+        setFanRepresentation(rep);
+    }
+
+    void setLightRepresentation(OCRepresentation& light)
+    {
+        AttributeMap attributeMap = light.getAttributeMap();
+
+        if(attributeMap.find("state") != attributeMap.end() && attributeMap.find("color") != attributeMap.end())
+        {
+            m_lightState = attributeMap["state"][0].compare("true") == 0;
+            m_lightColor= std::stoi(attributeMap["color"][0]);
+        }
+    }
+
+    void setFanRepresentation(OCRepresentation& fan)
+    {
+        AttributeMap attributeMap = fan.getAttributeMap();
+
+        if(attributeMap.find("state") != attributeMap.end() && attributeMap.find("speed") != attributeMap.end())
+        {
+            m_fanState = attributeMap["state"][0].compare("true") == 0;
+            m_fanSpeed = std::stoi(attributeMap["speed"][0]);
+        }
+    }
+
+
+    OCRepresentation getLightRepresentation() const
+    {
+        OCRepresentation light;
+
+        light.setUri(m_lightUri);
+
+        std::vector<std::string> interfaces;
+        interfaces.push_back(m_lightInterface);
+
+        light.setResourceInterfaces(interfaces);
+
+        std::vector<std::string> types;
+        types.push_back(m_lightType);
+
+        light.setResourceTypes(types);
+
+        AttributeMap attributeMap;
+        AttributeValues stateVal;
+        if(m_lightState)
+        {
+            stateVal.push_back("true");
+        }
+        else
+        {
+            stateVal.push_back("false");
+        }
+
+        AttributeValues colorVal;
+        colorVal.push_back(to_string(m_lightColor));
+
+        attributeMap["state"] = stateVal;
+        attributeMap["color"] = colorVal;
+
+        light.setAttributeMap(attributeMap);
+
+        return light;
+    }
+
+    OCRepresentation getFanRepresentation() const
+    {
+        OCRepresentation fan;
+        fan.setUri(m_fanUri);
+
+        std::vector<std::string> interfaces;
+        interfaces.push_back(m_fanInterface);
+
+        fan.setResourceInterfaces(interfaces);
+
+        std::vector<std::string> types;
+        types.push_back(m_fanType);
+
+        fan.setResourceTypes(types);
+
+        AttributeMap attributeMap;
+        AttributeValues stateVal;
+        if(m_fanState)
+        {
+            stateVal.push_back("true");
+        }
+        else
+        {
+            stateVal.push_back("false");
+        }
+
+        AttributeValues speedVal;
+        speedVal.push_back(to_string(m_fanSpeed));
+
+        attributeMap["state"] = stateVal;
+        attributeMap["speed"] = speedVal;
+
+        fan.setAttributeMap(attributeMap);
+        
+        return fan;
+    }
+
+    OCRepresentation getRoomRepresentation(void) const
+    {
+        OCRepresentation room;
+
+        room.setUri(m_roomUri);
+
+        std::vector<std::string> interfaces;
+        interfaces.push_back(m_roomInterface1);
+        interfaces.push_back(m_roomInterface2);
+        interfaces.push_back(m_roomInterface3);
+
+        room.setResourceInterfaces(interfaces);
+
+        std::vector<std::string> types;
+        types.push_back(m_roomType);
+
+        room.setResourceTypes(types);
+
+        std::vector<OCRepresentation> children;
+
+        OCRepresentation light = getLightRepresentation();
+        children.push_back(light);
+
+        OCRepresentation fan = getFanRepresentation();
+        children.push_back(fan);
+        room.setChildren(children);
+
+        return room;
+    }
+
+};
+
+// Create the instance of the resource class (in this case instance of class 'RoomResource').
+RoomResource myRoomResource;
+
+void entityHandlerRoom(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+{
+    cout << "\tIn Server CPP entity handler:\n";
+
+    if(request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        RequestHandlerFlag requestFlag = request->getRequestHandlerFlag();
+
+        if(requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if(requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\t\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if(requestType == "GET")
+            {
+                cout << "\t\t\trequestType : GET\n";
+
+                // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                OCRepresentation rep;
+                rep = myRoomResource.getRoomRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "PUT")
+            {
+                cout << "\t\t\trequestType : PUT\n";
+
+                 // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                // Get the representation from the request
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                myRoomResource.setRoomRepresentation(rep);
+
+                // Do related operations related to PUT request
+                rep = myRoomResource.getRoomRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if(requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if(requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\t\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+}
+
+void entityHandlerLight(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+{
+    cout << "\tIn Server CPP (Light) entity handler:\n";
+
+    if(request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        RequestHandlerFlag requestFlag = request->getRequestHandlerFlag();
+
+        if(requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if(requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\t\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if(requestType == "GET")
+            {
+                cout << "\t\t\trequestType : GET\n";
+
+                // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                OCRepresentation rep = myRoomResource.getLightRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "PUT")
+            {
+                cout << "\t\t\trequestType : PUT\n";
+
+                 // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                // Get the representation from the request
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                myRoomResource.setLightRepresentation(rep);
+
+                // Do related operations related to PUT request
+                rep = myRoomResource.getLightRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if(requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if(requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\t\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+}
+
+void entityHandlerFan(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+{
+    cout << "\tIn Server CPP (Fan) entity handler:\n";
+
+    if(request)
+    {
+        // Get the request type and request flag
+        std::string requestType = request->getRequestType();
+        RequestHandlerFlag requestFlag = request->getRequestHandlerFlag();
+
+        if(requestFlag == RequestHandlerFlag::InitFlag)
+        {
+            cout << "\t\trequestFlag : Init\n";
+
+            // entity handler to perform resource initialization operations
+        }
+        else if(requestFlag == RequestHandlerFlag::RequestFlag)
+        {
+            cout << "\t\trequestFlag : Request\n";
+
+            // If the request type is GET
+            if(requestType == "GET")
+            {
+                cout << "\t\t\trequestType : GET\n";
+
+                // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                OCRepresentation rep = myRoomResource.getFanRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "PUT")
+            {
+                cout << "\t\t\trequestType : PUT\n";
+
+                 // Check for query params (if any)
+                QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+                cout << "\t\t\tquery params: \n";
+                for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
+                // Get the representation from the request
+                OCRepresentation rep = request->getResourceRepresentation();
+
+                myRoomResource.setFanRepresentation(rep);
+
+                // Do related operations related to PUT request
+                rep = myRoomResource.getFanRepresentation();
+
+                if(response)
+                {
+                    // TODO Error Code
+                    response->setErrorCode(200);
+
+                    auto findRes = queryParamsMap.find("if");
+
+                    if(findRes != queryParamsMap.end())
+                    {
+                        response->setResourceRepresentation(rep, findRes->second);
+                    }
+                    else
+                    {
+                        response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
+                    }
+                }
+
+            }
+            else if(requestType == "POST")
+            {
+                // POST request operations
+            }
+            else if(requestType == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+        else if(requestFlag == RequestHandlerFlag::ObserverFlag)
+        {
+            cout << "\t\trequestFlag : Observer\n";
+        }
+    }
+    else
+    {
+        std::cout << "Request invalid" << std::endl;
+    }
+}
+
+int main()
+{
+    // Create PlatformConfig object
+
+    PlatformConfig cfg;
+    cfg.ipAddress = "192.168.1.10";
+    cfg.port = 56832;
+    cfg.mode = ModeType::Server;
+    cfg.serviceType = ServiceType::InProc;
+
+    // Create a OCPlatform instance.
+    // Note: Platform creation is synchronous call.
+    try
+    {
+        OCPlatform platform(cfg);
+
+        // Invoke createResource function of class light.
+
+        myRoomResource.createResources(platform);
+
+        // Perform app tasks
+        while(true)
+        {
+            // some tasks
+        }
+    }
+    catch(OCException e)
+    {
+        std::cout << "Exception in main: " << e.what();
+    }
+
+    // No explicit call to stop the platform.
+    // When OCPlatform destructor is invoked, internally we do platform cleanup
+}
index 71b86f0..3f7f258 100644 (file)
@@ -96,7 +96,10 @@ void onPut(const AttributeMap attributeMap, const int eCode)
         else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
             std::cout << endl << "ObserveAll is used." << endl << endl;
 
-        curResource->observe(OBSERVE_TYPE_TO_USE, &onObserve);
+        // TODO
+        QueryParamsMap test;
+
+        curResource->observe(OBSERVE_TYPE_TO_USE, test, &onObserve);
 
     }
     else
@@ -164,7 +167,10 @@ void getLightRepresentation(std::shared_ptr<OCResource> resource)
     {
         std::cout << "Getting Light Representation..."<<std::endl;
         // Invoke resource's get API with the callback parameter
-        resource->get(&onGet);
+
+        QueryParamsMap test;
+        test["if"] = BATCH_INTERFACE;
+        resource->get(test, &onGet);
     }
 }
 
@@ -244,7 +250,7 @@ int main(int argc, char* argv[]) {
 
     // Create PlatformConfig object
     PlatformConfig cfg;
-    cfg.ipAddress = "134.134.161.33";
+    cfg.ipAddress = "192.168.1.10";
     cfg.port = 5683;
     cfg.mode = ModeType::Client;
     cfg.serviceType = ServiceType::InProc;
index e27fa4f..ab6343f 100644 (file)
@@ -120,7 +120,8 @@ private:
             std::cout << "\tURI:  "<< resource->uri()<<std::endl;
 
             std::cout<<"Doing a get on q/foo."<<std::endl;
-            resource->get(std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
+            QueryParamsMap test;
+            resource->get(test, std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
         } 
     }
 
@@ -222,7 +223,7 @@ struct FooResource
                 {
                     std::cout<<"\t\t\trequestType : PUT"<<std::endl;
 
-                    setRepresentation(request->getResourceRepresentation());
+                    setRepresentation(request->getAttributeRepresentation());
 
                     if(response)
                     {
index b723607..eff1772 100644 (file)
@@ -198,6 +198,12 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
                 // Check for query params (if any)
                 QueryParamsMap queryParamsMap = request->getQueryParameters();
 
+                cout << "\t\t\tquery params: \n";
+                for(QueryParamsMap::iterator it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
+                {
+                    cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
+                }
+
                 // Process query params and do required operations ..
 
                 // Get the representation of this resource at this point and send it as response
@@ -222,7 +228,7 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
                 // Check queryParamsMap and do required operations ..
 
                 // Get the representation from the request
-                AttributeMap attributeMap = request->getResourceRepresentation();
+                AttributeMap attributeMap = request->getAttributeRepresentation();
 
                 myLightResource.setRepresentation(attributeMap);
 
index 6458cfd..f7425cf 100644 (file)
@@ -31,12 +31,22 @@ namespace OC
     {
     public:
         typedef std::shared_ptr<IClientWrapper> Ptr;
+
         virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType,
             std::function<void(std::shared_ptr<OCResource>)>& callback) = 0;
-        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, std::function<void(const AttributeMap, const int)>& callback)=0;
-        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback)=0;
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&, const int&)>& callback)=0;
+        
+        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, const QueryParamsMap& queryParams, 
+            std::function<void(const AttributeMap, const int)>& callback)=0;
+        
+        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, 
+            const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback)=0;
+
+        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, 
+            const std::string& host, const std::string& uri, const QueryParamsMap& queryParams, 
+            std::function<void(const AttributeMap&, const int&, const int&)>& callback)=0;
+        
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri)=0;
+        
         virtual ~IClientWrapper(){}
        
 
index 3f86475..c71ea30 100644 (file)
@@ -41,16 +41,28 @@ namespace OC
     {
     public:
         InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
+        
         virtual ~InProcClientWrapper();
 
-        virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(std::shared_ptr<OCResource>)>& callback);
-        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, std::function<void(const AttributeMap, const int)>& callback);
-        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback);
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&, const int&)>& callback);
+        virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, 
+            std::function<void(std::shared_ptr<OCResource>)>& callback);
+        
+        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, const QueryParamsMap& queryParams, 
+            std::function<void(const AttributeMap, const int)>& callback);
+        
+        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, 
+            const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback);
+        
+        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, 
+            const std::string& host, const std::string& uri, const QueryParamsMap& queryParams, 
+            std::function<void(const AttributeMap&, const int&, const int&)>& callback);
+        
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri);
         
         // Note: this should never be called by anyone but the handler for the listen command.  It is public becuase that needs to be a non-instance callback
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const boost::property_tree::ptree resourceNode);
+        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, 
+            const boost::property_tree::ptree resourceNode);
+    
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
index 43626f5..042f0be 100644 (file)
@@ -34,6 +34,7 @@
 #include "WrapperFactory.h"
 #include "OCResourceRequest.h"
 #include "OCResourceResponse.h"
+#include "OCRepresentation.h"
 
 namespace OC
 {
diff --git a/include/OCRepresentation.h b/include/OCRepresentation.h
new file mode 100644 (file)
index 0000000..e2226da
--- /dev/null
@@ -0,0 +1,114 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation 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 OCRepresentation.h
+
+/// @brief  This file contains the declaration of classes and its members 
+///         related to OCRepresentation
+
+#ifndef __OCREPRESENTATION_H
+#define __OCREPRESENTATION_H
+
+
+#include <OCApi.h>
+#include <OCResource.h>
+
+namespace OC
+{
+    class OCRepresentation
+    {
+
+    private:
+
+        std::string m_uri;
+        AttributeMap m_attributeMap;
+        std::vector<std::string> m_resourceTypes;
+        std::vector<std::string> m_resourceInterfaces;
+        bool m_observable; // TODO : do we need this here???
+        int errorCode;
+
+        std::vector<OCRepresentation> m_children;
+
+    public:
+
+        OCRepresentation() {}
+
+        std::string getUri(void) const
+        {
+            return m_uri;
+        }
+
+        void setUri(std::string uri)
+        {
+            m_uri = uri;
+        }
+
+        std::vector<OCRepresentation> getChildren(void) const
+        {
+            return m_children;
+        }
+
+        void setChildren(std::vector<OCRepresentation> children)
+        {
+            m_children = children;
+        }
+
+        OCResource* getResource() const
+        {
+            // TODO Needs to be implemented
+            OCResource* res = NULL;
+
+            return res;
+        }
+
+        AttributeMap getAttributeMap() const 
+        {
+            return m_attributeMap;
+        }
+
+        void setAttributeMap(AttributeMap map)
+        {
+            m_attributeMap = map;
+        }
+
+        std::vector<std::string> getResourceTypes() const
+        {
+            return m_resourceTypes;
+        }
+
+        void setResourceTypes(std::vector<std::string> resourceTypes)
+        {
+            m_resourceTypes = resourceTypes;
+        }
+
+        std::vector<std::string> getResourceInterfaces(void) const
+        {
+            return m_resourceInterfaces;
+        }
+
+        void setResourceInterfaces(std::vector<std::string> resourceInterfaces)
+        {
+            m_resourceInterfaces = resourceInterfaces;
+        }
+    };
+
+} // namespace OC
+
+#endif //__OCREPRESENTATION_H
index 40b5558..8ae37ae 100644 (file)
@@ -62,6 +62,7 @@ namespace OC
         
         /**
         * Function to get the attributes of a resource. 
+        * @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 also have the result from this Get operation 
@@ -69,13 +70,14 @@ namespace OC
         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
         * NOTE: OCStackResult is defined in ocstack.h.
         */
-        OCStackResult get(std::function<void(const AttributeMap, const int)> attributeHandler);
+        OCStackResult get(const QueryParamsMap& queryParametersMap, std::function<void(const AttributeMap, const int)> attributeHandler);
         
         /**
         * Function to get the attributes of a resource. 
         *
         * @param resourceType resourceType of the resource operate on
         * @param resourceInterface interface type of the resource to operate on
+        * @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 
@@ -94,8 +96,9 @@ namespace OC
         * NOTE: A client can traverse a tree or graph by doing successive GETs on the returned resources at a node.<br>
         * TODO: Implementation
         */
-        OCStackResult get(const std::string& resourceType, const std::string& resourceInterface,
-            std::function<void(const AttributeMap& attributeMap, const std::vector<std::string>& resourceUriList, const int& errorCode)> attributeHandler) { return OC_STACK_OK; }
+        OCStackResult get(const std::string& resourceType, const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
+            std::function<void(const AttributeMap& attributeMap, const std::vector<std::string>& resourceUriList, const int& errorCode)> attributeHandler) 
+            { return OC_STACK_OK; }
 
         /**
         * Function to set the attributes of a resource (via PUT)
@@ -110,7 +113,8 @@ namespace OC
         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
         * NOTE: OCStackResult is defined in ocstack.h.
         */
-        OCStackResult put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function< void(const AttributeMap,const int)> attributeHandler);
+        OCStackResult put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, 
+            std::function< void(const AttributeMap,const int)> attributeHandler);
 
         /**
         * Function to set the attributes of a resource (via PUT)
@@ -131,11 +135,13 @@ namespace OC
         * TODO: Implementation
         */
         OCStackResult put(const std::string& resourceType, const std::string& resourceInterface,
-            const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function< void(const AttributeMap&,const int&)> attributeHandler) { return OC_STACK_OK; }
+            const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, 
+            std::function< void(const AttributeMap&,const int&)> attributeHandler) { return OC_STACK_OK; }
 
         /**
         * Function to set observation on the resource
         * @param observeType allows the client to specify how it wants to observe.
+        * @param queryParametersMap map which can have the query parameter name and value
         * @param observeHandler handles callback
         *        The callback function will be invoked with a map of attribute name and values.
         *        The callback function will also have the result from this observe operation
@@ -143,7 +149,8 @@ namespace OC
         * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
         * NOTE: OCStackResult is defined in ocstack.h.
         */
-        OCStackResult observe(ObserveType observeType, std::function<void(const AttributeMap&, const int&, const int&)> observeHandler);
+        OCStackResult observe(ObserveType observeType, const QueryParamsMap& queryParametersMap, 
+            std::function<void(const AttributeMap&, const int&, const int&)> observeHandler);
 
         /**
         * Function to cancel the observation on the resource
index cd784b1..c31f560 100644 (file)
@@ -30,6 +30,7 @@
 #include <boost/property_tree/json_parser.hpp>
 
 #include "OCApi.h"
+#include "OCRepresentation.h"
 
 namespace OC
 {
@@ -75,13 +76,15 @@ namespace OC
         *  Provides the entire resource attribute representation
         *  @return std::map AttributeMap reference containing the name value pairs representing the resource's attributes
         */
-        const AttributeMap& getResourceRepresentation() const {return m_attributeMap;}
+        const AttributeMap& getAttributeRepresentation() const {return m_attributeMap;}
+        const OCRepresentation& getResourceRepresentation() const {return m_representation;}
 
     private:
         std::string m_requestType;
         QueryParamsMap m_queryParameters;
         RequestHandlerFlag m_requestHandlerFlag;
         AttributeMap m_attributeMap;
+        OCRepresentation m_representation;
 
     public:
         // TODO: This is not a public API for app developers.
@@ -98,14 +101,17 @@ namespace OC
             // TODO: The following JSON Parse implementation should be seperated into utitilites
             // and used wherever required.
             // e.g. parse(std::string& payload, Attributemap& attributeMap)
-
+            
             std::stringstream requestStream;
             requestStream << requestPayload;
             boost::property_tree::ptree root;
             boost::property_tree::read_json(requestStream, root);
-            boost::property_tree::ptree payload = root.get_child("oc.payload", boost::property_tree::ptree());
 
-            for(auto& item : payload)
+            // TODO this expects the representation oc:{} and not oc:[{}]
+            //      this representation is fine when setting for simple resource.
+            boost::property_tree::ptree payload = root.get_child("oc", boost::property_tree::ptree());
+
+            for(auto& item: payload)
             {
                 std::string name = item.first.data();
                 std::string value = item.second.data();
@@ -115,6 +121,8 @@ namespace OC
 
                 m_attributeMap[name] = values;
             }
+    
+            m_representation.setAttributeMap(m_attributeMap);
         }
 
         // TODO: This is not a public API for app developers.
index 2b36632..5c4c33f 100644 (file)
@@ -29,6 +29,7 @@
 #include "OCApi.h"
 #include <IServerWrapper.h>
 #include <ocstack.h>
+#include <OCRepresentation.h>
 
 using namespace std;
 
@@ -59,6 +60,218 @@ namespace OC
         void setErrorCode(const int eCode) { m_errorCode = eCode; }
 
         /**
+        *  API to set the entire resource attribute representation (BATCH)
+        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        */
+        void setResourceRepresentation(OCRepresentation& rep, std::string interface) { 
+            if(!interface.compare(LINK_INTERFACE))
+            {
+                setResourceRepresentationLL(rep);
+            }
+            else if(!interface.compare(BATCH_INTERFACE))
+            {
+                setResourceRepresentationBatch(rep);
+            }
+            else
+            {
+                setResourceRepresentationDefault(rep);
+            }
+            // TODO other interfaces
+        }
+
+        /**
+        *  API to set the entire resource attribute representation (Linked List Interface))
+        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        */
+        void setResourceRepresentationLL(OCRepresentation& rep) { 
+
+            // Default Set
+
+            ostringstream payload;
+
+            // Parent
+            payload << "{";
+            payload << "\"href\":"; 
+            payload << "\"" ;
+            payload << rep.getUri();
+            payload << "\"" ;
+            payload << "}";
+
+            // Children stuff
+            std::vector<OCRepresentation> children = rep.getChildren();
+            
+            for(auto oitr = children.begin(); oitr != children.end(); ++oitr)
+            {
+                payload << ",{\"href\":"; 
+        
+                payload << "\"" ;
+                payload << oitr->getUri();
+                payload << "\"" ;
+
+                payload << ",\"prop\":{";
+
+                payload << "\"rt\":[";
+                std::vector<std::string> types = oitr->getResourceTypes();
+                for(auto itr = types.begin(); itr != types.end(); ++itr)
+                {
+                    if(itr != types.begin())
+                    {
+                        payload << ',';
+                    }
+
+                    payload << *itr;
+                }
+                payload << "],";
+
+                payload << "\"if\":[";
+                std::vector<std::string> interfaces = oitr->getResourceInterfaces();
+                for(auto itr = interfaces.begin(); itr != interfaces.end(); ++itr)
+                {
+                    if(itr != interfaces.begin())
+                    {
+                        payload << ',';
+                    }
+
+                    payload << *itr;
+                }
+                payload << "]";
+
+                payload << "}}";
+            }
+
+            m_payload = payload.str();
+        }
+
+        /**
+        *  API to set the entire resource attribute representation (Default))
+        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        */
+        void setResourceRepresentationDefault(OCRepresentation& rep) { 
+
+            // Default Set
+
+            ostringstream payload;
+
+            // Parent
+            payload << "{";
+            payload << "\"href\":"; 
+            payload << "\"" ;
+            payload << rep.getUri();
+            payload << "\"" ;
+
+            payload << ",\"rep\":{";
+
+            AttributeMap attributes = rep.getAttributeMap();
+
+            for(auto itr = attributes.begin(); itr!= attributes.end(); ++ itr)
+            {
+                if(itr != attributes.begin())
+                {
+                    payload << ',';
+                }
+                payload << "\""<<itr->first<<"\":" << itr->second.front();
+            }
+
+            payload << "}},";
+
+            // Children stuff
+            std::vector<OCRepresentation> children = rep.getChildren();
+            
+            for(auto oitr = children.begin(); oitr != children.end(); ++oitr)
+            {
+                payload << ",{\"href\":"; 
+
+                payload << "\"" ;
+                payload << oitr->getUri();
+                payload << "\"" ;
+
+                payload << ",\"prop\":{";
+
+                payload << "\"rt\":[";
+                std::vector<std::string> types = oitr->getResourceTypes();
+                for(auto itr = types.begin(); itr != types.end(); ++itr)
+                {
+                    if(itr != types.begin())
+                    {
+                        payload << ',';
+                    }
+
+                    payload << *itr;
+                }
+                payload << "],";
+
+                payload << "\"if\":[";
+                std::vector<std::string> interfaces = oitr->getResourceInterfaces();
+                for(auto itr = interfaces.begin(); itr != interfaces.end(); ++itr)
+                {
+                    if(itr != interfaces.begin())
+                    {
+                        payload << ',';
+                    }
+
+                    payload << *itr;
+                }
+                payload << "]";
+
+                payload << "}}";
+            }
+
+            m_payload = payload.str();
+        }
+
+        /**
+        *  API to set the entire resource attribute representation (BATCH)
+        *  @param attributeMap reference containing the name value pairs representing the resource's attributes
+        */
+        void setResourceRepresentationBatch(OCRepresentation& rep) { 
+            ostringstream payload;
+
+            // Parent
+            payload << "{";
+            payload << "\"href\":"; 
+            payload << "\"" ;
+            payload << rep.getUri();
+            payload << "\"" ;
+            payload << "},";
+
+            std::vector<OCRepresentation> children = rep.getChildren();
+            
+            for(auto oitr = children.begin(); oitr != children.end(); ++oitr)
+            {
+                if(oitr != children.begin())
+                {
+                    payload << ',';
+                }
+
+                payload << "{";
+                
+                payload << "\"href\":"; 
+        
+                payload << "\"" ;
+                payload << oitr->getUri();
+                payload << "\"" ;
+
+                payload << ",\"rep\":{";
+
+                AttributeMap attributes = oitr->getAttributeMap();
+
+                for(AttributeMap::const_iterator itr = attributes.begin(); itr!= attributes.end(); ++ itr)
+                {
+                    if(itr != attributes.begin())
+                    {
+                        payload << ',';
+                    }
+                    payload << "\""<<itr->first<<"\":" << itr->second.front();
+                }
+
+                payload << "}}";
+            }
+
+            m_payload = payload.str();
+        }
+
+
+        /** 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
         */
@@ -67,7 +280,12 @@ namespace OC
             // TODO To be refactored
             ostringstream payload;
 
-            payload << "{\"oc\":{\"payload\":{";
+            payload << "{";
+            
+            // TODO fix this (do this programmatically)
+            payload << "\"href\":\"/a/room\"";
+
+            payload << ",\"rep\":{";
 
             for(AttributeMap::const_iterator itr = attributes.begin(); itr!= attributes.end(); ++ itr)
             {
@@ -78,7 +296,8 @@ namespace OC
                 // cout << itr->first << ":" <, itr->second.front() << endl;
                 payload << "\""<<itr->first<<"\":" << itr->second.front();
             }
-            payload << "}}}";
+
+            payload << "}}";
 
             m_payload = payload.str();
         }
index e01cca7..7534f25 100644 (file)
@@ -29,14 +29,24 @@ namespace OC
     {
     public:
         OutOfProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg) { }
-        virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(std::shared_ptr<OCResource>)>& callback) {return OC_STACK_NOTIMPL;}
+        
+        virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, 
+            std::function<void(std::shared_ptr<OCResource>)>& callback) {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, std::function<void(const AttributeMap, const int)>& callback){return OC_STACK_NOTIMPL;}
-        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback){return OC_STACK_NOTIMPL;}
-        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&, const int&)>& callback){return OC_STACK_NOTIMPL;}
+        virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, 
+            const QueryParamsMap& queryParams, std::function<void(const AttributeMap, const int)>& callback){return OC_STACK_NOTIMPL;}
+        
+        virtual OCStackResult SetResourceAttributes(const std::string& host, const std::string& uri, 
+            const AttributeMap& attributes, const QueryParamsMap& queryParams, std::function<void(const AttributeMap,const int)>& callback){return OC_STACK_NOTIMPL;}
+        
+        virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle, const std::string& host, 
+            const std::string& uri, const QueryParamsMap& queryParams, 
+            std::function<void(const AttributeMap&, const int&, const int&)>& callback){return OC_STACK_NOTIMPL;}
+        
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri){return OC_STACK_NOTIMPL;}
 
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const boost::property_tree::ptree resourceNode) {return nullptr;}
+        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, 
+            const boost::property_tree::ptree resourceNode) {return nullptr;}
     };
 }
 
index 18675a9..5e6e95a 100644 (file)
--- a/makefile
+++ b/makefile
@@ -19,7 +19,7 @@ CXX_INC         += -I./csdk/logger/include
 CXX_INC          += -I./csdk/libcoap
 
 # Force metatargets to build:
-.PHONY: prep_dirs c_sdk simpleserver simpleclient simpleclientserver
+.PHONY: prep_dirs c_sdk simpleserver simpleclient simpleclientserver roomserver roomclient
 
 all:   .PHONY
 
@@ -28,21 +28,24 @@ prep_dirs:
        -mkdir $(OBJ_DIR)
        -mkdir $(SAMPLES_OUT_DIR)
 
-c_sdk:
+c_sdk: 
        cd csdk && $(MAKE) "BUILD=$(BUILD)"
 
-examples:
-       cd examples && $(MAKE) "BUILD=$(BUILD)"
-
-simpleserver: OCLib.a
+simpleserver: OCLib.a examples/simpleserver.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/simpleserver.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/$(BUILD)/liboctbstack.a
 
-simpleclient: OCLib.a
+simpleclient: OCLib.a examples/simpleclient.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/simpleclient.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/$(BUILD)/liboctbstack.a
 
-simpleclientserver: OCLib.a
+simpleclientserver: OCLib.a examples/simpleclientserver.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/simpleclientserver.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/$(BUILD)/liboctbstack.a
 
+roomserver: OCLib.a examples/roomserver.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/roomserver.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/$(BUILD)/liboctbstack.a
+
+roomclient: OCLib.a examples/roomclient.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/roomclient.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/$(BUILD)/liboctbstack.a
+
 OCLib.a: OCPlatform.o OCResource.o OCReflect.o OCUtilities.o InProcServerWrapper.o InProcClientWrapper.o
        ar -cvq $(OBJ_DIR)/OCLib.a $(OBJ_DIR)/OCPlatform.o $(OBJ_DIR)/OCResource.o $(OBJ_DIR)/OCReflect.o $(OBJ_DIR)/OCUtilities.o $(OBJ_DIR)/InProcServerWrapper.o $(OBJ_DIR)/InProcClientWrapper.o
 
@@ -70,4 +73,4 @@ clean: clean_legacy
        cd csdk && $(MAKE) clean
        cd csdk && $(MAKE) deepclean
 clean_legacy:
-       -rm -f -v OCLib.a *.o simpleserver simpleclient simpleclientserver
+       -rm -f -v $(OBJ_DIR)/OCLib.a $(OBJ_DIR)/*.o $(SAMPLES_OUT_DIR)/*