2. Addressed review comments.
Change-Id: I8745b604d62d9c2e49fce1cedb3af185ae2f5f5b
"/door/left", false, doorTypes, ifaces);
OCResource::Ptr rightdoor = m_platform.constructResourceObject(resource->host(),
"/door/right", false, doorTypes, ifaces);
+ OCResource::Ptr randomdoor = m_platform.constructResourceObject(resource->host(),
+ "/door/random", false, doorTypes, ifaces);
light->get(QueryParamsMap(), GetCallback(
std::bind(&ClientFridge::getResponse, this, "Fridge Light", PH::_1,
std::bind(&ClientFridge::getResponse, this, "Right Door", PH::_1,
PH::_2, rightdoor, 3)
));
+ randomdoor->get(QueryParamsMap(), GetCallback(
+ std::bind(&ClientFridge::getResponse, this, "Random Door", PH::_1,
+ PH::_2, randomdoor, 4)
+ ));
}
// Note that resourceName, resource, and getId are all bound via the std::bind mechanism.
switch(getId)
{
case 1:
- bool isOn;
- rep.getValue("on",isOn);
- std::cout<<"The fridge light is "<< ((isOn)?"":"not ") <<"on"<<std::endl;
- break;
+ {
+ bool isOn;
+ rep.getValue("on",isOn);
+ std::cout<<"The fridge light is "<< ((isOn)?"":"not ") <<"on"<<std::endl;
+ }
+ break;
case 2:
case 3:
- bool isOpen;
- std::string side;
- rep.getValue("open", isOpen);
- rep.getValue("side", side);
- std::cout << "Door is "<<isOpen<<" and is on the "<<side<<std::endl;
- break;
+ {
+ bool isOpen;
+ std::string side;
+ rep.getValue("open", isOpen);
+ rep.getValue("side", side);
+ std::cout << "Door is "<<isOpen<<" and is on the "<<side<<std::endl;
+ }
+ break;
+ case 4:
+ {
+ // Get on random resource called.
+ std::string name;
+ rep.getValue("device_name", name);
+ std::cout << "Name of fridge: "<< name << std::endl;
+ break;
+ }
}
}
std::string resourceURI = "/device";
std::string resourceTypeName = "intel.fridge";
std::string resourceInterface = DEFAULT_INTERFACE;
- RegisterCallback cb = std::bind(&DeviceResource::entityHandler, this,PH::_1, PH::_2);
+ EntityHandler cb = std::bind(&DeviceResource::entityHandler, this,PH::_1, PH::_2);
+
+ EntityHandler defaultEH = std::bind(&DeviceResource::defaultEntityHandler, this,
+ PH::_1, PH::_2);
+
+ std::cout << "Setting device default entity handler\n";
+ platform.setDefaultDeviceEntityHandler(defaultEH);
+
uint8_t resourceProperty = OC_DISCOVERABLE;
OCStackResult result = platform.registerResource(m_resourceHandle,
resourceURI,
private:
OCRepresentation get()
{
- m_rep.setValue("device_name", "Intel Powered 2 door, 1 light refridgerator");
+ m_rep.setValue("device_name", std::string("Intel Powered 2 door, 1 light refridgerator"));
return m_rep;
}
}
}
}
+
+ virtual void defaultEntityHandler(std::shared_ptr<OCResourceRequest> request,
+ std::shared_ptr<OCResourceResponse> response)
+ {
+ if(request)
+ {
+ if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+ {
+ if(request->getRequestType() == "GET")
+ {
+ if(response)
+ {
+ std::cout<<"Default Entity Handler: Get Request"<<std::endl;
+ response->setErrorCode(200);
+ response->setResourceRepresentation(get(), "");
+ }
+ }
+ else
+ {
+ std::cout <<"Default Entity Handler: unsupported request type "
+ << request->getRequestType() << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "Default Entity Handler: unsupported request flag" <<std::endl;
+ }
+ }
+ }
+
};
class LightResource : public Resource
std::string resourceURI = "/light";
std::string resourceTypeName = "intel.fridge.light";
std::string resourceInterface = DEFAULT_INTERFACE;
- RegisterCallback cb = std::bind(&LightResource::entityHandler, this,PH::_1, PH::_2);
+ EntityHandler cb = std::bind(&LightResource::entityHandler, this,PH::_1, PH::_2);
uint8_t resourceProperty = 0;
OCStackResult result = platform.registerResource(m_resourceHandle,
resourceURI,
std::string resourceURI = "/door/"+ side;
std::string resourceTypeName = "intel.fridge.door";
std::string resourceInterface = DEFAULT_INTERFACE;
- RegisterCallback cb = std::bind(&DoorResource::entityHandler, this,PH::_1, PH::_2);
+ EntityHandler cb = std::bind(&DoorResource::entityHandler, this,PH::_1, PH::_2);
+
uint8_t resourceProperty = 0;
OCStackResult result = platform.registerResource(m_resourceHandle,
resourceURI,
}
}
}
+
};
class Refridgerator
uint8_t resourceProperty = OC_DISCOVERABLE;
- RegisterCallback eh(std::bind(&FooResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2));
+ EntityHandler eh(std::bind(&FooResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2));
OCStackResult result = platform.registerResource(m_resourceHandle, resourceURI, resourceTypeName,
resourceInterface,
eh, resourceProperty);
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback& entityHandler,
+ EntityHandler& entityHandler,
uint8_t resourceProperty) = 0;
virtual OCStackResult unregisterResource(
const OCResourceHandle& resourceHandle) = 0;
virtual OCStackResult startPresence(const unsigned int seconds) = 0;
virtual OCStackResult stopPresence() = 0;
+
+ virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler) = 0;
};
}
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback& entityHandler,
+ EntityHandler& entityHandler,
uint8_t resourceProperty);
virtual OCStackResult unregisterResource(
virtual OCStackResult startPresence(const unsigned int seconds);
virtual OCStackResult stopPresence();
+
+ virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler);
private:
void processFunc();
std::thread m_processThread;
const std::string BATCH_INTERFACE = "oc.mi.b";
typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
- typedef std::function<void(const std::shared_ptr<OCResourceRequest>, const std::shared_ptr<OCResourceResponse>)> RegisterCallback;
+ typedef std::function<void(const std::shared_ptr<OCResourceRequest>, const std::shared_ptr<OCResourceResponse>)> EntityHandler;
typedef std::function<void(OCStackResult, const unsigned int)> SubscribeCallback;
typedef std::function<void(const OCRepresentation&, const int)> GetCallback;
typedef std::function<void(const OCRepresentation&, const int)> PutCallback;
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback entityHandler,
+ EntityHandler entityHandler,
uint8_t resourceProperty);
/**
+ * Set default device entity handler
+ *
+ * @param entityHandler - entity handler to handle requests for
+ * any undefined resources or default actions.
+ * if NULL is passed it removes the device default entity handler.
+ *
+ * @return
+ * OC_STACK_OK - no errors
+ * OC_STACK_ERROR - stack process error
+ */
+ OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler);
+
+ /**
* This API unregisters a resource with the server
* NOTE: This API applies to server side only.
*
*
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success.<br>
* NOTE: OCStackResult is defined in ocstack.h. <br>
- * NOTE: bindResource must be used only after the both collection resource and
+ * NOTE: bindResource must be used only after the both collection resource and
* resource to add under a collections are created and respective handles obtained<br>
* <b>Example:</b> <br>
* Step 1: registerResource(homeResourceHandle, "a/home", "home", Link_Interface, entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE);<br>
* Step 2: registerResource(kitchenResourceHandle, "a/kitchen", "kitchen", Link_Interface, entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE);<br>
* Step 3: bindResource(homeResourceHandle, kitchenResourceHandle);<br>
- * At the end of Step 3, resource "a/home" will contain a reference to "a/kitchen".<br>
+ * At the end of Step 3, resource "a/home" will contain a reference to "a/kitchen".<br>
*/
OCStackResult bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle);
*
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
* NOTE: OCStackResult is defined in ocstack.h. <br>
- * NOTE: bindResources must be used only after the both collection resource and
+ * NOTE: bindResources must be used only after the both collection resource and
* list of resources to add under a collection are created and respective handles obtained <br>
* <b> Example: </b> <br>
* Step 1: registerResource(homeResourceHandle, "a/home", "home", Link_Interface, homeEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE);<br>
*
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
* NOTE: OCStackResult is defined in ocstack.h.<br>
- * NOTE: unbindResource must be used only after the both collection resource and
+ * NOTE: unbindResource must be used only after the both collection resource and
* resource to unbind from a collection are created and respective handles obtained<br>
* <b> Example </b> <br>
* Step 1: registerResource(homeResourceHandle, "a/home", "home", Link_Interface, entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE);<br>
* @param resourceHandleList List of resource handles to be unbound from the collection resource
*
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
- *
+ *
* NOTE: OCStackResult is defined in ocstack.h.<br>
- * NOTE: unbindResources must be used only after the both collection resource and
+ * NOTE: unbindResources must be used only after the both collection resource and
* list of resources resource to unbind from a collection are created and respective handles obtained. <br>
* <b>Example</b> <br>
* Step 1: registerResource(homeResourceHandle, "a/home", "home", Link_Interface, homeEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE);<br>
const std::string& resourceInterfaceName) const;
public:
- /**
+ /**
* Start Presence announcements.
*
* @param ttl - time to live
* stopped (potentially more to be added later).
*
* @param presenceHandle - a handle object that can be used to identify this subscription
- * request. It can be used to unsubscribe from these events in the future.
+ * request. It can be used to unsubscribe from these events in the future.
* It will be set upon successful return of this method.
* @param host - The IP address/addressable name of the server to subscribe to.
* @param presenceHandler - callback function that will receive notifications/subscription events
*
* @return OCStackResult - return value of the API. Returns OCSTACK_OK if success <br>
*/
- OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host,
+ OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host,
SubscribeCallback presenceHandler);
/**
* Creates a resource proxy object so that get/put/observe functionality
* can be used without discovering the object in advance. Note that the
* consumer of this method needs to provide all of the details required to
- * correctly contact and observe the object. If the consumer lacks any of
- * this information, they should discover the resource object normally.
+ * correctly contact and observe the object. If the consumer lacks any of
+ * this information, they should discover the resource object normally.
* Additionally, you can only create this object if OCPlatform was initialized
* to be a Client or Client/Server. Otherwise, this will return an empty
* shared ptr.
*
- * @param host - a string containing a resolvable host address of the server
- * holding the resource. Currently this should be in the format
- * coap://address:port, though in the future, we expect this to
+ * @param host - a string containing a resolvable host address of the server
+ * holding the resource. Currently this should be in the format
+ * coap://address:port, though in the future, we expect this to
* change to //address:port
*
* @param uri - the rest of the resource's URI that will permit messages to be
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback& entityHandler,
+ EntityHandler& entityHandler,
uint8_t resourceProperty)
{
virtual OCStackResult unregisterResource(
const OCResourceHandle& resourceHandle)
- { //Not implemented yet
+ {
+ //Not implemented yet
return OC_STACK_ERROR;
}
virtual OCStackResult bindTypeToResource(
const OCResourceHandle& resourceHandle,
const std::string& resourceTypeName)
- { //Not implemented yet
+ {
+ //Not implemented yet
return OC_STACK_NOTIMPL;
}
virtual OCStackResult bindInterfaceToResource(
const OCResourceHandle& resourceHandle,
const std::string& resourceInterfaceName)
- { //Not implemented yet
+ {
+ //Not implemented yet
return OC_STACK_NOTIMPL;
}
virtual OCStackResult startPresence(const unsigned int seconds)
- { //Not implemented yet
+ {
+ //Not implemented yet
return OC_STACK_NOTIMPL;
}
virtual OCStackResult stopPresence()
- { //Not implemented yet
+ {
+ //Not implemented yet
+ return OC_STACK_NOTIMPL;
+ }
+
+
+ virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler)
+ {
+ //Not implemented yet
return OC_STACK_NOTIMPL;
}
};
#include <OCUtilities.h>
using namespace std;
+using namespace OC;
-std::map <OCResourceHandle, OC::RegisterCallback> entityHandlerMap;
+std::map <OCResourceHandle, OC::EntityHandler> entityHandlerMap;
+EntityHandler defaultDeviceEntityHandler = 0;
-void defaultEntityHandler(const OC::OCResourceRequest::Ptr request, const OC::OCResourceResponse::Ptr response)
+void formResourceRequest(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * entityHandlerRequest,
+ std::shared_ptr<OCResourceRequest> pRequest)
{
- // TODO: 1) why is this ever even possible? 2) throw exception?
- std::clog << "Error: defaultEntityHandler() invoked" << std::endl;
-}
-
-OCEntityHandlerResult EntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest *entityHandlerRequest )
-{
- auto pRequest = std::make_shared<OC::OCResourceRequest>();
- auto pResponse = std::make_shared<OC::OCResourceResponse>();
-
- // TODO Utility to convert from C to C++ (every).
-
if(flag & OC_INIT_FLAG)
{
- // TODO We can fill the common data (resource Handle, etc.. )
- // init time.
pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::InitFlag);
}
+
if(flag & OC_REQUEST_FLAG)
{
pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::RequestFlag);
}
}
}
+
if(flag & OC_OBSERVE_FLAG)
{
pRequest->setRequestHandlerFlag(
pRequest->setObservationInfo(observationInfo);
}
}
+}
- // Finding the corresponding CPP Application entityHandler for a given resource
- auto entityHandlerEntry = entityHandlerMap.find(entityHandlerRequest->resource);
+void processResourceResponse(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * entityHandlerRequest,
+ std::shared_ptr<OCResourceResponse> pResponse)
+{
+ if(flag & OC_REQUEST_FLAG)
+ {
+ // TODO we could use const reference
+ std::string payLoad;
- if(entityHandlerEntry != entityHandlerMap.end()) {
- // Call CPP Application Entity Handler
- // TODO CPP Application also should return OC_EH_OK or OC_EH_ERROR
- if(entityHandlerEntry->second)
+ if(pResponse)
{
- entityHandlerEntry->second(pRequest, pResponse);
+ payLoad = pResponse->getPayload();
+ }
+ else
+ {
+ // TODO throw appropriate runtime error
+ std::clog << "Response is NULL" << endl;
+ }
+
+ if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
+ {
+ strncpy((char*)entityHandlerRequest->resJSONPayload,
+ payLoad.c_str(),
+ entityHandlerRequest->resJSONPayloadLen);
}
else
{
- std::clog << "C stack should not call again for parent resource" << std::endl;
+ // TODO throw appropriate runtime error
+ std::clog << "Payload is larger than the PayloadLen" << endl;
}
}
- else {
- std::clog << "No entity handler found." << std::endl;
+
+}
+
+OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * entityHandlerRequest)
+{
+ // TODO we need to have a better way of logging (with various levels of logging)
+ std::clog << "\nIn Default device entity handler wrapper: " << endl;
+
+ if(NULL == entityHandlerRequest)
+ {
+ std::clog << "Entity handler request is NULL." << endl;
return OC_EH_ERROR;
}
- if(flag & OC_REQUEST_FLAG)
+ auto pRequest = std::make_shared<OC::OCResourceRequest>();
+ auto pResponse = std::make_shared<OC::OCResourceResponse>();
+
+ formResourceRequest(flag, entityHandlerRequest, pRequest);
+
+ if(defaultDeviceEntityHandler)
{
- // TODO we could use const reference
- std::string payLoad = pResponse->getPayload();
+ defaultDeviceEntityHandler(pRequest, pResponse);
+ }
+ else
+ {
+ std::clog << "Default device entity handler was not set." << endl;
+ return OC_EH_ERROR;
+ }
- if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
+ processResourceResponse(flag, entityHandlerRequest, pResponse);
+
+ return OC_EH_OK;
+}
+
+
+OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * entityHandlerRequest )
+{
+ // TODO we need to have a better way of logging (with various levels of logging)
+ std::clog << "\nIn entity handler wrapper: " << endl;
+
+ if(NULL == entityHandlerRequest)
+ {
+ std::clog << "Entity handler request is NULL." << endl;
+ return OC_EH_ERROR;
+ }
+
+ auto pRequest = std::make_shared<OC::OCResourceRequest>();
+ auto pResponse = std::make_shared<OC::OCResourceResponse>();
+
+ formResourceRequest(flag, entityHandlerRequest, pRequest);
+
+
+ // Finding the corresponding CPP Application entityHandler for a given resource
+ auto entityHandlerEntry = entityHandlerMap.find(entityHandlerRequest->resource);
+
+ if(entityHandlerEntry != entityHandlerMap.end())
+ {
+ // Call CPP Application Entity Handler
+ // TODO CPP Application also should return OC_EH_OK or OC_EH_ERROR
+ if(entityHandlerEntry->second)
{
- strncpy((char*)entityHandlerRequest->resJSONPayload, payLoad.c_str(), entityHandlerRequest->resJSONPayloadLen);
+ entityHandlerEntry->second(pRequest, pResponse);
}
else
{
- // TODO throw appropriate runtime error
- // cout << "Payload is larger than the PayloadLen" << endl;
+ std::clog << "C stack should not call again for parent resource\n";
}
}
+ else
+ {
+ std::clog << "No entity handler found." << endl;
+ return OC_EH_ERROR;
+ }
+
+ processResourceResponse(flag, entityHandlerRequest, pResponse);
return OC_EH_OK;
}
OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, initType);
- // Setting default entity Handler
- entityHandlerMap[(OCResourceHandle) 0] = defaultEntityHandler;
-
if(OC_STACK_OK != result)
{
throw InitializeException("Error Initializing Stack", result);
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback& eHandler,
+ EntityHandler& eHandler,
uint8_t resourceProperties)
{
- OCStackResult result;
+ OCStackResult result = OC_STACK_ERROR;
auto cLock = m_csdkLock.lock();
resourceTypeName.c_str(), // const char * resourceTypeName
resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
resourceURI.c_str(), // const char * uri
- EntityHandler, // OCEntityHandler entityHandler
+ EntityHandlerWrapper, // OCEntityHandler entityHandler
resourceProperties // uint8_t resourceProperties
);
}
return result;
}
+ OCStackResult InProcServerWrapper::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
+ {
+ OCStackResult result = OC_STACK_ERROR;
+
+ defaultDeviceEntityHandler = entityHandler;
+
+ if(entityHandler)
+ {
+ result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper);
+ }
+ else
+ {
+ // If Null passed we unset
+ result = OCSetDefaultDeviceEntityHandler(NULL);
+ }
+
+ return result;
+ }
+
OCStackResult InProcServerWrapper::unregisterResource(const OCResourceHandle& resourceHandle)
{
auto cLock = m_csdkLock.lock();
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
- RegisterCallback entityHandler,
+ EntityHandler entityHandler,
uint8_t resourceProperty)
{
- OCStackResult result = OC_STACK_OK;
+ OCStackResult result = OC_STACK_ERROR;
if(m_server)
{
return result;
}
+ OCStackResult OCPlatform::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
+ {
+ OCStackResult result = OC_STACK_ERROR;
+
+ if(m_server)
+ {
+ try{
+ result = m_server->setDefaultDeviceEntityHandler(entityHandler);
+ }
+ catch(std::exception e) // TODO: define our own expception.
+ {
+ throw e;
+ }
+ }
+ return result;
+ }
OCStackResult OCPlatform::unregisterResource(const OCResourceHandle& resourceHandle) const
{
OCStackResult OCPlatform::unbindResource(OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
{
- OCStackResult result = OC_STACK_OK;
+ OCStackResult result = OC_STACK_ERROR;
try {
result = OCUnBindResource(collectionHandle, resourceHandle);
OCStackResult OCPlatform::unbindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
{
- OCStackResult result = OC_STACK_OK;
+ OCStackResult result = OC_STACK_ERROR;
try {
OCStackResult OCPlatform::bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle)
{
- OCStackResult result = OC_STACK_OK;
+ OCStackResult result = OC_STACK_ERROR;
try {
result = OCBindResource(collectionHandle, resourceHandle);
OCStackResult OCPlatform::bindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
{
- OCStackResult result = OC_STACK_OK;
+ OCStackResult result = OC_STACK_ERROR;
try {