All changes in the C++ stack to get the Get/put/StartObserve functionality working...
authorSashi Penta <sashi.kumar.penta@intel.com>
Tue, 5 Aug 2014 21:21:47 +0000 (14:21 -0700)
committerGerrit Code Review <gerrit@fmygit6002.fm.intel.com>
Tue, 5 Aug 2014 21:30:27 +0000 (14:30 -0700)
Patch3: OCStackResult return added to registerResource

Patch4: Simplified simpleserver.cpp

Patch5: Cleaned InProcServerWrapper.cpp

Patch6: Responded to a number of issues that came up as a part of the code review (thanks Jesse!)

Patch7: Review comments from Sudarshan/Sam

Patch8: Rebased on PS21 from Joey, enabled cancel, pushing so we can debug it.

Patch9: Got cancel working correctly, removed the Cancel callback, since we aren't provided with it from the lower layer

Patch10: Cleaned some tabs space. Changed the resource to core.light. Removed examples from examples. and other cleanups.

Patch11: Header file changes from Sudarshan. Fixed tabs.

Patch12: Rebase

Patch13: improved examples. Added myLightResource.setRepresentation()

Patch14: Simple one line change (adding a new line)

Change-Id: Ic6fb03372bf9ff2bca94ff9605fd5f30ce5fac1f

19 files changed:
Makefile
OCLib/InProcClientWrapper.cpp
OCLib/InProcServerWrapper.cpp
OCLib/OCPlatform.cpp
OCLib/OCResource.cpp
examples/simpleclient.cpp
examples/simpleserver.cpp
include/IClientWrapper.h
include/IServerWrapper.h
include/InProcClientWrapper.h
include/InProcServerWrapper.h
include/OCApi.h
include/OCPlatform.h
include/OCResource.h
include/OCResourceRequest.h
include/OCResourceResponse.h
include/OutOfProcClientWrapper.h
include/OutOfProcServerWrapper.h
include/ResourceInitException.h

index 1831b45329357f3f00812fec2f8ae208e44bf0bb..4e20df191fa04c872e61033730300449f0614a25 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
 
 CXX=g++
 #CXX=clang
-CXX_FLAGS=-std=c++11 -Wall -pthread -ggdb
+CXX_FLAGS=-std=c++11 -Wall -pthread 
 CXX_INC=-I./include/ -I./csdk/stack/include -I./csdk/ocsocket/include -I./csdk/ocrandom/include -I./csdk/logger/include
 
 # Force metatargets to build:
-.PHONY: c_sdk simpleserver simpleclient examples
+.PHONY: c_sdk simpleserver simpleclient
 
 all: .PHONY
 
@@ -47,7 +47,5 @@ simpleclient.o : examples/simpleclient.cpp
 
 clean: 
        rm -f -v OCLib.a *.o simpleserver simpleclient
-       cd examples && $(MAKE) clean
-
        cd csdk && $(MAKE) clean
        cd csdk && $(MAKE) deepclean
index 0247114ce7ccd282412588c4e9bd0e0142d1e002..35539c81da049e03147f007a5bb1c5742150d586 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 
-#include "OCResource.h"
 #include "InProcClientWrapper.h"
-
 #include "ocstack.h"
 
+#include "OCResource.h"
 using namespace std;
 
 
@@ -57,20 +56,20 @@ namespace OC
     {
         while(m_threadRun)
         {
-                       OCStackResult result;
-                       {
-                               std::lock_guard<std::mutex> lock(m_csdkLock);
-                               result = OCProcess();
-                       }
+            OCStackResult result;
+            {
+                std::lock_guard<std::mutex> lock(m_csdkLock);
+                result = OCProcess();
+            }
 
             if(result != OC_STACK_OK)
             {
                 // TODO: @Erich do something with result if failed?
             }
 
-            std::this_thread::yield();
+            //std::this_thread::yield();
             // To minimize CPU utilization we may wish to do this with sleep
-                       //std::this_thread::sleep_for(std::chrono::milliseconds(1));
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
         }
     }
 
@@ -78,72 +77,357 @@ namespace OC
  
     std::string convertOCAddrToString(OCDevAddr* addr)
     {
-       if(addr->size != 4) { return "NOT SUPPORTED ADDR;";}
+        // TODO: we currently assume this is a IPV4 address, need to figure out the actual value
 
-       if(addr->size == 4) // IPV4
-       {
-               std::ostringstream address;
-               address<<"coap://"<<addr->addr[0]<<"."<<addr->addr[1]<<"."<<addr->addr[2]<<"."<<addr->addr[3]<<"/";
-               return address.str();
-       }
+        uint8_t a, b, c, d;
+        uint16_t port;
 
-       // TODO: @Erich Convert the device address to a valid string!
-       return "";
+        if(OCDevAddrToIPv4Addr(addr, &a, &b, &c, &d) ==0 && OCDevAddrToPort(addr, &port)==0)
+        {
+            ostringstream os;
+            os << "coap://"<<(int)a<<'.'<<(int)b<<'.'<<(int)c<<'.'<<(int)d<<':'<<(int)port;
+            return os.str();
+        }
+        else
+        {
+            return "INVALID IP";
+        }
     }
 
+    struct ListenContext
+    {
+        std::function<void(std::shared_ptr<OCResource>)> callback;
+        IClientWrapper::Ptr clientWrapper;
+    };
+
+    
+    const std::string URIKEY = "href";
+    const std::string OBSERVABLEKEY = "obs";
+    const std::string RESOURCETYPESKEY= "rt";
+    const std::string INTERFACESKEY = "if";
 
-    OCStackApplicationResult listenCallback(void* ctx, OCClientResponse* clientResponse)
+    std::shared_ptr<OCResource> InProcClientWrapper::parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const boost::property_tree::ptree resourceNode)
     {
-       auto &callback =*(std::function <void(OCResource::Ptr)>*)ctx;
-       std::stringstream requestStream;
-       requestStream << clientResponse->resJSONPayload;
+        std::string uri = resourceNode.get<std::string>(URIKEY, "");
+        bool obs = resourceNode.get<int>(OBSERVABLEKEY,0) == 1;
+        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)
+        {
+            rTs.push_back(itr.second.data());
+        }
 
-       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 interfaces = resourceNode.get_child(INTERFACESKEY, boost::property_tree::ptree());
+        for(auto itr : interfaces)
+        {
+            ifaces.push_back(itr.second.data());
+        }
+        return std::shared_ptr<OCResource>(new OCResource(clientWrapper, host, uri, obs, rTs, ifaces));
+    }
+    
+    OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
+    {
+        if(clientResponse->result == OC_STACK_OK)
+        {
+            ListenContext* context = (ListenContext*)ctx;
+    
+            std::stringstream requestStream;
+            requestStream << clientResponse->resJSONPayload;
+            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 payloadItr : payload)
-       {
-               try
-               {
-                       std::string host = convertOCAddrToString(clientResponse->addr);
-                       OCResource::Ptr resource = std::make_shared<OCResource>(host, payloadItr.second);
-               
-                       // Note: the call to detach allows the underlying thread to continue until completion 
-                       //  and allows us to destroy the exec object.  
-                       //  This is apparently NOT a memory leak, as the thread will apparently take care of itself.
-                       //  Additionally, the only parameter here is
-                       //  a shared ptr, so OCResource will be disposed of properly upon completion of the callback handler.
-                       std::thread exec(callback,resource);
-                       exec.detach();
-               }
-               catch(ResourceInitException)
-               {
-                       // TODO: Do we want to handle this somehow?  Perhaps we need to log this?
-               }
-                       
-       }
-       delete clientResponse;
-       
-       return OC_STACK_KEEP_TRANSACTION;
+            for(auto payloadItr : payload)
+            {
+                try
+                {
+                    std::string host = convertOCAddrToString(clientResponse->addr);
+                    std::shared_ptr<OCResource> resource = context->clientWrapper->parseOCResource(context->clientWrapper, host, payloadItr.second);
+        
+                    // Note: the call to detach allows the underlying thread to continue until completion 
+                    //  and allows us to destroy the exec object.  
+                    //  This is apparently NOT a memory leak, as the thread will apparently take care of itself.
+                    //  Additionally, the only parameter here is
+                    //  a shared ptr, so OCResource will be disposed of properly upon completion of the callback handler.
+                    std::thread exec(context->callback,resource);
+                    exec.detach();
+                }
+                catch(ResourceInitException& e)
+                {
+                    std::cout << "Failed to create resource: "<< e.what() <<std::endl;
+                    // TODO: Do we want to handle this somehow?  Perhaps we need to log this?
+                }
+            
+            }
+            return OC_STACK_DELETE_TRANSACTION;
+
+        }
+        else
+        {
+            std::cout<<"listen Callback got failed result: " << clientResponse->result<<std::endl;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
     } 
 
