CPP Default entity handler functionality and misc fixes.
authorSashi Penta <sashi.kumar.penta@intel.com>
Thu, 21 Aug 2014 00:01:05 +0000 (17:01 -0700)
committerSashi Penta <sashi.kumar.penta@intel.com>
Thu, 21 Aug 2014 02:21:30 +0000 (19:21 -0700)
Patch 1:
Fixed simpleclient to work with Observe, along with JSON representation changes.

Patch 2:
Fixed some stuff in simpleclientserver, and other things.

Patch 3:
C++ change to discover multiple resources on a server

Patch 4:
C++ Default handler functionality.
Fixes in C Stack for Default entity hanlder for C++ stack to work.
Few other misc. fixes.

Patch 5: Changed entityHandler name to EntityHandler.

Added Try/Catch around read_json

Fix for simpleclientserver

Change-Id: I3e2006b73de22567ccb7d770d5843e5a5eebce47

12 files changed:
OCLib/InProcClientWrapper.cpp
OCLib/InProcServerWrapper.cpp
OCLib/OCPlatform.cpp
OCLib/OCUtilities.cpp
csdk/stack/src/occollection.c
csdk/stack/src/ocstack.c
examples/roomclient.cpp
examples/roomserver.cpp
examples/simpleclient.cpp
examples/simpleclientserver.cpp
include/OCResourceResponse.h
makefile

index c82bfa8..be63b91 100644 (file)
@@ -151,8 +151,22 @@ namespace OC
     
             std::stringstream requestStream;
             requestStream << clientResponse->resJSONPayload;
+
+            // TODO this should got logger
+            // std::cout << "Listen: " << clientResponse->resJSONPayload << std::endl;
+
             boost::property_tree::ptree root;
-            boost::property_tree::read_json(requestStream, root);
+
+            try
+            {
+                boost::property_tree::read_json(requestStream, root);
+            }
+            catch(boost::property_tree::json_parser::json_parser_error &e)
+            {
+                std::cout << "read_json failed: "<< e.what() <<std::endl;
+                // TODO: Do we want to handle this somehow? Perhaps we need to log this?
+                return OC_STACK_KEEP_TRANSACTION;
+            }
             
             boost::property_tree::ptree payload = root.get_child("oc", boost::property_tree::ptree());
             
@@ -176,9 +190,6 @@ 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;
 
@@ -352,7 +363,7 @@ namespace OC
         // TODO: in the future the cstack should be combining these two strings!
         ostringstream os;
         os << host << assembleSetResourceUri(uri, queryParams).c_str();
-        //std::cout << "GET URI: " << os.str() << std::endl;
+        std::cout << "GET URI: " << os.str() << std::endl;
         // TODO: end of above
 
         auto cLock = m_csdkLock.lock();
index 90eb46c..e2fc65b 100644 (file)
@@ -48,7 +48,7 @@ void defaultEntityHandler(const OC::OCResourceRequest::Ptr request, const OC::OC
     cout << "\nSomething wrong: We are in default entity handler: " << endl;
 }
 
-OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest ) {
+OCEntityHandlerResult 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;
@@ -103,7 +103,15 @@ 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);
+        if(entityHandlerEntry->second)
+        {
+            entityHandlerEntry->second(pRequest, pResponse);
+        }
+        else
+        {
+            // TODO Logging
+            std::cout << "C stack should not call again for parent resource\n";
+        }
     }
     else {
         std::cout << "No entity handler found."  << endl;
@@ -132,7 +140,7 @@ OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerReq
         if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
         {
             strncpy((char*)entityHandlerRequest->resJSONPayload, payLoad.c_str(), entityHandlerRequest->resJSONPayloadLen);
-            cout << (char*)entityHandlerRequest->resJSONPayload << endl;
+            cout << "Payload: " << (char*)entityHandlerRequest->resJSONPayload << endl;
         }
         else
         {
@@ -223,13 +231,26 @@ namespace OC
         {
             std::lock_guard<std::mutex> lock(*cLock);
 
-            result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+            if(NULL != eHandler)
+            {
+                result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
                             resourceTypeName.c_str(), // const char * resourceTypeName
                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
                             resourceURI.c_str(), // const char * uri
-                            entityHandler, // OCEntityHandler entityHandler
+                            EntityHandler, // OCEntityHandler entityHandler
                             resourceProperties // uint8_t resourceProperties
                             );
+            }
+            else
+            {
+                result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+                            resourceTypeName.c_str(), // const char * resourceTypeName
+                            resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+                            resourceURI.c_str(), // const char * uri
+                            NULL, // OCEntityHandler entityHandler
+                            resourceProperties // uint8_t resourceProperties
+                            );
+            }
 
             if(result != OC_STACK_OK)
             {
index f94fca2..1bb5997 100644 (file)
@@ -182,7 +182,7 @@ namespace OC
         return result;
     }
 
-    OCStackResult bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle)
+    OCStackResult OCPlatform::bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle)
     {
         OCStackResult result = OC_STACK_OK;
 
@@ -197,7 +197,7 @@ namespace OC
         return result;
     }
 
