From 6a74bd9637d8f9c9808bbbac5d9ff97f3497ed52 Mon Sep 17 00:00:00 2001 From: Sudarshan Prasad Date: Wed, 30 Jul 2014 06:00:56 -0700 Subject: [PATCH] Added modified header files and samples for aug 5 deliverable. Lots of TODOs to complete. But this will get the team going Fixed the author issue Change-Id: Ie2260641248a48ec4100882124223f462af9e19d --- OCLib/OCPlatform.cpp | 130 ++++++++++---------- OCLib/OCResource.cpp | 72 +++++------ examples/simpleclient.cpp | 243 ++++++++++++++++++++++++++++++------- examples/simpleserver.cpp | 281 ++++++++++++++++++++++++++----------------- include/OCApi.h | 53 ++++++-- include/OCPlatform.h | 184 +++++++++++++--------------- include/OCResource.h | 168 ++++++++++++++++++-------- include/OCResourceRequest.h | 100 +++++++++++++++ include/OCResourceResponse.h | 99 +++++++++++++++ 9 files changed, 919 insertions(+), 411 deletions(-) create mode 100644 include/OCResourceRequest.h create mode 100644 include/OCResourceResponse.h diff --git a/OCLib/OCPlatform.cpp b/OCLib/OCPlatform.cpp index ffe7eed..b0e9d7f 100644 --- a/OCLib/OCPlatform.cpp +++ b/OCLib/OCPlatform.cpp @@ -34,78 +34,80 @@ namespace OC { - // Constructor. Internally calls private init function - OCPlatform::OCPlatform(const PlatformConfig& config) - { - init(config); - } + // Constructor. Internally calls private init function + OCPlatform::OCPlatform(const PlatformConfig& config) + { + init(config); + } - // Destructor - OCPlatform::~OCPlatform(void) - { - std::cout << "platform destructor called" << std::endl; - cleanup(); - } + // Destructor + OCPlatform::~OCPlatform(void) + { + std::cout << "platform destructor called" << std::endl; + cleanup(); + } - void OCPlatform::init(const PlatformConfig& config) - { - std::unique_ptr wrapperInstance(new WrapperFactory()); - m_WrapperInstance = std::move(wrapperInstance); + void OCPlatform::init(const PlatformConfig& config) + { + std::unique_ptr wrapperInstance(new WrapperFactory()); + m_WrapperInstance = std::move(wrapperInstance); - if(config.mode == ModeType::Server) - { - // Call server wrapper init - m_server = m_WrapperInstance->CreateServerWrapper(config); - } - else if(config.mode == ModeType::Client) - { - // Call client wrapper init - m_client = m_WrapperInstance->CreateClientWrapper(config); - } - else - { - // This must be both server and client - m_server = m_WrapperInstance->CreateServerWrapper(config); - m_client = m_WrapperInstance->CreateClientWrapper(config); - } - } + if(config.mode == ModeType::Server) + { + // Call server wrapper init + m_server = m_WrapperInstance->CreateServerWrapper(config); + } + else if(config.mode == ModeType::Client) + { + // Call client wrapper init + m_client = m_WrapperInstance->CreateClientWrapper(config); + } + else + { + // This must be both server and client + m_server = m_WrapperInstance->CreateServerWrapper(config); + m_client = m_WrapperInstance->CreateClientWrapper(config); + } + } - void OCPlatform::cleanup() - { - if(m_server) - { - //delete m_server; - } + void OCPlatform::cleanup() + { + if(m_server) + { + //delete m_server; + } - if(m_client) - { - //delete m_client; - } - } + if(m_client) + { + //delete m_client; + } + } - void OCPlatform::findResource(const std::string& host, const std::string& resourceName, - std::function resourceHandler) - { - if(m_client) - { - m_client->ListenForResource(host, resourceName, resourceHandler); - } - } + void OCPlatform::findResource(const std::string& host, const std::string& resourceName, + std::function resourceHandler) + { + if(m_client) + { + m_client->ListenForResource(host, resourceName, resourceHandler); + } + } - void OCPlatform::registerResource(const std::string& resourceURI, const std::string& resourceTypeName, - property_binding_vector properties) - { - if(m_server) - { - try{ - m_server->registerResource(resourceURI, resourceTypeName, properties); - }catch(std::exception e) // define our own expception. - { - throw e; - } - } - } + void OCPlatform::registerResource(std::string& resourceURI, const std::string& resourceTypeName, const std::string& resourceInterface, + std::function entityHandler, ResourceFlag resourceFlag) + { + if(m_server) + { + try{ + // Adding below statement for compilation sake + property_binding_vector properties; + m_server->registerResource(resourceURI, resourceTypeName, properties); + }catch(std::exception e) // define our own expception. + { + throw e; + } + } + } } //namespace OC diff --git a/OCLib/OCResource.cpp b/OCLib/OCResource.cpp index db549f2..dc3d646 100644 --- a/OCLib/OCResource.cpp +++ b/OCLib/OCResource.cpp @@ -22,40 +22,40 @@ #include "OCReflect.h" namespace OC { - OCResource::OCResource(std::string host, boost::property_tree::ptree& resourceNode) : m_isCollection(false) - { - m_host = host; - m_uri = resourceNode.get("href",""); - m_isObservable = resourceNode.get("obs",0)==1; - - boost::property_tree::ptree resourceTypes = resourceNode.get_child("rt", boost::property_tree::ptree()); - for(auto itr : resourceTypes) - { - m_resourceTypes.push_back(itr.second.data()); - } - - boost::property_tree::ptree interfaces = resourceNode.get_child("if", boost::property_tree::ptree()); - for(auto itr : interfaces) - { - if(itr.second.data() == "oc.mi.ll") - { - m_isCollection = true; - } - - m_interfaces.push_back(itr.second.data()); - } - - // TODO: If collection, load children, assuming this becomes a thing - - // TODO: Load attributes, assuming this becomes a 'thing' - - if (m_uri.empty() || resourceTypes.empty() || interfaces.empty()) - { - throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty()); - } - } - - OCResource::~OCResource() - { - } + OCResource::OCResource(const std::string host, boost::property_tree::ptree& resourceNode) : m_isCollection(false) + { + m_host = host; + m_uri = resourceNode.get("href",""); + m_isObservable = resourceNode.get("obs",0)==1; + + boost::property_tree::ptree resourceTypes = resourceNode.get_child("rt", boost::property_tree::ptree()); + for(auto itr : resourceTypes) + { + m_resourceTypes.push_back(itr.second.data()); + } + + boost::property_tree::ptree interfaces = resourceNode.get_child("if", boost::property_tree::ptree()); + for(auto itr : interfaces) + { + if(itr.second.data() == "oc.mi.ll") + { + m_isCollection = true; + } + + m_interfaces.push_back(itr.second.data()); + } + + // TODO: If collection, load children, assuming this becomes a thing + + // TODO: Load attributes, assuming this becomes a 'thing' + + if (m_uri.empty() || resourceTypes.empty() || interfaces.empty()) + { + throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty()); + } + } + + OCResource::~OCResource() + { + } } // namespace OC diff --git a/examples/simpleclient.cpp b/examples/simpleclient.cpp index fde2c86..3168b1f 100644 --- a/examples/simpleclient.cpp +++ b/examples/simpleclient.cpp @@ -26,64 +26,217 @@ using namespace OC; -void foundResource(std::shared_ptr resource){ - - try - { - // Do some operations with resource object. - if(resource) - { - std::cout << "URI of the resource: " << resource->uri() << std::endl; - - std::cout << "Host address of the resource: " << resource->host() << std::endl; - } +const int SUCCESS_RESPONSE = 200; + +// callback handler on GET request +void onGet(const AttributeMap& attributeMap, const int& eCode) +{ + if(eCode == SUCCESS_RESPONSE) + { + for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it) + { + std::cout << "Attribute name: "<< it->first << " value: "; + for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) + { + std::cout << *valueItr << " "; + } + + std::cout << std::endl; + } + } + else + { + std::cout << "Response error: " << eCode << std::endl; + } +} + +// callback handler on PUT request +void onPut(const int& eCode) +{ + if(eCode == SUCCESS_RESPONSE) + { + std::cout << "Put request was successful" << std::endl; + } + else + { + std::cout << "Response error: " << eCode << std::endl; + } +} + +// callback handler on observation +void onObserve(const AttributeMap& attributeMap, const int& eCode) +{ + if(eCode == SUCCESS_RESPONSE) + { + std::cout << "Observe callback invoked" << std::endl; + for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it) + { + std::cout << "Attribute name: "<< it->first << " value: "; + for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) + { + std::cout << *valueItr << " "; + } + + std::cout << std::endl; + } + } + else + { + std::cout << "Response error: " << eCode << std::endl; + } +} + +// callback handler for observe cancellation +void onCancelObservation(const int& eCode) +{ + if(eCode == SUCCESS_RESPONSE) + { + std::cout << "Put request was successful" << std::endl; + } + else + { + std::cout << "Response error: " << eCode << std::endl; + } +} + +// Local function to put a different state for this resource +void putLightRepresentation(std::shared_ptr resource) +{ + if(resource) + { + // Create AttributeMap + AttributeMap attributeMap; + // Add the attribute name and values in the attribute map + AttributeValues stateVal; + stateVal.push_back("true"); + + AttributeValues powerVal; + powerVal.push_back("100"); + + attributeMap["state"] = stateVal; + attributeMap["power"] = powerVal; + + // Create QueryParameters Map and add query params (if any) + QueryParamsMap queryParamsMap; - else - { - std::cout << "Resource invalid" << std::endl; - } + // Invoke resource's pit API with attribute map, query map and the callback parameter + resource->put(attributeMap, queryParamsMap, &onPut); + } +} + +// Local function to get representation of light resource +void getLightRepresentation(std::shared_ptr resource) +{ + if(resource) + { + // Invoke resource's get API with the callback parameter + resource->get(&onGet); + } +} + +// Local function to observe on a resource (in this case light) +void observeOnLight(std::shared_ptr resource) +{ + if(resource) + { + // Invoke resource's observe API with the callback parameter + resource->observe(&onObserve); + } +} + +// Local function to cancel the observation on a resource +void cancelObservation(std::shared_ptr resource) +{ + if(resource) + { + // Invoke resource's cancelObserve API with the callback parameter + resource->cancelObserve(&onCancelObservation); + } +} + +// Callback to found resources +void foundResource(std::shared_ptr resource) +{ + std::string resourceURI; + std::string hostAddress; + try + { + // Do some operations with resource object. + if(resource) + { + // Get the resource URI + resourceURI = resource->uri(); + std::cout << "URI of the resource: " << resourceURI << std::endl; + + // Get the resource host address + hostAddress = resource->host(); + std::cout << "Host address of the resource: " << hostAddress << std::endl; + + if(resourceURI == "/a/light") + { + // Call a local function which will internally invoke get API on the resource pointer + getLightRepresentation(resource); + + // Do some operations + + // Call a local function which will internally invoke get API on the resource pointer + putLightRepresentation(resource); + + // Do some operations + + // Call a local function which will internally observe on this resource for further notifications + observeOnLight(resource); + + // Do some operations + + // Call a local function which will internally cancel observation on this resource + cancelObservation(resource); + } + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } - } - catch(OC::OCReflect::reflection_exception& e) - { - //log(e.what()); - } - catch(std::exception& e) - { - //log(e.what()); - } + } + catch(std::exception& e) + { + //log(e.what()); + } } int main() { - // Create PlatformConfig object + // Create PlatformConfig object - PlatformConfig cfg; - cfg.ipAddress = "134.134.161.33"; - cfg.port = 5683; - cfg.mode = ModeType::Client; - cfg.serviceType = ServiceType::InProc; + PlatformConfig cfg; + cfg.ipAddress = "134.134.161.33"; + cfg.port = 5683; + cfg.mode = ModeType::Client; + cfg.serviceType = ServiceType::InProc; - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. + // Create a OCPlatform instance. + // Note: Platform creation is synchronous call. - try - { - OCPlatform platform(cfg); + try + { + OCPlatform platform(cfg); - // Find all resources - platform.findResource("", "coap://224.0.1.187/oc/core", &foundResource); + // Find all resources + platform.findResource("", "coap://224.0.1.187/oc/core", &foundResource); - while(1) - { - } + while(true) + { + // some operations + } - }catch(OCException e) - { - //log(e.what()); - } + }catch(OCException e) + { + //log(e.what()); + } - return 0; + return 0; } diff --git a/examples/simpleserver.cpp b/examples/simpleserver.cpp index 1e60c21..ea23063 100644 --- a/examples/simpleserver.cpp +++ b/examples/simpleserver.cpp @@ -25,129 +25,192 @@ #include -#include "OCReflect.h" #include "OCPlatform.h" #include "OCApi.h" using namespace OC; -using namespace OC::OCReflect; + +// This is just a sample implementation of entity handler. +// Entity handler can be implemented in several ways by the manufacturer +void entityHandler(std::shared_ptr request, std::shared_ptr response) +{ + // add the headers in this map before sending the response + HeadersMap headersMap; + headersMap["content-type"] = "text"; + headersMap["server"] = "serverName"; + + if(request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + RequestHandlerFlag requestFlag = request->getRequestHandlerFlag(); + + if(requestFlag == RequestHandlerFlag::InitFlag) + { + // entity handler to perform resource initialization operations + } + else if(requestFlag == RequestHandlerFlag::RequestFlag) + { + // If the request type is GET + if(requestType == "GET") + { + // Check for query params (if any) + QueryParamsMap queryParamsMap = request->getQueryParameters(); + + // Process query params and do required operations .. + + // Get the representation of this resource at this point and send it as response + AttributeMap attributeMap; + AttributeValues stateVal; + stateVal.push_back("false"); + + AttributeValues powerVal; + powerVal.push_back("0"); + + attributeMap["state"] = stateVal; + attributeMap["power"] = powerVal; + + if(response) + { + response->setResponseHeaders(headersMap); + response->setHTTPErrorCode(200); + response->setResourceRepresentation(attributeMap); + } + } + else if(requestType == "PUT") + { + // Check for query params (if any) + QueryParamsMap queryParamsMap = request->getQueryParameters(); + + // Check queryParamsMap and do required operations .. + + // Get the representation from the request + AttributeMap attributeMap = request->getResourceRepresentation(); + + // Do related operations related to PUT request + // Change the attribute map accordingly and send a response + + AttributeValues stateVal; + stateVal.push_back("true"); + + AttributeValues powerVal; + powerVal.push_back("100"); + + attributeMap["state"] = stateVal; + attributeMap["power"] = powerVal; + + if(response) + { + response->setResponseHeaders(headersMap); + response->setHTTPErrorCode(200); + response->setResourceRepresentation(attributeMap); + } + } + else if(requestType == "POST") + { + // POST request operations + } + else if(requestType == "DELETE") + { + // DELETE request operations + } + } + else if(requestFlag == RequestHandlerFlag::ObserverFlag) + { + // perform observe related operations on the resource. + // Add the attributes to the map and send a response + + // on any attribute change on the light resource hardware, + // set the attributes and send response + AttributeMap attributeMap; + + AttributeValues stateVal; + stateVal.push_back("false"); + + AttributeValues powerVal; + powerVal.push_back("0"); + + attributeMap["state"] = stateVal; + attributeMap["power"] = powerVal; + + if(response) + { + response->setResponseHeaders(headersMap); + response->setHTTPErrorCode(200); + response->setResourceRepresentation(attributeMap); + } + } + } + else + { + std::cout << "Request invalid" << std::endl; + } +} /// This class represents a single resource named 'lightResource'. This resource has -/// two simple properties named 'state' and 'power' and they have respective setter -/// and getter methods. +/// two simple properties named 'state' and 'power' class LightResource { -private: - /// Access this property from a TB client - bool m_state; - int m_power; - public: - LightResource() - : m_state(false), m_power(0) - {} + /// Access this property from a TB client + bool m_state; + int m_power; public: - /// Setter method for the setting the power of this light resource - void setPower(int powerValue) - { - m_power = powerValue; - } - - /// Getter method for the getting the power of this light resource - int getPower() const - { - return m_power; - } - - /// Setter method for the setting the state of this light resource - void setState(bool state) - { - m_state = state; - } - - /// Getter method for the getting the state of this light resource - bool getState() const - { - return m_state; - } - -public: - /* Note that this does not need to be a member function: for classes you do not have - access to, you can accomplish this with a free function: */ - - /// This function binds the properties and methods to the server. - void createResourceWithPropeties(OC::OCPlatform& platform) - { - /* - We could typedef to simpler names! :) - typedef property_binding_vector OCPropertyBindings; - typedef property_binding OCPropertyBinding; - - OCPropertyBindings properties { - OCPropertyBinding("state", property_type::boolean), - OCPropertyBidning("power", property_type::integer) - - using OC::OCReflect::property_type; - using OC::OCReflect::property_binding; - - property_binding_vector properties { - property_binding("state", property_type::boolean), - property_binding("power", property_type::integer) - }; - */ - - auto properties { - property_binding{"state", property_type::boolean}, - property_binding{"power", property_type::integer} - }; - - std::string resourceURI = "/a/light"; - std::string resourceTypeName = "light"; - - // This will internally invoke registerResource method (which would eventually create - // resource). - - platform.registerResource(resourceURI, resourceTypeName, properties); - } + /// Constructor + LightResource(): m_state(false), m_power(0){} + + /* Note that this does not need to be a member function: for classes you do not have + access to, you can accomplish this with a free function: */ + + /// This function internally calls registerResource API. + void createResource(OC::OCPlatform& platform) + { + std::string resourceURI = "a/light"; // URI of the resource + std::string resourceTypeName = "light"; // resource type name. In this case, it is light + std::string resourceInterface = LINK_INTERFACE; // resource interface. + ResourceFlag resourceFlag = ResourceFlag::ObserverFlag; // set the resource flag to Observerable + + // This will internally create and register the resource. + platform.registerResource(resourceURI, resourceTypeName, resourceInterface, &entityHandler, resourceFlag); + } }; int main() { - // Create PlatformConfig object - - PlatformConfig cfg; - //cfg.ipAddress = "192.168.1.5"; - cfg.ipAddress = "134.134.161.33"; - cfg.port = 5683; - cfg.mode = ModeType::Server; - cfg.serviceType = ServiceType::InProc; - - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. - try - { - OCPlatform platform(cfg); - - // Create the instance of the resource class (in this case instance of class 'LightResource'). - // Invoke bindTo function of class light. - - LightResource myLightResource; - myLightResource.createResourceWithPropeties(platform); - - // Perform app tasks - while(true) - { - // some tasks - } - } - catch(OCException e) - { - //log(e.what()); - } - - - // No explicit call to stop the platform. - // When OCPlatform destructor is invoked, internally we do platform cleanup + // Create PlatformConfig object + + PlatformConfig cfg; + cfg.ipAddress = "134.134.161.33"; + cfg.port = 5683; + cfg.mode = ModeType::Server; + cfg.serviceType = ServiceType::InProc; + + // Create a OCPlatform instance. + // Note: Platform creation is synchronous call. + try + { + OCPlatform platform(cfg); + + // Create the instance of the resource class (in this case instance of class 'LightResource'). + // Invoke bindTo function of class light. + + LightResource myLightResource; + myLightResource.createResource(platform); + + // Perform app tasks + while(true) + { + // some tasks + } + } + catch(OCException e) + { + //log(e.what()); + } + + + // No explicit call to stop the platform. + // When OCPlatform destructor is invoked, internally we do platform cleanup } diff --git a/include/OCApi.h b/include/OCApi.h index 12fa379..23c61c9 100644 --- a/include/OCApi.h +++ b/include/OCApi.h @@ -23,6 +23,7 @@ #include #include +#include namespace OC { @@ -39,37 +40,65 @@ struct entity; namespace OC { enum class OCPlatformStatus { - PlatformUp, - PlatformDown + PlatformUp, + PlatformDown }; enum class OCAdvertisementStatus{ - None + None }; typedef std::string URI; enum class ServiceType { - InProc, - OutOfProc + InProc, + OutOfProc }; enum class ModeType { - Server, - Client, - Both + Server, + Client, + Both }; 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 + 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 }; + enum class RequestHandlerFlag + { + InitFlag, + RequestFlag, + ObserverFlag + }; + + enum class ResourceFlag + { + DiscoverableFlag, + ObserverFlag + }; + + // TODO: To find the complete JSon data structure and modify map value type + typedef std::vector AttributeValues; + typedef std::map AttributeMap; + + typedef std::map QueryParamsMap; + + typedef std::map HeadersMap; + + const std::string LINK_INTERFACE = "oc.mi.ll"; + const std::string BATCH_INTERFACE = "oc.mi.b"; + const std::string SENSOR_INTERFACE = "oc.mi.s"; + const std::string ACTUATOR_INTERFACE = "oc.mi.a"; + const std::string PARAMETER_INTERFACE = "oc.mi.p"; + const std::string READ_PARAMETER_INTERFACE = "oc.mi.rp"; + } // namespace OC -#endif +#endif diff --git a/include/OCPlatform.h b/include/OCPlatform.h index daa6a06..c499e08 100644 --- a/include/OCPlatform.h +++ b/include/OCPlatform.h @@ -20,8 +20,8 @@ /// @file OCPlatform.h -/// @brief This file contains the declaration of classes and its members related to -/// OCPlatform. +/// @brief This file contains the declaration of classes and its members related to +/// OCPlatform. #ifndef __OCPLATFORM_H #define __OCPLATFORM_H @@ -32,105 +32,93 @@ #include "OCResource.h" #include "OCPlatformHandler.h" #include "WrapperFactory.h" -#include - -using namespace OC::OCReflect; +#include "OCResourceRequest.h" +#include "OCResourceResponse.h" namespace OC { - using OC::OCReflect::property_type; - using OC::OCReflect::property_binding; - - /** - * @brief The core OC platform object initialized by the application or service via a static accessor. - * On successful initialization an instance of the OCPlatform is returned. - * Handler registered that receives various platform/stack updates. The stack object - * also provides methods for managing advertisement and discovery. - */ - class OCPlatform - { - public: - /** - * @fn Constructor for OCPlatform. Constructs a new OCPlatform from a given PlatformConfig with - * appropriate fields - * @param config - PlatformConfig struct which has details such as modeType (server/client/both), - * in-proc/out-of-proc etc. - */ - OCPlatform(const PlatformConfig& config); - - /** - * @fn Virtual destructor - */ - virtual ~OCPlatform(void); - - /** - * @fn API for Service and Resource Discovery - * - * @param host - Host IP Address of a service to direct resource discovery query. If null or - * empty, performs service discovery OR resource discovery query to ALL group members. - * @param filter - Filter Type - Can be one of two of the link - * format equivalent attribute types declared in table 7 of the - * OC-Lite-Product-Specification-V1 Document. Either "n" (i.e. Resource Name) or "rt" - * (i.e. Resource Type). Value - Can be any valid std::string that's defined to work with CoRE - * Link Attributes as defined in the RFC6690. - * @param handler - Handles callbacks, success states and failure states. - * - * Four modes of discovery defined as follows: - * (NULL/Empty, NULL/Empty) - Performs ALL service discovery AND ALL resource discovery. - * (NULL/Empty, Not Empty) - Performs query for a filtered/scoped/particular resource(s) - * from ALL services. - * (Not Empty, NULL/Empty) - Performs ALL resource discovery on a particular service. - * (Not Empty, Not Empty) - Performs query for a filtered/scoped/particular resource(s) - * from a particular service. - * - * Thread-Safety: TODO Determine if it is going to be safe to call in a UI thread - */ - void findResource(const std::string& host, const std::string& resourceName, - std::function resourceHandler); - - /** - * @fn Queries the network for available resources. - * - * NOTE: This gets posted to a new thread so it doesn't hold the UI or network thread. - * - * @param serviceURL - The URL to the service. NULL for a broadcast/multicast. - * @param resourceType - The resource type filter. NULL for match any. - * - * @throws This may throw if the service is not started, network is bad, etc. - * - * Thread-Safety: TODO Determine if it is going to be safe to call in a UI thread - */ - void findResourceByType(const std::string& serviceURL, const std::string& resourceType, - std::function resourceHandler); - - /** - * @fn Registers the resource with its name, type and list of properties - * - * NOTE: Properties are prepared prior to this call using generic functions from OCReflect - * - * @param resourceURI - The URI of the resoruce. - * @param resourceTypeName - The resource type. - * @param properties - vector of properties for this resource - * - */ - void registerResource(const std::string& resourceURI, const std::string& resourceTypeName, - property_binding_vector properties); - - private: - std::unique_ptr m_WrapperInstance; - IServerWrapper::Ptr m_server; - IClientWrapper::Ptr m_client; - - /** - * @fn Private function to initalize the platfrom - */ - void init(const PlatformConfig& config); - - /** - * @fn Private function cleanup the platform - */ - void cleanup(); - }; + /** + * @brief Both server and client must initialize the core platform by instantiating OCPlatform. + * On successful initialization, an instance of the OCPlatform is returned. + * APIs in OCPlatform provide mechanism to register a resource and host the resource + * on the server, find resources on the network etc. + */ + class OCPlatform + { + public: + /** + * Constructor for OCPlatform. Constructs a new OCPlatform from a given PlatformConfig with + * appropriate fields + * @param config PlatformConfig struct which has details such as modeType (server/client/both), + * in-proc/out-of-proc etc. + */ + OCPlatform(const PlatformConfig& config); + + /** + * Virtual destructor + */ + virtual ~OCPlatform(void); + + /** + * API for Service and Resource Discovery. + * NOTE: This API applies to client side only. + * + * @param host - Host IP Address of a service to direct resource discovery query. If null or + * empty, performs multicast resource discovery query + * @param resourceURI - name of the resource. If null or empty, performs search for all resource names + * @param handler - Handles callbacks, success states and failure states. + * + * Four modes of discovery defined as follows: + * (NULL/Empty, NULL/Empty) - Performs ALL service discovery AND ALL resource discovery. + * (NULL/Empty, Not Empty) - Performs query for a filtered/scoped/particular resource(s) + * from ALL services. + * (Not Empty, NULL/Empty) - Performs ALL resource discovery on a particular service. + * (Not Empty, Not Empty) - Performs query for a filtered/scoped/particular resource(s) + * from a particular service. + * NOTE: First parameter 'host' currently represents an IP address. This will change in future + * and will refer to endpoint interface so that we can refer to other transports such as BTH etc. + * Example: + * + */ + void findResource(const std::string& host, const std::string& resourceURI, + std::function resourceHandler); + + /** + * This API registers a resource with the server + * NOTE: This API applies to server side only. + * + * @param resourceURI - The URI of the resource. Example: "a/light". See NOTE below + * @param resourceTypeName - The resource type. Example: "light" + * @param resourceInterface - The resource interface (whether it is collection etc). + * @param entityHandler - entity handler callback. + * @param resourceFlag - flag to indicate discoverable/observable etc. + * + * 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" + * 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 + */ + void registerResource(std::string& resourceURI, const std::string& resourceTypeName, const std::string& resourceInterface, + std::function entityHandler, ResourceFlag resourceFlag); + + private: + std::unique_ptr m_WrapperInstance; + IServerWrapper::Ptr m_server; + IClientWrapper::Ptr m_client; + + /** + * Private function to initalize the platfrom + */ + void init(const PlatformConfig& config); + + /** + * Private function cleanup the platform + */ + void cleanup(); + }; } #endif //__OCPLATFORM_H diff --git a/include/OCResource.h b/include/OCResource.h index 5ffa693..278f0b3 100644 --- a/include/OCResource.h +++ b/include/OCResource.h @@ -20,8 +20,8 @@ /// @file OCResource.h -/// @brief This file contains the declaration of classes and its members related to -/// Resource. +/// @brief This file contains the declaration of classes and its members related to +/// Resource. #ifndef __OCRESOURCE_H #define __OCRESOURCE_H @@ -37,51 +37,125 @@ namespace OC { - /** - * @brief OCResource represents an OC resource. A resource could be a light controller, - * temperature sensor, smoke detector, etc. A resource comes with a well-defined - * contract or interface onto which you can perform different operations, such as - * turning on the light, getting the current temperature or subscribing for event - * notifications from the smoke detector. A resource can be composed of one or - * more resources. - */ - class OCResource - { - public: - typedef std::shared_ptr Ptr; - - OCResource(std::string host, boost::property_tree::ptree& resourceNode); - virtual ~OCResource(void); - - // Gets the device host URI - std::string host() const {return m_host;} - // Gets the device-relative URI for this resource - std::string uri() const {return m_uri;} - // bool whether it is possible to attach an observer to this resource - bool isObservable() const {return m_isObservable;} - // bool whether this is a collection type, and will have children that can be queried - bool isCollection() const {return m_isCollection;} - // a collection of the resource-type names - const std::vector resourceTypes() const {return m_resourceTypes;} - // a collection of the interfaces supported by this resource - const std::vector interfaces() const { return m_interfaces;} - // a collection of property objects that allow calling of properties on this Resource - const std::vector properties() const { return m_properties;} - // a collection of the names of the children of this resource, assuming it supports a collection interface - const std::vector children() const {return m_children;} - - - // a method which allows - private: - std::string m_uri; - std::string m_host; - bool m_isObservable; - bool m_isCollection; - std::vector m_resourceTypes; - std::vector m_interfaces; - std::vector m_properties; // TODO: give a better type once we have the ability to call one! - std::vector m_children; - }; + /** + * @brief OCResource represents an OC resource. A resource could be a light controller, + * temperature sensor, smoke detector, etc. A resource comes with a well-defined + * contract or interface onto which you can perform different operations, such as + * turning on the light, getting the current temperature or subscribing for event + * notifications from the smoke detector. A resource can be composed of one or + * more resources. + */ + class OCResource + { + public: + typedef std::shared_ptr Ptr; + + // TODO: This constructor needs to be removed when we give the final version + // TODO: See if we can do const prop tree + OCResource(const std::string host, boost::property_tree::ptree& resourceNode); + + virtual ~OCResource(void); + + /** + * Function to get the attributes of a resource. + * TODO : Need to have query params? Add implementation in .cpp + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Get operation + * This will have HTTP error codes + */ + void get(std::function attributeHandler) { return; } + + /** + * Function to set the attributes of a resource (via PUT) + * TODO Add implementation in .cpp + * @param AttributeMap Map which can either have all the attribute names and values + (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * (which will represent part of the resoruce state) via PUT + * @param queryParametersMap a map which will have the query parameters (if any) + * NOTE: For the current release, only '&' semantics will be provided + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have HTTP error codes + */ + void put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function attributeHandler) { return; } + + /** + * Function to set observation on the resource + * TODO Add implementation in .cpp + * @param observeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this observe operation + * This will have HTTP error codes + */ + void observe(std::function observeHandler) { return; } + + /** + * Function to cancel the observation on the resource + * TODO Add implementation in .cpp + * @param observeCancellationHandler handles callback + * The callback function will also have the result from this operation + * This will have HTTP error codes + */ + void cancelObserve(std::function observeCancellationHandler) { return; } + + /** + * Function to get the host address of this resource + * @return std::string host address + * NOTE: This might or might not be exposed in future due to security concerns + */ + std::string host() const {return m_host;} + + /** + * Function to get the URI for this resource + * @return std::string resource URI + */ + std::string uri() const {return m_uri;} + + /** + * Function to provide ability to check if this resource is observable or not + * @return bool true indicates resource is observable; false indicates resource is + * not observable. + */ + bool isObservable() const {return m_isObservable;} + + /* + * Allows the server to call notifyObserver + * @return bool true indicates this operation was success; false indicates this + * operation failed + */ + //static bool notifyObservers(const std::string& resourceURI); + + // bool whether this is a collection type, and will have children that can be queried + //bool isCollection() const {return m_isCollection;} + // a collection of the resource-type names + //const std::vector resourceTypes() const {return m_resourceTypes;} + // a collection of the interfaces supported by this resource + //const std::vector interfaces() const { return m_interfaces;} + // a collection of property objects that allow calling of properties on this Resource + //const std::vector properties() const { return m_properties;} + // a collection of the names of the children of this resource, assuming it supports a collection interface + //const std::vector children() const {return m_children;} + + /*void post(const AttributeMap&, std::function attributeHandler); + + NOTE: dont expose the host ip .. so some kind of handle is required + static OCResource::Ptr getResource(const std::string& host, const std::string& resourceURI, const std::string& resourceName, + const std::string interfaceName, bool observerable);*/ + + + private: + std::string m_uri; + std::string m_host; + bool m_isObservable; + bool m_isCollection; + std::vector m_resourceTypes; + std::vector m_interfaces; + std::vector m_children; + AttributeMap m_attributeMap; + }; } // namespace OC diff --git a/include/OCResourceRequest.h b/include/OCResourceRequest.h new file mode 100644 index 0000000..5b50f59 --- /dev/null +++ b/include/OCResourceRequest.h @@ -0,0 +1,100 @@ +//****************************************************************** +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file OCResourceRequest.h + +/// @brief This file contains the declaration of classes and its members related to +/// ResourceRequest. + +#ifndef __OCRESOURCEREQUEST_H +#define __OCRESOURCEREQUEST_H + +#include "OCApi.h" + +namespace OC +{ + /** + * @brief OCResourceRequest provides APIs to extract details from a request URI + */ + class OCResourceRequest + { + public: + typedef std::shared_ptr Ptr; + + /** + * Virtual destructor + */ + virtual ~OCResourceRequest(void); + + /** + * Retrieves the type of request string for the entity handler function to operate + * @return std::string request type. This could be 'GET'/'PUT'/'POST'/'DELETE' + */ + std::string getRequestType() const {return m_requestType;} + + /** + * Retrieves the payload from the request. + * NOTE: Query parameters are retrived in a separate API (see 'getRequestPayload') + * @return std:string request payload + */ + std::string getRequestPayload() const {return m_requestPayload;} + + /** + * Retrieves the query parameters from the request + * @return std::string query parameters in the request + */ + const QueryParamsMap& getQueryParameters() const {return m_queryParameters;} + + /** + * Retrieves the request handler flag type. This can be either INIT flag or REQUEST flag + * OBSERVE flag. + * NOTE: + * INIT indicates that the vendor's entity handler should go and perform initialization operations + * REQUEST indicates that it is a request of certain type (GET/PUT/POST/DELETE) and entity handler needs to perform + * corresponding operations + * OBSERVE indicates that the request is of type Observe and entity handler needs to perform corresponding operations + * @return std::string type of request flag + */ + RequestHandlerFlag getRequestHandlerFlag() const {return m_requestHandlerFlag;} + + /** + * Provides the entire resource attribute representation + * @return std::map AttributeMap reference containing the name value pairs representing the resource's attributes + */ + const AttributeMap& getResourceRepresentation() const {return m_attributeMap;} + + private: + std::string m_requestType; + std::string m_requestPayload; + QueryParamsMap m_queryParameters; + RequestHandlerFlag m_requestHandlerFlag; + AttributeMap m_attributeMap; + + private: + void setRequestType(const std::string& requestType); + void setRequestPayload(const std::string& requestPayload); + void setQueryParams(QueryParamsMap& queryParams); + void setRequestHandlerFlag(RequestHandlerFlag requestHandlerFlag); + void setResourceRepresentation(AttributeMap& attributeMap); + }; + +} // namespace OC + +#endif //__OCRESOURCEREQUEST_H diff --git a/include/OCResourceResponse.h b/include/OCResourceResponse.h new file mode 100644 index 0000000..1e34f06 --- /dev/null +++ b/include/OCResourceResponse.h @@ -0,0 +1,99 @@ +//****************************************************************** +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file OCResourceResponse.h + +/// @brief This file contains the declaration of classes and its members related to +/// ResourceResponse. + +#ifndef __OCRESOURCERESPONSE_H +#define __OCRESOURCERESPONSE_H + +#include "OCApi.h" + +namespace OC +{ + /** + * @brief OCResourceResponse provides APIs to set the response details + */ + class OCResourceResponse + { + public: + typedef std::shared_ptr Ptr; + + /** + * OCResourceResponse Construtor + * @param responseHeaders response header information in a map + * @param eCode HTTP error code for this response. + * @param attributeMap reference to AttributeMap which contains the full attribute representation + * of the resource. + */ + OCResourceResponse(HeadersMap& responseHeaders, int eCode, AttributeMap& attributeMap) : + m_responseHeaders(responseHeaders), m_HTTPErrorCode(eCode), m_attributeMap(attributeMap) {} + + /** + * Virtual destructor + */ + virtual ~OCResourceResponse(void); + + /** + * This API sets the response headers for the response + * @param responseHeaders std::string reference + */ + void setResponseHeaders(HeadersMap& responseHeaders) { m_responseHeaders = responseHeaders; } + + /** + * This API sets the HTTP error code for this response + * @param eCode HTTP error code to set + */ + void setHTTPErrorCode(const int eCode) { m_HTTPErrorCode = eCode; } + + /** + * API to set the entire resource attribute representation + * @param attributeMap reference containing the name value pairs representing the resource's attributes + */ + void setResourceRepresentation(AttributeMap& attributeMap) { m_attributeMap = attributeMap; } + + private: + HeadersMap m_responseHeaders; + int m_HTTPErrorCode; // TODO remove 'HTTP'. It can be any protocol and ISV need not know it + AttributeMap m_attributeMap; + + private: + + /** + * Get response headers + */ + HeadersMap& getResponseHeaders() const; + + /** + * Get HTTP status error code + */ + int getHTTPErrorCode() const; + + /** + * Get the resource attribute representation + */ + AttributeMap& getResourceRepresentation() const; + }; + +} // namespace OC + +#endif //__OCRESOURCERESPONSE_H -- 2.7.4