-    int InProcClientWrapper::ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void (OCResource::Ptr)>& callback)
+    OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void (std::shared_ptr<OCResource>)>& callback)
+    {
+        OCStackResult result;
+
+        OCCallbackData* cbdata = new OCCallbackData();
+
+        ListenContext* context = new ListenContext();
+        context->callback = callback;
+        context->clientWrapper = shared_from_this();
+
+        cbdata->context =  (void*)context;
+        cbdata->cb = listenCallback;
+
+        {
+            std::lock_guard<std::mutex> lock(m_csdkLock);
+            OCDoHandle handle;
+            result = OCDoResource(&handle, OC_REST_GET, resourceType.c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+        }
+        return result;
+    }
+   
+    struct GetSetContext
+    {
+        std::function<void(const AttributeMap&, const int&)> callback;
+    };
+    
+    AttributeMap parseGetSetCallback(OCClientResponse* clientResponse)
+    {
+        std::stringstream requestStream;
+        requestStream<<clientResponse->resJSONPayload;
+
+        if(strlen((char*)clientResponse->resJSONPayload) == 0)
+        {
+            return AttributeMap();
+        }
+
+        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());
+        
+        AttributeMap attrs;
+        for(auto& item : payload)
+        {
+            if(item.first.data() == URIKEY)
+            {
+                continue;
+            }
+
+            std::string name = item.first.data();
+            std::string value = item.second.data();
+            AttributeValues values;
+            values.push_back(value);
+            attrs[name] = values;
+        }
+
+        return attrs;
+    }
+    OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
+    {
+        if(clientResponse->result == OC_STACK_OK)
+        {
+            GetSetContext* context = (GetSetContext*)ctx;
+            AttributeMap attrs = parseGetSetCallback(clientResponse);
+        
+            std::thread exec(context->callback,attrs, 200);
+            exec.detach();
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+        else
+        {
+            std::cout<<"listen Callback got failed result: " << clientResponse->result<<std::endl;
+            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 result;
+        OCCallbackData* cbdata = new OCCallbackData();
+        GetSetContext* ctx = new GetSetContext();
+        ctx->callback = callback;
+        cbdata->context = (void*)ctx;
+        cbdata->cb = &getResourceCallback;
+
+        // TODO: in the future the cstack should be combining these two strings!
+        ostringstream os;
+        os << host << uri;
+
+        // TODO: end of above
+
+        {
+            std::lock_guard<std::mutex> lock(m_csdkLock);
+            OCDoHandle handle;
+            //TODO: use above and this line! result = OCDoResource(&handle, OC_REST_GET, uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
+            result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+        }
+        return result;
+    }
+
+    
+    OCStackApplicationResult setResourceCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
+    {
+        if(clientResponse->result == OC_STACK_OK)
+        {
+            GetSetContext* context = (GetSetContext*)ctx;
+            AttributeMap attrs = parseGetSetCallback(clientResponse);
+
+            std::thread exec(context->callback, attrs, 200);
+            exec.detach();
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+        else
+        {
+            std::cout<<"listen Callback got failed result: " << clientResponse->result<<std::endl;
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    
+    std::string InProcClientWrapper::assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams)
+    {
+        if(uri.back() == '/') 
+        {
+            uri.pop_back();
+        }
+
+        ostringstream paramsList;
+        if(queryParams.size() > 0)
+        {
+            paramsList << '?';
+        }
+
+        for(auto& param : queryParams)
+        {
+            paramsList << param.first <<'='<<param.second<<'&';
+        }
+
+        std::string ret = uri + paramsList.str();
+        return ret;
+    }
+    
+    std::string InProcClientWrapper::assembleSetResourcePayload(const AttributeMap& attributes)
+    {
+        ostringstream payload;
+        payload << "{\"oc\":{\"payload\":{";
+
+        for(AttributeMap::const_iterator itr = attributes.begin(); itr!= attributes.end(); ++ itr)
+        {
+            if(itr != attributes.begin())
+            {
+                payload << ',';    
+            }
+            
+            payload << "\""<<itr->first<<"\":\""<< itr->second.front()<<"\"";
+        }
+        payload << "}}}";
+        return payload.str();
+    }
+
+    OCStackResult InProcClientWrapper::SetResourceAttributes(const std::string& host, const std::string& uri, const AttributeMap& attributes, const QueryParamsMap& queryParams, std::function<void(const AttributeMap&,const int&)>& callback)
     {
-       OCStackResult result;
+        OCStackResult result; 
+        OCCallbackData* cbdata = new OCCallbackData();
+        GetSetContext* ctx = new GetSetContext();
+        ctx->callback = callback;
+        cbdata->cb = &setResourceCallback;
 
-       OCCallbackData* cbdata = new OCCallbackData();
-       cbdata->context = (void*)(&callback);
-       cbdata->cb = &listenCallback;
-       {
-               std::lock_guard<std::mutex> lock(m_csdkLock);
+        // TODO: in the future the cstack should be combining these two strings!
+        ostringstream os;
+        os << host << assembleSetResourceUri(uri, queryParams).c_str();
 
-               result = OCDoResource(OC_REST_GET, resourceType.c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+        // TODO: end of above
 
-       }
-               return result;
+        cbdata->context = (void*)ctx;
+        {
+            std::lock_guard<std::mutex> lock(m_csdkLock);
+            OCDoHandle handle;
+            //OCDoResource(&handle, OC_REST_PUT, assembleSetResourceUri(uri.c_str(), queryParams).c_str(), host.c_str(), assembleSetResourcePayload(uri, attributes).c_str(), OC_CONFIRMABLE, cbdata);
+            //TODO: use above and this line! result = OCDoResource(&handle, OC_REST_GET, uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
+            result = OCDoResource(&handle, OC_REST_PUT, os.str().c_str(), nullptr, assembleSetResourcePayload(attributes).c_str(), OC_NON_CONFIRMABLE, cbdata);
+        }
+        return result;
+    }
+
+    struct ObserveContext
+    {
+        std::function<void(const AttributeMap&, const int&)> callback;
+    };
+
+    OCStackApplicationResult observeResourceCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
+    {   
+        if(clientResponse->result == OC_STACK_OK)
+        {
+            ObserveContext* context = (ObserveContext*)ctx;
+            AttributeMap attrs = parseGetSetCallback(clientResponse);
+
+            std::thread exec(context->callback, attrs, 200);
+            exec.detach();
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+        else
+        {
+            std::cout<<"Observe Callback got failed result: "<<clientResponse->result << std::endl;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+    }
+    OCStackResult InProcClientWrapper::ObserveResource(OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&)>& callback)
+    {
+        OCStackResult result;
+        OCCallbackData* cbdata = new OCCallbackData();
+        ObserveContext* ctx = new ObserveContext();
+        ctx->callback = callback;
+        cbdata->context = (void*)ctx;
+        cbdata->cb = &observeResourceCallback;
+
+        ostringstream os;
+        os << host<< uri;
+
+        {
+            std::lock_guard<std::mutex> lock(m_csdkLock);
+            //result = OCDoResource(handle, OC_REST_OBSERVE,  uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
+            result = OCDoResource(handle, OC_REST_OBSERVE, os.str().c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+        }
+        return result;
+    }
+
+    struct UnobserveContext
+    {
+        std::function<void(const int&)> callback;
+    };
+
+    OCStackApplicationResult unobserveResourceCallback(void* ctx, OCDoHandle handle, OCClientResponse* clientResponse)
+    {
+        std::cout << "Unobserve callback called...."<<std::endl;
+        UnobserveContext* context = (UnobserveContext*)ctx;
+        if(clientResponse->result == OC_STACK_OK)
+        {
+            std::thread exec(context->callback, 200);
+            exec.detach();
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+        else
+        {
+            std::cout<<"Unobserve callback got failed result: "<<clientResponse->result <<std::endl;
+            std::thread exec(context->callback, clientResponse->result);
+            exec.detach();
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri)
+    {
+        OCStackResult result;
+        {
+            std::lock_guard<std::mutex> lock(m_csdkLock);
+            result = OCCancel(handle);  
+        }
+        return result;
     }
    }
index 925acc4f74fa0fe6c5d65387ba119f457c7b23fe..a051ea4927527f51174e54d911c7d13edbcf62a6 100644 (file)
 #include <cstdlib>
 #include <iostream>
 #include <algorithm>
+#include <map>
+#include <sstream>
+#include <string>
 
-#include "InProcServerWrapper.h"
+#include <InProcServerWrapper.h>
 #include <InitializeException.h>
 #include <OCReflect.h>
+#include <OCResourceRequest.h>
+#include <OCResourceResponse.h>
 #include <ocstack.h>
+#include <OCApi.h>
 
 
 using namespace OC::OCReflect;
 
 using namespace std;
 
-void entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest* eHandlerReq)
+std::map <OCResourceHandle, std::function<void(const OC::OCResourceRequest::Ptr, const OC::OCResourceResponse::Ptr)>> entityHandlerMap;
+
+void defaultEntityHandler(const OC::OCResourceRequest::Ptr request, const OC::OCResourceResponse::Ptr response)
 {
-    cout << "Resource Handler: " << eHandlerReq->resource << endl;
-    cout << "Method: "           << eHandlerReq->method << endl;
-    cout << "reqJSONPayLoad: "   << eHandlerReq->reqJSONPayload << endl;
+    cout << "\nSomething wrong: We are in default entity handler: " << endl;
+}
+
+OCStackResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest ) {
+   
+    // TODO @SASHI we need to have a better way of logging (with various levels of logging) 
+    cout << "\nIn C entity handler: " << endl;
+
+    // TODO @SASHI dow we need shared pointer?
+    auto pRequest = std::make_shared<OC::OCResourceRequest>();
+    auto pResponse = std::make_shared<OC::OCResourceResponse>();
+
+    // TODO @ SASHI Utility to convert from C to C++ (every).
+    switch (flag) {
+        case OC_INIT_FLAG:
+            // TODO @SASHI We can fill the common data (resource Handle, etc.. )
+            // init time.
+            pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::InitFlag);
+            break;
+        case OC_REQUEST_FLAG:
+            pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::RequestFlag);
+
+            if(entityHandlerRequest)
+            {
+                if(OC_REST_GET == entityHandlerRequest->method)
+                {
+                    // TODO @SASHI Why strings : "GET"??
+                    pRequest->setRequestType("GET");
+                }
+                
+                if(OC_REST_PUT == entityHandlerRequest->method)
+                {
+                    pRequest->setRequestType("PUT");
+                    pRequest->setPayload(std::string(reinterpret_cast<const char*>(entityHandlerRequest->reqJSONPayload)));
+                }
+            }
+            break;
+        case OC_OBSERVE_FLAG:
+            pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::ObserverFlag);
+            break;
+    }
+
+
+    // Finding the corresponding CPP Application entityHandler for a given resource
+    auto entityHandlerEntry = entityHandlerMap.find(entityHandlerRequest->resource);
+
+    if(entityHandlerEntry != entityHandlerMap.end()) {
+        // Call CPP Application Entity Handler
+        entityHandlerEntry->second(pRequest, pResponse);
+    }
+    else {
+        std::cout << "No eintity handler found."  << endl;
+        return OC_STACK_ERROR;
+    }
+
+
+    if(flag == OC_REQUEST_FLAG)
+    {
+        // TODO @SASHI we could use const reference
+        std::string payLoad = pResponse->getPayload();
+
+        if(OC_REST_GET == entityHandlerRequest->method) 
+        {
+            cout << "\t\t\tGoing from stack for GET: " << payLoad << endl;    
+        }
+        else if (OC_REST_PUT == entityHandlerRequest->method)
+        {
+            cout << "\t\t\tGoing from stack for PUT: " << payLoad << 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)
+        {
+            // TODO @SASHI throw std::runtime_error("out of memory");
+            cout << "Out of memory in copying to resJSONPayload" << endl; 
+        } 
+    }
+      
+    return OC_STACK_OK;
 }
 
 namespace OC
@@ -47,24 +133,28 @@ namespace OC
     {
         OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, OC_SERVER);
 
+        // Setting default entity Handler
+        entityHandlerMap[(OCResourceHandle) 0] = defaultEntityHandler;
+
         if(OC_STACK_OK != result)
         {
             throw InitializeException("Error Initializing Stack", result);
         }
-               
-               m_threadRun = true;
+
+        m_threadRun = true;
         m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
     }
-       
-       void InProcServerWrapper::processFunc()
+
+    void InProcServerWrapper::processFunc()
     {
         while(m_threadRun)
         {
-                       OCStackResult result;
-                       {
-                               std::lock_guard<std::mutex> lock(m_csdkLock);
-                               result = OCProcess();
-                       }
+            OCStackResult result;
+            {
+                // TODO Fix Lock issue
+                // std::lock_guard<std::mutex> lock(m_csdkLock);
+                result = OCProcess();
+            }
 
             if(result != OC_STACK_OK)
             {
@@ -74,63 +164,64 @@ namespace OC
 
             std::this_thread::yield();
             // To minimize CPU utilization we may wish to do this with sleep
-                       //std::this_thread::sleep_for(std::chrono::milliseconds(1));
+            //std::this_thread::sleep_for(std::chrono::milliseconds(1));
         }
     }
 
-    void InProcServerWrapper::registerResource(const std::string& resourceURI,
-                                const std::string& resourceTypeName,
-                                property_binding_vector properties)
-    {
-        using OC::OCReflect::property_type;
-        using OC::OCReflect::property_binding;
-        using namespace OC::OCReflect::OCStack;
+    OCStackResult InProcServerWrapper::registerResource(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface, 
+                    std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> eHandler,
+                    uint8_t resourceProperties)
 
-        std::vector<std::string> reps { convert(properties) };
-
-        char *resourceTypeRepresentation = flatten(reps);
-
-        std::cout << "Resource type representation: " << resourceTypeRepresentation << "\n";
-
-        OCResourceHandle resourceHandle;
-
-               {
-                       std::lock_guard<std::mutex> lock(m_csdkLock);
+    {
+        OCStackResult  result;
 
-                       OCStackResult  result;
+        cout << "Registering Resource: \n";
+        cout << "\tResource URI: " << resourceURI << endl;
+        cout << "\tResource TypeName: " << resourceTypeName  << endl;
+        cout << "\tResource Interface: " << resourceInterface << endl;
 
-                       result = OCCreateResource(&resourceHandle, // OCResourceHandle *handl
-                                                       resourceTypeName.c_str(), // const char * resourceTypeName
-                                                       resourceTypeRepresentation, //const char * resourceTypeRepresentation
-                                                       "core.rw", //const char * resourceInterfaceName
-                                                       OC_REST_GET | OC_REST_PUT, // uint8_t allowedMethods
-                                                       resourceURI.c_str(), // const char * uri
-                                                       entityHandler, // OCEntityHandler entityHandler
-                                                       OC_DISCOVERABLE | OC_OBSERVABLE // uint8_t resourceProperties
-                                                       );
+        {
+            // TODO @SASHI : Something wrong with lock usage
+            // std::lock_guard<std::mutex> lock(m_csdkLock);
+
+            result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+                            resourceTypeName.c_str(), // const char * resourceTypeName
+                            "state:oc.bt.b;power:oc.bt.i", // TODO @SASHI why are we still sending this??
+                            resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+                            OC_REST_GET | OC_REST_PUT, // uint8_t allowedMethods
+                            resourceURI.c_str(), // const char * uri
+                            entityHandler, // OCEntityHandler entityHandler
+                            resourceProperties // uint8_t resourceProperties
+                            );
 
             if(result != OC_STACK_OK)
             {
-                cout << "Something wrong in OCCreateResource" << endl;
+                cout << "\tSomething wrong in creating the resource" << endl;
+                resourceHandle = (OCResourceHandle) 0;
                 // TODO: SASHI
             }
             else
             {
-                cout << "Resource creation is successful" << endl;
+                cout << "\tResource creation is successful with resource handle:  " << resourceHandle << endl;
+                entityHandlerMap[resourceHandle] = eHandler;
             }
-            
-               }
-
+        }
+    
+        return result;
     }
 
     InProcServerWrapper::~InProcServerWrapper()
     {
-               if(m_processThread.joinable())
+        if(m_processThread.joinable())
         {
             m_threadRun = false;
             m_processThread.join();
         }
-       
+
         OCStop();
     }
 }
index b0e9d7fac1e04f82cb2d9bfb8765d5b62c388ec2..c936f138933ba40f3edf81bee634054ac91dbbfc 100644 (file)
@@ -31,6 +31,7 @@
 #include <random>
 
 #include "OCPlatform.h"
+#include "OCApi.h"
 
 namespace OC 
 {
@@ -47,6 +48,11 @@ namespace OC
         cleanup();
     }
 
+    OCStackResult OCPlatform::notifyObservers(OCResourceHandle resourceHandle)
+    {
+        return OCNotifyObservers(resourceHandle);
+    }
+
     void OCPlatform::init(const PlatformConfig& config)
     {
         std::unique_ptr<WrapperFactory> wrapperInstance(new WrapperFactory());
@@ -84,30 +90,42 @@ namespace OC
     }
 
     
-    void OCPlatform::findResource(const std::string& host, const std::string& resourceName, 
+    OCStackResult OCPlatform::findResource(const std::string& host, const std::string& resourceName, 
         std::function<void(OCResource::Ptr)> resourceHandler)
     {
+        OCStackResult result = OC_STACK_OK;
+
         if(m_client)
         {
+            // TODO this should return
             m_client->ListenForResource(host, resourceName, resourceHandler);
         }
+        
+        return result;
     }
     
 
-    void OCPlatform::registerResource(std::string& resourceURI, const std::string& resourceTypeName, const std::string& resourceInterface, 
-            std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler, ResourceFlag resourceFlag)
+    OCStackResult OCPlatform::registerResource(OCResourceHandle& resourceHandle, 
+                std::string& resourceURI, 
+                const std::string& resourceTypeName, 
+                const std::string& resourceInterface, 
+                std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler, 
+                uint8_t resourceProperty)
     {
+        OCStackResult result = OC_STACK_OK;
+
         if(m_server)
         {
             try{
-                                // Adding below statement for compilation sake
-                                property_binding_vector properties;
-                m_server->registerResource(resourceURI, resourceTypeName, properties); 
-            }catch(std::exception e) // define our own expception. 
+                result = m_server->registerResource(resourceHandle, resourceURI, resourceTypeName, resourceInterface, entityHandler, resourceProperty); 
+            }
+            catch(std::exception e) // define our own expception. 
             {
                 throw e;
             }
         }
+
+        return result;
     }
 
 } //namespace OC
index dc3d6460ca172c83f90ec37f64c2697a52b12780..ab90ea7032ea5f0a62722160f5513f51a2bf6d3f 100644 (file)
 #include "OCReflect.h"
 
 namespace OC {
-    OCResource::OCResource(const std::string host, boost::property_tree::ptree& resourceNode) : m_isCollection(false)
-    {
-        m_host = host;
-        m_uri = resourceNode.get<std::string>("href","");
-        m_isObservable = resourceNode.get<int>("obs",0)==1;
-        
-        boost::property_tree::ptree resourceTypes = resourceNode.get_child("rt", boost::property_tree::ptree());
-        for(auto itr : resourceTypes)
+    OCResource::OCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, 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)
+    {
+        m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE) != m_interfaces.end();
+
+        if (m_uri.empty() || resourceTypes.empty() || interfaces.empty()|| ! m_clientWrapper)
+        {
+            throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty(), m_clientWrapper.get() == nullptr);
+        }
+    }
+
+    OCResource::~OCResource()
+    {
+    }
+
+    OCStackResult OCResource::get(std::function<void(const AttributeMap&, const int&)> attributeHandler)
+    {
+        return m_clientWrapper->GetResourceAttributes(m_host, m_uri, attributeHandler);
+    }
+
+    OCStackResult OCResource::put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function<void(const AttributeMap&, const int&)> attributeHandler)
+    {
+        return m_clientWrapper->SetResourceAttributes(m_host, m_uri, attributeMap, queryParametersMap, attributeHandler);
+    }
+
+    OCStackResult OCResource::observe(std::function<void(const AttributeMap&, const int&)> observeHandler)
+    {
+        if(m_observeHandle != nullptr)
         {
-            m_resourceTypes.push_back(itr.second.data());
+            return OC_STACK_INVALID_PARAM;
         }
-        
-        boost::property_tree::ptree interfaces = resourceNode.get_child("if", boost::property_tree::ptree());
-        for(auto itr : interfaces)
+        else
+        {
+            return m_clientWrapper->ObserveResource(&m_observeHandle, m_host, m_uri, observeHandler);
+        }
+    }
+
+    OCStackResult OCResource::cancelObserve()
+    {
+        if(m_observeHandle == nullptr)
         {
-            if(itr.second.data() == "oc.mi.ll")
-            {
-                m_isCollection = true;
-            }
-        
-            m_interfaces.push_back(itr.second.data());
+            return OC_STACK_INVALID_PARAM;
         }
-        
-        // TODO: If collection, load children, assuming this becomes a thing
-        
-        // TODO: Load attributes, assuming this becomes a 'thing'
-        
-        if (m_uri.empty() || resourceTypes.empty() || interfaces.empty())
+        else
         {
-            throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty());
+            OCStackResult ret = m_clientWrapper->CancelObserveResource(m_observeHandle, m_host, m_uri);
+            m_observeHandle = nullptr;
+            return ret;
         }
     }
