Sample implementation of ocf_light 63/24263/24
authorGeorge Nash <george.nash@intel.com>
Fri, 9 Feb 2018 22:57:25 +0000 (14:57 -0800)
committerNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Mon, 2 Apr 2018 17:09:05 +0000 (17:09 +0000)
This sample borrows a lot of code from the server
sample generated from the DeviceBuilder project
https://github.com/openconnectivityfoundation/DeviceBuilder

Eventhough this borrows a lot of code from the
DeviceBuilder project it has been modified to make
it more useful as an example separating the code into
smaller classes and adding helper classes.

This code has been run against the OCF CTT. See the
README.md file for more information about the CTT
results.

Change-Id: If0ae5e3527517bb722648a614fbd96f13ad01144
Signed-off-by: George Nash <george.nash@intel.com>
21 files changed:
resource/examples/SConscript
resource/examples/ocf_light/BinarySwitchResource.cpp [new file with mode: 0644]
resource/examples/ocf_light/BinarySwitchResource.h [new file with mode: 0644]
resource/examples/ocf_light/DimmingLightControl.cpp [new file with mode: 0644]
resource/examples/ocf_light/DimmingLightControl.h [new file with mode: 0644]
resource/examples/ocf_light/DimmingLightServer.cpp [new file with mode: 0644]
resource/examples/ocf_light/DimmingLightServer.h [new file with mode: 0644]
resource/examples/ocf_light/DimmingResource.cpp [new file with mode: 0644]
resource/examples/ocf_light/DimmingResource.h [new file with mode: 0644]
resource/examples/ocf_light/Platform.cpp [new file with mode: 0644]
resource/examples/ocf_light/Platform.h [new file with mode: 0644]
resource/examples/ocf_light/README.md [new file with mode: 0644]
resource/examples/ocf_light/Resource.h [new file with mode: 0644]
resource/examples/ocf_light/SConscript [new file with mode: 0644]
resource/examples/ocf_light/dimming_light_server.cpp [new file with mode: 0644]
resource/examples/ocf_light/dl_PICS.json [new file with mode: 0644]
resource/examples/ocf_light/dl_server_introspection.dat [new file with mode: 0644]
resource/examples/ocf_light/dl_server_introspection.json [new file with mode: 0644]
resource/examples/ocf_light/dl_server_security.dat [new file with mode: 0644]
resource/examples/ocf_light/dl_server_security.json [new file with mode: 0644]
resource/examples/ocf_light/dl_server_security.json.in [new file with mode: 0644]

index 4c55fe8..5ff2978 100644 (file)
@@ -148,6 +148,8 @@ if target_os in ['msys_nt', 'windows']:
         mediaserver = examples_env.Program('mediaserver', 'mediaserver.cpp')
         examples += [mediaserver]
 
+examples_env.SConscript('ocf_light/SConscript', exports='examples_env')
+
 examples_env.Alias("examples", examples)
 examples_env.AppendTarget('examples')
 examples_env.Alias("install", examples)
