Updated Makefile to support different build targets.
authorJesse Williamson <jesse.f.williamson@intel.com>
Tue, 26 Aug 2014 19:49:54 +0000 (12:49 -0700)
committerJesse Williamson <jesse.f.williamson@intel.com>
Fri, 29 Aug 2014 15:53:55 +0000 (08:53 -0700)
Removed delegating ctors (work-around non-conforming compiler).
Configuration requires explicit ctor.
Restructured client/server program; review fixes; hopefully
extricated from the dangerous world of b0rked commits.

Change-Id: I68462b3d0306d969ba92b5e7affb515aebe03be3

22 files changed:
OCLib/InProcClientWrapper.cpp
OCLib/OCPlatform.cpp
examples/makefile
examples/ocicuc/Makefile
examples/ocicuc/Makefile.debug [deleted file]
examples/ocicuc/client.cpp
examples/ocicuc/demo_client.hpp [new file with mode: 0644]
examples/ocicuc/driver.cpp
examples/ocicuc/light_resource.cpp [new file with mode: 0644]
examples/ocicuc/light_resource.hpp [new file with mode: 0644]
examples/ocicuc/server.cpp
examples/ocicuc/utility.cpp [new file with mode: 0644]
examples/ocicuc/utility.hpp [new file with mode: 0644]
examples/roomclient.cpp
examples/roomserver.cpp
examples/simpleclient.cpp
examples/simpleclientserver.cpp
examples/simpleserver.cpp
include/InProcClientWrapper.h
include/OCApi.h
include/OCPlatform.h
makefile

index 8ba56c3..1bf1106 100644 (file)
@@ -29,13 +29,14 @@ using namespace std;
 namespace OC
 {
     InProcClientWrapper::InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg)