-    
-    OCResource::~OCResource()
+
+    std::string OCResource::host() const 
+    {
+        return m_host;
+    }
+    std::string OCResource::uri() const 
+    {
+        return m_uri;
+    }
+    bool OCResource::isObservable() const 
     {
+        return m_isObservable;
     }
 } // namespace OC
index 3168b1f101151a52866000039a57566c6e621e65..9a750d647b57b8120c0950dbdb4f3ffec4ef15ec 100644 (file)
 // OCClient.cpp : Defines the entry point for the console application.
 //
 #include <string>
-
+#include <cstdlib>
+#include <pthread.h>
 #include "OCPlatform.h"
 
 using namespace OC;
 
 const int SUCCESS_RESPONSE = 200; 
+std::shared_ptr<OCResource> curResource;
 
-// callback handler on GET request
-void onGet(const AttributeMap& attributeMap, const int& eCode)
+int observe_count()
+{
+    static int oc = 0;
+    return ++oc;
+}
+
+void onObserve(const AttributeMap& attributeMap, const int& eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
+        std::cout << "OBSERVE RESULT:"<<std::endl;
         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
         {
-            std::cout << "Attribute name: "<< it->first << " value: ";
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
             for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
             {
-                std::cout << *valueItr << " ";
+                std::cout <<"\t"<< *valueItr << " ";
             }
 
             std::cout << std::endl;
         }
-    }
-    else
-    {
-        std::cout << "Response error: " << eCode << std::endl;
-    }
-}
+        
+        if(observe_count() > 3)
+        {
+            std::cout<<"Cancelling Observe..."<<std::endl;
+            OCStackResult result = curResource->cancelObserve();
 
-// callback handler on PUT request
-void onPut(const int& eCode)
-{
-    if(eCode == SUCCESS_RESPONSE)
-    {
-        std::cout << "Put request was successful" << std::endl;
+            std::cout << "Cancel result: "<< result <<std::endl;
+            sleep(10);
+            std::cout << "DONE"<<std::endl;
+            std::exit(0);
+        }
     }
     else
     {
-        std::cout << "Response error: " << eCode << std::endl;
+        std::cout << "onObserve Response error: " << eCode << std::endl;
+        std::exit(-1);
     }
 }
 