-    OCStackResult bindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
+    OCStackResult OCPlatform::bindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
     {
         OCStackResult result = OC_STACK_OK;
 
index e11c97f..de8f730 100644 (file)
@@ -74,7 +74,7 @@ OC::Utilities::QueryParamsKeyVal OC::Utilities::getQueryParams(const std::string
             break;
         }
 
-        coap_uri_t coapuri = {0};
+        coap_uri_t coapuri = {{0}};
         unsigned char* uristr = reinterpret_cast<unsigned char*>(const_cast<char*>(_uri.c_str()));
 
         if(coap_split_uri(uristr, _uri.length(), &coapuri) < 0)
index df7db4e..9b039bf 100644 (file)
@@ -223,13 +223,19 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
     stackRet = BuildRootResourceJSON(resource, ehRequest);
     if (stackRet == OC_STACK_OK)
     {
+        OCResourceHandle origResourceHandle = ehRequest->resource;
+
         for  (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
         {
             OCResource* temp = resource->rsrcResources[i];
             if (temp)
             {
                 //TODO ("Proper Error handling");
+
+                ehRequest->resource = (OCResourceHandle) temp;
+
                 ehRet = temp->entityHandler(OC_REQUEST_FLAG, ehRequest);
+
                 if(ehRet == OC_EH_OK)
                 {
                     unsigned char* buffer = ehRequest->resJSONPayload;
@@ -239,7 +245,7 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
                     ehRequest->resJSONPayload = buffer;
                     if ( resource->rsrcResources[i+1] && ehRequest->resJSONPayloadLen > sizeof(OC_JSON_SEPARATOR) )
                     {
-                        *buffer = OC_JSON_SEPARATOR;
+                        * buffer = OC_JSON_SEPARATOR;
                         buffer++;
                         ehRequest->resJSONPayload = buffer;
                         ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - 1;
@@ -256,6 +262,8 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
                break;
             }
         }
+
+        ehRequest->resource = origResourceHandle;
     }
     return stackRet;
 }
index baf9b14..3c1ef97 100644 (file)
@@ -73,6 +73,7 @@ OCStackResult HandleStackRequests(OCRequest * request)
     {
         result = BuildJSONResponse(resHandling, resource, request);
     }
+
     return result;
 }
 
index 7fb0eb2..b171f61 100644 (file)
@@ -186,7 +186,6 @@ void getRoomRepresentation(std::shared_ptr<OCResource> resource)
 // Callback to found resources
 void foundResource(std::shared_ptr<OCResource> resource)
 {
-
     if(curResource)
     {
         std::cout << "Found another resource, ignoring"<<std::endl;
@@ -245,8 +244,7 @@ int main(int argc, char* argv[]) {
         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);
+        platform.findResource("", "coap://224.0.1.187/oc/core", &foundResource);
         std::cout<< "Finding Resource... " <<std::endl;
         while(true)
         {
index 8c88aa3..ed217f0 100644 (file)
@@ -91,7 +91,7 @@ public:
         // This will internally create and register the resource.
         OCStackResult result = platform.registerResource(
                                     m_roomHandle, m_roomUri, m_roomType,
-                                    m_roomInterface1, &entityHandlerRoom, 
+                                    m_roomInterface1, NULL, //entityHandlerRoom, 
                                     OC_DISCOVERABLE | OC_OBSERVABLE
                                   );
 
@@ -114,7 +114,7 @@ public:
 
         result = platform.registerResource(
                                     m_lightHandle, m_lightUri, m_lightType,
-                                    m_lightInterface, &entityHandlerLight, 
+                                    m_lightInterface, entityHandlerLight, 
                                     OC_DISCOVERABLE | OC_OBSERVABLE
                                    );
 
@@ -125,7 +125,7 @@ public:
 
         result = platform.registerResource(
                                     m_fanHandle, m_fanUri, m_fanType,
-                                    m_fanInterface, &entityHandlerFan, 
+                                    m_fanInterface, entityHandlerFan, 
                                     OC_DISCOVERABLE | OC_OBSERVABLE
                                    );
 
@@ -134,6 +134,18 @@ public:
             cout << "Resource creation (fan) was unsuccessful\n";
         }
 
+        result = platform.bindResource(m_roomHandle, m_lightHandle);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding fan resource to room was unsuccessful\n";
+        }
+
+        result = platform.bindResource(m_roomHandle, m_fanHandle);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Binding light resource to room was unsuccessful\n";
+        }
+
     }
 
     void setRoomRepresentation(OCRepresentation& rep)
index f525e44..2a4bc51 100644 (file)
@@ -38,10 +38,12 @@ int observe_count()
     return ++oc;
 }
 