-            :m_threadRun(false), m_csdkLock(csdkLock)
+            : m_threadRun(false), m_csdkLock(csdkLock),
+              m_cfg { cfg }
     {
         // if the config type is server, we ought to never get called.  If the config type
         // is both, we count on the server to run the thread and do the initialize
-        if(cfg.mode == ModeType::Client)
+        if(m_cfg.mode == ModeType::Client)
         {
-            OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, OC_CLIENT);
+            OCStackResult result = OCInit(m_cfg.ipAddress.c_str(), m_cfg.port, OC_CLIENT);
 
             if(OC_STACK_OK != result)
             {
@@ -219,7 +220,11 @@ namespace OC
         {
             std::lock_guard<std::mutex> lock(*cLock);
             OCDoHandle handle;
-            result = OCDoResource(&handle, OC_REST_GET, resourceType.c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+            result = OCDoResource(&handle, OC_REST_GET, 
+                                  resourceType.c_str(), 
+                                  nullptr, nullptr, 
+                                  static_cast<OCQualityOfService>(m_cfg.QoS), 
+                                  cbdata);
         }
         else
         {
@@ -378,8 +383,10 @@ namespace OC
         {
             std::lock_guard<std::mutex> lock(*cLock);
             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);
+            result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(), 
+                                  nullptr, nullptr, 
+                                  static_cast<OCQualityOfService>(m_cfg.QoS), 
+                                  cbdata);
         }
         else
         {
@@ -472,9 +479,11 @@ namespace OC
         {
             std::lock_guard<std::mutex> lock(*cLock);
             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);
+            result = OCDoResource(&handle, OC_REST_PUT, 
+                                  os.str().c_str(), nullptr, 
+                                  assembleSetResourcePayload(attributes).c_str(), 
+                                  static_cast<OCQualityOfService>(m_cfg.QoS), 
+                                  cbdata);
         }
         else
         {
@@ -537,8 +546,11 @@ namespace OC
         if(cLock)
         {
             std::lock_guard<std::mutex> lock(*cLock);
-            //result = OCDoResource(handle, OC_REST_OBSERVE,  uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
-            result = OCDoResource(handle, method, os.str().c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
+            result = OCDoResource(handle, method, 
+                                  os.str().c_str(), nullptr, 
+                                  nullptr, 
+                                  static_cast<OCQualityOfService>(m_cfg.QoS), 
+                                  cbdata);
         }
         else
         {
index 4eb91cd..1007fa6 100644 (file)
@@ -38,15 +38,14 @@ namespace OC
 {
     // Constructor. Internally calls private init function
     OCPlatform::OCPlatform(const PlatformConfig& config)
+     : m_cfg(config)
     {
-        init(config);
+        init(m_cfg);
     }
 
-    // Destructor
     OCPlatform::~OCPlatform(void)
     {
         std::cout << "platform destructor called" << std::endl;
-        cleanup();
     }
 
     OCStackResult OCPlatform::notifyObservers(OCResourceHandle resourceHandle)
@@ -78,19 +77,6 @@ namespace OC
         }
     }
 
-    void OCPlatform::cleanup()
-    {
-        if(m_server)
-        {
-            m_server.reset();
-        }
-
-        if(m_client)
-        {
-            m_client.reset();
-        }
-    }
-
     OCResource::Ptr OCPlatform::constructResourceObject(const std::string& host, const std::string& uri,
                 bool isObservable, const std::vector<std::string>& resourceTypes,
                 const std::vector<std::string>& interfaces)
index 3ab1dcc..da740ff 100644 (file)
@@ -5,9 +5,9 @@ CXX           := g++
 #CXX     := clang
 OUT_DIR          := $(PWD)/$(BUILD)
 
-CXX_FLAGS.debug     := -g3 -std=c++0x -Wall -pthread
+CXX_FLAGS.debug     := -O0 -g3 -std=c++0x -Wall -pthread
 
-CXX_FLAGS.release   := -std=c++0x -Wall -pthread
+CXX_FLAGS.release   := -O3 -std=c++0x -Wall -pthread 
 
 CXX_INC          := -I../include/
 CXX_INC          += -I../csdk/stack/include
@@ -17,7 +17,7 @@ CXX_INC         += -I../csdk/logger/include
 CXX_INC          += -I../csdk/libcoap
 
 # Force metatargets to build:
-.PHONY: prep_dirs simpleserver simpleclient simpleclientserver roomserver roomclient
+.PHONY: prep_dirs simpleserver simpleclient simpleclientserver roomserver roomclient ocicuc
 
 all: .PHONY
 
@@ -39,6 +39,10 @@ roomserver: roomserver.cpp
 roomclient: roomclient.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ roomclient.cpp $(CXX_INC) ../$(BUILD)/obj/OCLib.a ../csdk/$(BUILD)/liboctbstack.a
 
+ocicuc:
+       cd ocicuc && $(MAKE)
+
 clean: 
        rm -rf $(OUT_DIR)/*
+       cd ocicuc && $(MAKE) clean
 
index b8bcf2d..bc79d11 100644 (file)
@@ -1,8 +1,18 @@
+# override with `make BUILD=release`
+# default to release build
+BUILD    := release
+CXX          := g++
+#CXX     := clang
+OUT_DIR          := $(PWD)/$(BUILD)
+
+CXX_FLAGS.debug     := -O0 -g3 -std=c++0x -Wall -pthread
+
+CXX_FLAGS.release   := -O3 -std=c++0x -Wall -pthread 
 
 # Please note that many of these settings are unused at the moment on account of the rush to get this out the door-- look carefully
-# at the actual commands to see which are relevant:
+# at the actual commands to see which are relevant (this makefile needs to be rewritten):
 
-OC_CSDK=../../../ccf-resource/csdk
+OC_CSDK=../../ccf-resource/csdk
 OC_STACK=$(OC_CSDK)/stack
 OC_OCCOAP=$(OC_CSDK)/occoap
 OC_SOCKET=$(OC_CSDK)/ocsocket
@@ -11,13 +21,14 @@ OC_LOGGER=$(OC_CSDK)/logger
 OC_LIB=$(OC_CSDK)/liboctbstack.a
 
 OCLIB=../..
-OCLIB_LIB=../../release/obj/OCLib.a #$(OCLIB)/release/obj/OCLib.a
+OCLIB_LIB=$(OCLIB)/$(BUILD)/obj/OCLib.a #$(OCLIB)/release/obj/OCLib.a
 
 BOOST_BASE=/usr/local/boost
 BOOST_INC=$(BOOST_BASE)/include
 BOOST_LIB=$(BOOST_BASE)/lib
 
-CXX_CC=g++ -std=c++0x -ggdb
+CXX_CC=g++ -std=c++0x -O3
+#CXX_CC=g++ -std=c++0x -O0 -ggdb # debug
 #CXX_CC=clang -std=c++0x -lstdc++
 
 CXX_FLAGS=-Wall 
@@ -29,26 +40,28 @@ CXX_LIBS=-L$(BOOST_LIB) $(OC_LIB) $(OCLIB_LIB) -lpthread -lboost_program_options
 
 CXX=$(CXX_CC) $(CXX_FLAGS) $(CXX_INC) $(CXX_LIBS)
 
-.PHONY: init driver client server
+.PHONY: init driver resources client server
 
-all: init driver client server
-       @echo Remember to \"export LD_LIBRARY_PATH=$(BOOST_LIB)\:\$$LD_LIBRARY_PATH\"
+all: init driver resources client server 
        
 init:
        rm -f *.o ./client ./server
 
 driver:
-       $(CXX_CC) -Wall -pthread  -c driver.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ 
+       $(CXX_CC) -Wall -pthread  -c driver.cpp utility.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ 
+
+resources:
+       $(CXX_CC) -Wall -pthread -c light_resource.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ 
 
 client:
        $(CXX_CC) -pthread  -c client.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ -I/usr/local/include $(CXX_INC) $(CXX_FLAGS)
 
-       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o client driver.o client.o ../../release/obj/OCLib.a ../../csdk/release/liboctbstack.a -lboost_program_options $(CXX_INC) $(CXX_FLAGS) 
+       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o client driver.o utility.o client.o ../../$(BUILD)/obj/OCLib.a ../../csdk/$(BUILD)/liboctbstack.a -lboost_program_options $(CXX_INC) $(CXX_FLAGS) 
 
-server:
+server: resources
        $(CXX_CC) -pthread  -c server.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ -I/usr/local/include $(CXX_INC) 
 
-       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o server driver.o server.o ../../release/obj/OCLib.a ../../csdk/release/liboctbstack.a -lboost_program_options $(CXX_INC) 
+       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o server driver.o utility.o server.o light_resource.o ../../$(BUILD)/obj/OCLib.a ../../csdk/$(BUILD)/liboctbstack.a -lboost_program_options $(CXX_INC) 
 
 clean:
-       rm -f server.o client.o driver.o server client
+       rm -f server.o client.o driver.o utility.o light_resource.o server client
diff --git a/examples/ocicuc/Makefile.debug b/examples/ocicuc/Makefile.debug
deleted file mode 100644 (file)
index 8567182..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-OC_CSDK=../../../ccf-resource/csdk
-OC_STACK=$(OC_CSDK)/stack
-OC_OCCOAP=$(OC_CSDK)/occoap
-OC_SOCKET=$(OC_CSDK)/ocsocket
-OC_RANDOM=$(OC_CSDK)/ocrandom
-OC_LOGGER=$(OC_CSDK)/logger
-OC_LIB=$(OC_CSDK)/liboctbstack.a
-
-OCLIB=../..
-OCLIB_LIB=../../debug/obj/OCLib.a #$(OCLIB)/debug/obj/OCLib.a
-
-BOOST_BASE=/usr/local/boost
-BOOST_INC=$(BOOST_BASE)/include
-BOOST_LIB=$(BOOST_BASE)/lib
-
-
-CXX_CC=g++ -std=c++0x
-#CXX_CC=clang -std=c++0x -lstdc++
-
-CXX_FLAGS=-Wall -O0 -ggdb
-
-# There's probably nicer Makefile magic for this, but hopefully it will suffice:
-CXX_INC=-I$(OCLIB)/include -I$(OC_STACK)/include -I$(OC_SOCKET)/include -I$(OC_RANDOM)/include -I$(OC_LOGGER)/include -I$(OC_OCCOAP)/include -I$(BOOST_INC)
-
-CXX_LIBS=-L$(BOOST_LIB) $(OC_LIB) $(OCLIB_LIB) -lpthread -lboost_program_options
-
-CXX=$(CXX_CC) $(CXX_FLAGS) $(CXX_INC) $(CXX_LIBS)
-
-.PHONY: init driver client server
-
-all: init driver client server
-       @echo Remember to \"export LD_LIBRARY_PATH=$(BOOST_LIB)\:\$$LD_LIBRARY_PATH\"
-       
-init:
-       rm -f \*\.o ./client ./server
-
-driver:
-       $(CXX_CC) -Wall -pthread  -c driver.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ -O0 -g
-
-client:
-       $(CXX_CC) -pthread  -c client.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ -I/usr/local/include $(CXX_INC) $(CXX_FLAGS)
-
-       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o client driver.o client.o ../../debug/obj/OCLib.a ../../csdk/liboctbstack.a -lboost_program_options $(CXX_INC) $(CXX_FLAGS) -O0 -g
-
-server:
-       $(CXX_CC) -pthread  -c server.cpp -I../../include/ -I../../csdk/stack/include -I../../csdk/ocsocket/include -I../../csdk/ocrandom/include -I../../csdk/logger/include -I/usr/local/include/boost/ -I/usr/local/include $(CXX_INC) -O0 -g
-
-       $(CXX_CC) -std=c++0x -Wall -L/usr/local/boost/lib/ -I/usr/local/boost/include -pthread  -o server driver.o server.o ../../debug/obj/OCLib.a ../../csdk/liboctbstack.a -lboost_program_options $(CXX_INC) -O0 -g
-
index e747898..b96be2d 100644 (file)
@@ -33,6 +33,9 @@
 #include "OCPlatform.h"
 
 #include "exec.hpp"
+#include "utility.hpp"
+
+#include "demo_client.hpp"
 
 namespace Intel { namespace OCDemo {
 
@@ -57,174 +60,6 @@ auto make_description()
  return desc;
 }
 
-// Prettyprinters:
-std::ostream& operator<<(std::ostream& os, const OC::AttributeMap& attrs)
-{
- for(const auto& attr : attrs)
-  {
-        os << "Attribute \"" << attr.first << "\": ";
-
-        for(const auto& val : attr.second)
-         os << val << "; ";
-  }
-
- return os;
-}
-
-int observe_count()
-{
- static unsigned long long oc = 0;
- return ++oc;
-}
-
-/* Helpers for measuring request times: */
-typedef std::pair< 
-                    std::chrono::time_point<std::chrono::high_resolution_clock>, 
-                    std::chrono::time_point<std::chrono::high_resolution_clock> 
-                 > clock_interval;
-
-struct call_times
-{
- static map<string, clock_interval> timings;
-
- void reset(const std::string& entry) { timings[entry] = make_pair(chrono::high_resolution_clock::now(), chrono::high_resolution_clock::time_point()); }
-
- void mark(const std::string& name)
- {
-    auto e = timings.find(name);
-
-    if(timings.end() == e)
-     {
-        reset(name);
-        return;
-     }
-
-    auto& tp = (*e).second;
-
-    if(tp.first > tp.second)
-     timings[name].second = chrono::high_resolution_clock::now();
-  }
-
-  void report()
-  {
-    cout << "Time marks:\n";
-
-    for_each(begin(timings), end(timings), [](const std::pair<std::string, clock_interval>& tm) -> void {
-        using namespace std::chrono;
-
-    const std::string& name     { tm.first };
-
-    const std::chrono::time_point<std::chrono::high_resolution_clock>& request_time    { tm.second.first };
-    const std::chrono::time_point<std::chrono::high_resolution_clock>& response_time   { tm.second.second };
-
-    cout << '\t' << name << ": ";
-
-    if(request_time > response_time)
-     {
-        cout << "<waiting>\n";
-        return;
-     }
-
-    auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(response_time - request_time).count();
-    cout << elapsed_ms << "ms (";
-
-    auto elapsed_us = std::chrono::duration_cast<std::chrono::microseconds>(response_time - request_time).count();
-    cout << elapsed_us << "us)\n";
-   });
-  }
-
-  void report_and_reset(const string& name)
-  {
-       mark(name), report(), reset(name);
-  }
-
-} call_timer;
-
-map<string, clock_interval> call_times::timings;
-
-class resource_handler;
-
-class resource_handle
-{
- friend class resource_handler;
- private:
- const std::string                     URI;
- std::shared_ptr<OC::OCResource>       resource;
-
- public:
- resource_handle(const std::string& URI_, std::shared_ptr<OC::OCResource> resource_)
-  : URI(URI_),
-    resource(resource_)
- {}
-
- resource_handle(const std::string& URI_)
-  : resource_handle(URI_, nullptr)
- {}
-
- // Callbacks (note that the signature after binding will match exactly:
- private:
- void onFoundResource(std::shared_ptr<OC::OCResource> in_resource);
- void onResourceGet(OC::OCRepresentation rep, const int error_code);
- void onResourcePut(const OC::OCRepresentation rep, const int error_code);
- void onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number);
-};
-
-class resource_handler
-{
- OC::OCPlatform& platform;
-
- static std::vector<std::shared_ptr<resource_handle>> resources;    // URI -> Maybe resource
-
- public:
- resource_handler(OC::OCPlatform& platform_, const std::vector<std::string>& resource_URIs_);
- resource_handler(OC::OCPlatform& platform_);
-
- public:
- bool has(const std::string& URI)
- {
-    for(const auto& r : resources)
-     {
-      if(URI == r->URI)
-       return true;
-     }
-
-    return false;
- }
-
- void add(const std::string& URI)
- {
-    if(!has(URI))
-     resources.emplace_back(std::make_shared<resource_handle>(URI));
- }
-
- void find_resources()
- {
-        for(const auto& resource : resources)
-         {
-                std::cout << "* Finding resources \"" << resource->URI << "\".\n";
-
-                call_timer.mark("find_resources");
-
-                platform.findResource("", resource->URI, 
-                                      std::bind(&resource_handle::onFoundResource, resource, std::placeholders::_1));
-         } 
- }
-};
-
-std::vector<std::shared_ptr<resource_handle>> resource_handler::resources;
-
-resource_handler::resource_handler(OC::OCPlatform& platform_, const std::vector<std::string>& resource_URIs)
- : platform(platform_)
-{
- for(const auto& URI : resource_URIs)
-  add(URI);
-}
-
-resource_handler::resource_handler(OC::OCPlatform& platform_)
-  : resource_handler::resource_handler(platform_, {})
-{}
-
 int exec(const boost::program_options::variables_map& vm)
 {
  using namespace std;
@@ -233,7 +68,8 @@ int exec(const boost::program_options::variables_map& vm)
                           OC::ServiceType::InProc,              // in-process server
                           OC::ModeType::Client,                 // client mode
                           vm["host_ip"].as<string>(),           // host
-                          vm["host_port"].as<uint16_t>()        // port
+                          vm["host_port"].as<uint16_t>(),       // port
+                          OC::QualityOfService::NonConfirmable 
                         });
 
  vector<string> resource_URIs;
@@ -271,7 +107,7 @@ int exec(const boost::program_options::variables_map& vm)
  for(const auto& resource_URI : resource_URIs)
   cout << resource_URI << '\n';
 
- resource_handler resources(platform, resource_URIs);
Intel::OCDemo::client::resource_handler resources(platform, resource_URIs);
 
  // Register callbacks and wait for resources:
  resources.find_resources();
@@ -283,139 +119,5 @@ int exec(const boost::program_options::variables_map& vm)
  return 0;
 }
 
-void resource_handle::onFoundResource(std::shared_ptr<OC::OCResource> in_resource)
-{
- using std::cout;
-
- cout << "* onFoundResource():\n";
-
- try
-  {
-       if(nullptr == in_resource)
-        throw OC::OCException("invalid resource passed to client callback");
-
-       call_timer.report_and_reset("find_resources");
-
-       // Now, fixup our own representation ptr:
-       resource = in_resource;
-
-       /* Note: You can combine the host and URI to get a unique identifier, for
-       example to filter out events you aren't interested in. Here, we just report the
-       data: */
-       cout << "resource URI: " << resource->uri() << "; "
-            << "host address: " << resource->host() << '\n';
-
-       call_timer.mark("get_resource");
-
-       OC::QueryParamsMap qpm;
-
-       resource->get(qpm, std::bind(&resource_handle::onResourceGet, this, 
-                                    std::placeholders::_1, std::placeholders::_2));
-  }
- catch(OC::OCException& e)
-  {
-        std::cerr << "onFoundResource(): exception " << e.reason() << ": " << e.what() << '\n';
-  }
- catch(std::exception& e)
-  {
-        std::cerr << "onFoundResource(): exception: " << e.what() << '\n';
-  }
-}
-
-void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int error_code)
-{
- using std::cout;
-
- cout << "onResourceGet():\n";
-
- call_timer.report_and_reset("get_resource");
-
- if(error_code)
-  {
-        std::cerr << "onResourceGet(): error: " << error_code << '\n';
-        return;
-  }
-
- if(nullptr == resource)
-  {
-        std::cerr << "onResourceGet(): empty resource pointer.\n";
-        return;
-  }
-
- std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
-
- // Now, make a change to the light representation (replacing, rather than parsing): 
- OC::AttributeMap attrs {
-                         { "state", { "true" } },
-                         { "power", { "10" } }
-                        };
-
- std::cout << "output attributes:\n" << attrs << '\n';
-
- call_timer.mark("put_resource");
-
- OC::OCRepresentation out_rep;
- out_rep.setAttributeMap(attrs); 
- resource->put(out_rep, OC::QueryParamsMap(), 
-               std::bind(&resource_handle::onResourcePut, this, std::placeholders::_1, std::placeholders::_2));
-}
-
-void resource_handle::onResourcePut(const OC::OCRepresentation rep, const int error_code)
-{
- std::cout << "onResourcePut():\n";
-
- call_timer.report_and_reset("put_resource");
-
- if(0 != error_code)
-  {
-        std::ostringstream os;
-
-        os << "onResourcePut(): error code " << error_code << " from server response.";
-
-        throw OC::OCException(os.str());
-  }
-
- std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
-
- call_timer.mark("observe_resource");
-
- // Start an observer:
- resource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
-                    std::bind(&resource_handle::onObserve, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
-}
-
-void resource_handle::onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
-{
- if(0 != error_code)
-  {
-    std::ostringstream os;
-    os << "onObserve(): error " << error_code << " from callback.\n";
-    throw OC::OCException(os.str());
-  }
-
- std::cout << "onObserve(): sequence number: " << sequence_number << ":\n";
-
- call_timer.report_and_reset("observe_resource");
-
- std::cout << rep.getAttributeMap() << '\n';
-
- const auto oc = observe_count();
-
- std::cout << "onObserve(): observation count is: " << oc << '\n';
-
- // We don't want to be observed forever for purposes of this demo:
- if(10 <= oc)
-  {
-    std::cout << "onObserve(): cancelling observation.\n";
-
-    const auto result = resource->cancelObserve();
-
-    std::cout << "onObserve(): result of cancellation: " << result << ".\n";
-    
-    this_thread::sleep_for(chrono::seconds(10));
-  }
-}
-
 }} // namespace Intel::OCDemo
 