-// callback handler on observation
-void onObserve(const AttributeMap& attributeMap, const int& eCode)
+// callback handler on PUT request
+void onPut(const AttributeMap& attributeMap, const int& eCode)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
-        std::cout << "Observe callback invoked" << std::endl;
+        std::cout << "PUT request was successful" << std::endl;
+        
         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
         {
-            std::cout << "Attribute name: "<< it->first << " value: ";
+            std::cout << "\tAttribute name: "<< it->first << " value: ";
             for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)
             {
-                std::cout << *valueItr << " ";
+                std::cout <<"\t"<< *valueItr << " ";
             }
 
             std::cout << std::endl;
         }
+        curResource->observe(&onObserve);
     }
     else
     {
-        std::cout << "Response error: " << eCode << std::endl;
-    }
-}
-
-// callback handler for observe cancellation
-void onCancelObservation(const int& eCode)
-{
-    if(eCode == SUCCESS_RESPONSE)
-    {
-        std::cout << "Put request was successful" << std::endl;
-    }
-    else
-    {
-        std::cout << "Response error: " << eCode << std::endl;
+        std::cout << "onPut Response error: " << eCode << std::endl;
+        std::exit(-1);
     }
 }
 
@@ -104,6 +101,7 @@ void putLightRepresentation(std::shared_ptr<OCResource> resource)
 {
     if(resource)
     {
+        std::cout << "Putting light representation..."<<std::endl;
         // Create AttributeMap
         AttributeMap attributeMap;
         // Add the attribute name and values in the attribute map
@@ -111,7 +109,7 @@ void putLightRepresentation(std::shared_ptr<OCResource> resource)
         stateVal.push_back("true");
 
         AttributeValues powerVal; 
-        powerVal.push_back("100");
+        powerVal.push_back("10");
 
         attributeMap["state"] = stateVal;
         attributeMap["power"] = powerVal; 
@@ -124,39 +122,51 @@ void putLightRepresentation(std::shared_ptr<OCResource> resource)
     }
 }
 
-// Local function to get representation of light resource
-void getLightRepresentation(std::shared_ptr<OCResource> resource)
+// callback handler on GET request
+void onGet(const AttributeMap& attributeMap, const int& eCode)
 {
-    if(resource)
+    if(eCode == SUCCESS_RESPONSE)
     {
-        // Invoke resource's get API with the callback parameter
-        resource->get(&onGet);
-    }
-}
+        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 << " ";
+            }
 
-// Local function to observe on a resource (in this case light)
-void observeOnLight(std::shared_ptr<OCResource> resource)
-{
-    if(resource)
+            std::cout << std::endl;
+        }
+
+        putLightRepresentation(curResource);
+    }
+    else
     {
-        // Invoke resource's observe API with the callback parameter
-        resource->observe(&onObserve);
+        std::cout << "onGet Response error: " << eCode << std::endl;
+        std::exit(-1);
     }
 }
