--- /dev/null
+/**
+ * @brief TODO
+ * @date Created 12.06.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ * between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ * Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:a.gudz@samsung.com">Andriy Gudz, a.gudz@samsung.com</A>
+ */
+
+#include <iostream>
+#include <condition_variable>
+#include <stdexcept>
+#include <thread>
+#include <chrono>
+#include <time.h>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+#include <gtest/gtest.h>
+
+#include "iotivity.h"
+
+#include "IOT_EasySetup.h"
+#include "IOT_Device.h"
+#include "IOT_Enrollee.h"
+#include "IOT_Enroller.h"
+#include "IOT_Resource.h"
+#include "IOT_AirconResource.h"
+#include "IOT_PowerResource.h"
+#include "IOT_ReportResource.h"
+#include "IOT_PolicyResource.h"
+
+using namespace std;
+using namespace OC;
+using namespace NetworkManager;
+namespace PH = std::placeholders;
+
+bool isListOfObservers = false;
+bool isSecure = false;
+bool isSlowResponse = false;
+
+class LightResource
+{
+
+public:
+ /// Access this property from a TB client
+ std::string m_name;
+ bool m_state;
+ int m_power;
+ std::string m_lightUri;
+ OCResourceHandle m_resourceHandle;
+ OCRepresentation m_lightRep;
+ ObservationIds m_interestedObservers;
+
+public:
+ /// Constructor
+ LightResource()
+ : m_name("John's light"), m_state(false), m_power(0), m_lightUri("/a/emo"),
+ m_resourceHandle(nullptr)
+ {
+ // Initialize representation
+ m_lightRep.setUri(m_lightUri);
+
+ m_lightRep.setValue("state", m_state);
+ m_lightRep.setValue("power", m_power);
+ m_lightRep.setValue("name", m_name);
+ }
+
+ /* Note that this does not need to be a member function: for classes you do not have
+ access to, you can accomplish this with a free function: */
+
+ /// This function internally calls registerResource API.
+ void createResource()
+ {
+ //URI of the resource
+ std::string resourceURI = m_lightUri;
+ //resource type name. In this case, it is light
+ std::string resourceTypeName = "core.emo";
+ // resource interface.
+ std::string resourceInterface = DEFAULT_INTERFACE;
+
+ // OCResourceProperty is defined ocstack.h
+ uint8_t resourceProperty;
+ if(isSecure)
+ {
+ resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE;
+ }
+ else
+ {
+ resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+ }
+ EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1);
+
+ // This will internally create and register the resource.
+ OCStackResult result = OCPlatform::registerResource(
+ m_resourceHandle, resourceURI, resourceTypeName,
+ resourceInterface, cb, resourceProperty);
+
+ if (OC_STACK_OK != result)
+ {
+ cout << "Resource creation was unsuccessful\n";
+ }
+ }
+
+ OCStackResult createResource1()
+ {
+ // URI of the resource
+ std::string resourceURI = "/a/light1";
+ // resource type name. In this case, it is light
+ std::string resourceTypeName = "core.light";
+ // resource interface.
+ std::string resourceInterface = DEFAULT_INTERFACE;
+
+ // OCResourceProperty is defined ocstack.h
+ uint8_t resourceProperty;
+ if(isSecure)
+ {
+ resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE;
+ }
+ else
+ {
+ resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
+ }
+ EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1);
+
+ OCResourceHandle resHandle;
+
+ // This will internally create and register the resource.
+ OCStackResult result = OCPlatform::registerResource(
+ resHandle, resourceURI, resourceTypeName,
+ resourceInterface, cb, resourceProperty);
+
+ if (OC_STACK_OK != result)
+ {
+ cout << "Resource creation was unsuccessful\n";
+ }
+
+ return result;
+ }
+
+ OCResourceHandle getHandle()
+ {
+ return m_resourceHandle;
+ }
+
+ // Puts representation.
+ // Gets values from the representation and
+ // updates the internal state
+ void put(OCRepresentation& rep)
+ {
+ try
+ {
+ if (rep.getValue("state", m_state))
+ {
+ cout << "\t\t\t\t" << "state: " << m_state << endl;
+ }
+ else
+ {
+ cout << "\t\t\t\t" << "state not found in the representation" << endl;
+ }
+
+ if (rep.getValue("power", m_power))
+ {
+ cout << "\t\t\t\t" << "power: " << m_power << endl;
+ }
+ else
+ {
+ cout << "\t\t\t\t" << "power not found in the representation" << endl;
+ }
+ }
+ catch (exception& e)
+ {
+ cout << e.what() << endl;
+ }
+
+ }
+
+ // Post representation.
+ // Post can create new resource or simply act like put.
+ // Gets values from the representation and
+ // updates the internal state
+ OCRepresentation post(OCRepresentation& rep)
+ {
+ static int first = 1;
+
+ // for the first time it tries to create a resource
+ if(first)
+ {
+ first = 0;
+
+ if(OC_STACK_OK == createResource1())
+ {
+ OCRepresentation rep1;
+ rep1.setValue("createduri", std::string("/a/light1"));
+
+ return rep1;
+ }
+ }
+
+ // from second time onwards it just puts
+ put(rep);
+ return get();
+ }
+
+
+ // gets the updated representation.
+ // Updates the representation with latest internal state before
+ // sending out.
+ OCRepresentation get()
+ {
+ m_lightRep.setValue("state", m_state);
+ m_lightRep.setValue("power", m_power);
+
+ return m_lightRep;
+ }
+
+ void addType(const std::string& type) const
+ {
+ OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type);
+ if (OC_STACK_OK != result)
+ {
+ cout << "Binding TypeName to Resource was unsuccessful\n";
+ }
+ }
+
+ void addInterface(const std::string& iface) const
+ {
+ OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, iface);
+ if (OC_STACK_OK != result)
+ {
+ cout << "Binding TypeName to Resource was unsuccessful\n";
+ }
+ }
+
+private:
+// This is just a sample implementation of entity handler.
+// Entity handler can be implemented in several ways by the manufacturer
+ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
+ {
+ cout << "\tIn Server CPP entity handler:\n";
+ OCEntityHandlerResult ehResult = OC_EH_ERROR;
+ if(request)
+ {
+ // Get the request type and request flag
+ std::string requestType = request->getRequestType();
+ int requestFlag = request->getRequestHandlerFlag();
+
+ if(requestFlag & RequestHandlerFlag::RequestFlag)
+ {
+ cout << "\t\trequestFlag : Request\n";
+ auto pResponse = std::make_shared<OC::OCResourceResponse>();
+ pResponse->setRequestHandle(request->getRequestHandle());
+ pResponse->setResourceHandle(request->getResourceHandle());
+
+ // Check for query params (if any)
+ QueryParamsMap queries = request->getQueryParameters();
+
+ if (!queries.empty())
+ {
+ std::cout << "\nQuery processing upto entityHandler" << std::endl;
+ }
+ for (auto it : queries)
+ {
+ std::cout << "Query key: " << it.first << " value : " << it.second
+ << std:: endl;
+ }
+
+ // If the request type is GET
+ if(requestType == "GET")
+ {
+ cout << "\t\t\trequestType : GET\n";
+
+ pResponse->setResponseResult(OC_EH_OK);
+ pResponse->setResourceRepresentation(get());
+ if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+ {
+ ehResult = OC_EH_OK;
+ }
+ }
+ else if(requestType == "PUT")
+ {
+ cout << "put not supported";
+ }
+ else if(requestType == "POST")
+ {
+ cout << "post not supported";
+ }
+ else if(requestType == "DELETE")
+ {
+ cout << "Delete request received" << endl;
+ }
+ }
+
+ if(requestFlag & RequestHandlerFlag::ObserverFlag)
+ {
+ cout << "observe not supported";
+ }
+ }
+ else
+ {
+ std::cout << "Request invalid" << std::endl;
+ }
+
+ return ehResult;
+ }
+
+};
+
+static string getPSPath()
+{
+ char SVR_DB_FILE_PATH[1000] = {0};
+ ssize_t size = readlink("/proc/self/exe", SVR_DB_FILE_PATH, sizeof(SVR_DB_FILE_PATH));
+ if (size == 0 || size == sizeof(SVR_DB_FILE_PATH))
+ throw runtime_error("readlink error");
+ return string(SVR_DB_FILE_PATH) + "_ps.dat";
+}
+
+static FILE* client_open(const char *path, const char *mode)
+{
+ (void) path;
+ return fopen(getPSPath().c_str(), mode);
+}
+
+/**
+ * Test check report sender functional
+ */
+TEST(test_emo, DISABLED_server)
+{
+ OCPersistentStorage ps{client_open, fread, fwrite, fclose, unlink};
+ PlatformConfig cfg{ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, QualityOfService::HighQos, &ps};
+
+ static mutex mtx;
+ unique_lock<mutex> lck(mtx);
+ condition_variable cvar;
+
+ try
+ {
+ OCPlatform::Configure(cfg);
+ OCPlatform::start();
+
+ LightResource light;
+ light.createResource();
+
+ cvar.wait(lck);
+
+ OCPlatform::stop();
+ }
+ catch (NMexception& e)
+ {
+ ADD_FAILURE() << e.what() << " " << e.errorCode();
+ }
+ catch (std::exception& e)
+ {
+ ADD_FAILURE() << e.what();
+ }
+}
+
+
+std::shared_ptr<OCResource> curResource;
+std::mutex curResourceLock;
+
+void foundResource(std::shared_ptr<OCResource> resource)
+{
+ try
+ {
+ std::string resourceURI = resource->uri();
+ std::string resourceHost = resource->host();
+ std::string resourceDuid = resource->sid();
+ lock_guard<std::mutex> lock(curResourceLock);
+ if(!curResource)
+ {
+ curResource = resource;
+ cout << "\tFound: " << resourceURI << " " <<
+ resourceHost << " " << resourceDuid << endl << flush;
+ //resource->observe(ObserveType::ObserveAll, QueryParamsMap(), &onObserve);
+ }
+ }
+ catch(std::exception& e)
+ {
+ std::cerr << "Exception in foundResource: " << e.what() << std::endl;
+ }
+}
+
+
+/**
+ * Test check report sender functional
+ */
+TEST(test_emo, DISABLED_client)
+{
+ OCPersistentStorage ps{client_open, fread, fwrite, fclose, unlink};
+ PlatformConfig cfg{ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, QualityOfService::HighQos, &ps};
+
+ static mutex mtx;
+ unique_lock<mutex> lck(mtx);
+ condition_variable cvar;
+
+ try
+ {
+ OCPlatform::Configure(cfg);
+ OCPlatform::start();
+
+ std::ostringstream requestURI;
+ requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << "core.emo";
+ OCPlatform::findResource("", requestURI.str() /*requestURI.str()*/, CT_DEFAULT, &foundResource);
+ std::cout << "Finding Resource... " << std::endl;
+
+ cvar.wait_for(lck, std::chrono::seconds(60));
+
+ OCPlatform::stop();
+ }
+ catch (NMexception& e)
+ {
+ ADD_FAILURE() << e.what() << " " << e.errorCode();
+ }
+ catch (std::exception& e)
+ {
+ ADD_FAILURE() << e.what();
+ }
+}