diff --git a/examples/ocicuc/demo_client.hpp b/examples/ocicuc/demo_client.hpp
new file mode 100644 (file)
index 0000000..d6aad00
--- /dev/null
@@ -0,0 +1,225 @@
+
+/* Example client program (this is not a library header, don't include it in random programs): */
+
+namespace Intel { namespace OCDemo { namespace client {
+
+// Although not "done" here, this could be expanded into an interface to handle any sort of
+// resource:
+class resource_handle
+{
+ friend class resource_handler;
+ private:
+ const std::string                     URI;
+ std::shared_ptr<OC::OCResource>       resource;
+
+ public:
+ resource_handle(const std::string& URI_, std::shared_ptr<OC::OCResource> resource_)
+  : URI(URI_),
+    resource(resource_)
+ {}
+
+ resource_handle(const std::string& URI_)
+  : URI(URI_)
+ {}
+
+ // Callbacks (note that the signature after binding will match exactly:
+ private:
+ void onFoundResource(std::shared_ptr<OC::OCResource> in_resource);
+ void onResourceGet(OC::OCRepresentation rep, const int error_code);
+ void onResourcePut(const OC::OCRepresentation rep, const int error_code);
+ void onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number);
+};
+
+class resource_handler
+{
+ OC::OCPlatform& platform;
+
+ static std::vector<std::shared_ptr<resource_handle>> resources;    // URI -> Maybe resource
+
+ public:
+ resource_handler(OC::OCPlatform& platform_, const std::vector<std::string>& resource_URIs_);
+ resource_handler(OC::OCPlatform& platform_);
+
+ public:
+ bool has(const std::string& URI)
+ {
+    for(const auto& r : resources)
+     {
+      if(URI == r->URI)
+       return true;
+     }
+
+    return false;
+ }
+
+ void add(const std::string& URI)
+ {
+    if(!has(URI))
+     resources.emplace_back(std::make_shared<resource_handle>(URI));
+ }
+
+ void find_resources()
+ {
+        for(const auto& resource : resources)
+         {
+                std::cout << "* Finding resources \"" << resource->URI << "\".\n";
+
+                call_timer.mark("find_resources");
+
+                platform.findResource("", resource->URI, 
+                                      std::bind(&resource_handle::onFoundResource, resource, std::placeholders::_1));
+         } 
+ }
+};
+
+std::vector<std::shared_ptr<resource_handle>> resource_handler::resources;
+
+resource_handler::resource_handler(OC::OCPlatform& platform_, const std::vector<std::string>& resource_URIs)
+ : platform(platform_)
+{
+ for(const auto& URI : resource_URIs)
+  add(URI); 
+}
+
+resource_handler::resource_handler(OC::OCPlatform& platform_)
+  : platform(platform_)
+{}
+
+void resource_handle::onFoundResource(std::shared_ptr<OC::OCResource> in_resource)
+{
+ using std::cout;
+
+ cout << "* onFoundResource():\n";
+
+ try
+  {
+       if(nullptr == in_resource)
+        throw OC::OCException("invalid resource passed to client callback");
+
+       call_timer.report_and_reset("find_resources");
+
+       // Now, fixup our own representation ptr:
+       resource = in_resource;
+
+       /* Note: You can combine the host and URI to get a unique identifier, for
+       example to filter out events you aren't interested in. Here, we just report the
+       data: */
+       cout << "resource URI: " << resource->uri() << "; "
+            << "host address: " << resource->host() << '\n';
+
+       call_timer.mark("get_resource");
+
+       OC::QueryParamsMap qpm;
+
+       resource->get(qpm, std::bind(&resource_handle::onResourceGet, this, 
+                                    std::placeholders::_1, std::placeholders::_2));
+  }
+ catch(OC::OCException& e)
+  {
+        std::cerr << "onFoundResource(): exception " << e.reason() << ": " << e.what() << '\n';
+  }
+ catch(std::exception& e)
+  {
+        std::cerr << "onFoundResource(): exception: " << e.what() << '\n';
+  }
+}
+
+void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int error_code)
+{
+ using std::cout;
+
+ cout << "onResourceGet():\n";
+
+ call_timer.report_and_reset("get_resource");
+
+ if(error_code)
+  {
+        std::cerr << "onResourceGet(): error: " << error_code << '\n';
+        return;
+  }
+
+ if(nullptr == resource)
+  {
+        std::cerr << "onResourceGet(): empty resource pointer.\n";
+        return;
+  }
+
+ std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
+
+ // Now, make a change to the light representation (replacing, rather than parsing): 
+ OC::AttributeMap attrs {
+                         { "state", { "true" } },
+                         { "power", { "10" } }
+                        };
+
+ std::cout << "output attributes:\n" << attrs << '\n';
+
+ call_timer.mark("put_resource");
+
+ OC::OCRepresentation out_rep;
+ out_rep.setAttributeMap(attrs); 
+ resource->put(out_rep, OC::QueryParamsMap(), 
+               std::bind(&resource_handle::onResourcePut, this, std::placeholders::_1, std::placeholders::_2));
+}
+
+void resource_handle::onResourcePut(const OC::OCRepresentation rep, const int error_code)
+{
+ std::cout << "onResourcePut():\n";
+
+ call_timer.report_and_reset("put_resource");
+
+ if(0 != error_code)
+  {
+        std::ostringstream os;
+
+        os << "onResourcePut(): error code " << error_code << " from server response.";
+
+        throw OC::OCException(os.str());
+  }
+
+ std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
+
+ call_timer.mark("observe_resource");
+
+ // Start an observer:
+ resource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
+                    std::bind(&resource_handle::onObserve, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+}
+
+void resource_handle::onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
+{
+ if(0 != error_code)
+  {
+    std::ostringstream os;
+    os << "onObserve(): error " << error_code << " from callback.\n";
+    throw OC::OCException(os.str());
+  }
+
+ std::cout << "onObserve(): sequence number: " << sequence_number << ":\n";
+
+ call_timer.report_and_reset("observe_resource");
+
+ std::cout << rep.getAttributeMap() << '\n';
+
+ const auto oc = observe_count();
+
+ std::cout << "onObserve(): observation count is: " << oc << '\n';
+
+ // We don't want to be observed forever for purposes of this demo:
+ if(10 <= oc)
+  {
+    std::cout << "onObserve(): cancelling observation.\n";
+
+    const auto result = resource->cancelObserve();
+
+    std::cout << "onObserve(): result of cancellation: " << result << ".\n";
+    
+    this_thread::sleep_for(chrono::seconds(10));
+  }
+}
+
+}}} // namespace Intel::OCDemo::client
+
+
index 218f9d0..9173224 100644 (file)
@@ -24,7 +24,6 @@ auto parse_options(boost::program_options::options_description& desc, int argc,
  po::store(po::command_line_parser(argc,argv).options(desc).positional(popts).run(), 
            vm);
 
- // JFW: po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);
 
  return vm;
diff --git a/examples/ocicuc/light_resource.cpp b/examples/ocicuc/light_resource.cpp
new file mode 100644 (file)
index 0000000..56a2a7f
--- /dev/null
@@ -0,0 +1,207 @@
+#include "light_resource.hpp"
+
+namespace Intel { namespace OCDemo {
+
+std::atomic<bool> LightResource::shutdown_flag(false);
+std::thread LightResource::observe_thread;
+
+void LightResource::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 LightResource::getRepresentation(AttributeMap& attributeMap) const
+{
+ attributeMap["state"] = { (m_state ? "true" : "false") };
+ attributeMap["power"] = { to_string(m_power) };
+}
+
+void LightResource::addType(const OC::OCPlatform& platform, const std::string& type) const
+{
+ OCStackResult result = platform.bindTypeToResource(m_resourceHandle, type);
+ if(OC_STACK_OK != result)
+  cout << "Binding TypeName to Resource was unsuccessful, result was " << result << '\n';
+}
+
+void LightResource::addInterface(const OC::OCPlatform& platform, const std::string& interface) const
+{
+ OCStackResult result = platform.bindInterfaceToResource(m_resourceHandle, interface);
+
+ if(OC_STACK_OK != result)
+  cout << "Binding TypeName to Resource was unsuccessful, result was " << result << '\n';
+}
+
+void LightResource::createResource(OC::OCPlatform& platform, const unsigned int resource_number)
+{
+ string resourceURI      { make_URI(resource_number) };
+ string resourceTypeName { "core.light" };
+
+ cout << "registering resource: " << resourceURI << '\n';
+ cout << "registering type name \"" << resourceTypeName << "\".\n";
+
+ // This will internally create and register the resource, binding the current instance's method as a callback:
+ OCStackResult result = platform.registerResource(
+                                            m_resourceHandle, resourceURI, resourceTypeName,
+                                            DEFAULT_INTERFACE, 
+                                            std::bind(&LightResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2), 
+                                            OC_DISCOVERABLE | OC_OBSERVABLE);
+
+  if (OC_STACK_OK != result)
+   std::cout << "Resource creation failed.\n";
+}
+
+void LightResource::observe_function()
+{
+ cerr << "Observation thread is spinning up.\n";
+
+ while(!shutdown_flag)
+  {
+    std::this_thread::sleep_for(std::chrono::seconds(2));
+
+    if(!m_observation)
+     continue;
+
+    m_power += 10;
+
+    const auto result = OCPlatform::notifyObservers(getHandle());
+
+    // Stop notifications when there are no more observers:
+    if(OC_STACK_NO_OBSERVERS == result)
+     {
+        m_observation = 0;
+     }
+  }
+
+ cerr << "Observation thread is shutting down.\n";
+}
+
+// This is just a sample implementation of entity handler.
+// Entity handler can be implemented in several ways by the manufacturer
+void LightResource::entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+{
+    if(!request)
+     {
+        cerr << "entityHandler(): Received invalid request object.\n";
+        return;
+     }
+
+    if(!response)
+     {
+        cerr << "entityHandler(): Received invalid response object.\n";
+        return;
+     }
+
+    switch(request->getRequestHandlerFlag())   
+    {
+        default:
+                cerr << "entityHandler(): invalid request flag\n";
+                break;
+
+        case RequestHandlerFlag::InitFlag:
+                cerr << "entityHandler(): Initialization requested.\n";
+                break;
+
+        case RequestHandlerFlag::RequestFlag:
+                dispatch_request(request->getRequestType(), request, response);
+                break;
+
+        case RequestHandlerFlag::ObserverFlag:
+                handle_observe_event(request, response);
+                break;
+    }
+}
+
+void LightResource::dispatch_request(const std::string& request_type, std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
+{
+ std::cout << "dispatch_request(): " << request_type << '\n';
+
+ if("GET" == request_type)
+  return handle_get_request(request, response);
+
+ if("PUT" == request_type)
+  return handle_put_request(request, response);
+
+ if("POST" == request_type)
+  return handle_post_request(request, response);
+
+ if("DELETE" == request_type)
+  return handle_delete_request(request, response);
+
+ cerr << "entityHandler(): Invalid request type \"" << request_type << "\".\n";
+}
+
+void LightResource::handle_get_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
+{
+ cout << "handle_get_request():\n";
+
+ const auto query_params_map = request->getQueryParameters();
+
+ // ...do any processing of the query here...
+
+ // Get a representation of the resource and send it back as a response:
+ AttributeMap attribute_map;
+
+ getRepresentation(attribute_map);
+
+ response->setErrorCode(200);
+ response->setResourceRepresentation(attribute_map);
+}
+
+void LightResource::handle_put_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
+{
+ // Here's how you would get any query parameters:
+ const auto query_params_map = request->getQueryParameters();
+ // ...do something with the query parameters (if there were any)...
+
+ auto attribute_map = request->getAttributeRepresentation();
+
+ setRepresentation(attribute_map);
+ getRepresentation(attribute_map);  // in case we changed something
+
+ if(!response)
+  return;
+
+ response->setErrorCode(200);
+ response->setResourceRepresentation(attribute_map); 
+}
+
+void LightResource::handle_post_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+{
+ // ...demo-code...
+ response->setErrorCode(200);
+
+ auto attribute_map = request->getAttributeRepresentation();
+ getRepresentation(attribute_map);
+ response->setResourceRepresentation(attribute_map);
+}
+
+void LightResource::handle_delete_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
+{
+ // ...demo-code...
+ response->setErrorCode(200);
+
+ auto attribute_map = request->getAttributeRepresentation();
+ getRepresentation(attribute_map);
+ response->setResourceRepresentation(attribute_map);
+}
+
+// Set up observation in a separate thread:
+void LightResource::handle_observe_event(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
+{
+ if(observe_thread.joinable())
+  return; 
+
+ observe_thread = thread(bind(&LightResource::observe_function, this));
+ observe_thread.detach();
+}
+
+
+
+}} // namespace Intel::OCDemo
+
diff --git a/examples/ocicuc/light_resource.hpp b/examples/ocicuc/light_resource.hpp
new file mode 100644 (file)
index 0000000..bfb1692
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef __LIGHT_RESOURCE_HPP
+ #define __LIGHT_RESOURCE_HPP
+
+#include <map>
+#include <atomic>
+#include <thread>
+#include <string>
+#include <ostream>
+#include <sstream>
+#include <iostream>
+#include <functional>
+
+#include "OCApi.h"
+#include "OCResource.h"
+#include "OCPlatform.h"
+
+/* An example of a server-side resource: */
+namespace Intel { namespace OCDemo {
+
+using namespace OC;
+using namespace std;
+
+/// This class represents a single resource named 'lightResource'. This resource has
+/// two simple properties named 'state' and 'power'
+class LightResource
+{
+ public:
+    bool m_state;       // off or on?
+    int m_power;        // power level
+
+    private:
+    atomic<bool> m_observation; // are we under observation?
+
+    private:
+    static atomic<bool> shutdown_flag;
+    static thread observe_thread;
+
+    private:
+    OCResourceHandle m_resourceHandle;
+
+    public:
+    LightResource()
+     : m_state(false), 
+       m_power(0),
+       m_observation(false)
+    {}
+
+    ~LightResource()
+    {
+        shutdown_flag = true;
+
+        if(observe_thread.joinable())
+         observe_thread.join();
+    }
+
+    private:
+    inline std::string make_URI(const unsigned int resource_number) const
+    {
+        return std::string("/a/light") + "_" + std::to_string(resource_number); 
+    }
+
+    public:
+    // This function internally calls registerResource API.
+    void createResource(OC::OCPlatform& platform, const unsigned int resource_number);
+
+    OCResourceHandle getHandle() const { return m_resourceHandle; }
+
+    void setRepresentation(AttributeMap& attributeMap);
+    void getRepresentation(AttributeMap& attributeMap) const;
+
+    void addType(const OC::OCPlatform& platform, const std::string& type) const;
+    void addInterface(const OC::OCPlatform& platform, const std::string& interface) const;
+
+    private:
+    void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+
+    private:
+    void observe_function();
+
+    // Request handlers:
+    private:
+    void dispatch_request(const std::string& request_type, std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+     void handle_get_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+     void handle_put_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+     void handle_post_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+     void handle_delete_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+     void handle_observe_event(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
+};
+
+}} // namespace Intel::OCDemo
+
+#endif 
index f18f5d2..a564624 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <map>
-#include <atomic>
-#include <thread>
-#include <string>
-#include <ostream>
-#include <sstream>
-#include <iostream>
-#include <functional>
-
-#include <boost/program_options.hpp>
-
-#include "OCApi.h"
-#include "OCResource.h"
-#include "OCPlatform.h"
-
 #include "exec.hpp"
+#include "utility.hpp"
+
+#include "light_resource.hpp"
 
 namespace Intel { namespace OCDemo {
 
@@ -57,279 +45,6 @@ auto make_description()
  return desc;
 }
 
-}} // namespace Intel::OCDemo
-
-namespace Intel { namespace OCDemo {
-
-using namespace OC;
-using namespace std;
-
-/// This class represents a single resource named 'lightResource'. This resource has
-/// two simple properties named 'state' and 'power'
-class LightResource
-{
- public:
-    bool m_state;       // off or on?
-    int m_power;        // power level
-
-    private:
-    atomic<bool> m_observation; // are we under observation?
-
-    private:
-    static atomic<bool> shutdown_flag;
-    static thread observe_thread;
-
-    private:
-    OCResourceHandle m_resourceHandle;
-
-    public:
-    LightResource()
-     : m_state(false), 
-       m_power(0),
-       m_observation(false)
-    {}
-
-    ~LightResource()
-    {
-        shutdown_flag = true;
-
-        if(observe_thread.joinable())
-         observe_thread.join();
-    }
-
-    private:
-    std::string make_URI(const unsigned int resource_number) const
-    {
-        return std::string("/a/light") + "_" + std::to_string(resource_number); 
-    }
-
-    public:
-    // This function internally calls registerResource API.
-    void createResource(OC::OCPlatform& platform, const unsigned int resource_number);
-
-    OCResourceHandle getHandle() const { return m_resourceHandle; }
-
-    void setRepresentation(AttributeMap& attributeMap);
-    void getRepresentation(AttributeMap& attributeMap) const;
-
-    void addType(const OC::OCPlatform& platform, const std::string& type) const;
-    void addInterface(const OC::OCPlatform& platform, const std::string& interface) const;
-
-    private:
-    void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-
-    private:
-    void observe_function();
-
-    // Request handlers:
-    private:
-    void dispatch_request(const std::string& request_type, std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-     void handle_get_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-     void handle_put_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-     void handle_post_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-     void handle_delete_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-     void handle_observe_event(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
-};
-
-atomic<bool> LightResource::shutdown_flag(false);
-thread LightResource::observe_thread;
-
-void LightResource::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 LightResource::getRepresentation(AttributeMap& attributeMap) const
-{
- attributeMap["state"] = { (m_state ? "true" : "false") };
- attributeMap["power"] = { to_string(m_power) };
-}
-
-void LightResource::addType(const OC::OCPlatform& platform, const std::string& type) const
-{
- OCStackResult result = platform.bindTypeToResource(m_resourceHandle, type);
- if(OC_STACK_OK != result)
-  cout << "Binding TypeName to Resource was unsuccessful, result was " << result << '\n';
-}
-
-void LightResource::addInterface(const OC::OCPlatform& platform, const std::string& interface) const
-{
- OCStackResult result = platform.bindInterfaceToResource(m_resourceHandle, interface);
-
- if(OC_STACK_OK != result)
-  cout << "Binding TypeName to Resource was unsuccessful, result was " << result << '\n';
-}
-
-void LightResource::createResource(OC::OCPlatform& platform, const unsigned int resource_number)
-{
- string resourceURI      { make_URI(resource_number) };
- string resourceTypeName { "core.light" };
-
- cout << "registering resource: " << resourceURI << '\n';
- cout << "registering type name \"" << resourceTypeName << "\".\n";
-
- // This will internally create and register the resource, binding the current instance's method as a callback:
- OCStackResult result = platform.registerResource(
-                                            m_resourceHandle, resourceURI, resourceTypeName,
-                                            DEFAULT_INTERFACE, 
-                                            std::bind(&LightResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2), 
-                                            OC_DISCOVERABLE | OC_OBSERVABLE);
-
-  if (OC_STACK_OK != result)
-   std::cout << "Resource creation failed.\n";
-}
-
-void LightResource::observe_function()
-{
- cerr << "Observation thread is spinning up.\n";
-
- while(!shutdown_flag)
-  {
-    std::this_thread::sleep_for(std::chrono::seconds(2));
-
-    if(!m_observation)
-     continue;
-
-    m_power += 10;
-
-    const auto result = OCPlatform::notifyObservers(getHandle());
-
-    // Stop notifications when there are no more observers:
-    if(OC_STACK_NO_OBSERVERS == result)
-     {
-        m_observation = 0;
-     }
-  }
-
- cerr << "Observation thread is shutting down.\n";
-}
-
-// This is just a sample implementation of entity handler.
-// Entity handler can be implemented in several ways by the manufacturer
-void LightResource::entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
-{
-    if(!request)
-     {
-        cerr << "entityHandler(): Received invalid request object.\n";
-        return;
-     }
-
-    if(!response)
-     {
-        cerr << "entityHandler(): Received invalid response object.\n";
-        return;
-     }
-
-    switch(request->getRequestHandlerFlag())   
-    {
-        default:
-                cerr << "entityHandler(): invalid request flag\n";
-                break;
-
-        case RequestHandlerFlag::InitFlag:
-                cerr << "entityHandler(): Initialization requested.\n";
-                break;
-
-        case RequestHandlerFlag::RequestFlag:
-                dispatch_request(request->getRequestType(), request, response);
-                break;
-
-        case RequestHandlerFlag::ObserverFlag:
-                handle_observe_event(request, response);
-                break;
-    }
-}
-
-void LightResource::dispatch_request(const std::string& request_type, std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
-{
- std::cout << "dispatch_request(): " << request_type << '\n';
-
- if("GET" == request_type)
-  return handle_get_request(request, response);
-
- if("PUT" == request_type)
-  return handle_put_request(request, response);
-
- if("POST" == request_type)
-  return handle_post_request(request, response);
-
- if("DELETE" == request_type)
-  return handle_delete_request(request, response);
-
- cerr << "entityHandler(): Invalid request type \"" << request_type << "\".\n";
-}
-
-void LightResource::handle_get_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
-{
- cout << "handle_get_request():\n";
-
- const auto query_params_map = request->getQueryParameters();
-
- // ...do any processing of the query here...
-
- // Get a representation of the resource and send it back as a response:
- AttributeMap attribute_map;
-
- getRepresentation(attribute_map);
-
- response->setErrorCode(200);
- response->setResourceRepresentation(attribute_map);
-}
-
-void LightResource::handle_put_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
-{
- // Here's how you would get any query parameters:
- const auto query_params_map = request->getQueryParameters();
- // ...do something with the query parameters (if there were any)...
-
- auto attribute_map = request->getAttributeRepresentation();
-
- setRepresentation(attribute_map);
- getRepresentation(attribute_map);  // in case we changed something
-
- if(!response)
-  return;
-
- response->setErrorCode(200);
- response->setResourceRepresentation(attribute_map); 
-}
-
-void LightResource::handle_post_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
-{
- // ...demo-code...
- response->setErrorCode(200);
-
- auto attribute_map = request->getAttributeRepresentation();
- getRepresentation(attribute_map);
- response->setResourceRepresentation(attribute_map);
-}
-
-void LightResource::handle_delete_request(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
-{
- // ...demo-code...
- response->setErrorCode(200);
-
- auto attribute_map = request->getAttributeRepresentation();
- getRepresentation(attribute_map);
- response->setResourceRepresentation(attribute_map);
-}
-
-// Set up observation in a separate thread:
-void LightResource::handle_observe_event(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response) 
-{
- if(observe_thread.joinable())
-  return; 
-
- observe_thread = thread(bind(&LightResource::observe_function, this));
- observe_thread.detach();
-}
-
 int exec(const boost::program_options::variables_map& vm)
 {
  using namespace std;
@@ -338,16 +53,17 @@ int exec(const boost::program_options::variables_map& vm)
 
  OC::OCPlatform platform({ 
                           OC::ServiceType::InProc,              // in-process server
-                          OC::ModeType::Both,                   // run as server and as client
+                          OC::ModeType::Server,                 // run in server mode
                           vm["host_ip"].as<string>(),           // host
-                          vm["host_port"].as<uint16_t>()        // port
+                          vm["host_port"].as<uint16_t>(),       // port
+                          OC::QualityOfService::NonConfirmable      
                         });
 
  std::cout << "Ok." << std::endl;
 
  vector<string> resource_URIs;
 
- vector<shared_ptr<LightResource>> lights;
+ vector<shared_ptr<Intel::OCDemo::LightResource>> lights;
 
  const unsigned long& nresources = vm["nres"].as<unsigned long>();
 
@@ -357,7 +73,7 @@ int exec(const boost::program_options::variables_map& vm)
   {
         cout << "Registering resource " << resource_number << ": " << std::flush;
 
-        auto lr = make_shared<LightResource>();
+        auto lr = make_shared<Intel::OCDemo::LightResource>();
 
         lr->createResource(platform, resource_number);
         lr->addType(platform, std::string("core.brightlight"));
diff --git a/examples/ocicuc/utility.cpp b/examples/ocicuc/utility.cpp
new file mode 100644 (file)
index 0000000..823e57f
--- /dev/null
@@ -0,0 +1,81 @@
+#include <chrono>
+#include <string>
+#include <iostream>
+#include <algorithm>
+
+#include "utility.hpp"
+
+namespace Intel { namespace OCDemo {
+
+int observe_count()
+{
+ static unsigned long long oc = 0;
+ return ++oc;
+}
+
+}} // namespace Intel::OCDemo
+
+// Helper for measuring call times:
+namespace Intel { namespace OCDemo {
+
+using std::cout;
+using namespace std::chrono;
+
+call_times call_timer;
+
+void call_times::reset(const std::string& entry) 
+{ 
+ timings[entry] = make_pair(high_resolution_clock::now(), std::chrono::high_resolution_clock::time_point()); 
+}
+
+void call_times::mark(const std::string& name)
+{
+ auto e = timings.find(name);
+
+    if(timings.end() == e)
+     {
+        reset(name);
+        return;
+     }
+
+    auto& tp = (*e).second;
+
+    if(tp.first > tp.second)
+     timings[name].second = high_resolution_clock::now();
+  }
+
+void call_times::report()
+{
+ cout << "Time marks:\n";
+
+ for_each(begin(timings), end(timings), 
+ [](const std::pair<std::string, clock_interval>& tm) -> void 
+ {
+    const std::string& name     { tm.first };
+
+    const time_point<high_resolution_clock>& request_time    { tm.second.first };
+    const time_point<high_resolution_clock>& response_time   { tm.second.second };
+
+    cout << '\t' << name << ": ";
+
+    if(request_time > response_time)
+     {
+        cout << "<waiting>\n";
+        return;
+     }
+
+    auto elapsed_ms = duration_cast<std::chrono::milliseconds>(response_time - request_time).count();
+    cout << elapsed_ms << "ms (";
+
+    auto elapsed_us = duration_cast<std::chrono::microseconds>(response_time - request_time).count();
+    cout << elapsed_us << "us)\n";
+ });
+}
+
+void call_times::report_and_reset(const std::string& name)
+{
+ mark(name), report(), reset(name);
+}
+
+
+}} // namespace Intel::OCDemo
diff --git a/examples/ocicuc/utility.hpp b/examples/ocicuc/utility.hpp
new file mode 100644 (file)
index 0000000..3c8b628
--- /dev/null
@@ -0,0 +1,85 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __OC_OCDEMO_UTILITY_H
+ #define __OC_OCDEMO_UTILITY_H
+
+#include <map>
+#include <tuple>
+#include <chrono>
+#include <ostream>
+
+#include "OCApi.h"
+
+namespace Intel { namespace OCDemo {
+
+// Prettyprinter for AttributeMaps:
+inline std::ostream& operator<<(std::ostream& os, const OC::AttributeMap& attrs)
+{
+ for(const auto& attr : attrs)
+  {
+        os << "Attribute \"" << attr.first << "\": ";
+
+        for(const auto& val : attr.second)
+         os << val << "; ";
+  }
+
+ return os;
+}
+
+/* A static observation counter: */
+int observe_count();
+
+/* Helpers for measuring request times: */
+typedef std::pair< 
+                    std::chrono::time_point<std::chrono::high_resolution_clock>, 
+                    std::chrono::time_point<std::chrono::high_resolution_clock> 
+                 > clock_interval;
+
+struct call_times
+{
+ public:
+ bool display_reports;
+
+ public:
+ std::map<std::string, clock_interval> timings;
+
+ public:
+ call_times()
+  : display_reports(true)
+ {}
+
+ call_times(const bool& display_reports_)
+  : display_reports(display_reports_)
+ {}
+ public:
+ void reset(const std::string& entry);
+ void mark(const std::string& name);
+
+ void report();
+ void report_and_reset(const std::string& name);
+};
+
+extern call_times call_timer; 
+}} // namespace Intel::OCDemo
+
+#endif
index 2077c8f..f9311a3 100644 (file)
@@ -244,11 +244,13 @@ void foundResource(std::shared_ptr<OCResource> resource)
 int main(int argc, char* argv[]) {
 
     // Create PlatformConfig object
-    PlatformConfig cfg;
-    cfg.ipAddress = "192.168.1.10";
-    cfg.port = 5683;
-    cfg.mode = ModeType::Client;
-    cfg.serviceType = ServiceType::InProc;
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Client,
+        "192.168.1.10",
+        5683,
+        OC::QualityOfService::NonConfirmable
+    };
 
     // Create a OCPlatform instance.
     // Note: Platform creation is synchronous call.
index 5ea4128..664479d 100644 (file)
@@ -630,12 +630,13 @@ void entityHandlerFan(std::shared_ptr<OCResourceRequest> request, std::shared_pt
 int main()
 {
     // Create PlatformConfig object
-
-    PlatformConfig cfg;
-    cfg.ipAddress = "192.168.1.10";
-    cfg.port = 56832;
-    cfg.mode = ModeType::Server;
-    cfg.serviceType = ServiceType::InProc;
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Server,
+        "192.168.1.10",
+        56832,
+        OC::QualityOfService::NonConfirmable
+    };
 
     // Create a OCPlatform instance.
     // Note: Platform creation is synchronous call.
index f1089e6..4df1c95 100644 (file)
@@ -313,11 +313,13 @@ int main(int argc, char* argv[]) {
     }
 
     // Create PlatformConfig object
-    PlatformConfig cfg;
-    cfg.ipAddress = "192.168.1.10";
-    cfg.port = 5683;
-    cfg.mode = ModeType::Client;
-    cfg.serviceType = ServiceType::InProc;
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Client,
+        "192.168.1.10",
+        5683,
+        OC::QualityOfService::NonConfirmable
+    };
 
     // Create a OCPlatform instance.
     // Note: Platform creation is synchronous call.
index 1a34588..25e6d9a 100644 (file)
@@ -303,11 +303,13 @@ struct FooResource
 };
 int main()
 {
-    PlatformConfig cfg;
-    cfg.ipAddress = "134.134.161.33";
-    cfg.port = 56833;
-    cfg.mode = ModeType::Both;
-    cfg.serviceType = ServiceType::InProc;
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Both,
+        "134.134.161.33",
+        56833,
+        OC::QualityOfService::NonConfirmable
+    };
 
     FooResource fooRes;
 
index afa9b18..14f5115 100644 (file)
@@ -329,12 +329,13 @@ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<O
 int main()
 {
     // Create PlatformConfig object
-
-    PlatformConfig cfg;
-    cfg.ipAddress = "134.134.161.33";
-    cfg.port = 56832;
-    cfg.mode = ModeType::Server;
-    cfg.serviceType = ServiceType::InProc;
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Server,
+        "134.134.161.33",
+        56832,
+        OC::QualityOfService::NonConfirmable
+    };
 
     // Create a OCPlatform instance.
     // Note: Platform creation is synchronous call.
index 1000582..9b82e44 100644 (file)
@@ -1,6 +1,6 @@
 //******************************************************************
 //
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. 
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 //
@@ -41,7 +41,6 @@ namespace OC
     {
     public:
         InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
-        
         virtual ~InProcClientWrapper();
 
         virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, 
@@ -60,9 +59,7 @@ namespace OC
         virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri);
         
         // Note: this should never be called by anyone but the handler for the listen command.  It is public becuase that needs to be a non-instance callback
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, 
-            const boost::property_tree::ptree resourceNode);
-    
+        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const boost::property_tree::ptree resourceNode);
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
@@ -72,6 +69,8 @@ namespace OC
         std::weak_ptr<std::mutex> m_csdkLock;
         std::vector<std::function<void(OCClientResponse*)>> callbackList;
 
+    private:
+        PlatformConfig m_cfg;
     };
 }
 
index c86ed15..f221a85 100644 (file)
@@ -26,6 +26,8 @@
 #include <vector>
 #include <map>
 
+#include "ocstack.h"
+
 namespace OC {
 
 
@@ -65,12 +67,33 @@ namespace OC {
      Both
  };
 
+ enum class QualityOfService : uint8_t
+ {
+    Confirmable     = OC_CONFIRMABLE,
+    NonConfirmable  = OC_NON_CONFIRMABLE
+ };
+
  struct PlatformConfig
  {
-     ServiceType serviceType; // This will indicate whether it is InProc or OutOfProc
-     ModeType mode; // This will indicate whether we want to do server, client or both
-     std::string ipAddress; // This is the ipAddress of the server to connect to
-     uint16_t port; // Port of the server
+    ServiceType                serviceType;   // This will indicate whether it is InProc or OutOfProc
+    ModeType                   mode;          // This will indicate whether we want to do server, client or both
+    std::string                ipAddress;     // This is the ipAddress of the server to connect to
+    uint16_t                   port;          // Port of the server
+
+    QualityOfService           QoS;
+
+    public:
+    PlatformConfig(const ServiceType serviceType_,
+                   const ModeType mode_,
+                   const std::string& ipAddress_,
+                   const uint16_t port_,
+                   const QualityOfService QoS_)
+     : serviceType(serviceType_),
+       mode(mode_),
+       ipAddress(ipAddress_),
+       port(port_),
+       QoS(QoS_)
+    {}
  };
 
  enum class RequestHandlerFlag
index 999e2ee..f57910c 100644 (file)
@@ -115,7 +115,7 @@ namespace OC
         * 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"
-        * Example, a relative URI: 'a/light' will result in a fully qualified URI: //134.134.161.33/oc/a/light"
+        * Example, a relative URI: 'a/light' will result in a fully qualified URI: //192.168.1.1/oc/a/light"
         * 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
@@ -255,20 +255,21 @@ namespace OC
         OCResource::Ptr constructResourceObject(const std::string& host, const std::string& uri,
                         bool isObservable, const std::vector<std::string>& resourceTypes,
                         const std::vector<std::string>& interfaces);
+
+    private:
+        PlatformConfig m_cfg;
+
     private:
         std::unique_ptr<WrapperFactory> m_WrapperInstance;
         IServerWrapper::Ptr m_server;
         IClientWrapper::Ptr m_client;
         std::shared_ptr<std::mutex> m_csdkLock;
+
+    private:
         /**
         *  Private function to initalize the platfrom
         */
         void init(const PlatformConfig& config);
-
-        /**
-        *  Private function cleanup the platform
-        */
-        void cleanup();
     };
 }
 
index 6ec33f7..1f7a3e5 100644 (file)
--- a/makefile
+++ b/makefile
@@ -6,9 +6,9 @@ CXX           := g++
 OUT_DIR          := $(PWD)/$(BUILD)
 OBJ_DIR          := $(OUT_DIR)/obj
 
-CXX_FLAGS.debug     := -g3 -std=c++0x -Wall -pthread
+CXX_FLAGS.debug     := -g3 -std=c++0x -Wall -pthread -O0
 
-CXX_FLAGS.release   := -std=c++0x -Wall -pthread
+CXX_FLAGS.release   := -std=c++0x -Wall -pthread -O3
 
 CXX_INC          := -I./include/
 CXX_INC          += -I./csdk/stack/include