-
-// Local function to cancel the observation on a resource
-void cancelObservation(std::shared_ptr<OCResource> resource)
+// Local function to get representation of light resource
+void getLightRepresentation(std::shared_ptr<OCResource> resource)
 {
     if(resource)
     {
-        // Invoke resource's cancelObserve API with the callback parameter
-        resource->cancelObserve(&onCancelObservation);
+        std::cout << "Getting Light Representation..."<<std::endl;
+        // Invoke resource's get API with the callback parameter
+        resource->get(&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
@@ -164,33 +174,20 @@ void foundResource(std::shared_ptr<OCResource> resource)
         // Do some operations with resource object. 
         if(resource)
         {
+            std::cout<<"DISCOVERED Resource:"<<std::endl;
             // Get the resource URI
             resourceURI = resource->uri();
-            std::cout << "URI of the resource: " << resourceURI << std::endl;
+            std::cout << "\tURI of the resource: " << resourceURI << std::endl;
             
             // Get the resource host address
             hostAddress = resource->host();
-            std::cout << "Host address of the resource: " << hostAddress << std::endl;      
+            std::cout << "\tHost address of the resource: " << hostAddress << std::endl;      
 
             if(resourceURI == "/a/light")
             {
+                curResource = resource;
                 // Call a local function which will internally invoke get API on the resource pointer
                 getLightRepresentation(resource); 
-
-                // Do some operations 
-
-                // Call a local function which will internally invoke get API on the resource pointer
-                putLightRepresentation(resource); 
-
-                // Do some operations 
-
-                // Call a local function which will internally observe on this resource for further notifications
-                observeOnLight(resource);
-
-                // Do some operations
-
-                // Call a local function which will internally cancel observation on this resource
-                cancelObservation(resource);
             }
         }
         else
@@ -223,10 +220,10 @@ int main()
     try
     {
         OCPlatform platform(cfg);
-
+        std::cout << "Created Platform..."<<std::endl;
         // Find all resources
-        platform.findResource("", "coap://224.0.1.187/oc/core", &foundResource);
-
+        platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.light", &foundResource);
+        std::cout<< "Finding Resource... " <<std::endl;
         while(true)
         {
             // some operations
index ea23063e6587f917675147c81c9949a9b4f0096a..dccbbed6325c5c860fb31a2a675f9a45fde1b0fb 100644 (file)
 
 #include <functional>
 
+#include <pthread.h>
+
 #include "OCPlatform.h"
 #include "OCApi.h"
 
 using namespace OC;
+using namespace std;
+
+int gObservation = 0;
+
+// Forward declaring the entityHandler
+void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+
+/// This class represents a single resource named 'lightResource'. This resource has 
+/// two simple properties named 'state' and 'power' 
+
+class LightResource
+{
+public:
+    /// Access this property from a TB client 
+    bool m_state;
+    int m_power;
+    OCResourceHandle m_resourceHandle;
+
+public:
+    /// Constructor
+    LightResource(): m_state(false), m_power(0){}
+
+    /* Note that this does not need to be a member function: for classes you do not have
+    access to, you can accomplish this with a free function: */
+    
+    /// This function internally calls registerResource API.
+    void createResource(OC::OCPlatform& platform)
+    {
+        std::string resourceURI = "/a/light"; // URI of the resource
+        std::string resourceTypeName = "core.light"; // resource type name. In this case, it is light
+        std::string resourceInterface = PARAMETER_INTERFACE; // resource interface.
+
+        // OCResourceProperty is defined ocstack.h
+        uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+
+        // This will internally create and register the resource. 
+        OCStackResult result = platform.registerResource(
+                                    m_resourceHandle, resourceURI, resourceTypeName, 
+                                    resourceInterface, &entityHandler, resourceProperty); 
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation was unsuccessful\n";
+        }
+    }
+
+    OCResourceHandle getHandle()
+    {
+        return m_resourceHandle;
+    }
+
+    void setRepresentation(AttributeMap& attributeMap)
+    {
+        cout << "\t\t\t" << "Received representation: " << endl;
+        cout << "\t\t\t\t" << "power: " << attributeMap["power"][0] << endl;
+        cout << "\t\t\t\t" << "state: " << attributeMap["state"][0] << endl;
+
+        m_state = attributeMap["state"][0].compare("true") == 0;
+        m_power = std::stoi(attributeMap["power"][0]);
+    }
+
+    void getRepresentation(AttributeMap& attributeMap)
+    {
+        AttributeValues stateVal;
+        if(m_state)
+        {
+            stateVal.push_back("true");
+        }
+        else
+        {
+            stateVal.push_back("false");
+        }
+
+        AttributeValues powerVal;
+        powerVal.push_back(to_string(m_power));
+
+        attributeMap["state"] = stateVal;
+        attributeMap["power"] = powerVal;
+    }
+};
+
+// Create the instance of the resource class (in this case instance of class 'LightResource'). 
+LightResource myLightResource;
+
+// ChangeLightRepresentaion is an observation function,
+// which notifies any changes to the resource to stack
+// via notifyObservers
+void * ChangeLightRepresentation (void *param)
+{
+    // This function continuously monitors for the changes
+    while (1)
+    {
+        sleep (5);
+        
+        if (gObservation)
+        {
+            // If under observation if there are any changes to the light resource
+            // we call notifyObservors
+            //
+            // For demostration we are changing the power value and notifying.
+            myLightResource.m_power += 10; 
+
+            cout << "\nPower updated to : " << myLightResource.m_power << endl;
+            cout << "Notifying observers with resource handle: " << myLightResource.getHandle() << endl;
+            
+            OCStackResult result = OCPlatform::notifyObservers(myLightResource.getHandle());
+
+            if(OC_STACK_NO_OBSERVERS == result)
+            {
+                cout << "No More observers, stopping notifications" << endl;
+                gObservation = 0;
+            }
+        }
+    }
+
+    return NULL;
+}
+
 
 // This is just a sample implementation of entity handler. 
 // Entity handler can be implemented in several ways by the manufacturer
 void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
 {
-    // add the headers in this map before sending the response
-    HeadersMap headersMap; 
-    headersMap["content-type"] = "text";
-    headersMap["server"] = "serverName";
+    cout << "\tIn Server CPP entity handler:\n";
 
     if(request)
     {
@@ -47,13 +164,19 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
 
         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();
 
@@ -61,24 +184,20 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
 
                 // Get the representation of this resource at this point and send it as response
                 AttributeMap attributeMap; 
-                AttributeValues stateVal; 
-                stateVal.push_back("false");
-
-                AttributeValues powerVal; 
-                powerVal.push_back("0");
 
-                attributeMap["state"] = stateVal;
-                attributeMap["power"] = powerVal; 
+                myLightResource.getRepresentation(attributeMap);
 
                 if(response)
-                {
-                    response->setResponseHeaders(headersMap);
-                    response->setHTTPErrorCode(200);
+                {   
+                    // TODO Error Code
+                    response->setErrorCode(200);
                     response->setResourceRepresentation(attributeMap);
                 }
             }
             else if(requestType == "PUT")
             {
+                cout << "\t\t\trequestType : PUT\n";
+
                 // Check for query params (if any)
                 QueryParamsMap queryParamsMap = request->getQueryParameters();
 
@@ -86,23 +205,16 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
 
                 // Get the representation from the request
                 AttributeMap attributeMap = request->getResourceRepresentation();
-                
-                // Do related operations related to PUT request 
-                // Change the attribute map accordingly and send a response
 
-                AttributeValues stateVal; 
-                stateVal.push_back("true");
+                myLightResource.setRepresentation(attributeMap);
 
-                AttributeValues powerVal; 
-                powerVal.push_back("100");
-
-                attributeMap["state"] = stateVal;
-                attributeMap["power"] = powerVal; 
+                // Do related operations related to PUT request 
+                
+                myLightResource.getRepresentation(attributeMap);
 
                 if(response)
                 {
-                    response->setResponseHeaders(headersMap);
-                    response->setHTTPErrorCode(200);
+                    response->setErrorCode(200);
                     response->setResourceRepresentation(attributeMap);
                 }
             }
@@ -117,28 +229,21 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
         }
         else if(requestFlag == RequestHandlerFlag::ObserverFlag)
         {
-            // perform observe related operations on the resource. 
-            // Add the attributes to the map and send a response
-
-            // on any attribute change on the light resource hardware, 
-            // set the attributes and send response
-            AttributeMap attributeMap;
+            pthread_t threadId;
             
-            AttributeValues stateVal; 
-            stateVal.push_back("false");
-
-            AttributeValues powerVal; 
-            powerVal.push_back("0");
+            cout << "\t\trequestFlag : Observer\n";
+            gObservation = 1;
 
-            attributeMap["state"] = stateVal;
-            attributeMap["power"] = powerVal; 
-
-            if(response)
+            static int startedThread = 0;
+            
+            // Observation happens on a different thread in ChangeLightRepresentation function.
+            // If we have not created the thread already, we will create one here.
+            if(!startedThread)
             {
-                response->setResponseHeaders(headersMap);
-                response->setHTTPErrorCode(200);
-                response->setResourceRepresentation(attributeMap);
+                pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
+                startedThread = 1;
             }
+            
         }
     }
     else
@@ -147,43 +252,13 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
     }
 }
 
-/// This class represents a single resource named 'lightResource'. This resource has 
-/// two simple properties named 'state' and 'power' 
-
-class LightResource
-{
-public:
-    /// Access this property from a TB client 
-    bool m_state;
-    int m_power;
-
-public:
-    /// Constructor
-    LightResource(): m_state(false), m_power(0){}
-
-    /* Note that this does not need to be a member function: for classes you do not have
-    access to, you can accomplish this with a free function: */
-    
-    /// This function internally calls registerResource API.
-    void createResource(OC::OCPlatform& platform)
-    {
-        std::string resourceURI = "a/light"; // URI of the resource
-        std::string resourceTypeName = "light"; // resource type name. In this case, it is light
-        std::string resourceInterface = LINK_INTERFACE; // resource interface.
-        ResourceFlag resourceFlag = ResourceFlag::ObserverFlag; // set the resource flag to Observerable
-
-        // This will internally create and register the resource. 
-        platform.registerResource(resourceURI, resourceTypeName, resourceInterface, &entityHandler, resourceFlag); 
-    }
-};
-
 int main()
 {
     // Create PlatformConfig object
 
     PlatformConfig cfg;
     cfg.ipAddress = "134.134.161.33";
-    cfg.port = 5683;
+    cfg.port = 56832;
     cfg.mode = ModeType::Server;
     cfg.serviceType = ServiceType::InProc;
     
@@ -193,12 +268,10 @@ int main()
     {
         OCPlatform platform(cfg);
 
-        // Create the instance of the resource class (in this case instance of class 'LightResource'). 
-        // Invoke bindTo function of class light. 
+        // Invoke createResource function of class light. 
 
-        LightResource myLightResource;
         myLightResource.createResource(platform);
-        
+
         // Perform app tasks
         while(true)
         {
index b887e365d0c66e69db946f0ab5a3b4a4742d9873..620e7fb01656c41567e8f2d5461d41fe2a0583b3 100644 (file)
 #include <string>
 
 #include <OCApi.h>
-#include <OCResource.h>
-
 namespace OC
 {
-       class OCResource;
-    class IClientWrapper
+    class IClientWrapper : public std::enable_shared_from_this<IClientWrapper>
     {
     public:
         typedef std::shared_ptr<IClientWrapper> Ptr;
-
-        virtual int ListenForResource(const std::string& serviceUrl, const std::string& resourceType,
-            std::function<void(OCResource::Ptr)>& callback) = 0;
+        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(OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, const int&)>& callback)=0;
+        virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri)=0;
         virtual ~IClientWrapper(){}
+       
 
+        // 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)=0;
     private:
     };
 }
index 87b4c6d3fa063b39b2c0346de6eb96ba3a394110..839eb812c46dae26dab9e36f28c12987f33aa499 100644 (file)
@@ -25,6 +25,9 @@
 #include <string>
 
 #include <OCReflect.h>
+#include <OCResourceRequest.h>
+#include <OCResourceResponse.h>
+#include <OCApi.h>
 
 using namespace OC::OCReflect;
 
@@ -37,9 +40,14 @@ namespace OC
 
         virtual ~IServerWrapper(){};
 
-        virtual void registerResource(  const std::string& resourceURI, 
-                                const std::string& resourceTypeName,
-                                property_binding_vector properties) = 0; 
+        virtual OCStackResult registerResource(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI, 
+                    const std::string& resourceTypeName, 
+                    const std::string& resourceInterface,
+                    std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler,
+                    uint8_t resourceProperty) = 0;
+
     };
 }
 
index b5fd8cbf55b3be5cf70e74df160bd1786bc1e3b6..c63da16e95cb8011edbdd30e9c1c5828e282a3db 100644 (file)
@@ -43,15 +43,24 @@ namespace OC
         InProcClientWrapper(PlatformConfig cfg);
         virtual ~InProcClientWrapper();
 
-        virtual int ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(OCResource::Ptr)>& 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, 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(OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, 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);
     private:
         void listeningFunc();
+        std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
+        std::string assembleSetResourcePayload(const AttributeMap& attributes);
         std::thread m_listeningThread;
         bool m_threadRun;
         std::mutex m_resourceListenerLock;
-               std::mutex m_csdkLock;
+        std::mutex m_csdkLock;
         std::vector<std::function<void(OCClientResponse*)>> callbackList;
+
     };
 }
 