diff --git a/resource/examples/ocf_light/BinarySwitchResource.cpp b/resource/examples/ocf_light/BinarySwitchResource.cpp
new file mode 100644 (file)
index 0000000..6485bcc
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#include <iostream>
+#include <vector>
+#include <thread>
+
+#include "BinarySwitchResource.h"
+#include "OCPlatform.h"
+
+#define INTERFACE_KEY "if"
+
+using namespace OC;
+namespace PH = std::placeholders;
+
+BinarySwitchResource::BinarySwitchResource(std::string resourceUri):
+        m_nr_resource_types{1},
+        m_nr_resource_interfaces{2},
+        m_interestedObservers{},
+        m_var_value_rt{},
+        m_var_value_n{},
+        m_var_value_if{},
+        m_var_value_value{}
+{
+    std::cout << "Running: BinarySwitchResource constructor" << std::endl;
+
+    // VS2013 will fail list initialization so use array initialization
+    m_resourceUri = resourceUri;
+    m_RESOURCE_TYPE[0] = "oic.r.switch.binary";
+    m_RESOURCE_INTERFACE[0] = "oic.if.baseline";
+    m_RESOURCE_INTERFACE[1] = "oic.if.a";
+    m_IF_UPDATE[0] = "oic.if.a";
+    m_IF_UPDATE[1] = "oic.if.rw";
+    m_IF_UPDATE[2] = "oic.if.baseline";
+    m_var_name_rt = "rt";
+    m_var_name_n = "n";
+    m_var_name_if = "if";
+    m_var_name_value = "value";
+
+    // initialize member variables /binaryswitch
+    // initialize vector rt
+    m_var_value_rt.push_back("oic.r.switch.binary");
+    m_var_value_n = "";  // current value of property "n"
+    // initialize vector if
+    m_var_value_if.push_back("oic.if.baseline");
+    m_var_value_if.push_back("oic.if.a");
+
+    m_var_value_value = true; // current value of property "value"
+}
+
+BinarySwitchResource::~BinarySwitchResource(void) { }
+
+OCStackResult BinarySwitchResource::registerResource(uint8_t resourceProperty)
+{
+    EntityHandler cb = std::bind(&BinarySwitchResource::entityHandler, this, PH::_1);
+    OCStackResult result = OC_STACK_ERROR;
+    result = OCPlatform::registerResource(m_resourceHandle,
+                                          m_resourceUri,
+                                          m_RESOURCE_TYPE[0],
+                                          m_RESOURCE_INTERFACE[0],
+                                          cb,
+                                          resourceProperty );
+    if (OC_STACK_OK != result)
+    {
+        std::cerr << "Failed to register BinarySwitchResoruce." << std::endl;
+        return result;
+    }
+
+    // add the additional resource types
+    for( int a = 1; a < m_nr_resource_types; a++ )
+    {
+        result = OCPlatform::bindTypeToResource(m_resourceHandle, m_RESOURCE_TYPE[a].c_str());
+        if (OC_STACK_OK != result)
+        {
+            std::cerr << "Could not bind resource type:" << m_RESOURCE_INTERFACE[a] << std::endl;
+            return result;
+        }
+    }
+    // add the additional interfaces
+    for( int a = 1; a < m_nr_resource_interfaces; a++)
+    {
+        result = OCPlatform::bindInterfaceToResource(m_resourceHandle, m_RESOURCE_INTERFACE[a].c_str());
+        if (OC_STACK_OK != result)
+        {
+            std::cerr << "Could not bind interface:" << m_RESOURCE_INTERFACE[a] << std::endl;
+            return result;
+        }
+    }
+
+    std::cout << "BinarySwitchResource:" << std::endl;
+    std::cout << "\t" << "# resource interfaces: " << m_nr_resource_interfaces << std::endl;
+    std::cout << "\t" << "# resource types     : " << m_nr_resource_types << std::endl;
+
+    return result;
+}
+
+bool BinarySwitchResource::getValue(void)
+{
+    return m_var_value_value;
+}
+
+void BinarySwitchResource::setValue(bool newValue)
+{
+    m_var_value_value  = newValue;
+    std::cout << "\t\t" << "property 'value': " << m_var_value_value << std::endl;
+}
+
+OCStackResult BinarySwitchResource::sendNotification(void)
+{
+    OCStackResult sResult = OC_STACK_OK;
+    if ( m_interestedObservers.size() > 0) {
+        std::cout << "Notifying list "  << m_interestedObservers.size() << " of observers\n";
+        auto pResponse = std::make_shared<OC::OCResourceResponse>();
+        sResult = OCPlatform::notifyListOfObservers(m_resourceHandle,
+                                                    m_interestedObservers,
+                                                    pResponse);
+    }
+    return sResult;
+}
+
+OC::OCRepresentation BinarySwitchResource::get(OC::QueryParamsMap queries)
+{
+    OC_UNUSED(queries);
+
+    m_rep.setValue(m_var_name_rt,  m_var_value_rt );
+    m_rep.setValue(m_var_name_n, m_var_value_n );
+    m_rep.setValue(m_var_name_if,  m_var_value_if );
+    m_rep.setValue(m_var_name_value, m_var_value_value );
+
+    return m_rep;
+}
+
+OCEntityHandlerResult BinarySwitchResource::post(OC::QueryParamsMap queries, const OC::OCRepresentation& rep)
+{
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+    OC_UNUSED(queries);
+
+    try {
+        if (rep.hasAttribute(m_var_name_value))
+        {
+            // value exist in payload
+
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+
+    if (ehResult == OC_EH_OK)
+    {
+        // no error: assign the variables
+        try {
+            if (rep.hasAttribute(m_var_name_rt))
+            {
+                rep.getValue(m_var_name_rt, m_var_value_rt);
+                int first = 1;
+                std::cout << "\t\t" << "property 'rt' : " ;
+                for(auto myvar: m_var_value_rt)
+                {
+                    if (first)
+                    {
+                        std::cout << myvar;
+                        first = 0;
+                    }
+                    else
+                    {
+                        std::cout << "," << myvar;
+                    }
+                }
+                std::cout <<  std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'rt' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.getValue(m_var_name_n, m_var_value_n ))
+            {
+                std::cout << "\t\t" << "property 'n' : " << m_var_value_n << std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'n' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.hasAttribute(m_var_name_if))
+            {
+                rep.getValue(m_var_name_if, m_var_value_if);
+                int first = 1;
+                std::cout << "\t\t" << "property 'if' : " ;
+                for(auto myvar: m_var_value_if)
+                {
+                    if (first)
+                    {
+                        std::cout << myvar;
+                        first = 0;
+                    }
+                    else
+                    {
+                        std::cout << "," << myvar;
+                    }
+                }
+                std::cout <<  std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'if' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.getValue(m_var_name_value, m_var_value_value ))
+            {
+                std::cout << "\t\t" << "property 'value': " << m_var_value_value << std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'value' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+    }
+    return ehResult;
+}
+
+OCEntityHandlerResult BinarySwitchResource::entityHandler(std::shared_ptr<OC::OCResourceRequest> request)
+{
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    if (request)
+    {
+        std::cout << "In entity handler for BinarySwitchResource, URI is : "
+                << request->getResourceUri() << std::endl;
+
+        // Check for query params (if any)
+        QueryParamsMap queries = request->getQueryParameters();
+        if (!queries.empty())
+        {
+            std::cout << "\nQuery processing up to entityHandler" << std::endl;
+        }
+        for (auto it : queries)
+        {
+            std::cout << "Query key: " << it.first << " value : " << it.second
+                    << std::endl;
+        }
+        // get the value, so that we can AND it to check which flags are set
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if (requestFlag & RequestHandlerFlag::RequestFlag)
+        {
+            // request flag is set
+            auto pResponse = std::make_shared<OC::OCResourceResponse>();
+            pResponse->setRequestHandle(request->getRequestHandle());
+            pResponse->setResourceHandle(request->getResourceHandle());
+
+            if (request->getRequestType() == "GET")
+            {
+                std::cout<<"BinarySwitchResource Get Request"<< std::endl;
+
+                pResponse->setResourceRepresentation(get(queries), "");
+                if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                {
+                    ehResult = OC_EH_OK;
+                }
+            }
+
+            else if (request->getRequestType() == "POST")
+            {
+                std::cout <<"BinarySwitchResource Post Request"<<std::endl;
+                bool  handle_post = true;
+
+                if (queries.size() > 0)
+                {
+                    for (const auto &eachQuery : queries)
+                    {
+                        std::string key = eachQuery.first;
+                        if (key.compare(INTERFACE_KEY) == 0)
+                        {
+                            std::string value = eachQuery.second;
+                            if (in_updatable_interfaces(value) == false)
+                            {
+                                std::cout << "Update request received via interface: " << value
+                                        << " . This interface is not authorized to update resource!!" << std::endl;
+                                pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_FORBIDDEN);
+                                handle_post = false;
+                                ehResult = OC_EH_ERROR;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (handle_post)
+                {
+                    ehResult = post(queries, request->getResourceRepresentation());
+                    if (ehResult == OC_EH_OK)
+                    {
+                        pResponse->setResourceRepresentation(get(queries), "");
+                    }
+                    else
+                    {
+                        pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_ERROR);
+                    }
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        if (OC_STACK_OK != sendNotification() )
+                        {
+                            std::cerr << "NOTIFY failed." << std::endl;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                std::cout << "BinarySwitchResource unsupported request type (delete,put,..)"
+                        << request->getRequestType() << std::endl;
+                pResponse->setResponseResult(OC_EH_ERROR);
+                OCPlatform::sendResponse(pResponse);
+                ehResult = OC_EH_ERROR;
+            }
+        }
+
+        if (requestFlag & RequestHandlerFlag::ObserverFlag)
+        {
+            // observe flag is set
+            std::cout << "\t\trequestFlag : Observer ";
+            ObservationInfo observationInfo = request->getObservationInfo();
+            ((ObserveAction::ObserveRegister == observationInfo.action) ? std::cout << "Register\n" : std::cout << "Unregister\n");
+            if (ObserveAction::ObserveRegister == observationInfo.action)
+            {
+                // add observer
+                m_interestedObservers.push_back(observationInfo.obsId);
+            }
+            else if (ObserveAction::ObserveUnregister == observationInfo.action)
+            {
+                // delete observer
+                m_interestedObservers.erase(std::remove(
+                                            m_interestedObservers.begin(),
+                                            m_interestedObservers.end(),
+                                            observationInfo.obsId),
+                                            m_interestedObservers.end());
+            }
+            ehResult = OC_EH_OK;
+        }
+    }
+    return ehResult;
+}
diff --git a/resource/examples/ocf_light/BinarySwitchResource.h b/resource/examples/ocf_light/BinarySwitchResource.h
new file mode 100644 (file)
index 0000000..1575452
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_BINARYSWITCHRESOURCE_H_
+#define EXAMPLE_OCF_LIGHT_BINARYSWITCHRESOURCE_H_
+
+#include <vector>
+#include <string>
+#include "Resource.h"
+
+#include "OCApi.h"
+#include "OCRepresentation.h"
+
+/**
+ * Class implements the OCF oic.r.switch.binary resource.
+ *
+ * This class is responsible for handling GET and POST requests sent from
+ * a client
+ */
+class BinarySwitchResource : public Resource
+{
+public:
+    /**
+     * constructor
+     *
+     * @param resourceUri the uri the resource will be register with
+     */
+    BinarySwitchResource(std::string resourceUri = "/binaryswitch");
+
+    /**
+     * destructor
+     */
+    virtual ~BinarySwitchResource(void);
+
+    /**
+     * Register the resource with the server
+     *
+     * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+     * setting resourceProperty as OC_OBSERVABLE will allow observation
+     * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and observation
+     * setting resourceProperty as OC_SECURE the resource supports access via secure endpoints
+     * setting resourceProperty as OC_NONSECURE the resource supports access via non-secure endpoints
+     * setting resourceProperty as OC_SECURE | OC_NONSECURE will allow access via secure and non-secure endpoints
+     *
+     * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+     */
+    OCStackResult registerResource(uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+
+    /**
+     * get the value of the binary switch
+     *
+     * @return value of the binary switch
+     */
+    bool getValue(void);
+
+    /**
+     * set the value of the binary switch
+     *
+     * @param newValue new binaryswitch value
+     */
+    void setValue(bool newValue);
+
+    /**
+     * Attempt to send out notifications to observing clients.
+     * If no value on the device has been changed the notification
+     * may not be sent.
+     *
+     * @return OC_STACK_OK on success
+     */
+    OCStackResult sendNotification(void);
+
+private:
+
+    /**
+     * Make the payload for the retrieve function (e.g. GET)
+     *
+     * @param queries the query parameters for this call
+     */
+    OC::OCRepresentation get(OC::QueryParamsMap queries);
+
+    /**
+     * Parse the payload for the update function (e.g. POST)
+     *
+     * @param queries the query parameters for this call
+     * @param rep the response to get the property values from
+     *
+     * @return OCEntityHandlerResult OC_EH_OK on success or other result indicating failure.
+     */
+    OCEntityHandlerResult post(OC::QueryParamsMap queries, const OC::OCRepresentation& rep);
+
+    // resource types and interfaces as array..
+    std::string m_resourceUri;
+    std::string m_RESOURCE_TYPE[1]; // rt value (as an array)
+    std::string m_RESOURCE_INTERFACE[2]; // interface if (as an array)
+    std::string m_IF_UPDATE[3]; // updateble interfaces
+    int m_nr_resource_types;
+    int m_nr_resource_interfaces;
+    OC::ObservationIds m_interestedObservers;
+
+    // member variables for path: /binaryswitch
+    std::vector<std::string>  m_var_value_rt;
+    std::string m_var_name_rt; // the name for the attribute
+
+    std::string m_var_value_n; // the value for the attribute
+    std::string m_var_name_n; // the name for the attribute
+
+
+    std::vector<std::string>  m_var_value_if;
+    std::string m_var_name_if; // the name for the attribute
+
+    bool m_var_value_value; // the value for the attribute
+    std::string m_var_name_value; // the name for the attribute
+
+protected:
+    /**
+     * Check if the interface is an updatable interface.
+     *
+     * @param  interface_name the interface name used during the request
+     *
+     * @return true: updatable interface
+     */
+    bool in_updatable_interfaces(std::string interface_name)
+    {
+        for (int i=0; i<3; i++)
+        {
+            if (m_IF_UPDATE[i].compare(interface_name) == 0)
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * The entity handler for this resource
+     *
+     * @param request the incoming request to handle
+     *
+     * @return OCEntityHandlerResult OC_EH_OK on success or other result indicating failure.
+     */
+    virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OC::OCResourceRequest> request);
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_BINARYSWITCHRESOURCE_H_ */
diff --git a/resource/examples/ocf_light/DimmingLightControl.cpp b/resource/examples/ocf_light/DimmingLightControl.cpp
new file mode 100644 (file)
index 0000000..b2b2462
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+#include "DimmingLightControl.h"
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+
+//using namespace std;
+
+DimmingLightControl::DimmingLightControl(DimmingLightServer& dimmingLightServer):
+    m_quit{false},
+    m_dimmingLightServer{dimmingLightServer}
+{ }
+
+DimmingLightControl::~DimmingLightControl(void) { }
+
+void DimmingLightControl::process(void)
+{
+    help();
+    std::string cmd;
+    do
+    {
+        std::getline(std::cin, cmd);
+        std::vector<std::string> token;
+        std::stringstream ss(cmd);
+        std::string tok;
+        while (getline(ss, tok, ' '))
+        {
+            if (!tok.empty())
+            {
+                token.push_back(tok);
+            }
+        }
+        if (token.size() == 1)
+        {
+            if ("ON" == token[0] || "on" == token[0]) {
+                m_dimmingLightServer.m_binaryswitchInstance.setValue(true);
+                if (OC_STACK_OK != m_dimmingLightServer.m_binaryswitchInstance.sendNotification())
+                {
+                    std::cerr << "NOTIFY failed." << std::endl;
+                }
+            }
+            else if ("OFF" == token[0] || "off" == token[0]) {
+                m_dimmingLightServer.m_binaryswitchInstance.setValue(false);
+                if (OC_STACK_OK != m_dimmingLightServer.m_binaryswitchInstance.sendNotification())
+                {
+                    std::cerr << "NOTIFY failed." << std::endl;
+                }
+            }
+            else if ("toggle" == token[0]) {
+                bool tmp = m_dimmingLightServer.m_binaryswitchInstance.getValue();
+                m_dimmingLightServer.m_binaryswitchInstance.setValue(!tmp);
+                if (OC_STACK_OK != m_dimmingLightServer.m_binaryswitchInstance.sendNotification())
+                {
+                    std::cerr << "NOTIFY failed." << std::endl;
+                }
+            }
+            else if ("info" == token[0]) {
+                info();
+            }
+            else if ("help" == token[0] || "h" == token[0]) {
+                help();
+            }
+            else if ("quit" == token[0] || "q" == token[0])
+            {
+                m_quit = true;
+            }
+        }
+        else if (token.size() == 2)
+        {
+            if ("dim" == token[0]) {
+                int value = atoi(token[1].c_str());
+                if (value >= 0 && value <= 100)
+                {
+                    m_dimmingLightServer.m_dimmingInstance.setDimmingSetting(value);
+                    if (OC_STACK_OK != m_dimmingLightServer.m_dimmingInstance.sendNotification())
+                    {
+                        std::cerr << "NOTIFY failed." << std::endl;
+                    }
+                }
+                else
+                {
+                    std::cerr << "the dim value must between 0 and 100" << std::endl;
+                }
+            }
+        }
+        else {
+            help();
+        }
+    } while (!m_quit);
+}
+
+void DimmingLightControl::info(void)
+{
+    std::cout <<
+            "**************************************\n"
+            " binary switch value: " << ((m_dimmingLightServer.m_binaryswitchInstance.getValue()) ? "ON" : "OFF") << std::endl;
+    std::cout <<
+            " dimming setting: " << m_dimmingLightServer.m_dimmingInstance.getDimmingSetting() << std::endl;
+    std::cout <<
+            "**************************************\n";
+}
+
+void DimmingLightControl::help(void)
+{
+    std::cout <<
+            "**************************************\n"
+            " Control the server locally:\n"
+            " 'on': turn the light on\n"
+            " 'off': turn the light off\n"
+            " 'toggle': flip the light value\n"
+            " 'dim [0-100]': change the dimming setting\n"
+            " 'info': print current server values"
+            " 'quit' or 'q': exit server\n"
+            " 'help` or 'h': help\n"
+            "**************************************\n";
+}
diff --git a/resource/examples/ocf_light/DimmingLightControl.h b/resource/examples/ocf_light/DimmingLightControl.h
new file mode 100644 (file)
index 0000000..ecb5a00
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_DIMMINGLIGHTCONTROL_H_
+#define EXAMPLE_OCF_LIGHT_DIMMINGLIGHTCONTROL_H_
+#include "DimmingLightServer.h"
+
+/**
+ * Used to controlling the Dimming light sample locally via command line.
+ * This is a friend class to the DimmingLightServer.
+ */
+class DimmingLightControl {
+public:
+    DimmingLightControl(DimmingLightServer& dimmingLightServer);
+    virtual ~DimmingLightControl(void);
+
+    /**
+     * Continually process commandline commands that can be used to control the
+     * dimming light locally.
+     *
+     * Calling this function will block till user provides a commandline command
+     * to exit.
+     */
+    void process(void);
+private:
+    /**
+     * Print the values of the binary switch server and the dimming server
+     */
+    void info(void);
+
+    /**
+     * Print a help message to inform the user of valid commands.
+     */
+    void help(void);
+    bool m_quit;
+    DimmingLightServer& m_dimmingLightServer;
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_DIMMINGLIGHTCONTROL_H_ */
diff --git a/resource/examples/ocf_light/DimmingLightServer.cpp b/resource/examples/ocf_light/DimmingLightServer.cpp
new file mode 100644 (file)
index 0000000..e3b3ef2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#include <iostream>
+
+#include "DimmingLightServer.h"
+#include "OCPlatform.h"
+
+using namespace OC;
+
+DimmingLightServer::DimmingLightServer(void):
+m_binaryswitchInstance(),
+m_dimmingInstance()
+{
+    std::cout << "Running: DimmingLightServer constructor" << std::endl;
+}
+
+DimmingLightServer::~DimmingLightServer(void)
+{
+    std::cout << "Running: DimmingLightServer destructor" << std::endl;
+}
+
+OCStackResult DimmingLightServer::registerResources(uint8_t resourceProperty)
+{
+    OCStackResult result = OC_STACK_ERROR;
+    result = m_binaryswitchInstance.registerResource(resourceProperty);
+    if (OC_STACK_OK != result)
+    {
+        return result;
+    }
+    result = m_dimmingInstance.registerResource(resourceProperty);
+    return result;
+}
diff --git a/resource/examples/ocf_light/DimmingLightServer.h b/resource/examples/ocf_light/DimmingLightServer.h
new file mode 100644 (file)
index 0000000..d416c6d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_DIMMINGLIGHTSERVER_H_
+#define EXAMPLE_OCF_LIGHT_DIMMINGLIGHTSERVER_H_
+
+#include "BinarySwitchResource.h"
+#include "DimmingResource.h"
+
+/**
+ * Enables registering the resources for the dimming light server
+ */
+class DimmingLightServer
+{
+    friend class DimmingLightControl;
+public:
+    /**
+     *  constructor
+     */
+    DimmingLightServer(void);
+
+    /**
+     *  destructor
+     */
+    ~DimmingLightServer(void);
+
+    /**
+     * Register the resources with the server
+     *
+     * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+     * setting resourceProperty as OC_OBSERVABLE will allow observation
+     * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and observation
+     * setting resourceProperty as OC_SECURE the resource supports access via secure endpoints
+     * setting resourceProperty as OC_NONSECURE the resource supports access via non-secure endpoints
+     * setting resourceProperty as OC_SECURE | OC_NONSECURE will allow access via secure and non-secure endpoints
+     *
+     * @param resourceProperty indicates the property of the resources. Defined in octypes.h.
+     */
+    OCStackResult registerResources(uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+
+private:
+    // Resources that are part of this server
+    BinarySwitchResource  m_binaryswitchInstance;
+    DimmingResource  m_dimmingInstance;
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_DIMMINGLIGHTSERVER_H_ */
diff --git a/resource/examples/ocf_light/DimmingResource.cpp b/resource/examples/ocf_light/DimmingResource.cpp
new file mode 100644 (file)
index 0000000..5637e81
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#include <iostream>
+
+#include "DimmingResource.h"
+#include "OCPlatform.h"
+
+#define INTERFACE_KEY "if"
+
+using namespace OC;
+namespace PH = std::placeholders;
+
+DimmingResource::DimmingResource(std::string resourceUri):
+        m_nr_resource_types{1},
+        m_nr_resource_interfaces{2},
+        m_interestedObservers{},
+        m_var_value_dimmingSetting{100},
+        m_var_value_n{},
+        m_var_value_if{},
+        m_var_value_rt{}
+{
+    std::cout << "Running: DimmingResource constructor" << std::endl;
+    std::string resourceURI = "/dimming";
+
+    // VS2013 will fail list initialization so use array initialization
+    m_resourceUri = resourceUri;
+    m_RESOURCE_TYPE[0] = "oic.r.light.dimming";
+    m_RESOURCE_INTERFACE[0] = "oic.if.baseline";
+    m_RESOURCE_INTERFACE[1] = "oic.if.a";
+    m_IF_UPDATE[0] = "oic.if.a";
+    m_IF_UPDATE[1] = "oic.if.rw";
+    m_IF_UPDATE[2] = "oic.if.baseline";
+    m_var_name_dimmingSetting = "dimmingSetting";
+    m_var_name_n = "n";
+    m_var_name_if = "if";
+    m_var_name_rt = "rt";
+
+    // initialize member variables /dimming
+    m_var_value_dimmingSetting = 0; // current value of property "dimmingSetting"
+    m_var_value_n = "";  // current value of property "n"
+    // initialize vector if
+    m_var_value_if.push_back("oic.if.baseline");
+    m_var_value_if.push_back("oic.if.a");
+    // initialize vector rt
+    m_var_value_rt.push_back("oic.r.light.dimming");
+}
+
+DimmingResource::~DimmingResource(void) { }
+
+OCStackResult DimmingResource::registerResource(uint8_t resourceProperty)
+{
+    EntityHandler cb = std::bind(&DimmingResource::entityHandler, this, PH::_1);
+    OCStackResult result = OC_STACK_ERROR;
+    result = OCPlatform::registerResource(m_resourceHandle,
+                                          m_resourceUri,
+                                          m_RESOURCE_TYPE[0],
+                                          m_RESOURCE_INTERFACE[0],
+                                          cb,
+                                          resourceProperty);
+    if (OC_STACK_OK != result)
+    {
+        std::cerr << "Failed to register BinarySwitchResoruce." << std::endl;
+        return result;
+    }
+
+    /// add the additional resource types
+    for( int a = 1; a < m_nr_resource_types; a++ )
+    {
+        result = OCPlatform::bindTypeToResource(m_resourceHandle, m_RESOURCE_TYPE[a].c_str());
+        if (OC_STACK_OK != result)
+        {
+            std::cerr << "Could not bind resource type:" << m_RESOURCE_INTERFACE[a] << std::endl;
+            return result;
+        }
+    }
+    // add the additional interfaces
+    for( int a = 1; a < m_nr_resource_interfaces; a++)
+    {
+        result = OCPlatform::bindInterfaceToResource(m_resourceHandle, m_RESOURCE_INTERFACE[a].c_str());
+        if (OC_STACK_OK != result)
+        {
+            std::cerr << "Could not bind interface:" << m_RESOURCE_INTERFACE[a] << std::endl;
+            return result;
+        }
+    }
+
+    std::cout << "DimmingResource:" << std::endl;
+    std::cout << "\t" << "# resource interfaces: " << m_nr_resource_interfaces << std::endl;
+    std::cout << "\t" << "# resource types     : " << m_nr_resource_types << std::endl;
+
+    return result;
+}
+
+int DimmingResource::getDimmingSetting(void)
+{
+    return m_var_value_dimmingSetting;
+}
+
+void DimmingResource::setDimmingSetting(int dimmingSetting)
+{
+    if (dimmingSetting >= 0 && dimmingSetting <= 100)
+    {
+        m_var_value_dimmingSetting = dimmingSetting;
+        std::cout << "\t\t" << "property 'dimmingSetting': " << m_var_value_dimmingSetting << std::endl;
+    } else {
+        std::cerr << "the dimmingSetting must between 0 and 100" << std::endl;
+    }
+}
+
+OCStackResult DimmingResource::sendNotification(void)
+{
+    OCStackResult sResult = OC_STACK_OK;
+    if ( m_interestedObservers.size() > 0) {
+        std::cout << "Notifying list"  << m_interestedObservers.size() << " of observers\n";
+        auto pResponse = std::make_shared<OC::OCResourceResponse>();
+        sResult = OCPlatform::notifyListOfObservers(m_resourceHandle,
+                                                    m_interestedObservers,
+                                                    pResponse);
+    }
+    return sResult;
+}
+
+OC::OCRepresentation DimmingResource::get(OC::QueryParamsMap queries)
+{
+    OC_UNUSED(queries);
+
+    m_rep.setValue(m_var_name_dimmingSetting, m_var_value_dimmingSetting );
+    m_rep.setValue(m_var_name_n, m_var_value_n );
+    m_rep.setValue(m_var_name_if,  m_var_value_if );
+    m_rep.setValue(m_var_name_rt,  m_var_value_rt );
+
+    return m_rep;
+}
+
+OCEntityHandlerResult DimmingResource::post(OC::QueryParamsMap queries, const OC::OCRepresentation& rep)
+{
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+    OC_UNUSED(queries);
+
+    try {
+        if (rep.hasAttribute(m_var_name_dimmingSetting))
+        {
+            // allocate the variable
+            int value;
+            // get the actual value from the payload
+            rep.getValue(m_var_name_dimmingSetting, value);
+
+            // value exist in payload
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << e.what() << std::endl;
+    }
+
+    if (ehResult == OC_EH_OK)
+    {
+        // no error: assign the variables
+        try {
+            // value exist in payload
+            if (rep.getValue(m_var_name_dimmingSetting, m_var_value_dimmingSetting ))
+            {
+                std::cout << "\t\t" << "property 'dimmingSetting': " << m_var_value_dimmingSetting << std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'dimmingSetting' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.getValue(m_var_name_n, m_var_value_n ))
+            {
+                std::cout << "\t\t" << "property 'n' : " << m_var_value_n << std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'n' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.hasAttribute(m_var_name_if))
+            {
+                rep.getValue(m_var_name_if, m_var_value_if);
+                int first = 1;
+                std::cout << "\t\t" << "property 'if' : " ;
+                for(auto myvar: m_var_value_if)
+                {
+                    if (first)
+                    {
+                        std::cout << myvar;
+                        first = 0;
+                    }
+                    else
+                    {
+                        std::cout << "," << myvar;
+                    }
+                }
+                std::cout <<  std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'if' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        try {
+            if (rep.hasAttribute(m_var_name_rt))
+            {
+                rep.getValue(m_var_name_rt, m_var_value_rt);
+                int first = 1;
+                std::cout << "\t\t" << "property 'rt' : " ;
+                for(auto myvar: m_var_value_rt)
+                {
+                    if (first)
+                    {
+                        std::cout << myvar;
+                        first = 0;
+                    }
+                    else
+                    {
+                        std::cout << "," << myvar;
+                    }
+                }
+                std::cout <<  std::endl;
+            }
+            else
+            {
+                std::cout << "\t\t" << "property 'rt' not found in the representation" << std::endl;
+            }
+        }
+        catch (std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+    }
+    return ehResult;
+}
+
+OCEntityHandlerResult DimmingResource::entityHandler(std::shared_ptr<OC::OCResourceRequest> request)
+{
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    if (request)
+    {
+        std::cout << "In entity handler for DimmingResource, URI is : "
+                << request->getResourceUri() << std::endl;
+
+        // Check for query params (if any)
+        QueryParamsMap queries = request->getQueryParameters();
+        if (!queries.empty())
+        {
+            std::cout << "\nQuery processing up to entityHandler" << std::endl;
+        }
+        for (auto it : queries)
+        {
+            std::cout << "Query key: " << it.first << " value : " << it.second
+                    << std::endl;
+        }
+        // get the value, so that we can AND it to check which flags are set
+        int requestFlag = request->getRequestHandlerFlag();
+
+        if (requestFlag & RequestHandlerFlag::RequestFlag)
+        {
+            // request flag is set
+            auto pResponse = std::make_shared<OC::OCResourceResponse>();
+            pResponse->setRequestHandle(request->getRequestHandle());
+            pResponse->setResourceHandle(request->getResourceHandle());
+
+            if (request->getRequestType() == "GET")
+            {
+                std::cout<<"DimmingResource Get Request"<< std::endl;
+
+                pResponse->setResourceRepresentation(get(queries), "");
+                if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                {
+                    ehResult = OC_EH_OK;
+                }
+            }
+
+            else if (request->getRequestType() == "POST")
+            {
+                std::cout <<"DimmingResource Post Request"<<std::endl;
+                bool  handle_post = true;
+
+                if (queries.size() > 0)
+                {
+                    for (const auto &eachQuery : queries)
+                    {
+                        std::string key = eachQuery.first;
+                        if (key.compare(INTERFACE_KEY) == 0)
+                        {
+                            std::string value = eachQuery.second;
+                            if (in_updatable_interfaces(value) == false)
+                            {
+                                std::cout << "Update request received via interface: " << value
+                                        << " . This interface is not authorized to update resource!!" << std::endl;
+                                pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_FORBIDDEN);
+                                handle_post = false;
+                                ehResult = OC_EH_ERROR;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (handle_post)
+                {
+                    ehResult = post(queries, request->getResourceRepresentation());
+                    if (ehResult == OC_EH_OK)
+                    {
+                        pResponse->setResourceRepresentation(get(queries), "");
+                    }
+                    else
+                    {
+                        pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_ERROR);
+                    }
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        if (OC_STACK_OK != sendNotification() )
+                        {
+                            std::cerr << "NOTIFY failed." << std::endl;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                std::cout << "DimmingResource unsupported request type (delete,put,..)"
+                        << request->getRequestType() << std::endl;
+                pResponse->setResponseResult(OC_EH_ERROR);
+                OCPlatform::sendResponse(pResponse);
+                ehResult = OC_EH_ERROR;
+            }
+        }
+
+        if (requestFlag & RequestHandlerFlag::ObserverFlag)
+        {
+            // observe flag is set
+            std::cout << "\t\trequestFlag : Observer ";
+            ObservationInfo observationInfo = request->getObservationInfo();
+            ((ObserveAction::ObserveRegister == observationInfo.action) ? std::cout << "Register\n" : std::cout << "Unregister\n");
+            if (ObserveAction::ObserveRegister == observationInfo.action)
+            {
+                // add observer
+                m_interestedObservers.push_back(observationInfo.obsId);
+            }
+            else if (ObserveAction::ObserveUnregister == observationInfo.action)
+            {
+                // delete observer
+                m_interestedObservers.erase(std::remove(
+                                            m_interestedObservers.begin(),
+                                            m_interestedObservers.end(),
+                                            observationInfo.obsId),
+                                            m_interestedObservers.end());
+            }
+            ehResult = OC_EH_OK;
+        }
+    }
+    return ehResult;
+}
diff --git a/resource/examples/ocf_light/DimmingResource.h b/resource/examples/ocf_light/DimmingResource.h
new file mode 100644 (file)
index 0000000..5a48e9e
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_DIMMINGRESOURCE_H_
+#define EXAMPLE_OCF_LIGHT_DIMMINGRESOURCE_H_
+
+#include <vector>
+#include <string>
+#include "Resource.h"
+
+#include "OCApi.h"
+#include "OCRepresentation.h"
+
+class DimmingResource : public Resource
+{
+public:
+    /*
+     * constructor
+     *
+     * @param resourceUri the uri the resource will be register with
+     */
+    DimmingResource(std::string resourceUri = "/dimming");
+
+    /*
+     * destructor
+     */
+    virtual ~DimmingResource(void);
+
+    /*
+     * get the dimmingSetting
+     *
+     * @return the dimmingSetting
+     */
+    int getDimmingSetting(void);
+
+    /*
+     * set the dimmingSetting
+     *
+     * @param dimmingSetting a number between 0-100 to set the dimming
+     */
+    void setDimmingSetting(int dimmingSetting);
+
+    /*
+     * Attempt to send out notifications to observing clients.
+     * If no value on the device has been changed the notification
+     * may not be sent.
+     *
+     * @return OC_STACK_OK on success
+     */
+    OCStackResult sendNotification(void);
+
+    /*
+     * Register the resource with the server
+     *
+     * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+     * setting resourceProperty as OC_OBSERVABLE will allow observation
+     * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and observation
+     * setting resourceProperty as OC_SECURE the resource supports access via secure endpoints
+     * setting resourceProperty as OC_NONSECURE the resource supports access via non-secure endpoints
+     * setting resourceProperty as OC_SECURE | OC_NONSECURE will allow access via secure and non-secure endpoints
+     *
+     * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+     */
+    OCStackResult registerResource(uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
+private:
+
+    /*
+     * Make the payload for the retrieve function (e.g. GET)
+     *
+     * @param queries  the query parameters for this call
+     *
+     * @return OCRepresentaiton with the dimming resource parameters assigned.
+     */
+    OC::OCRepresentation get(OC::QueryParamsMap queries);
+
+    /*
+     * Parse the payload for the update function (e.g. POST)
+     *
+     * @param queries  the query parameters for this call
+     * @param rep  the response to get the property values from
+     *
+     * @return OCEntityHandlerResult OC_EH_OK on success or other result indicating failure.
+     */
+    OCEntityHandlerResult post(OC::QueryParamsMap queries, const OC::OCRepresentation& rep);
+
+    // resource types and interfaces as array..
+    std::string m_resourceUri;
+    std::string m_RESOURCE_TYPE[1]; // rt value (as an array)
+    std::string m_RESOURCE_INTERFACE[2]; // interface if (as an array)
+    std::string m_IF_UPDATE[3]; // updateble interfaces
+    int m_nr_resource_types;
+    int m_nr_resource_interfaces;
+    OC::ObservationIds m_interestedObservers;
+
+    // member variables for path: /dimming
+    int m_var_value_dimmingSetting; // the value for the attribute
+    std::string m_var_name_dimmingSetting; // the name for the attribute
+
+    std::string m_var_value_n; // the value for the attribute
+    std::string m_var_name_n; // the name for the attribute
+
+
+    std::vector<std::string>  m_var_value_if;
+    std::string m_var_name_if; // the name for the attribute
+
+
+    std::vector<std::string>  m_var_value_rt;
+    std::string m_var_name_rt; // the name for the attribute
+
+protected:
+    /*
+     * Check if the interface is an updatable interface.
+     *
+     * @param  interface_name the interface name used during the request
+     *
+     * @return true: updatable interface
+     */
+    bool in_updatable_interfaces(std::string interface_name)
+    {
+        for (int i=0; i<3; i++)
+        {
+            if (m_IF_UPDATE[i].compare(interface_name) == 0)
+                return true;
+        }
+        return false;
+    }
+
+    /*
+     * The entity handler for this resource
+     *
+     * @param request the incoming request to handle
+     *
+     * @return OCEntityHandlerResult OC_EH_OK on success or other result indicating failure.
+     */
+    virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OC::OCResourceRequest> request);
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_DIMMINGRESOURCE_H_ */
diff --git a/resource/examples/ocf_light/Platform.cpp b/resource/examples/ocf_light/Platform.cpp
new file mode 100644 (file)
index 0000000..03f15d9
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#include <iostream>
+
+#include "OCPlatform.h"
+#include "Platform.h"
+
+using namespace OC;
+
+/**
+ *  server_fopen
+ *  opens file
+ *  implements redirection to open:
+ * - initial security settings
+ * - introspection file
+ * @param path path+filename of the file to open
+ * @param mode mode of the file to open
+ * @return the filehandle of the opened file (or error)
+ */
+FILE* server_fopen(const char* path, const char* mode)
+{
+    FILE* fileptr = NULL;
+
+    if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
+    {
+        // reading the security initial setup file
+        fileptr = fopen("dl_server_security.dat", mode);
+        std::cout << "reading security file 'dl_server_security.dat' ptr: " << fileptr << std::endl;
+        return fileptr;
+    }
+    else if (0 == strcmp(path, OC_INTROSPECTION_FILE_NAME))
+    {
+        // reading the introspection file
+        fileptr = fopen("dl_server_introspection.dat", mode);
+        std::cout << "reading introspection file  'dl_server_introspection.dat' ptr: " << fileptr << std::endl;
+        return fileptr;
+    }
+    else
+    {
+        std::cout << "persistent storage - server_fopen: " << path << std::endl;
+        return fopen(path, mode);
+    }
+}
+
+// Create persistent storage handlers
+OCPersistentStorage ps{server_fopen, fread, fwrite, fclose, unlink};
+
+Platform::Platform(void)
+{
+    std::cout << "Running Platform constructor" << std::endl;
+    dataModelVersions.push_back("ocf.res.1.3.0");
+    dataModelVersions.push_back("ocf.sh.1.3.0");
+    // create the platform
+    PlatformConfig cfg
+    {
+        ServiceType::InProc,
+        ModeType::Server,
+        &ps
+    };
+    OCPlatform::Configure(cfg);
+    setPlatformInfo(m_platformId, m_manufacturerName, m_manufacturerLink,
+                    m_modelNumber, m_dateOfManufacture, m_platformVersion, m_operatingSystemVersion,
+                    m_hardwareVersion, m_firmwareVersion, m_supportLink, m_systemTime);
+
+}
+
+Platform::~Platform(void)
+{
+    std::cout << "Running Platform destructor" << std::endl;
+    deletePlatformInfo();
+}
+
+OCStackResult Platform::start(void)
+{
+    return OCPlatform::start();
+}
+
+OCStackResult Platform::registerPlatformInfo(void)
+{
+    OCStackResult result = OC_STACK_ERROR;
+    result = OCPlatform::registerPlatformInfo(platformInfo);
+    return result;
+}
+
+
+OCPlatformInfo* Platform::getPlatformInfo(void)
+{
+    return &platformInfo;
+}
+
+OCStackResult Platform::stop(void)
+{
+    return OCPlatform::stop();
+}
+
+/**
+ *  DuplicateString
+ *
+ * @param targetString  destination string, will be allocated
+ * @param sourceString  source string, e.g. will be copied
+
+ *  TODO: don't use strncpy
+ */
+void DuplicateString(char ** targetString, std::string sourceString)
+{
+    *targetString = new char[sourceString.length() + 1];
+    strncpy(*targetString, sourceString.c_str(), (sourceString.length() + 1));
+}
+
+void Platform::setPlatformInfo(std::string platformID, std::string manufacturerName,
+        std::string manufacturerUrl, std::string modelNumber, std::string dateOfManufacture,
+        std::string platformVersion, std::string operatingSystemVersion,
+        std::string hardwareVersion, std::string firmwareVersion, std::string supportUrl,
+        std::string systemTime)
+{
+    DuplicateString(&platformInfo.platformID, platformID);
+    DuplicateString(&platformInfo.manufacturerName, manufacturerName);
+    DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl);
+    DuplicateString(&platformInfo.modelNumber, modelNumber);
+    DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture);
+    DuplicateString(&platformInfo.platformVersion, platformVersion);
+    DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion);
+    DuplicateString(&platformInfo.hardwareVersion, hardwareVersion);
+    DuplicateString(&platformInfo.firmwareVersion, firmwareVersion);
+    DuplicateString(&platformInfo.supportUrl, supportUrl);
+    DuplicateString(&platformInfo.systemTime, systemTime);
+}
+
+void Platform::deletePlatformInfo(void)
+{
+    delete[] platformInfo.platformID;
+    delete[] platformInfo.manufacturerName;
+    delete[] platformInfo.manufacturerUrl;
+    delete[] platformInfo.modelNumber;
+    delete[] platformInfo.dateOfManufacture;
+    delete[] platformInfo.platformVersion;
+    delete[] platformInfo.operatingSystemVersion;
+    delete[] platformInfo.hardwareVersion;
+    delete[] platformInfo.firmwareVersion;
+    delete[] platformInfo.supportUrl;
+    delete[] platformInfo.systemTime;
+}
+
+/**
+ *  SetDeviceInfo
+ *  Sets the device information ("oic/d"), from the member variables
+
+ * @return OC_STACK_ERROR or OC_STACK_OK
+ */
+OCStackResult Platform::setDeviceInfo()
+{
+    OCStackResult result = OC_STACK_ERROR;
+
+    /*
+     * For IoTivity v1.3 use the the C function OCGetResourceHandleAtUri
+     * OCResourceHandle handle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
+     */
+    OCResourceHandle handle = OCPlatform::getResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
+    if (handle == NULL)
+    {
+        std::cout << "Failed to find resource " << OC_RSRVD_DEVICE_URI << std::endl;
+        return result;
+    }
+    result = OCPlatform::bindTypeToResource(handle, deviceType);
+    if (result != OC_STACK_OK)
+    {
+        std::cout << "Failed to add device type" << std::endl;
+        return result;
+    }
+
+    result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION,
+            dataModelVersions);
+    if (result != OC_STACK_OK)
+    {
+        std::cout << "Failed to set data model versions" << std::endl;
+        return result;
+    }
+
+    result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, specVersion);
+    if (result != OC_STACK_OK)
+    {
+        std::cout << "Failed to set spec version" << std::endl;
+        return result;
+    }
+
+    result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_PROTOCOL_INDEPENDENT_ID,
+            protocolIndependentID);
+    if (result != OC_STACK_OK)
+    {
+        std::cout << "Failed to set piid" << std::endl;
+        return result;
+    }
+
+    result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, deviceName);
+    if (result != OC_STACK_OK)
+    {
+        std::cout << "Failed to set device name" << std::endl;
+        return result;
+    }
+    return OC_STACK_OK;
+}
diff --git a/resource/examples/ocf_light/Platform.h b/resource/examples/ocf_light/Platform.h
new file mode 100644 (file)
index 0000000..c1bbef2
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_PLATFORM_H_
+#define EXAMPLE_OCF_LIGHT_PLATFORM_H_
+
+#include <vector>
+#include <string>
+#include "OCPlatform.h"
+
+class Platform
+{
+public:
+    Platform(void);
+    virtual ~Platform(void);
+
+    OCStackResult start(void);
+    OCStackResult registerPlatformInfo(void);
+    OCPlatformInfo* getPlatformInfo(void);
+    OCStackResult stop(void);
+
+    /**
+     *  SetDeviceInfo
+     *  Sets the device information ("oic/d"), from the globals
+
+     * @return OC_STACK_ERROR or OC_STACK_OK
+     */
+    OCStackResult setDeviceInfo(void);
+
+private:
+    // Set of strings for each of platform Info fields
+    std::string m_platformId = "0A3E0D6F-DBF5-404E-8719-D6880042463A";
+    std::string m_manufacturerName = "ocf";
+    std::string m_manufacturerLink = "https://ocf.org/";
+    std::string m_modelNumber = "ModelNumber";
+    std::string m_dateOfManufacture = "2017-12-01";
+    std::string m_platformVersion = "1.0";
+    std::string m_operatingSystemVersion = "myOS";
+    std::string m_hardwareVersion = "1.0";
+    std::string m_firmwareVersion = "1.0";
+    std::string m_supportLink = "https://ocf.org/";
+    std::string m_systemTime = "2017-12-01T12:00:00.52Z";
+
+    /**
+     *  SetPlatformInfo
+     *  Sets the platform information ("oic/p"), from the globals
+
+     * @param platformID the platformID
+     * @param manufacturerName the manufacturerName
+     * @param manufacturerUrl the manufacturerUrl
+     * @param modelNumber the modelNumber
+     * @param platformVersion the platformVersion
+     * @param operatingSystemVersion the operatingSystemVersion
+     * @param hardwareVersion the hardwareVersion
+     * @param firmwareVersion the firmwareVersion
+     * @param supportUrl the supportUrl
+     * @param systemTime the systemTime
+     */
+    void setPlatformInfo(std::string platformID, std::string manufacturerName,
+            std::string manufacturerUrl, std::string modelNumber, std::string dateOfManufacture,
+            std::string platformVersion, std::string operatingSystemVersion,
+            std::string hardwareVersion, std::string firmwareVersion, std::string supportUrl,
+            std::string systemTime);
+
+    /**
+     *  deletePlatformInfo
+     *  Deletes the allocated platform information
+     */
+    void deletePlatformInfo(void);
+    // OCPlatformInfo Contains all the platform info to be stored
+    OCPlatformInfo platformInfo;
+
+public:
+    std::string  protocolIndependentID = "fa008167-3bbf-4c9d-8604-c9bcb96cb712";
+
+    // Set of strings for each of device info fields
+    std::string  deviceName = "Binary Switch";
+    std::string  deviceType = "oic.d.light";
+    std::string  specVersion = "ocf.1.0.0";
+    std::vector<std::string> dataModelVersions;
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_PLATFORM_H_ */
diff --git a/resource/examples/ocf_light/README.md b/resource/examples/ocf_light/README.md
new file mode 100644 (file)
index 0000000..e138aaa
--- /dev/null
@@ -0,0 +1,125 @@
+# Introduction\r
+This contains sample implementation of an OCF smart light using resources\r
+defined by the OCF smart home project.\r
+\r
+The code was originally generated using the\r
+[OCF DeviceBuilder](https://github.com/openconnectivityfoundation/DeviceBuilder)\r
+project.\r
+\r
+The output from DeviceBuilder is a single giant C++ file. That output was\r
+separated into individual classes.\r
+\r
+The code has several goals:\r
+    - provide a reference implementation showing how implement a C++ IoTivity\r
+      server.\r
+    - Try and demonstrate using IoTivity in a way that is reusable for other\r
+      developers\r
+\r
+# What this sample code contains\r
+- `dimming_light_server.cpp`: contains the main function for the code.\r
+- `Platform.h` and `Platform.cpp`: code responsible for starting the\r
+  IoTivity platform and registering platform information like the date of\r
+  manufacture, platform ID, etc. This code is also responsible registering\r
+  device information like device type and device name.\r
+- `Resource.h`: base class for all OCF resources.\r
+- `BinarySwitchResource.h` and `BinarySwitchResource.cpp`: an\r
+  implementation of the `oic.r.switch.binary` resource type.\r
+- `DimmingResource.h` and `DimmingResource.cpp`: an implementation\r
+  of the `oic.r.light.dimming` resource type.\r
+- `DimmingLightServer.h` and `DimmingLightServer.cpp`: combine\r
+  BinarySwitchResource and the DimmingResource and make them available as a\r
+  single object.\r
+- `DimmingLightControl.h` and `DimmingLightControl.cpp` adds commandline\r
+  control of the dimming light sample when running. This is useful for testing\r
+  notifications or verifying operation of the device.\r
+- `dl_server_introspection.json`: introspect file representing the dimming\r
+  light. This file is primarily a reference file provided so the developer knows\r
+  the contents of the `dl_server_introspection.dat` file.\r
+- `dl_server_introspection.dat`: contains the same information as\r
+  `dl_server_introspection.json` but it is [cbor](http://cbor.io) encoded.\r
+- `dl_server_security.json.in` This a reference file that is the same as\r
+  `dl_server_security.json` except is it annotated with comments describing the\r
+  different parts of the security file.\r
+- `dl_server_security.json`: reference file to see the contents of\r
+  `dl_server_security.dat` This contains the initial security settings used\r
+  by the device at startup. This is file is specifically designed for to place\r
+  the device in the Ready for Ownership Transfer Method (RFOTM) state.\r
+- `dl_server_security.dat`: [cbor](http://cbor.io) encoded version of the\r
+  `dl_server_security.json` file. This must be encoded using the\r
+  `json2cbor` tool provided with IoTivity.\r
+- `dl_PICS.json`: This file contains the settings needed to run the dimming\r
+  light sample on the OCF Conformance Test Tool (CTT)\r
+- `SConscript`: build script used to build code using\r
+  [SCons](http://scons.org/) build tool\r
+- `readme.md`: this readme file.\r
+\r
+# The OCF Conformance Test Tool (CTT)\r
+## Obtaining the CTT\r
+\r
+The OCF Conformance Test Tool or CTT is the primary tool used to certify that a\r
+server or client is conforms to the OCF specifications. The CTT tool is only\r
+available to members of the Open Connectivity Foundation(OCF).\r
+\r
+There are many membership levels for individuals wishing to join the\r
+Open Connectivity Foundation OCF. Go [here](https://openconnectivity.org/foundation/join)\r
+for information on joining.\r
+\r
+The CTT is available to all OCF members. Even to the members at a Basic Membership\r
+level which if free and has no annual dues. At the Basic Membership level the CTT\r
+can only be used for pre-testing purposes. It can not be used to certify devices.\r
+\r
+Once OFC membership has been obtained the CTT can be downloaded from the\r
+[OCF Test Tool Resources page](https://workspace.openconnectivity.org/kws/test_tools/).\r
+\r
+The dimming light server was tested against CTT2.1 that was released January 2018.\r
+\r
+## PICS file\r
+\r
+The dimming light server comes with a `PICS.json` file. This file contains\r
+the information the CTT needs to test the server. Please, select this file when\r
+asked to select a PICS file by the CTT. Do not use the default PICS file.\r
+\r
+IoTivity implements security virtual resources that are currently optional in\r
+the OCF specification. Currently there is no mechanism available to opt out of\r
+these resources. The `oic.r.crl`, `oic.r.csr`, and `oic.r.roles`\r
+resource need to be declared in the PICS file.\r
+\r
+## CTT info\r
+\r
+When CTT pops up:\r
+"reset to ready for OTM" of "reset to RFOTM" means you need to:\r
+1. Stop your device\r
+2. Reset/replace security databases with a new/unowned one.\r
+    e.g. copy the ORIGINAL security file to the executable directory.\r
+3. Start your device.\r
+\r
+Note if the device being tested crashes during testing you will also need to\r
+reset the security state to a not onboarded state. This is mentioned in the test\r
+case log of CTT when the CTT can not reset the device state properly.\r
+\r
+## Running the `dimming_light_server` against the CTT\r
+\r
+All tests should pass or be skipped with the following four exceptions.\r
+\r
+1. `CT1.1.5 Authority of an OCF URI` will fail with a warning stating\r
+the anchor properties values are the same before and after onboarding. This\r
+warning is due to Section 13.12.1 of the OCF Security Specification v1.3.1.\r
+Before a the device is onboarded it **should** present a temporary non-repeated\r
+values for device id. This is not required for certification. Currently IoTivity\r
+does not support this security/privacy feature.\r
+\r
+2. `CT1.7.3.2 Device Identity (persistent and semi-persistent)`\r
+This warning is a result of the same fake device id privacy feature as `CT1.1.5`\r
+It is not required for certification.\r
+\r
+3. `CT1.7.8.11 Implicit Behavior of SVR Properties in Each Device State`\r
+is currently failing due to a specification change so this can be unchecked or\r
+ignored.\r
+\r
+4. `CT1.7.12.5 Verify RFOTM behavior when OTM sequence does not complete`\r
+will fail with a warning stating the connection should be dropped after 65\r
+seconds. This warning is due to a optional requirement in section 13.7 of the\r
+OCF Security Specification v1.3.1 that states an ownership transfer session\r
+**should** not exceed 60 seconds. The OTM should fail, be disconnected, and\r
+transition to RESET. Once again IoTivity currently does not support this\r
+optional requirement and it is not required for certification.\r
diff --git a/resource/examples/ocf_light/Resource.h b/resource/examples/ocf_light/Resource.h
new file mode 100644 (file)
index 0000000..bad9f97
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Copyright 2018 Intel Corporation All Rights Reserved.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+#ifndef EXAMPLE_OCF_LIGHT_RESOURCE_H_
+#define EXAMPLE_OCF_LIGHT_RESOURCE_H_
+
+#include "octypes.h"
+#include "OCRepresentation.h"
+#include "OCResourceRequest.h"
+
+/**
+* default Resource class, so that we have to define less variables/functions.
+*/
+class Resource
+{
+public:
+    /**
+     * destructor
+     */
+    virtual ~Resource() { };
+protected:
+    OCResourceHandle m_resourceHandle;
+    OC::OCRepresentation m_rep;
+
+    /**
+     * Virtual entity handler for this resource. Child classes are responsible
+     * for implementing this function.
+     *
+     * @param request the incoming request to handle
+     *
+     * @return OCEntityHandlerResult OC_EH_OK on success or other result indicating failure.
+     */
+    virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OC::OCResourceRequest> request)=0;
+};
+
+#endif /* EXAMPLE_OCF_LIGHT_RESOURCE_H_ */
diff --git a/resource/examples/ocf_light/SConscript b/resource/examples/ocf_light/SConscript
new file mode 100644 (file)
index 0000000..1727d51
--- /dev/null
@@ -0,0 +1,36 @@
+#******************************************************************
+#
+# Copyright 2018 Intel 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('examples_env')
+
+examples_env.AppendUnique(CPPPATH=[
+    Dir('.').srcnode().path
+])
+
+ocf_light_files = [
+    'dimming_light_server.cpp',
+    'BinarySwitchResource.cpp',
+    'DimmingLightControl.cpp',
+    'DimmingLightServer.cpp',
+    'DimmingResource.cpp',
+    'Platform.cpp',
+]
+
+output = examples_env.Program(ocf_light_files)
\ No newline at end of file
diff --git a/resource/examples/ocf_light/dimming_light_server.cpp b/resource/examples/ocf_light/dimming_light_server.cpp
new file mode 100644 (file)
index 0000000..179c645
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ *\r
+ * Copyright 2018 Intel Corporation All Rights Reserved.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+\r
+#include <signal.h>\r
+#include <string>\r
+#include <iostream>\r
+\r
+#ifdef HAVE_WINDOWS_H\r
+#include <windows.h>\r
+#endif\r
+\r
+#include "DimmingLightServer.h"\r
+#include "Platform.h"\r
+#include "DimmingLightControl.h"\r
+\r
+// main application\r
+// starts the server\r
+int main(void)\r
+{\r
+    Platform platform;\r
+    if (OC_STACK_OK != platform.start())\r
+    {\r
+        std::cerr << "Failed to start the IoTivity platform." << std::endl;\r
+        return 1;\r
+    }\r
+    // initialize "oic/p"\r
+    std::cout << "oic/p" << std::endl;\r
+    if (OC_STACK_OK != platform.registerPlatformInfo())\r
+    {\r
+        std::cerr << "Failed Platform Registration (oic/p)." << std::endl;\r
+    }\r
+    // initialize "oic/d"\r
+    std::cout << "oic/d" << std::endl;\r
+    if (OC_STACK_OK != platform.setDeviceInfo())\r
+    {\r
+        std::cerr << "Failed Device Registration (oic/d)." << std::endl;\r
+    }\r
+\r
+    std::cout << "device type: " <<  platform.deviceType << std::endl;\r
+    std::cout << "platformID: " <<  platform.getPlatformInfo()->platformID << std::endl;\r
+    std::cout << "platform independent: " << platform.protocolIndependentID << std::endl;\r
+\r
+    // create the server\r
+    DimmingLightServer server;\r
+    if (OC_STACK_OK != server.registerResources())\r
+    {\r
+        std::cerr << "Failed to register resources server resources." << std::endl;\r
+        return 1;\r
+    }\r
+\r
+    DimmingLightControl clc(server);\r
+    // process function will block till user types 'q' or 'quit'\r
+    clc.process();\r
+\r
+    if (OC_STACK_OK != platform.stop())\r
+    {\r
+        std::cerr << "Failed to stop the IoTivity platform." << std::endl;\r
+    }\r
+\r
+    return 0;\r
+}\r
diff --git a/resource/examples/ocf_light/dl_PICS.json b/resource/examples/ocf_light/dl_PICS.json
new file mode 100644 (file)
index 0000000..5ad5b23
--- /dev/null
@@ -0,0 +1,32 @@
+{
+    "device": "test1",
+    "company": "Open Connectivity Foundation",
+    "role": "Server",
+    "supportedVerticalProfile": [
+        "Smart Home"
+    ],
+    "supportedDeviceTypes": [
+        "oic.d.light"
+    ],
+    "icv": "ocf.1.0.0",
+    "dmv": "ocf.res.1.3.0, ocf.sh.1.3.0",
+    "resources": [
+        "oic.r.switch.binary",
+        "oic.r.light.dimming",
+        "oic.r.csr",
+        "oic.r.crl",
+        "oic.r.roles",
+        "oic.r.sp"
+    ],
+    "jurisdictionSwitch": false,
+    "OTM": [
+        "oic.sec.doxm.jw"
+    ],
+    "contentFormatVersion": [ "1.0.0" ],
+    "acceptVersion": [ "1.0.0" ],
+
+    "multiValueQuerySupport": false,
+    "observableOICRES": false,
+    "persistentDeviceuuid": false,
+    "sct": 1
+}
\ No newline at end of file
diff --git a/resource/examples/ocf_light/dl_server_introspection.dat b/resource/examples/ocf_light/dl_server_introspection.dat
new file mode 100644 (file)
index 0000000..f37e3b3
Binary files /dev/null and b/resource/examples/ocf_light/dl_server_introspection.dat differ
diff --git a/resource/examples/ocf_light/dl_server_introspection.json b/resource/examples/ocf_light/dl_server_introspection.json
new file mode 100644 (file)
index 0000000..d26bd57
--- /dev/null
@@ -0,0 +1,371 @@
+{
+    "produces":[
+        "application/json"
+    ],
+    "parameters":{
+        "interface20":{
+            "enum":[
+                "oic.if.baseline",
+                "oic.if.r"
+            ],
+            "in":"query",
+            "type":"string",
+            "name":"if"
+        },
+        "interface":{
+            "enum":[
+                "oic.if.baseline",
+                "oic.if.a"
+            ],
+            "in":"query",
+            "type":"string",
+            "name":"if"
+        }
+    },
+    "swagger":"2.0",
+    "consumes":[
+        "application/json"
+    ],
+    "definitions":{
+        "Dimming":{
+            "required":[
+                "dimmingSetting"
+            ],
+            "type":"object",
+            "properties":{
+                "n":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "if":{
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "enum":[
+                            "oic.if.baseline",
+                            "oic.if.a"
+                        ],
+                        "type":"string"
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "rt":{
+                    "default":[
+                        "oic.r.light.dimming"
+                    ],
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "type":"string",
+                        "maxLength":64
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "dimmingSetting":{
+                    "type":"integer",
+                    "description":""
+                }
+            }
+        },
+        "BinarySwitch":{
+            "required":[
+                "value"
+            ],
+            "type":"object",
+            "properties":{
+                "rt":{
+                    "default":[
+                        "oic.r.switch.binary"
+                    ],
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "type":"string",
+                        "maxLength":64
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "n":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "if":{
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "enum":[
+                            "oic.if.baseline",
+                            "oic.if.a"
+                        ],
+                        "type":"string"
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "value":{
+                    "type":"boolean",
+                    "description":""
+                }
+            }
+        },
+        "Platform":{
+            "required":[
+                "pi",
+                "mnmn"
+            ],
+            "type":"object",
+            "properties":{
+                "mnos":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "mnmn":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "mnpv":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "st":{
+                    "format":"date-time",
+                    "type":"string",
+                    "readOnly":true,
+                    "description":""
+                },
+                "pi":{
+                    "allOf":[
+                        {
+                            "pattern":"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
+                            "type":"string",
+                            "description":""
+                        },
+                        {
+                            "readOnly":true,
+                            "description":""
+                        }
+                    ]
+                },
+                "id":{
+                    "anyOf":[
+                        {
+                            "type":"string",
+                            "maxLength":64
+                        },
+                        {
+                            "pattern":"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
+                            "type":"string",
+                            "description":""
+                        }
+                    ],
+                    "readOnly":true,
+                    "description":""
+                },
+                "mnhw":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "rt":{
+                    "default":[
+                        "oic.wk.p"
+                    ],
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "type":"string",
+                        "maxLength":64
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "if":{
+                    "readOnly":true,
+                    "type":"array",
+                    "items":{
+                        "enum":[
+                            "oic.if.baseline",
+                            "oic.if.r"
+                        ],
+                        "type":"string"
+                    },
+                    "description":"",
+                    "minItems":1
+                },
+                "mnmo":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "mnml":{
+                    "format":"uri",
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":256
+                },
+                "mnsl":{
+                    "format":"uri",
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":256
+                },
+                "mnfv":{
+                    "type":"string",
+                    "readOnly":true,
+                    "description":"",
+                    "maxLength":64
+                },
+                "mndt":{
+                    "allOf":[
+                        {
+                            "pattern":"^([0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|2[0-9]|1[0-9]|0[1-9])$",
+                            "type":"string",
+                            "description":""
+                        },
+                        {
+                            "readOnly":true,
+                            "description":""
+                        }
+                    ]
+                }
+            }
+        }
+    },
+    "info":{
+        "license":{
+            "name":"copyright 2016-2017 Open Connectivity Foundation, Inc. All rights reserved."
+        },
+        "version":"v1.1.0-20160519",
+        "title":"Binary Switch"
+    },
+    "paths":{
+        "/oic/p":{
+            "get":{
+                "responses":{
+                    "200":{
+                        "schema":{
+                            "$ref":"#/definitions/Platform"
+                        },
+                        "description":""
+                    }
+                },
+                "parameters":[
+                    {
+                        "$ref":"#/parameters/interface20"
+                    }
+                ],
+                "description":""
+            }
+        },
+        "/binaryswitch":{
+            "post":{
+                "responses":{
+                    "200":{
+                        "schema":{
+                            "$ref":"#/definitions/BinarySwitch"
+                        },
+                        "description":""
+                    }
+                },
+                "parameters":[
+                    {
+                        "$ref":"#/parameters/interface"
+                    },
+                    {
+                        "required":true,
+                        "in":"body",
+                        "schema":{
+                            "$ref":"#/definitions/BinarySwitch"
+                        },
+                        "name":"body"
+                    }
+                ],
+                "description":""
+            },
+            "get":{
+                "responses":{
+                    "200":{
+                        "schema":{
+                            "$ref":"#/definitions/BinarySwitch"
+                        },
+                        "description":""
+                    }
+                },
+                "parameters":[
+                    {
+                        "$ref":"#/parameters/interface"
+                    }
+                ],
+                "description":""
+            }
+        },
+        "/dimming":{
+            "post":{
+                "responses":{
+                    "200":{
+                        "schema":{
+                            "$ref":"#/definitions/Dimming"
+                        },
+                        "description":""
+                    },
+                    "403":{
+                        "schema":{
+                            "$ref":"#/definitions/Dimming"
+                        },
+                        "description":""
+                    }
+                },
+                "parameters":[
+                    {
+                        "$ref":"#/parameters/interface"
+                    },
+                    {
+                        "required":true,
+                        "in":"body",
+                        "schema":{
+                            "$ref":"#/definitions/Dimming"
+                        },
+                        "name":"body"
+                    }
+                ],
+                "description":""
+            },
+            "get":{
+                "responses":{
+                    "200":{
+                        "schema":{
+                            "$ref":"#/definitions/Dimming"
+                        },
+                        "description":""
+                    }
+                },
+                "parameters":[
+                    {
+                        "$ref":"#/parameters/interface"
+                    }
+                ],
+                "description":""
+            }
+        }
+    },
+    "schemes":[
+        "http"
+    ]
+}
\ No newline at end of file
diff --git a/resource/examples/ocf_light/dl_server_security.dat b/resource/examples/ocf_light/dl_server_security.dat
new file mode 100644 (file)
index 0000000..3cf8bdb
Binary files /dev/null and b/resource/examples/ocf_light/dl_server_security.dat differ
diff --git a/resource/examples/ocf_light/dl_server_security.json b/resource/examples/ocf_light/dl_server_security.json
new file mode 100644 (file)
index 0000000..3928c60
--- /dev/null
@@ -0,0 +1,64 @@
+{
+    "acl": {
+        "aclist2": [
+            {
+                "aceid": 1,
+                "subject": { "conntype": "anon-clear" },
+                "resources": [
+                    { "href": "/oic/res" },
+                    { "href": "/oic/d" },
+                    { "href": "/oic/p" },
+                    { "wc": "-" }
+                ],
+                "permission": 2
+            },
+            {
+                "aceid": 2,
+                "subject": { "conntype": "auth-crypt" },
+                "resources": [
+                    { "href": "/oic/res" },
+                    { "href": "/oic/d" },
+                    { "href": "/oic/p" },
+                    { "wc": "+" }
+                ],
+                "permission": 2
+            },
+            {
+                "aceid": 3,
+                "subject": { "conntype": "anon-clear" },
+                "resources": [
+                    { "href": "/oic/sec/doxm" }
+                ],
+                "permission": 14
+            },
+            {
+                "aceid": 4,
+                "subject": { "conntype": "auth-crypt" },
+                "resources": [
+                    { "href": "/oic/sec/doxm" },
+                    { "href": "/oic/sec/roles" }
+                ],
+                "permission": 14
+            }
+        ],
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    },
+    "pstat": {
+        "dos": { "s": 1, "p": false },
+        "isop": false,
+        "cm": 2,
+        "tm": 0,
+        "om": 4,
+        "sm": 4,
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    },
+    "doxm": {
+        "oxms": [0],
+        "oxmsel": 0,
+        "sct": 1,
+        "owned": false,
+        "deviceuuid": "12345678-1234-1234-1234-123456789012",
+        "devowneruuid": "00000000-0000-0000-0000-000000000000",
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    }
+}
diff --git a/resource/examples/ocf_light/dl_server_security.json.in b/resource/examples/ocf_light/dl_server_security.json.in
new file mode 100644 (file)
index 0000000..fedd1fc
--- /dev/null
@@ -0,0 +1,273 @@
+{
+    /*
+     * Access Control List: iotivity assumes that resources are hosted by a
+     * server and are made available to clients subject to access control and
+     * authorization mechanisms.
+     *
+     * In order to be successfully accessed by a client, a resource must have an
+     * Access Control Entry (ACE) which grants access. Lacking a matching ACE,
+     * requests for the resource will be denied.
+     *
+     * The following ACL is intended for onboarding purposes. Onboarding is the
+     * process where a device becomes operational and is able to interact with
+     * other devices. The following ACEs enable ownership transfer (i.e.
+     * a user claims ownership of the device). With the addition of wildcard
+     * entries to improve user and developer experience by giving intuitive
+     * access behavior after onboarding.
+     *
+     * Ownership transfer via Owner Transfer Methods (OTM) is the first step in
+     * the onboarding it is intended to be done with an OnBoarding Tool (OBT)
+     * that can then be used to provision the device by adding adding/removing
+     * ACEs.
+     */
+    "acl": {
+        /*
+         * aclist2 is an array of ACEs this is used by the server to apply
+         * access control to its local resources.
+         */
+        "aclist2": [
+            /*
+             * This ACE gives RETRIEVE access to all non-authenticated endpoints to
+             *
+             *  - `/oic/res` used for device discovery
+             *  - `/oic/d` used for device information
+             *  - `/oic/p` used for platform information
+             *  - wildcard `-` user resources created with OC_NONSECURE
+             */
+            {
+                /*
+                 * Each ACE is expected to have a unique number. This is used by
+                 * provisioning/onboarding tools to retrieve, update, and delete
+                 * entries.
+                 */
+                "aceid": 1,
+                /*
+                 * The subject determines which client(s) the ACE applies to.
+                 * In this case the ACE is using a subject that
+                 * matches based on connection or message protection type.
+                 *
+                 * - `"conntype": "anon-clear"` ACE will match the subject if
+                 *   the client is not authenticated and the data is not
+                 *   encrypted.
+                 * - `"conntype": ""auth-crypt"` ACE will match the subject if
+                 *   the client is authenticated and the data is encrypted.
+                 *
+                 * `subject` can be connection type (as shown), a role, or
+                 *  device id.
+                 *
+                 * The ACEs in this list are limited to connection type subjects.
+                 * Other subject types should be added using a separate tool,
+                 * after OTM has completed.
+                 */
+                "subject": { "conntype": "anon-clear" },
+                /*
+                 * The application's resources to which this ACE applies. See
+                 * list of resources and there meaning listed above.
+                 */
+                "resources": [
+                    { "href": "/oic/res" },
+                    { "href": "/oic/d" },
+                    { "href": "/oic/p" },
+                    { "wc": "-" }
+                ],
+                /*
+                 * Permission is a bitmask encoding of CRUDN permissions.
+                 * (CRUDN: CREATE, RETRIEVE, UPDATE, DELETE, NOTIFY)
+                 * The bitmask is CRUDN read in reverse or NDURC so a bit mask
+                 * bxxx0,0001 (1) would have CREATE permission. A bit mask of
+                 * bxxx0,0010 (2) would have RETRIEVE permission. A bit mask of
+                 * bxxx0,0011 (3) would have permission to CREATE and RETRIEVE.
+                 * A bit mask of bxxx1,1111 would have access to all CRUDN
+                 * permissions.
+                 */
+                "permission": 2
+            },
+            /*
+             * This ACE gives READ access to all authenticated endpoints to
+             *
+             *  - `/oic/res` used for device discovery
+             *  - `/oic/d` used for device information
+             *  - `/oic/p` used for platform information
+             *  - wildcard `+` user resources created with OC_SECURE
+             */
+            {
+                "aceid": 2,
+                "subject": { "conntype": "auth-crypt" },
+                "resources": [
+                    { "href": "/oic/res" },
+                    { "href": "/oic/d" },
+                    { "href": "/oic/p" },
+                    { "wc": "+" }
+                ],
+                "permission": 2
+            },
+            /*
+             * This ACE gives READ, UPDATE, and DELETE access to all
+             * non-authenticated endpoints to Device Ownership Transfer Method
+             * (doxm).
+             *
+             * **NOTE:** the OBT should remove this ACE after onboarding to
+             * prevent another client from subsequently re-onboarding the device.
+             *
+             *  - `/oic/sec/doxm` is used for device ownership transfer.
+             */
+            {
+                "aceid": 3,
+                "subject": { "conntype": "anon-clear" },
+                "resources": [
+                    { "href": "/oic/sec/doxm" }
+                ],
+                "permission": 14
+            },
+            /*
+             * This ACE gives READ, UPDATE, and DELETE access to all
+             * non-authenticated endpoints to Device Ownership Transfer Method
+             * (doxm).
+             *
+             *  - `/oic/sec/doxm` is used for device ownership transfer.
+             *  - `/oic/sec/roles` contains all roles that have been asserted to
+             *    the server. Roles assertion is beyond the scope of this
+             *    documentation please see OCF Security Specification v1.3.1
+             *    section 10.3.1 for more information.
+             */
+            {
+                "aceid": 4,
+                "subject": { "conntype": "auth-crypt" },
+                "resources": [
+                    { "href": "/oic/sec/doxm" },
+                    { "href": "/oic/sec/roles" }
+                ],
+                "permission": 14
+            }
+        ],
+        /*
+         * This is the Resource Owner Id it must be a nil uuid value. The device
+         * ownership transfer system (DOTS) will configure the rowneruuid when
+         * a successful owner transfer session is established.
+         */
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    },
+    /*
+     * The `/oic/sec/pstat` resource maintains the device provisioning status.
+     */
+    "pstat": {
+        /*
+         * Device onboarding state
+         * `s` is the onboarding state:
+         *   - 0: RESET (Reset)
+         *   - 1: RFOTM (Ready For Ownership Transfer Method)
+         *   - 2: RFPRO (Ready For Provisioning)
+         *   - 3: RFNOP (Ready For Normal Operation)
+         *   - 4: SRESET (Soft Reset)
+         * `p` is the device onboarding state pending.
+         */
+        "dos": { "s": 1, "p": false },
+        /*
+         * Is Device Operational. This is false except when the device enters
+         * the RFNOP state. So it is false when in the RFOTM state.
+         */
+        "isop": false,
+        /*
+         * Current Mode: a bitmask that is changed depending on the
+         * onboarding state. RFOTM state it should be set to 00xx,xx10. Meaning
+         * device paring mode is enabled. Allowing owner transfer operations.
+         */
+        "cm": 2,
+        /*
+         * Target Mode: another bitmask this should be 0. More
+         * information about the target mode can be found in the OCF Security
+         * Specification
+         */
+        "tm": 0,
+        /*
+         * Operational Mode: this bitmask specifies the operational mode.
+         *
+         * Mask bx0000,0100 (4) is Client-directed provisioning. More
+         * information about the operational mode can be found in the OCF
+         * Security Specification
+         */
+        "om": 4,
+        /*
+         * Supported Mode is a bitmask indicating supported provisioning service
+         * operation modes.
+         *
+         * Mask bx0000,0100 (4) is Client-directed provisioning. More
+         * information about the operational mode can be found in the OCF
+         * Security Specification
+         */
+        "sm": 4,
+        /*
+         * This is the Resource Owner Id it must be a nil uuid value. The device
+         * ownership transfer system (DOTS) will configure the rowneruuid when
+         * a successful owner transfer session is established.
+         */
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    },
+    /*
+     * Device Ownership Transfer Method
+     */
+    "doxm": {
+        /*
+         * Array of owner-transfer-methods.
+         *
+         * If the code supports multiple owner-transfer-methods multiple values
+         * can be listed. The entries appear in the order of preference.
+         *
+         * The Security Specification Defines the following OTM types
+         *  - `0` (`oic.sec.doxm.jw`) the just-works method. This relies on
+         *    anonymous Diffie-Hellman key agreement protocol to allow a DOTS
+         *    to add ownership The first DOTS to assert device ownership is the
+         *    device that gains ownership. Any subsequent attempts to take
+         *    ownership will fail unless the device is RESET first. Just-works
+         *    is very useful for ease of use but may be inappropriate in
+         *    situations where multiple individuals may be onboarding devices.
+         *  - `1` (`oic.sec.doxm.rdp`) the new device randomly generates a PIN that
+         *    that is communicated via an out-of-band channel to a DOTS. Random
+         *    PIN onboarding resembles pairing done with Bluetooth devices. It
+         *    helps ensure the device seen by the DOTS is indead the device
+         *    being onboarded.
+         *  - `2` (`oic.sec.doxm.mfgcert`) the new device is presumed to have been
+         *    manufactured with an embedded asymmetic private key that is used
+         *    during TLS handshake at device onboarding.
+         *  - 0xFF00~0FFFF are reserved for vendor specific OTM use. And must be
+         *    looked up.
+         */
+        "oxms": [0],
+        /*
+         * The selected owner-transfer-method.This may be change by the doxm if
+         * the DOTS wishes to use a different OTM listed in `oxms`. In other
+         * words, DOTS is free to choose a stronger or weaker OTM even if it
+         * supports all the OTMs.
+         */
+        "oxmsel": 0,
+        /*
+         * Supported Credential Types. This value should contain all the
+         * credential types implemented by the device, so the OBT can select
+         * only supported credentials to use with the device.
+         */
+        "sct": 1,
+        /*
+         * Device ownership status. The DOTS is responsible for setting this to
+         * true after an owner transfer session is established.
+         */
+        "owned": false,
+        /*
+         * This is the is a uuid that identifies the device. This value is
+         * reflected into the oic.wk.d device id (`di`). If the device is
+         * un-owned the framework may not share this deviceuuid, to protect
+         * identifying information.
+         */
+        "deviceuuid": "12345678-1234-1234-1234-123456789012",
+        /*
+         * The device owner uuid. This should be nil it will be updated by the
+         * DOTS.
+         */
+        "devowneruuid": "00000000-0000-0000-0000-000000000000",
+        /*
+         * This is the Resource Owner Id it must be a nil uuid value. The device
+         * ownership transfer system (DOTS) will configure the rowneruuid when
+         * a successful owner transfer session is established.
+         */
+        "rowneruuid": "00000000-0000-0000-0000-000000000000"
+    }
+}