-void onObserve(const AttributeMap& attributeMap, const int& eCode, const int& sequenceNumber)
+void onObserve(const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
 {
     if(eCode == SUCCESS_RESPONSE)
     {
+        AttributeMap attributeMap = rep.getAttributeMap();
+
         std::cout << "OBSERVE RESULT:"<<std::endl;
         std::cout << "\tSequenceNumber: "<< sequenceNumber << endl;
         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)
@@ -111,6 +113,15 @@ void onPut(const OCRepresentation& rep, const int eCode)
             }
         }
 
+        if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
+            std::cout << endl << "Observe is used." << endl << endl;
+        else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
+            std::cout << endl << "ObserveAll is used." << endl << endl;
+
+        QueryParamsMap test;
+
+        curResource->observe(OBSERVE_TYPE_TO_USE, test, &onObserve);
+
     }
     else
     {
@@ -209,7 +220,6 @@ void getLightRepresentation(std::shared_ptr<OCResource> resource)
         // Invoke resource's get API with the callback parameter
 
         QueryParamsMap test;
-        test["if"] = BATCH_INTERFACE;
         resource->get(test, &onGet);
     }
 }
index ab6343f..dd5900f 100644 (file)
@@ -25,6 +25,7 @@
 ///
 #include <memory>
 #include <iostream>
+#include <stdexcept>
 #include <condition_variable>
 #include <map>
 #include <vector>