index f03e79133ee4cea77774a91758668598e486ec23..de4627ee96cfed47b10bfdfd1db5700303720037 100644 (file)
@@ -24,9 +24,8 @@
 #include <thread>
 #include <mutex>
 #include <ocstack.h>
-#include <OCApi.h>
+
 #include <IServerWrapper.h>
-#include <OCReflect.h>
 
 using namespace OC::OCReflect;
 
@@ -38,10 +37,14 @@ namespace OC
         InProcServerWrapper(PlatformConfig cfg);
         virtual ~InProcServerWrapper();
 
-        void registerResource(  const std::string& resourceURI, 
-                                const std::string& resourceTypeName,
-                                property_binding_vector properties); 
-                                                               
+        virtual OCStackResult registerResource(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface,
+                    std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler,
+                    uint8_t resourceProperty);
+
        private:
                void processFunc();
                std::thread m_processThread;
index 23c61c948669d36590d11ed03d15569e3975a265..834dedd33c77c98b4234f423d3ae0ca71023a596 100644 (file)
@@ -78,24 +78,28 @@ namespace OC {
     ObserverFlag
  };
 
- enum class ResourceFlag
- {
-     DiscoverableFlag,
-     ObserverFlag
- };
-
  // TODO: To find the complete JSon data structure and modify map value type
+ // Typedef for attribute values and attribute map. 
  typedef std::vector<std::string> AttributeValues;
  typedef std::map<std::string, AttributeValues> AttributeMap; 
 
+ // Typedef for query parameter map
  typedef std::map<std::string, std::string> QueryParamsMap;
 
- typedef std::map<std::string, std::string> HeadersMap;
-
+ // const strings for different interfaces
+ // Used in discovering (GET) links to other resources of a container/collection.  
  const std::string LINK_INTERFACE = "oc.mi.ll";
+
+ // Used in GET, PUT, POST, DELETE methods on links to other resources of a container/collection. 
  const std::string BATCH_INTERFACE = "oc.mi.b";
+
+ // Used to signify that the resource supports ONLY GET method 
  const std::string SENSOR_INTERFACE = "oc.mi.s";
+
+ // Used to signify that the resource supports GET, PUT, POST, DELETE methods
  const std::string ACTUATOR_INTERFACE = "oc.mi.a";
+
+ // OPENS 
  const std::string PARAMETER_INTERFACE = "oc.mi.p";
  const std::string READ_PARAMETER_INTERFACE = "oc.mi.rp";
 
index c499e087fdf312ef4e95cd3b772575410a1688bd..39d8a203e728e7208f96d99e2a861111516d3fac 100644 (file)
@@ -59,6 +59,18 @@ namespace OC
         */
         virtual ~OCPlatform(void);
 
+        /**
+        * API for notifying core that resource's attributes have changed. 
+        *
+        * @param OCResourceHandle resource handle of the resource
+        *
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
+        * NOTE: This API is for server side only. 
+        * NOTE: OCResourceHandle is defined in ocstack.h. 
+        * NOTE: OCStackResult is defined in ocstack.h. 
+        */
+        static OCStackResult notifyObservers(OCResourceHandle resourceHandle);
+
         /**
         * API for Service and Resource Discovery. 
         * NOTE: This API applies to client side only.
@@ -75,24 +87,30 @@ namespace OC
         *        (Not Empty, NULL/Empty) - Performs ALL resource discovery on a particular service. 
         *        (Not Empty, Not Empty) - Performs query for a filtered/scoped/particular resource(s) 
         *                                  from a particular service.
+        * 
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
         * NOTE: First parameter 'host' currently represents an IP address. This will change in future
         * and will refer to endpoint interface so that we can refer to other transports such as BTH etc.
-        * Example:
-        * 
+        * NOTE: OCStackResult is defined in ocstack.h. 
         */
