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
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)
{
{
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
{
{
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
{
{
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
{
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
{
{
// 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)
}
}
- 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)
#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
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
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
+# 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
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
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
+++ /dev/null
-
-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
-
#include "OCPlatform.h"
#include "exec.hpp"
+#include "utility.hpp"
+
+#include "demo_client.hpp"
namespace Intel { namespace OCDemo {
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;
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;
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();
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
--- /dev/null
+
+/* 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
+
+
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;
--- /dev/null
+#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
+
--- /dev/null
+#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
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#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 {
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;
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>();
{
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"));
--- /dev/null
+#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
--- /dev/null
+//******************************************************************
+//
+// 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
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.
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.
}
// 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.
};
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;
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.
//******************************************************************
//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
{
public:
InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
-
virtual ~InProcClientWrapper();
virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType,
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);
std::weak_ptr<std::mutex> m_csdkLock;
std::vector<std::function<void(OCClientResponse*)>> callbackList;
+ private:
+ PlatformConfig m_cfg;
};
}
#include <vector>
#include <map>
+#include "ocstack.h"
+
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
* 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
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();
};
}
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