using namespace OC;
namespace PH = std::placeholders;
+// Option ID for API version and client token
+const uint16_t API_VERSION = 2048;
+const uint16_t TOKEN = 3000;
+
class ClientFridge
{
public:
OCResource::Ptr randomdoor = m_platform.constructResourceObject(resource->host(),
"/door/random", false, doorTypes, ifaces);
+ // Set header options with API version and token
+ HeaderOptions headerOptions;
+ try
+ {
+ // Set API version and client token
+ HeaderOption::OCHeaderOption apiVersion(API_VERSION, "v.1.0");
+ HeaderOption::OCHeaderOption clientToken(TOKEN, "21ae43gf");
+ headerOptions.push_back(apiVersion);
+ headerOptions.push_back(clientToken);
+ }
+ catch(OCException& e)
+ {
+ std::cout << "Error creating HeaderOption: " << e.what() << std::endl;
+ }
+
+
+ // Setting header options will send above options in all requests
+ // Header options are set per resource.
+ // Below, header options are set only for device resource
+ resource->setHeaderOptions(headerOptions);
+
+ resource->get(QueryParamsMap(), GetCallback(
+ std::bind(&ClientFridge::getResponse, this, "Device", PH::_1,
+ PH::_2, PH::_3, resource, 0)
+ ));
light->get(QueryParamsMap(), GetCallback(
std::bind(&ClientFridge::getResponse, this, "Fridge Light", PH::_1,
- PH::_2, light, 1)
+ PH::_2, PH::_3, light, 1)
));
leftdoor->get(QueryParamsMap(), GetCallback(
std::bind(&ClientFridge::getResponse, this, "Left Door", PH::_1,
- PH::_2, leftdoor, 2)
+ PH::_2, PH::_3, leftdoor, 2)
));
rightdoor->get(QueryParamsMap(), GetCallback(
std::bind(&ClientFridge::getResponse, this, "Right Door", PH::_1,
- PH::_2, rightdoor, 3)
+ PH::_2, PH::_3, rightdoor, 3)
));
randomdoor->get(QueryParamsMap(), GetCallback(
std::bind(&ClientFridge::getResponse, this, "Random Door", PH::_1,
- PH::_2, randomdoor, 4)
+ PH::_2, PH::_3, randomdoor, 4)
));
}
// it is possible to attach ANY arbitrary data to do whatever you would like here. It may,
// however be a better fit to wrap each call in an object so a fuller context (and additional
// requests) can be easily made inside of a simple context
- void getResponse(const std::string& resourceName, const OCRepresentation rep, const int eCode,
- OCResource::Ptr resource, int getId)
+ void getResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
+ const OCRepresentation rep, const int eCode, OCResource::Ptr resource, int getId)
{
std::cout << "Got a response from get from the "<<resourceName<< std::endl;
std::cout << "Get ID is "<<getId<<" and resource URI is "<<resource->uri()<<std::endl;
std::cout << "The Attribute Data is: "<<std::endl;
+ for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
+ {
+ if(it->getOptionID() == API_VERSION)
+ {
+ std::cout << "Server API version in GET response: " <<
+ it->getOptionData() << std::endl;
+ }
+ }
+
switch(getId)
{
+ case 0:
+ {
+ // Get on device
+ std::string name;
+ rep.getValue("device_name", name);
+ std::cout << "Name of device: "<< name << std::endl;
+ break;
+ }
case 1:
{
bool isOn;
using namespace OC;
namespace PH = std::placeholders;
+// Option ID for API version and client token
+const uint16_t API_VERSION = 2048;
+const uint16_t TOKEN = 3000;
+
+// Setting API version and token (shared out of band with client)
+// This assumes the fact that this server responds
+// only with a server with below version and token
+const std::string FRIDGE_CLIENT_API_VERSION = "v.1.0";
+const std::string FRIDGE_CLIENT_TOKEN = "21ae43gf";
+
class Resource
{
protected:
{
if(request)
{
- if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+ // Get the header options from the request
+ HeaderOptions headerOptions = request->getHeaderOptions();
+ std::string clientAPIVersion;
+ std::string clientToken;
+
+ // Search the header options map and look for API version and Client token
+ for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
{
- if(request->getRequestType() == "GET")
+ uint16_t optionID = it->getOptionID();
+ if(optionID == API_VERSION)
{
- if(response)
+ clientAPIVersion = it->getOptionData();
+ std::cout << " Client API version: " << clientAPIVersion << std::endl;
+ }
+ else if(optionID == TOKEN)
+ {
+ clientToken = it->getOptionData();
+ std::cout << " Client token: " << clientToken << std::endl;
+ }
+ else
+ {
+ std::cout << " Invalid header option " << std::endl;
+ }
+ }
+
+ // In this case Server entity handler verifies API version
+ // and client token. If they are valid, client requests are handled.
+ if(clientAPIVersion == FRIDGE_CLIENT_API_VERSION && clientToken == FRIDGE_CLIENT_TOKEN)
+ {
+ HeaderOptions serverHeaderOptions;
+ try
+ {
+ // Set API version from server side
+ HeaderOption::OCHeaderOption apiVersion(API_VERSION, FRIDGE_CLIENT_API_VERSION);
+ serverHeaderOptions.push_back(apiVersion);
+ }
+ catch(OCException& e)
+ {
+ std::cout << "Error creating HeaderOption in server: " << e.what() << std::endl;
+ }
+
+ if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+ {
+ if(request->getRequestType() == "GET")
{
- std::cout<<"DeviceResource Get Request"<<std::endl;
- response->setErrorCode(200);
- response->setResourceRepresentation(get(), "");
+ if(response)
+ {
+ std::cout<<"DeviceResource Get Request"<<std::endl;
+ response->setErrorCode(200);
+ response->setHeaderOptions(serverHeaderOptions);
+ response->setResourceRepresentation(get(), "");
+ }
+ }
+ else
+ {
+ std::cout <<"DeviceResource unsupported request type "
+ << request->getRequestType() << std::endl;
}
}
else
{
- std::cout <<"DeviceResource unsupported request type "
- << request->getRequestType() << std::endl;
+ std::cout << "DeviceResource unsupported request flag" <<std::endl;
}
}
else
{
- std::cout << "DeviceResource unsupported request flag" <<std::endl;
+ std::cout << "Unsupported/invalid header options/values" << std::endl;
}
}
}
}
else
{
- std::cout <<"Light unsupported request type "
+ std::cout << "Light unsupported request type"
<< request->getRequestType() << std::endl;
}
}
virtual void entityHandler(std::shared_ptr<OCResourceRequest> request,
std::shared_ptr<OCResourceResponse> response)
{
+ std::cout << "EH of door invoked " << std::endl;
if(request)
{
std::cout << "In entity handler for Door, URI is : "
}
// callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
}
// Callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
class resource_handle
{
friend class resource_handler;
-
+
private:
const std::string URI;
std::shared_ptr<OC::OCResource> resource;
// 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);
+ void onResourceGet(const OC::HeaderOptions& headerOptions,
+ OC::OCRepresentation rep, const int error_code);
+ void onResourcePut(const OC::HeaderOptions& headerOptions, const OC::OCRepresentation rep,
+ const int error_code);
+ void onObserve(const OC::HeaderOptions& headerOptions, const OC::OCRepresentation rep,
+ const int error_code, const int& sequence_number);
};
class resource_handler
call_timer.mark("find_resources");
- platform.findResource("", resource->URI,
+ platform.findResource("", resource->URI,
std::bind(&resource_handle::onFoundResource, resource, std::placeholders::_1));
- }
+ }
}
};
: platform(platform_)
{
for(const auto& URI : resource_URIs)
- add(URI);
+ add(URI);
}
resource_handler::resource_handler(OC::OCPlatform& platform_)
OC::QueryParamsMap qpm;
- resource->get(qpm, std::bind(&resource_handle::onResourceGet, this,
- std::placeholders::_1, std::placeholders::_2));
+ resource->get(qpm, std::bind(&resource_handle::onResourceGet, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
catch(OC::OCException& e)
{
}
}
-void resource_handle::onResourceGet(const OC::OCRepresentation rep, const int error_code)
+void resource_handle::onResourceGet(const OC::HeaderOptions& headerOptions,
+ const OC::OCRepresentation rep, const int error_code)
{
using std::cout;
std::cout << "input attributes:\n" << rep.getAttributeMap() << '\n';
- // Now, make a change to the light representation (replacing, rather than parsing):
+ // Now, make a change to the light representation (replacing, rather than parsing):
OC::AttributeMap attrs {
{ "state", { "true" } },
{ "power", { "10" } }
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));
+ out_rep.setAttributeMap(attrs);
+
+ resource->put(out_rep, OC::QueryParamsMap(),
+ std::bind(&resource_handle::onResourcePut, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3));
}
-void resource_handle::onResourcePut(const OC::OCRepresentation rep, const int error_code)
+void resource_handle::onResourcePut(const OC::HeaderOptions& headerOptions,
+ const OC::OCRepresentation rep, const int error_code)
{
std::cout << "onResourcePut():\n";
// 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));
+ std::bind(&resource_handle::onObserve, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ std::placeholders::_4));
}
-void resource_handle::onObserve(const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
+void resource_handle::onObserve(const OC::HeaderOptions& headerOptions,
+ const OC::OCRepresentation rep, const int error_code, const int& sequence_number)
{
if(0 != error_code)
{
const auto result = resource->cancelObserve();
std::cout << "onObserve(): result of cancellation: " << result << ".\n";
-
+
this_thread::sleep_for(chrono::seconds(10));
}
}
// Forward declaration
void putRoomRepresentation(std::shared_ptr<OCResource> resource);
-void onPut(const OCRepresentation& rep, const int eCode);
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
// callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
}
// callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
return ++oc;
}
-void onObserve(const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
+void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep,
+ const int& eCode, const int& sequenceNumber)
{
if(eCode == SUCCESS_RESPONSE)
{
}
}
-void onPost2(const OCRepresentation& rep, const int eCode)
+void onPost2(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
}
}
-void onPost(const OCRepresentation& rep, const int eCode)
+void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
}
// callback handler on PUT request
-void onPut(const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
}
// Callback handler on GET request
-void onGet(const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
private:
bool m_isFoo;
int m_barCount;
- void putResourceInfo(const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
+ void putResourceInfo(const HeaderOptions& headerOptions,
+ const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
{
std::cout << "In PutResourceInfo" << std::endl;
}
}
- void getResourceInfo(const OCRepresentation rep, const int eCode)
+ void getResourceInfo(const HeaderOptions& headerOptions, const OCRepresentation rep,
+ const int eCode)
{
std::cout << "In getResourceInfo" << std::endl;
rep2.setValue("isFoo", m_isFoo);
rep2.setValue("barCount", m_barCount);
- m_resource->put(rep2, QueryParamsMap(), PutCallback(std::bind(&ClientWorker::putResourceInfo, this, rep2, std::placeholders::_1, std::placeholders::_2)));
+ m_resource->put(rep2, QueryParamsMap(),
+ PutCallback(std::bind(&ClientWorker::putResourceInfo, this, std::placeholders::_1,
+ rep2, std::placeholders::_2, std::placeholders::_3)));
}
}
std::cout<<"Doing a get on q/foo."<<std::endl;
- resource->get(QueryParamsMap(), GetCallback(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
+ resource->get(QueryParamsMap(),
+ GetCallback(std::bind(&ClientWorker::getResourceInfo, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
}
}
virtual OCStackResult GetResourceRepresentation(const std::string& host,
const std::string& uri, const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions,
GetCallback& callback)=0;
virtual OCStackResult PutResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& rep,
- const QueryParamsMap& queryParams,
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
PutCallback& callback) = 0;
virtual OCStackResult PostResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& rep,
- const QueryParamsMap& queryParams,
- PutCallback& callback) = 0;
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PostCallback& callback) = 0;
virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
const std::string& host, const std::string& uri,
- const QueryParamsMap& queryParams,
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
ObserveCallback& callback)=0;
virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
- const std::string& uri)=0;
+ const std::string& uri, const HeaderOptions& headerOptions)=0;
virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
SubscribeCallback& presenceHandler)=0;
virtual OCStackResult GetResourceRepresentation(const std::string& host,
const std::string& uri, const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions,
GetCallback& callback);
virtual OCStackResult PutResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& attributes,
- const QueryParamsMap& queryParams, PutCallback& callback);
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PutCallback& callback);
virtual OCStackResult PostResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& attributes,
- const QueryParamsMap& queryParams, PostCallback& callback);
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PostCallback& callback);
virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
- ObserveCallback& callback);
+ const HeaderOptions& headerOptions, ObserveCallback& callback);
virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
- const std::string& uri);
+ const std::string& uri, const HeaderOptions& headerOptions);
virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
SubscribeCallback& presenceHandler);
void listeningFunc();
std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
std::string assembleSetResourcePayload(const OCRepresentation& attributes);
+ void assembleHeaderOptions(OCHeaderOption options[],
+ const HeaderOptions& headerOptions);
std::thread m_listeningThread;
bool m_threadRun;
std::weak_ptr<std::recursive_mutex> m_csdkLock;
#include <boost/variant.hpp>
#include "ocstack.h"
+#include "OCHeaderOption.h"
#include <OCException.h>
namespace OC
}
}
+ // Typedef for header option vector
+ // OCHeaderOption class is in HeaderOption namespace
+ typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions;
// Typedef for query parameter map
typedef std::map<std::string, std::string> QueryParamsMap;
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>)> 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;
- typedef std::function<void(const OCRepresentation&, const int)> PostCallback;
- typedef std::function<void(const OCRepresentation&, const int, const int)> ObserveCallback;
+
+ typedef std::function<void(const HeaderOptions&,
+ const OCRepresentation&, const int)> GetCallback;
+
+ typedef std::function<void(const HeaderOptions&,
+ const OCRepresentation&, const int)> PostCallback;
+
+ typedef std::function<void(const HeaderOptions&,
+ const OCRepresentation&, const int)> PutCallback;
+
+ typedef std::function<void(const HeaderOptions&,
+ const OCRepresentation&, const int, const int)> ObserveCallback;
} // namespace OC
#endif
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH 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 OCHeaderOption.h
+
+/// @brief This file contains the declaration of classes and its members related to
+/// OCHeaderOption.
+
+#ifndef __OCHEADEROPTION_H
+#define __OCHEADEROPTION_H
+
+#include <OCException.h>
+
+namespace OC
+{
+ namespace HeaderOption
+ {
+ /**
+ * @brief OCHeaderOption class allows to create instances which comprises optionID
+ * and optionData as members. These are used in setting Header options.
+ * After creating instances of OCHeaderOptions, use setHeaderOptions API
+ * (in OCResource.h) to set header Options.
+ * NOTE: HeaderOptionID is an unsigned integer value which MUST be within
+ * range of 2048 to 3000 inclusive of lower and upper bound.
+ * HeaderOptions instance creation fails if above condition is not satisfied.
+ */
+ const uint16_t MIN_HEADER_OPTIONID = 2048;
+ const uint16_t MAX_HEADER_OPTIONID = 3000;
+
+ class OCHeaderOption
+ {
+ private:
+ uint16_t m_optionID;
+ std::string m_optionData;
+
+ public:
+ /**
+ * OCHeaderOption constructor
+ */
+ OCHeaderOption(uint16_t optionID, std::string optionData):
+ m_optionID(optionID),
+ m_optionData(optionData)
+ {
+ if(!(optionID >= MIN_HEADER_OPTIONID && optionID <= MAX_HEADER_OPTIONID))
+ {
+ throw OCException("Error:OptionID valid only from 2048 to 3000 inclusive");
+ }
+ }
+
+ /**
+ * API to get Option ID
+ * @return unsigned integer option ID
+ */
+ uint16_t getOptionID() const
+ {
+ return m_optionID;
+ }
+
+ /*
+ * API to get Option data
+ * @return std::string of option data
+ */
+ std::string getOptionData() const
+ {
+ return m_optionData;
+ }
+ };
+ } // namespace HeaderOption
+} // namespace OC
+
+#endif //__OCHEADEROPTION_H
* @param queryParametersMap map which can have the query parameter name and value
* @param attributeHandler handles callback
* The callback function will be invoked with a map of attribute name and values.
- * The callback function will be invoked with a list of URIs if 'get' is invoked on a resource container
- * (list will be empty if not a container)
- * The callback function will also have the result from this Get operation. This will have error codes
+ * The callback function will be invoked with a list of URIs if 'get' is invoked on a
+ * resource container (list will be empty if not a container)
+ * The callback function will also have the result from this Get operation. This will
+ * have error codes
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
* NOTE: OCStackResult is defined in ocstack.h.<br>
* <b>Example:</b><br>
- * Consider resource "a/home" (with link interface and resource type as home) contains links to "a/kitchen" and "a/room".
+ * Consider resource "a/home" (with link interface and resource type as home) contains links
+ * to "a/kitchen" and "a/room".
* Step 1: get("home", Link_Interface, &onGet)<br>
- * Callback onGet will receive a) Empty attribute map because there are no attributes for a/home b) list with
- * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET operation<br>
- * NOTE: A resource may contain single or multiple resource types. Also, a resource may contain single or multiple interfaces.<br>
- * Currently, single GET request is allowed to do operate on single resource type or resource interface. In future, a single GET <br>
+ * Callback onGet will receive a) Empty attribute map because there are no attributes for
+ * a/home b) list with
+ * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET
+ * operation<br>
+ * NOTE: A resource may contain single or multiple resource types. Also, a resource may
+ * contain single or multiple interfaces.<br>
+ * Currently, single GET request is allowed to do operate on single resource type or resource
+ * interface. In future, a single GET <br>
* can operate on multiple resource types and interfaces. <br>
- * NOTE: A client can traverse a tree or graph by doing successive GETs on the returned resources at a node.<br>
+ * NOTE: A client can traverse a tree or graph by doing successive GETs on the returned
+ * resources at a node.<br>
*/
- OCStackResult get(const std::string& resourceType, const std::string& resourceInterface, const QueryParamsMap& queryParametersMap, GetCallback attributeHandler);
+ OCStackResult get(const std::string& resourceType, const std::string& resourceInterface,
+ const QueryParamsMap& queryParametersMap, GetCallback attributeHandler);
/**
* Function to set the representation of a resource (via PUT)
* This will have error codes.
* The Representation parameter maps 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
* @return OCStackResult return value of this API. Returns OC_STACK_OK if success. <br>
* NOTE: OCStackResult is defined in ocstack.h. <br>
*/
OCStackResult cancelObserve();
+ /**
+ * Function to set header information.
+ * @param headerOptions std::vector where header information(header optionID and optionData
+ * is passed
+ *
+ * NOTE: Once the headers information is set, it will be applicable to GET, PUT and observe
+ * request. <br>
+ * setHeaderOptions can be used multiple times if headers need to be modifed by the client.
+ * Latest headers will be used to send in the request. <br>
+ * NOTE: Initial support is only for two headers. If headerMap consists of more than two
+ * header options, they will be ignored. <br>
+ * Use unsetHeaderOptions API to clear the header information.
+ */
+ void setHeaderOptions(const HeaderOptions& headerOptions)
+ {
+ m_headerOptions = headerOptions;
+ }
+
+ /**
+ * Function to unset header options.
+ */
+ void unsetHeaderOptions()
+ {
+ m_headerOptions.clear();
+ }
+
/**
* Function to get the host address of this resource
* @return std::string host address
std::vector<std::string> m_interfaces;
std::vector<std::string> m_children;
OCDoHandle m_observeHandle;
+ HeaderOptions m_headerOptions;
private:
- OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host, const std::string& uri,
- bool observable, const std::vector<std::string>& resourceTypes, const std::vector<std::string>& interfaces);
+ OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
+ const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces);
};
} // namespace OC
return m_resourceUri;
}
+ /** This API retrieves headerOptions which was sent from a client
+ * @return std::map HeaderOptions with the header options
+ */
+ const HeaderOptions& getHeaderOptions() const {return m_headerOptions;}
private:
std::string m_requestType;
int m_requestHandlerFlag;
OCRepresentation m_representation;
ObservationInfo m_observationInfo;
+ HeaderOptions m_headerOptions;
public:
// TODO: This is not a public API for app developers.
m_observationInfo = observationInfo;
}
+ // TODO: This is not a public API for app developers.
+ // This function will not be exposed in future
+ void setHeaderOptions(const HeaderOptions& headerOptions)
+ {
+ m_headerOptions = headerOptions;
+ }
};
-
-} // namespace OC
+ }// namespace OC
#endif //__OCRESOURCEREQUEST_H
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/// @file OCResourceResponse.h
+/// @file OCResourceResponse.h
-/// @brief This file contains the declaration of classes and its members related to
+/// @brief This file contains the declaration of classes and its members related to
/// ResourceResponse.
#ifndef __OCRESOURCERESPONSE_H
*/
void setErrorCode(const int eCode) { m_errorCode = eCode; }
+ /**
+ * This API allows to set headerOptions in the response
+ * @param headerOptions HeaderOptions vector consisting of OCHeaderOption objects
+ */
+ void setHeaderOptions(const HeaderOptions& headerOptions)
+ {
+ m_headerOptions = headerOptions;
+ }
+
/**
* API to set the entire resource attribute representation
* @param attributeMap reference containing the name value pairs representing
/**
* API to set the entire resource attribute representation
- * @param attributeMap reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap reference containing the name value pairs representing the resource's
+ * attributes
*/
void setResourceRepresentation(OCRepresentation& rep) {
// Call the default
/**
* API to set the entire resource attribute representation
- * @param attributeMap rvalue reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap rvalue reference containing the name value pairs representing the
+ * resource's attributes
*/
void setResourceRepresentation(OCRepresentation&& rep) {
// Call the above function
/**
* API to set the entire resource attribute representation (Linked List Interface))
- * @param attributeMap reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap reference containing the name value pairs representing the resource's
+ * attributes
*/
void setResourceRepresentationLL(OCRepresentation& rep) {
/**
* API to set the entire resource attribute representation (Default))
- * @param attributeMap reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap reference containing the name value pairs representing the resource's
+ * attributes
*/
void setResourceRepresentationDefault(OCRepresentation& rep) {
/**
* API to set the entire resource attribute representation (BATCH)
- * @param attributeMap reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap reference containing the name value pairs representing the resource's
+ * attributes
*/
void setResourceRepresentationBatch(OCRepresentation& rep) {
ostringstream payload;
/** TODO remove this once after above function stabilize.
* API to set the entire resource attribute representation
- * @param attributeMap reference containing the name value pairs representing the resource's attributes
+ * @param attributeMap reference containing the name value pairs representing the
+ * resource's attributes
*/
- void setResourceRepresentation(AttributeMap& attributes) {
+ void setResourceRepresentation(AttributeMap& attributes) {
// TODO To be refactored
ostringstream payload;
payload << "{";
-
+
// TODO fix this (do this programmatically)
payload << "\"href\":\"/a/room\"";
private:
std::string m_payload;
int m_errorCode;
+ HeaderOptions m_headerOptions;
// TODO only stack should have visibility and apps should not
public:
- /**
- * Get error code
+ /**
+ * Get error code
+ */
+ int getErrorCode() const;
+
+ /**
+ * This API allows to retrieve headerOptions from a response
*/
- int getErrorCode() const;
+ const HeaderOptions& getHeaderOptions() const
+ {
+ return m_headerOptions;
+ }
/**
* Get the resource attribute representation
*/
- AttributeMap& getResourceRepresentation() const;
+ AttributeMap& getResourceRepresentation() const;
// TODO This should go away & just use getResourceRepresentation
std::string getPayload()
const std::string& resourceType, FindCallback& callback) {return OC_STACK_NOTIMPL;}
virtual OCStackResult GetResourceRepresentation(const std::string& host,
- const std::string& uri, const QueryParamsMap& queryParams, GetCallback& callback)
+ const std::string& uri, const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions, GetCallback& callback)
{return OC_STACK_NOTIMPL;}
virtual OCStackResult PutResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& attributes,
- const QueryParamsMap& queryParams, PutCallback& callback)
+ const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions, PutCallback& callback)
{return OC_STACK_NOTIMPL;}
virtual OCStackResult PostResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& attributes,
- const QueryParamsMap& queryParams, PostCallback& callback)
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PostCallback& callback)
{return OC_STACK_NOTIMPL;}
virtual OCStackResult ObserveResource(ObserveType observeType, OCDoHandle* handle,
const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions,
ObserveCallback& callback){return OC_STACK_NOTIMPL;}
virtual OCStackResult CancelObserveResource(OCDoHandle handle, const std::string& host,
- const std::string& uri){return OC_STACK_NOTIMPL;}
+ const std::string& uri,
+ const HeaderOptions& headerOptions){return OC_STACK_NOTIMPL;}
virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper,
const std::string& host, const boost::property_tree::ptree resourceNode)
OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
{
std::stringstream requestStream;
+
requestStream<<clientResponse->resJSONPayload;
if(strlen((char*)clientResponse->resJSONPayload) == 0)
{
return root_resource;
}
+ void parseServerHeaderOptions(OCClientResponse* clientResponse,
+ HeaderOptions& serverHeaderOptions)
+ {
+ if(clientResponse)
+ {
+ // Parse header options from server
+ uint16_t optionID;
+ std::string optionData;
+
+ for(int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
+ {
+ optionID = clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
+ optionData = reinterpret_cast<const char*>
+ (clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData);
+ HeaderOption::OCHeaderOption headerOption(optionID, optionData);
+ serverHeaderOptions.push_back(headerOption);
+ }
+ }
+ else
+ {
+ // clientResponse is invalid
+ // TODO check proper logging
+ std::cout << " Invalid response " << std::endl;
+ }
+ }
+
OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle,
OCClientResponse* clientResponse)
{
GetContext* context = static_cast<GetContext*>(ctx);
OCRepresentation rep;
-
+ HeaderOptions serverHeaderOptions;
if(clientResponse->result == OC_STACK_OK)
{
+ parseServerHeaderOptions(clientResponse, serverHeaderOptions);
rep = parseGetSetCallback(clientResponse);
}
- std::thread exec(context->callback, rep, clientResponse->result);
+ std::thread exec(context->callback, serverHeaderOptions, rep, clientResponse->result);
exec.detach();
return OC_STACK_DELETE_TRANSACTION;
}
+
OCStackResult InProcClientWrapper::GetResourceRepresentation(const std::string& host,
- const std::string& uri, const QueryParamsMap& queryParams, GetCallback& callback)
+ const std::string& uri, const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions, GetCallback& callback)
{
OCStackResult result;
OCCallbackData cbdata = {0};
std::lock_guard<std::recursive_mutex> lock(*cLock);
OCDoHandle handle;
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+ assembleHeaderOptions(options, headerOptions);
result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(),
nullptr, nullptr,
static_cast<OCQualityOfService>(m_cfg.QoS),
&cbdata,
- NULL, 0);
+ options, headerOptions.size());
}
else
{
{
SetContext* context = static_cast<SetContext*>(ctx);
OCRepresentation attrs;
+ HeaderOptions serverHeaderOptions;
if(clientResponse->result == OC_STACK_OK)
{
+ parseServerHeaderOptions(clientResponse, serverHeaderOptions);
attrs = parseGetSetCallback(clientResponse);
}
- std::thread exec(context->callback, attrs, clientResponse->result);
+ std::thread exec(context->callback, serverHeaderOptions, attrs, clientResponse->result);
exec.detach();
return OC_STACK_DELETE_TRANSACTION;
}
OCStackResult InProcClientWrapper::PostResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& rep,
- const QueryParamsMap& queryParams, PostCallback& callback)
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PostCallback& callback)
{
OCStackResult result;
OCCallbackData cbdata = {0};
if(cLock)
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
OCDoHandle handle;
+
+ assembleHeaderOptions(options, headerOptions);
result = OCDoResource(&handle, OC_REST_POST,
os.str().c_str(), nullptr,
assembleSetResourcePayload(rep).c_str(),
static_cast<OCQualityOfService>(m_cfg.QoS),
- &cbdata, NULL, 0);
+ &cbdata, options, headerOptions.size());
}
else
{
OCStackResult InProcClientWrapper::PutResourceRepresentation(const std::string& host,
const std::string& uri, const OCRepresentation& rep,
- const QueryParamsMap& queryParams, PutCallback& callback)
+ const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+ PutCallback& callback)
{
OCStackResult result;
OCCallbackData cbdata = {0};
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
OCDoHandle handle;
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+ assembleHeaderOptions(options, headerOptions);
result = OCDoResource(&handle, OC_REST_PUT,
os.str().c_str(), nullptr,
assembleSetResourcePayload(rep).c_str(),
static_cast<OCQualityOfService>(m_cfg.QoS),
&cbdata,
- NULL, 0);
+ options, headerOptions.size());
}
else
{
{
ObserveContext* context = static_cast<ObserveContext*>(ctx);
OCRepresentation attrs;
+ HeaderOptions serverHeaderOptions;
uint32_t sequenceNumber = clientResponse->sequenceNumber;
+
if(clientResponse->result == OC_STACK_OK)
{
+ parseServerHeaderOptions(clientResponse, serverHeaderOptions);
attrs = parseGetSetCallback(clientResponse);
}
- std::thread exec(context->callback, attrs, clientResponse->result, sequenceNumber);
+ std::thread exec(context->callback, serverHeaderOptions, attrs,
+ clientResponse->result, sequenceNumber);
exec.detach();
return OC_STACK_KEEP_TRANSACTION;
}
OCStackResult InProcClientWrapper::ObserveResource(ObserveType observeType, OCDoHandle* handle,
const std::string& host, const std::string& uri, const QueryParamsMap& queryParams,
- ObserveCallback& callback)
+ const HeaderOptions& headerOptions, ObserveCallback& callback)
{
OCStackResult result;
OCCallbackData cbdata = {0};
os << host << assembleSetResourceUri(uri, queryParams).c_str();
std::lock_guard<std::recursive_mutex> lock(*cLock);
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+ assembleHeaderOptions(options, headerOptions);
result = OCDoResource(handle, method,
os.str().c_str(), nullptr,
nullptr,
static_cast<OCQualityOfService>(m_cfg.QoS),
&cbdata,
- NULL, 0);
+ options, headerOptions.size());
}
else
{
}
OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle,
- const std::string& host, const std::string& uri)
+ const std::string& host, const std::string& uri, const HeaderOptions& headerOptions)
{
OCStackResult result;
auto cLock = m_csdkLock.lock();
if(cLock)
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
- result = OCCancel(handle, OC_NON_CONFIRMABLE, NULL, 0);
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+ assembleHeaderOptions(options, headerOptions);
+ result = OCCancel(handle, OC_NON_CONFIRMABLE, options, headerOptions.size());
}
else
{
return result;
}
+
+ void InProcClientWrapper::assembleHeaderOptions(OCHeaderOption options[],
+ const HeaderOptions& headerOptions)
+ {
+ int i = 0;
+
+ for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it)
+ {
+ options[i].protocolID = OC_COAP_ID;
+ options[i].optionID = static_cast<uint16_t>(it->getOptionID());
+ options[i].optionLength = (it->getOptionData()).length() + 1;
+ memcpy(options[i].optionData, (it->getOptionData()).c_str(),
+ (it->getOptionData()).length() + 1);
+ i++;
+ }
+ }
}
pRequest->setQueryParams(qp);
}
}
+ if(entityHandlerRequest->numRcvdVendorSpecificHeaderOptions != 0)
+ {
+ //Set the header options here.
+ uint16_t optionID;
+ std::string optionData;
+ HeaderOptions headerOptions;
+
+ for(int i = 0; i < MAX_HEADER_OPTIONS; i++)
+ {
+ optionID = entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionID;
+ optionData = reinterpret_cast<const char*>
+ (entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData);
+ HeaderOption::OCHeaderOption headerOption(optionID, optionData);
+ headerOptions.push_back(headerOption);
+ }
+ pRequest->setHeaderOptions(headerOptions);
+ }
if(OC_REST_GET == entityHandlerRequest->method)
{
{
// TODO we could use const reference
std::string payLoad;
+ HeaderOptions serverHeaderOptions;
if(pResponse)
{
payLoad = pResponse->getPayload();
+ serverHeaderOptions = pResponse->getHeaderOptions();
}
else
{
if (payLoad.size() < entityHandlerRequest->resJSONPayloadLen)
{
+ int i = 0;
+ entityHandlerRequest->numSendVendorSpecificHeaderOptions =
+ serverHeaderOptions.size();
+ for (auto it=serverHeaderOptions.begin(); it != serverHeaderOptions.end(); ++it)
+ {
+ entityHandlerRequest->sendVendorSpecificHeaderOptions[i].protocolID = OC_COAP_ID;
+ entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionID =
+ static_cast<uint16_t>(it->getOptionID());
+ entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionLength =
+ (it->getOptionData()).length() + 1;
+ memcpy(entityHandlerRequest->sendVendorSpecificHeaderOptions[i].optionData,
+ (it->getOptionData()).c_str(),
+ (it->getOptionData()).length() + 1);
+ i++;
+ }
+
strncpy((char*)entityHandlerRequest->resJSONPayload,
payLoad.c_str(),
entityHandlerRequest->resJSONPayloadLen);
uint8_t resourceProperty)
{
return checked_guard(m_server, &IServerWrapper::registerResource,
- ref(resourceHandle), resourceURI, resourceTypeName, resourceInterface, entityHandler, resourceProperty);
+ ref(resourceHandle), resourceURI, resourceTypeName,
+ resourceInterface, entityHandler, resourceProperty);
}
OCStackResult OCPlatform::unregisterResource(const OCResourceHandle& resourceHandle) const
using OC::checked_guard;
OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
- const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
- const std::vector<std::string>& interfaces)
+ const std::string& uri, bool observable,
+ const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces)
: m_clientWrapper(clientWrapper), m_uri(uri), m_host(host), m_isObservable(observable),
m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces),
m_observeHandle(nullptr)
GetCallback attributeHandler)
{
return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
- m_host, m_uri, queryParametersMap, attributeHandler);
+ m_host, m_uri, queryParametersMap, m_headerOptions, attributeHandler);
}
OCStackResult OCResource::get(const std::string& resourceType,
- const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
- GetCallback attributeHandler)
+ const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
+ GetCallback attributeHandler)
{
QueryParamsMap mapCpy(queryParametersMap);
}
OCStackResult OCResource::put(const OCRepresentation& rep,
- const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
+ const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
{
return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
- m_host, m_uri, rep, queryParametersMap, attributeHandler);
+ m_host, m_uri, rep, queryParametersMap, m_headerOptions, attributeHandler);
}
OCStackResult OCResource::put(const std::string& resourceType,
}
OCStackResult OCResource::post(const OCRepresentation& rep,
- const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
+ const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
{
return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
- m_host, m_uri, rep, queryParametersMap, attributeHandler);
+ m_host, m_uri, rep, queryParametersMap, m_headerOptions, attributeHandler);
}
OCStackResult OCResource::post(const std::string& resourceType,
}
OCStackResult OCResource::observe(ObserveType observeType,
- const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
+ const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
{
if(m_observeHandle != nullptr)
{
return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
observeType, &m_observeHandle, m_host,
- m_uri, queryParametersMap, observeHandler);
+ m_uri, queryParametersMap, m_headerOptions, observeHandler);
}
OCStackResult OCResource::cancelObserve()
}
return checked_guard(m_clientWrapper.lock(), &IClientWrapper::CancelObserveResource,
- m_observeHandle, m_host, m_uri);
+ m_observeHandle, m_host, m_uri, m_headerOptions);
}
std::string OCResource::host() const