-        void findResource(const std::string& host, const std::string& resourceURI, 
+        OCStackResult findResource(const std::string& host, const std::string& resourceURI, 
             std::function<void(OCResource::Ptr)> resourceHandler);
 
         /**
         * This API registers a resource with the server
         * NOTE: This API applies to server side only.
         * 
+        * @param resourceHandle - Upon successful registration, resourceHandle will be filled
         * @param resourceURI - The URI of the resource. Example: "a/light". See NOTE below
         * @param resourceTypeName - The resource type. Example: "light"
         * @param resourceInterface - The resource interface (whether it is collection etc). 
         * @param entityHandler - entity handler callback. 
-        * @param resourceFlag - flag to indicate discoverable/observable etc.
+        * @param resourceProperty - indicates the property of the resource. Defined in ocstack.h. 
+        * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+        * setting resourceProperty as OC_OBSERVABLE will allow observation
+        * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and observation
         * 
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success.
         * NOTE: "a/light" is a relative URI. 
         * Above relative URI will be prepended (by core) with a host IP + namespace "oc"
         * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
@@ -100,9 +118,14 @@ namespace OC
         * First parameter can take a relative URI and core will take care of preparing the fully qualified URI 
         * OR
         * first paramter can take fully qualified URI and core will take that as is for further operations
+        * NOTE: OCStackResult is defined in ocstack.h. 
         */
-        void registerResource(std::string& resourceURI, const std::string& resourceTypeName, const std::string& resourceInterface, 
-            std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler, ResourceFlag resourceFlag); 
+        OCStackResult registerResource(OCResourceHandle& resourceHandle, 
+                        std::string& resourceURI, 
+                        const std::string& resourceTypeName, 
+                        const std::string& resourceInterface, 
+                        std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler, 
+                        uint8_t resourceProperty);
 
     private:
         std::unique_ptr<WrapperFactory> m_WrapperInstance;
index 278f0b39e50a94ffe9d31078d2b68c8b6a2fc92b..9db8b6af75e1d1c70cb6df81ae010ffaa0d4ee29 100644 (file)
@@ -18,7 +18,7 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-/// @file OCResource.h 
+/// @file OCResource.h
 
 /// @brief  This file contains the declaration of classes and its members related to 
 ///         Resource.
 
 #include <memory>
 #include <random>
+#include <algorithm>
 
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/json_parser.hpp>
 
 #include <OCApi.h>
 #include <ResourceInitException.h>
+#include <IClientWrapper.h>
+#include <InProcClientWrapper.h>
 
 namespace OC
 {
@@ -47,86 +50,79 @@ namespace OC
     */
     class OCResource
     {
+    friend class InProcClientWrapper;
     public:
         typedef std::shared_ptr<OCResource> Ptr;
 
-        // TODO: This constructor needs to be removed when we give the final version
-        // TODO: See if we can do const prop tree
-        OCResource(const std::string host, boost::property_tree::ptree& resourceNode);
-
+        /**
+        * Virtual destructor
+        */
         virtual ~OCResource(void);
         
         /**
         * Function to get the attributes of a resource. 
-        * TODO : Need to have query params? Add implementation in .cpp
         * @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 
-        *        This will have HTTP error codes
+        *        This will have error codes
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
+        * NOTE: OCStackResult is defined in ocstack.h.
         */
-        void get(std::function<void(const AttributeMap&, const int&)> attributeHandler) { return; }
+        OCStackResult get(std::function<void(const AttributeMap&, const int&)> attributeHandler);
 
         /**
         * Function to set the attributes of a resource (via PUT)
-        * TODO Add implementation in .cpp
-        * @param AttributeMap Map 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 
-        *        (which will represent part of the resoruce state) via PUT
-        * @param queryParametersMap a map which will have the query parameters (if any)
-        * NOTE: For the current release, only '&' semantics will be provided
-        * @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 Put operation 
-        *        This will have HTTP error codes
+        * @param AttributeMap Map 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
+        *        The callback function will be invoked with a map of attribute name and values.
+        *        The callback function will also have the result from this Put operation
+        *        This will have error codes
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
+        * NOTE: OCStackResult is defined in ocstack.h.
         */
-        void put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function<void(const int&)> attributeHandler) { return; } 
+        OCStackResult put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function< void(const AttributeMap&,const int&)> attributeHandler);
 
         /**
-        * Function to set observation on the resource 
-        * TODO Add implementation in .cpp
+        * Function to set observation on the resource
         * @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 
-        *        This will have HTTP error codes
+        *        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
+        *        This will have error codes
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
+        * NOTE: OCStackResult is defined in ocstack.h.
         */
-        void observe(std::function<void(const AttributeMap&, const int&)> observeHandler) { return; }
+        OCStackResult observe(std::function<void(const AttributeMap&, const int&)> observeHandler);
 
         /**
         * Function to cancel the observation on the resource
-        * TODO Add implementation in .cpp
         * @param observeCancellationHandler handles callback
-        *        The callback function will also have the result from this operation 
-        *        This will have HTTP error codes
+        *        The callback function will also have the result from this operation
+        *        This will have error codes
+        * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. 
+        * NOTE: OCStackResult is defined in ocstack.h.
         */
-        void cancelObserve(std::function<void(const int&)> observeCancellationHandler) { return; }
+        OCStackResult cancelObserve();
 
         /**
         * 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
         */
-        std::string host() const {return m_host;}
-        
+        std::string host() const;
+
         /**
         * Function to get the URI for this resource
-        * @return std::string resource URI 
+        * @return std::string resource URI
         */
-        std::string uri() const {return m_uri;}
+        std::string uri() const;
 
         /**
         * Function to provide ability to check if this resource is observable or not
         * @return bool true indicates resource is observable; false indicates resource is
         *         not observable.
         */
-        bool isObservable() const {return m_isObservable;}
-
-        /*
-        * Allows the server to call notifyObserver
-        * @return bool true indicates this operation was success; false indicates this 
-        * operation failed
-        */
-        //static bool notifyObservers(const std::string& resourceURI); 
+        bool isObservable() const;
 
         // bool whether this is a collection type, and will have children that can be queried
         //bool isCollection() const {return m_isCollection;}
@@ -141,12 +137,13 @@ namespace OC
 
         /*void post(const AttributeMap&, std::function<void(const int&)> attributeHandler);
 
-        NOTE: dont expose the host ip .. so some kind of handle is required 
-        static OCResource::Ptr getResource(const std::string& host, const std::string& resourceURI, const std::string& resourceName, 
+        NOTE: dont expose the host ip .. so some kind of handle is required
+        static OCResource::Ptr getResource(const std::string& host, const std::string& resourceURI, const std::string& resourceName,
             const std::string interfaceName, bool observerable);*/
 
-    
-    private:    
+
+    private:
+        IClientWrapper::Ptr m_clientWrapper;
         std::string m_uri;
         std::string m_host;
         bool m_isObservable;
@@ -155,6 +152,11 @@ namespace OC
         std::vector<std::string> m_interfaces;
         std::vector<std::string> m_children;
         AttributeMap m_attributeMap;
+        OCDoHandle m_observeHandle;
+
+    private:
+        OCResource(IClientWrapper::Ptr 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 5b50f5940a742d770c584e2549e334258eb755f1..f5d497e8acbf66bfa0877b86570e481436855bff 100644 (file)
@@ -26,6 +26,9 @@
 #ifndef __OCRESOURCEREQUEST_H
 #define __OCRESOURCEREQUEST_H
 
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+
 #include "OCApi.h"
 
 namespace OC
@@ -41,7 +44,9 @@ namespace OC
         /**
         *  Virtual destructor 
         */
-        virtual ~OCResourceRequest(void);
+        virtual ~OCResourceRequest(void)
+        {
+        }
 
         /**
         *  Retrieves the type of request string for the entity handler function to operate
@@ -49,13 +54,6 @@ namespace OC
         */
         std::string getRequestType() const {return m_requestType;}
         
-        /**
-        *  Retrieves the payload from the request.
-        *  NOTE: Query parameters are retrived in a separate API (see 'getRequestPayload')
-        *  @return std:string request payload
-        */
-        std::string getRequestPayload() const {return m_requestPayload;}
-
         /**
         *  Retrieves the query parameters from the request
         *  @return std::string query parameters in the request
@@ -63,8 +61,7 @@ namespace OC
         const QueryParamsMap& getQueryParameters() const {return m_queryParameters;}
 
         /**
-        *  Retrieves the request handler flag type. This can be either INIT flag or REQUEST flag 
-        *  OBSERVE flag. 
+        *  Retrieves the request handler flag type. This can be either INIT flag or REQUEST flag or OBSERVE flag. 
         *  NOTE: 
         *  INIT indicates that the vendor's entity handler should go and perform initialization operations
         *  REQUEST indicates that it is a request of certain type (GET/PUT/POST/DELETE) and entity handler needs to perform 
@@ -82,17 +79,57 @@ namespace OC
 
     private:
         std::string m_requestType;
-        std::string m_requestPayload;
         QueryParamsMap m_queryParameters;
         RequestHandlerFlag m_requestHandlerFlag;
         AttributeMap m_attributeMap;
 
-    private:
-        void setRequestType(const std::string& requestType);
-        void setRequestPayload(const std::string& requestPayload);
-        void setQueryParams(QueryParamsMap& queryParams);
-        void setRequestHandlerFlag(RequestHandlerFlag requestHandlerFlag);
-        void setResourceRepresentation(AttributeMap& attributeMap);
+    public:
+        // TODO: This is not a public API for app developers. 
+        // This function will not be exposed in future 
+        void setRequestType(const std::string& requestType)
+        {
+            m_requestType = requestType;
+        }
+
+        // TODO: This is not a public API for app developers. 
+        // This function will not be exposed in future
+        void setPayload(const std::string& requestPayload)
+        {
+            // 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)
+            {
+                std::string name = item.first.data();
+                std::string value = item.second.data();
+
+                AttributeValues values;
+                values.push_back(value);
+
+                m_attributeMap[name] = values;
+            }
+        }
+
+        // TODO: This is not a public API for app developers. 
+        // This function will not be exposed in future
+        void setQueryParams(QueryParamsMap& queryParams)
+        {
+
+        }
+
+        // TODO: This is not a public API for app developers. 
+        // This function will not be exposed in future
+        void setRequestHandlerFlag(RequestHandlerFlag requestHandlerFlag)
+        {
+            m_requestHandlerFlag = requestHandlerFlag;
+        }
     };
 
 } // namespace OC
index 1e34f06354620e416c81e51924590db98178bc1b..2b36632bacea8b1fa8097336fe0c998c75da9ef3 100644 (file)
 #define __OCRESOURCERESPONSE_H
 
 #include "OCApi.h"
+#include <IServerWrapper.h>
+#include <ocstack.h>
+
+using namespace std;
 
 namespace OC
 {
@@ -39,59 +43,68 @@ namespace OC
         typedef std::shared_ptr<OCResourceResponse> Ptr;
 
         /**
-        *  OCResourceResponse Construtor
-        *  @param responseHeaders response header information in a map
-        *  @param eCode HTTP error code for this response.
-        *  @param attributeMap reference to AttributeMap which contains the full attribute representation
-        *  of the resource.
+        *  Default destructor 
         */
-        OCResourceResponse(HeadersMap& responseHeaders, int eCode, AttributeMap& attributeMap) : 
-                m_responseHeaders(responseHeaders), m_HTTPErrorCode(eCode), m_attributeMap(attributeMap) {}
+        OCResourceResponse() {}
 
         /**
         *  Virtual destructor 
         */
-        virtual ~OCResourceResponse(void);
+        virtual ~OCResourceResponse(void) {}
 
         /**
-        *  This API sets the response headers for the response
-        *  @param responseHeaders std::string reference 
-        */
-        void setResponseHeaders(HeadersMap& responseHeaders) { m_responseHeaders = responseHeaders; }
-        
-        /**
-        *  This API sets the HTTP error code for this response
-        *  @param eCode HTTP error code to set
+        *  This API sets the error code for this response
+        *  @param eCode error code to set
         */
-        void setHTTPErrorCode(const int eCode) { m_HTTPErrorCode = eCode; }
+        void setErrorCode(const int eCode) { m_errorCode = eCode; }
 
         /**
         *  API to set the entire resource attribute representation
         *  @param attributeMap reference containing the name value pairs representing the resource's attributes
         */
-        void setResourceRepresentation(AttributeMap& attributeMap) { m_attributeMap = attributeMap; }
+        void setResourceRepresentation(AttributeMap& attributes) { 
 
-    private:
-        HeadersMap m_responseHeaders;
-        int m_HTTPErrorCode; // TODO remove 'HTTP'. It can be any protocol and ISV need not know it 
-        AttributeMap m_attributeMap;
+            // TODO To be refactored
+            ostringstream payload;
+
+            payload << "{\"oc\":{\"payload\":{";
+
+            for(AttributeMap::const_iterator itr = attributes.begin(); itr!= attributes.end(); ++ itr)
+            {
+                if(itr != attributes.begin())
+                {
+                    payload << ',';
+                }
+                // cout << itr->first << ":" <, itr->second.front() << endl;
+                payload << "\""<<itr->first<<"\":" << itr->second.front();
+            }
+            payload << "}}}";
+
+            m_payload = payload.str();
+        }
 
     private:
+        std::string m_payload;
+        int m_errorCode;
+
+    // TODO only stack should have visibility and apps should not
+    public:
 
         /** 
-        * Get response headers
-        */
-        HeadersMap& getResponseHeaders() const; 
-        /** 
-        * Get HTTP status error code 
+        * Get error code 
         */
-        int getHTTPErrorCode() const; 
+        int getErrorCode() const; 
 
         /**
         * Get the resource attribute representation
         */
         AttributeMap& getResourceRepresentation() const; 
+
+        // TODO This should go away & just use getResourceRepresentation 
+        std::string getPayload()
+        {
+            return m_payload;
+        }
     };
 
 } // namespace OC