@@ -35,8 +36,13 @@ using namespace OC;
 class ClientWorker
 {
 private:
-    void putResourceInfo(const AttributeMap requestedPut, const AttributeMap attrMap, const int eCode)
+    void putResourceInfo(const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
     {
+       std::cout << "In PutResourceInfo" << std::endl;
+
+       AttributeMap requestedPut = rep.getAttributeMap();
+       AttributeMap attrMap = rep2.getAttributeMap();
+
        std::cout <<"Clientside Put response to get was: "<<std::endl;
        std::cout <<"ErrorCode: "<<eCode <<std::endl;
 
@@ -71,8 +77,10 @@ private:
        }
     }
 
-    void getResourceInfo(const AttributeMap attrMap, const int eCode)
+    void getResourceInfo(const OCRepresentation rep, const int eCode)
     {
+        std::cout << "In getResourceInfo" << std::endl;
+        AttributeMap attrMap = rep.getAttributeMap();
 
         std::cout<<"Clientside response to get was: "<<std::endl;
         std::cout<<"Error Code: "<<eCode<<std::endl;
@@ -93,16 +101,21 @@ private:
             }
 
             std::cout << "Doing a put on q/foo" <<std::endl;
-            AttributeMap attrMap2(attrMap);
-            attrMap2["isFoo"][0] ="false";
-            attrMap2["barCount"][0]="211";
+            OCRepresentation rep2(rep);
+            AttributeMap attrMap2 = rep2.getAttributeMap(); 
+
+            attrMap2["isFoo"].push_back("false");
+            attrMap2["barCount"].push_back("211");
 
-            m_resource->put(attrMap2, QueryParamsMap(), std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::putResourceInfo, this, attrMap2, std::placeholders::_1, std::placeholders::_2)));
+            rep2.setAttributeMap(attrMap2);
+
+            m_resource->put(rep2, QueryParamsMap(), std::function<void(const OCRepresentation, const int)>(std::bind(&ClientWorker::putResourceInfo, this, rep2, std::placeholders::_1, std::placeholders::_2)));
         }
     }
 
     void foundResource(std::shared_ptr<OCResource> resource)
     {    
+        std::cout << "In foundResource" << std::endl;
         if(resource && resource->uri() == "/q/foo")
         {
             {
@@ -121,7 +134,7 @@ private:
 
             std::cout<<"Doing a get on q/foo."<<std::endl;
             QueryParamsMap test;
-            resource->get(test, std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
+            resource->get(test, std::function<void(const OCRepresentation, const int)>(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
         } 
     }
 
@@ -174,8 +187,10 @@ struct FooResource
         return true;
     }
 
-    void getRepresentation(AttributeMap& attributeMap)
+    void getRepresentation(OCRepresentation& rep)
     {
+        AttributeMap attributeMap;
+
         AttributeValues isFooVal;
         isFooVal.push_back(m_isFoo ? "true" : "false");
 
@@ -184,14 +199,26 @@ struct FooResource
 
         attributeMap["isFoo"] = isFooVal;
         attributeMap["barCount"] = barCt;
+        
+        rep.setAttributeMap(attributeMap);
     }
 
-    void setRepresentation(const AttributeMap& attributeMap)
+    void setRepresentation(OCRepresentation& rep)
     {
-        auto fooVector = attributeMap.at("isFoo");
-        m_isFoo = fooVector[0] == "true";
-        auto barVector = attributeMap.at("barCount");
-        m_barCount = std::stoi(barVector[0]);
+        AttributeMap attributeMap(rep.getAttributeMap());
+    
+        try
+         {
+            auto fooVector = attributeMap.at("isFoo");
+            m_isFoo = fooVector[0] == "true";
+            auto barVector = attributeMap.at("barCount");
+            m_barCount = std::stoi(barVector[0]);
+            rep.setAttributeMap(attributeMap);
+         }
+        catch(std::out_of_range& e)
+         {
+            std::cerr << "setRepresentation(): unable to look up values in attributeMap: " << e.what() << '\n';
+         }
     }
 
     void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
@@ -210,27 +237,28 @@ struct FooResource
                 {
                     std::cout<<"\t\t\trequestType : GET"<<std::endl;
 
-                    AttributeMap attrs;
-                    getRepresentation(attrs);
+                    OCRepresentation rep;
+                    getRepresentation(rep);
 
                     if(response)
                     {
                         response->setErrorCode(200);
-                        response->setResourceRepresentation(attrs);
+                        response->setResourceRepresentation(rep, "");
                     }
                 }
                 else if (request->getRequestType() == "PUT")
                 {
                     std::cout<<"\t\t\trequestType : PUT"<<std::endl;
 
-                    setRepresentation(request->getAttributeRepresentation());
+                    OCRepresentation rep = request->getResourceRepresentation();
+                    setRepresentation(rep);
 
                     if(response)
                     {
                         response->setErrorCode(200);
-                        AttributeMap attrs;
-                        getRepresentation(attrs);
-                        response->setResourceRepresentation(attrs);
+                        OCRepresentation rep;
+                        getRepresentation(rep);
+                        response->setResourceRepresentation(rep, "");
                     }
                 }
                 else
index 5c4c33f..bdcc288 100644 (file)
@@ -172,7 +172,7 @@ namespace OC
                 payload << "\""<<itr->first<<"\":" << itr->second.front();
             }
 
-            payload << "}},";
+            payload << "}}";
 
             // Children stuff
             std::vector<OCRepresentation> children = rep.getChildren();
@@ -232,16 +232,13 @@ namespace OC
             payload << "\"" ;
             payload << rep.getUri();
             payload << "\"" ;
-            payload << "},";
+            payload << "}";
 
             std::vector<OCRepresentation> children = rep.getChildren();
             
             for(auto oitr = children.begin(); oitr != children.end(); ++oitr)
             {
-                if(oitr != children.begin())
-                {
-                    payload << ',';
-                }
+                payload << ',';
 
                 payload << "{";
                 
index 4c4c489..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 roomserver roomclient
+.PHONY: prep_dirs c_sdk simpleserver simpleclient simpleclientserver roomserver roomclient
 
 all:   .PHONY