index f211da8df8eaefe11dc5ae788814fc44784c60d8..644b59fdf1b628acd7c47cd8a19ba4dae6ae46f3 100644 (file)
@@ -29,7 +29,14 @@ namespace OC
     {
     public:
         OutOfProcClientWrapper(PlatformConfig cfg) { }
-       virtual int ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(OCResource::Ptr)>& callback) {return 0;}
+        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(OCDoHandle* handle, const std::string& host, const std::string& uri, std::function<void(const AttributeMap&, 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;}
     };
 }
 
index 3fce1cb059b81fc6e1f65a82056a321e42a66da8..dd1e0d94a9c1ff8d157d6aaaf821ae17ddc428fd 100644 (file)
 
 #include <OCApi.h>
 
-#include <OCReflect.h>
-
-using namespace OC::OCReflect;
-
 namespace OC
 {
     class OutOfProcServerWrapper : public IServerWrapper
@@ -34,12 +30,18 @@ namespace OC
     public:
         OutOfProcServerWrapper(PlatformConfig cfg) {};
 
-        void registerResource( const std::string& resourceURI,
-                                                    const std::string& resourceTypeName,
-                                                    property_binding_vector properties)
+        virtual OCStackResult registerResource(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface,
+                    std::function<void(const OCResourceRequest::Ptr, const OCResourceResponse::Ptr)> entityHandler,
+                    uint8_t resourceProperty)
+
         {
+            // Not implemented
+            return OC_STACK_ERROR;
         }
-
     };
 }
 
index 08c484d0af146b181b2e35572fa25efd4d356c97..30526372b6d0bde5e23ee24c4da580e75e7c1d91 100644 (file)
@@ -29,53 +29,65 @@ namespace OC
     class ResourceInitException : public std::exception
     {
     public:
-        ResourceInitException(bool missingUri, bool missingType, bool missingInterface)
-               : m_missingUri(missingUri), m_missingType(missingType), m_missingInterface(missingInterface)
+        ResourceInitException(bool missingUri, bool missingType, bool missingInterface, bool missingClientWrapper)
+        : m_missingUri(missingUri), m_missingType(missingType), m_missingInterface(missingInterface), m_missingClientWrapper(missingClientWrapper)
         {
         }
-               
-               bool isUriMissing()
-               {
-                       return m_missingUri;
-               }
-               
-               bool isTypeMissing()
-               {
-                       return m_missingType;
-               }
-               
-               bool isInterfaceMissing()
-               {
-                       return m_missingInterface;
-               }
-               
-               std::string Reason()
-               {
-                       std::string ret;
-                       
-                       if(isUriMissing())
-                       {
-                               ret += "Missing URI;";
-                       }
-                       
-                       if(isTypeMissing())
-                       {
-                               ret += "Missing Resource Type;";
-                       }
-                       
-                       if(isInterfaceMissing())
-                       {
-                               ret += "Missing Interface;";
-                       }
-                       
-                       return ret;
-               }
+        
+        bool isClientWrapperMissing() const
+        {
+            return m_missingClientWrapper;
+        }
+
+        bool isUriMissing() const
+        {
+            return m_missingUri;
+        }
+        
+        bool isTypeMissing() const
+        {
+            return m_missingType;
+        }
+        
+        bool isInterfaceMissing() const
+        {
+            return m_missingInterface;
+        }
+        
+        virtual const char* what() noexcept 
+        {
+            std::string ret;
+            
+            if(isUriMissing())
+            {
+                ret += "Missing URI;";
+            }
+            
+            if(isTypeMissing())
+            {
+                ret += "Missing Resource Type;";
+            }
+            
+            if(isInterfaceMissing())
+            {
+                ret += "Missing Interface;";
+            }
+            
+            if(isClientWrapperMissing())
+            {
+                ret += "Missing ClientWrapper;";
+            }
+
+            return ret.c_str();
+        }
 
     private:
+
         bool m_missingUri;
-               bool m_missingType;
-               bool m_missingInterface;
+        bool m_missingType;
+        bool m_missingInterface;
+        bool m_missingClientWrapper;
     };
 }
 
-#endif
\ No newline at end of file
+#endif