Hub resource stub added
authori.metelytsia <i.metelytsia@samsung.com>
Thu, 15 Jun 2017 14:09:20 +0000 (17:09 +0300)
committeri.metelytsia <i.metelytsia@samsung.com>
Fri, 16 Jun 2017 06:20:17 +0000 (09:20 +0300)
device_core/iotivity_lib/IoT/IOT_HubResource.cpp [new file with mode: 0644]
device_core/iotivity_lib/IoT/IOT_HubResource.h [new file with mode: 0644]
device_core/iotivity_lib/IoT/IOT_Resource.cpp
device_core/iotivity_lib/IoT/IOT_Resource.h
device_core/iotivity_lib/inc/hub_client.h [new file with mode: 0644]
device_core/iotivity_lib/src/hub_client.cpp [new file with mode: 0644]
device_core/nmdaemon/main_thread.cpp
device_core/utest/CMakeLists.txt
device_core/utest/test_iot_dev_manager.cpp

diff --git a/device_core/iotivity_lib/IoT/IOT_HubResource.cpp b/device_core/iotivity_lib/IoT/IOT_HubResource.cpp
new file mode 100644 (file)
index 0000000..8a04981
--- /dev/null
@@ -0,0 +1,104 @@
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+#include "IOT_Resource.h"
+#include "IOT_HubResource.h"
+
+using namespace OC;
+
+/*******************************************************/
+/*******************************************************/
+IOT_HubResource::IOT_HubResource(const std::string& _uri, const std::vector<std::string>& _types, const std::vector<std::string>& _interfaces) :
+    IOT_Resource(_uri, _types, _interfaces), m_devices("")
+{
+    m_representation.setValue("devices", m_devices);
+}
+
+/*******************************************************/
+/*******************************************************/
+/*virtual*/ void IOT_HubResource::setRepresentation(OCRepresentation& _rep)
+{
+    std::string devices;
+
+    if(_rep.getValue("devices", devices))
+    {
+        m_devices = devices;
+        m_representation.setValue("devices", m_devices);
+        propagate();
+    }
+}
+
+static const std::string s_devs = IOT_PrimitiveDeviceList::makeList({{"1", "dev 1", "aircon", "model 1"},{"2", "dev 2", "washer", "model 1"},{"3", "dev 3", "lamp", "model 1"} });
+
+/*******************************************************/
+/*******************************************************/
+/*virtual*/ OCEntityHandlerResult IOT_HubResource::entityHandler(std::shared_ptr<OCResourceRequest> _request)
+{
+    OCEntityHandlerResult res = OC_EH_ERROR;
+
+    if(_request)
+    {
+        std::string rt = _request->getRequestType();
+        int rf = _request->getRequestHandlerFlag();
+
+        if(rf & RequestHandlerFlag::RequestFlag)
+        {
+            if(rt == "GET")
+            {
+                m_devices = s_devs;
+                m_representation.setValue("devices", m_devices);
+
+                if(sendRepresentation(_request) == OC_STACK_OK)
+                    res = OC_EH_OK;
+            }
+            else if(rt == "PUT")
+            {
+                // PUT request operations
+            }
+            else if(rt == "POST")
+            {
+                OCRepresentation rep = _request->getResourceRepresentation();
+                printRepresentation(rep);
+
+                setRepresentation(rep);
+                if(sendRepresentation(_request) == OC_STACK_OK)
+                    res = OC_EH_OK;
+            }
+            else if(rt == "DELETE")
+            {
+                // DELETE request operations
+            }
+        }
+
+        if(rf & RequestHandlerFlag::ObserverFlag)
+        {
+            ObservationInfo info = _request->getObservationInfo();
+            if(info.action == ObserveAction::ObserveRegister)
+            {
+                m_interested_observers.push_back(info.obsId);
+            }
+            else if(info.action == ObserveAction::ObserveUnregister)
+            {
+                m_interested_observers.erase(remove(m_interested_observers.begin(), m_interested_observers.end(), info.obsId), m_interested_observers.end());
+            }
+        }
+    }
+    else
+    {
+        //cout << "Request invalid" << endl;
+    }
+
+    return res;
+}
+
+/*******************************************************/
+/*******************************************************/
+/*friend*/ std::ostream& operator<<(std::ostream& _os, const IOT_HubResource& _obj)
+{
+    _os << _obj.m_devices;
+    return _os;
+}
diff --git a/device_core/iotivity_lib/IoT/IOT_HubResource.h b/device_core/iotivity_lib/IoT/IOT_HubResource.h
new file mode 100644 (file)
index 0000000..ca9cc05
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef __IOT_HUB_RESOURCE_H__
+#define __IOT_HUB_RESOURCE_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <time.h>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+#include "IOT_Resource.h"
+
+using namespace OC;
+
+/*******************************************************/
+/*******************************************************/
+class IOT_PrimitiveDevice final
+{
+public:
+    IOT_PrimitiveDevice(const std::string& _did = "", const std::string& _name = "", const std::string& _type = "", const std::string& _model = "") :
+        m_did(_did), m_name(_name), m_type(_type), m_model(_model)
+    {
+    }
+
+    friend std::ostream& operator<<(std::ostream& _os, const IOT_PrimitiveDevice& _obj)
+    {
+        _os << makeDevice(_obj.m_did, _obj.m_name, _obj.m_type, _obj.m_model);
+        return _os;
+    }
+
+    static std::string makeDevice(const std::string& _did = "", const std::string& _name = "", const std::string& _type = "", const std::string& _model = "")
+    {
+        std::ostringstream oss;
+        oss << "\t{\n";
+        oss << "\t\t\"did\": \"" << _did << "\",\n";
+        oss << "\t\t\"name\": \"" << _name << "\",\n";
+        oss << "\t\t\"type\": \"" << _type << "\",\n";
+        oss << "\t\t\"model\": \"" << _model << "\"\n";
+        oss << "\t},\n";
+        return oss.str();
+    }
+
+private:
+    std::string m_did;
+    std::string m_name;
+    std::string m_type;
+    std::string m_model;
+};
+
+/*******************************************************/
+/*******************************************************/
+class IOT_PrimitiveDeviceList final
+{
+public:
+    IOT_PrimitiveDeviceList(const std::vector<IOT_PrimitiveDevice>& _devs = std::vector<IOT_PrimitiveDevice>{}) :
+        m_devs(_devs)
+    {
+    }
+
+    friend std::ostream& operator<<(std::ostream& _os, const IOT_PrimitiveDeviceList& _obj)
+    {
+        _os << makeList(_obj.m_devs);
+        return _os;
+    }
+
+    static std::string makeList(const std::vector<IOT_PrimitiveDevice>& _devs = std::vector<IOT_PrimitiveDevice>{})
+    {
+        std::ostringstream oss;
+        oss << "[\n";
+        for(auto it : _devs)
+            oss << it;
+        if(_devs.size() != 0)
+        {
+            oss.seekp(oss.str().size() - 2);
+            oss << "\n";
+        }
+        oss << "]\n";
+        return oss.str();
+    }
+
+private:
+    std::vector<IOT_PrimitiveDevice> m_devs;
+};
+
+/*******************************************************/
+/*******************************************************/
+class IOT_HubResource : public IOT_Resource
+{
+public:
+    IOT_HubResource(const std::string& _uri, const std::vector<std::string>& _types, const std::vector<std::string>& _interfaces);
+    IOT_HubResource(const IOT_HubResource& _obj) = default;
+
+    virtual ~IOT_HubResource() = default;
+
+    IOT_HubResource& operator=(const IOT_HubResource& _obj) = default;
+
+    virtual void setRepresentation(OCRepresentation& _rep);
+
+    virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> _request);
+
+    friend std::ostream& operator<<(std::ostream& _os, const IOT_HubResource& _obj);
+
+private:
+    std::string m_devices;
+};
+
+#endif /* __IOT_HUB_RESOURCE_H__ */
index befe395..3dfcd0d 100644 (file)
@@ -229,8 +229,32 @@ OCStackResult IOT_Resource::observeResource(const std::shared_ptr<OCResource> _r
 
 OCStackResult IOT_Resource::cancelObserve(const std::shared_ptr<OC::OCResource> _resource)
 {
-    OCStackResult result = _resource->cancelObserve();
-    return result;
+    return _resource->cancelObserve();
+}
+
+OCStackResult IOT_Resource::get(const std::shared_ptr<OC::OCResource> _resource, const std::string& _type, const std::string& _interface, const QueryParamsMap& _query_params)
+{
+    OCStackResult res = OC_STACK_ERROR;
+
+    if(_resource)
+    {
+        std::mutex mtx;
+        std::unique_lock<std::mutex> lck(mtx);
+        std::condition_variable cvar;
+        res = _resource->get(   _type,
+                                _interface,
+                                _query_params,
+                                [&](const HeaderOptions&, const OCRepresentation& _rep, const int _ecode)
+                                {
+//                                    if(_ecode != 4)
+//                                        res = static_cast<OCStackResult>(_ecode);
+//                                    std::cout << "!!!!!!!!!!!!!!!!11 : " << _ecode << " " << representationToString(_rep) << std::endl;
+                                    cvar.notify_all();
+                                }   );
+        cvar.wait(lck);
+    }
+
+    return res;
 }
 
 OCStackResult IOT_Resource::post(const std::shared_ptr<OC::OCResource> _resource, const std::string& _type,
index 72712cc..a1e4899 100644 (file)
@@ -69,6 +69,8 @@ public:
 
     static OCStackResult cancelObserve(const std::shared_ptr<OC::OCResource> _resource);
 
+    static OCStackResult get(const std::shared_ptr<OC::OCResource> _resource, const std::string& _type, const std::string& _interface, const QueryParamsMap& _query_params);
+
     static OCStackResult post(const std::shared_ptr<OC::OCResource> _resource, const std::string& _type, const std::string& _interface, const OCRepresentation& _representation, const QueryParamsMap& _query_params);
 
     static std::string representationToString(const OCRepresentation& _rep);
diff --git a/device_core/iotivity_lib/inc/hub_client.h b/device_core/iotivity_lib/inc/hub_client.h
new file mode 100644 (file)
index 0000000..9e2daaf
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * @brief  Hub resource client
+ * @date   Created 18.05.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:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
+#ifndef HUB_CLIENT_H
+#define HUB_CLIENT_H
+
+#include <string>
+#include <memory>
+#include <string>
+#include <OCApi.h>
+#include <OCPlatform.h>
+
+namespace NetworkManager
+{
+/**
+ * @brief The HubClient class provide connection to hub resource
+ */
+class HubClient
+{
+    static const std::string HUB_RESOURCE_TYPE;
+    std::shared_ptr<OC::OCResource> resource;
+public:
+    /**
+     * @brief Constructor
+     * @param host [in] IoT Cloud host address
+     */
+    HubClient(const std::string& host);
+
+    /**
+     * @brief true if resource found and false otherwise
+     */
+    operator bool() const;
+
+    /**
+     * @brief getPrimitiveDevices get list of primitive devices
+     * @param query [in] parameters used for reports filtering
+     * @return report in JSON format
+     */
+    std::string getPrimitiveDevices(const OC::QueryParamsMap& query);
+};
+
+} // namespace NetworkManager
+
+
+#endif // HUB_CLIENT_H
diff --git a/device_core/iotivity_lib/src/hub_client.cpp b/device_core/iotivity_lib/src/hub_client.cpp
new file mode 100644 (file)
index 0000000..ff7b253
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * @brief  Hub resource client
+ * @date   Created 18.05.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:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
+#include "network_manager_tag.h"
+#include "logging.h"
+#include <functional>
+#include <chrono>
+#include "iotivity.h"
+#include "hub_client.h"
+#include "resource_callbacks.h"
+
+using namespace OC;
+
+namespace PH = std::placeholders;
+
+namespace NetworkManager
+{
+
+const std::string HubClient::HUB_RESOURCE_TYPE{"device.hub"};
+
+HubClient::HubClient(const std::string& host)
+{
+    std::string requestURI{OC_RSRVD_WELL_KNOWN_URI};
+    FindResourceCallback::Sptr callback = std::make_shared<FindResourceCallback>(HUB_RESOURCE_TYPE);
+
+    OCPlatform::findResource(host, requestURI, CT_DEFAULT, bind_callback(callback, PH::_1));
+
+    if (!callback->wait())
+    {
+        LOG_E(TAG, "HubClient found callback not called.");
+    }
+    else
+    {
+        resource = callback->resource;
+    }
+}
+
+HubClient::operator bool() const
+{
+    return (bool)resource;
+}
+
+std::string HubClient::getPrimitiveDevices(const OC::QueryParamsMap& query)
+{
+    std::string devices;
+
+    if(resource)
+    {
+        GetResourceCallback::Sptr callback = std::make_shared<GetResourceCallback>();
+
+        auto result = resource->get(query, bind_callback(callback, PH::_1, PH::_2, PH::_3));
+
+        if (OC_STACK_OK != result)
+        {
+            throw IoTInternalError("HubClient::getPrimitiveDevices error", result);
+        }
+
+        if (!callback->wait())
+        {
+            throw IoTInternalError("HubClient::getPrimitiveDevices callback not called", EC_UNAUTHORIZED);
+        }
+        else
+        {
+            callback->representation.getValue("devices", devices);
+        }
+    }
+
+    return devices;
+}
+
+} // namespace NetworkManager
index e1de6f2..11aa6c0 100644 (file)
@@ -16,6 +16,7 @@
 #include "IOT_PowerResource.h"
 #include "IOT_ReportResource.h"
 #include "IOT_PolicyResource.h"
+#include "IOT_HubResource.h"
 
 #include "iot_policy_enforce.h"
 
@@ -63,7 +64,6 @@ void main_thread::routine()
         std::string device_id = IOT_Device::getDeviceId();
 
 #ifndef __BUILD_PRIMITIVE__
-
         std::shared_ptr<IOT_Enrollee> enrollee;
 
         nmdaemon_config config;
@@ -85,12 +85,7 @@ void main_thread::routine()
         }
 
         std::string host = enrollee->host();
-#else
-        // TODO: Implement initialization for the primitive device
-        std::string host{""};
-#endif
 
-#ifndef __BUILD_PRIMITIVE__
         write_log(  "[MAIN_THREADS] enrollee : \n\thost[%s] \n\tauth_provider[%s] \n\tauth_code[%s] \n\tuid[%s] \n\taccess_token[%s] \n\tdevice_id[%s]\n",
                     host.c_str(),
                     enrollee->auth_provider().c_str(),
@@ -98,29 +93,24 @@ void main_thread::routine()
                     enrollee->uid().c_str(),
                     enrollee->access_token().c_str(),
                     device_id.c_str()   );
+#else
+        // TODO: Implement initialization for the primitive device
+        std::string host{""};
 #endif
 
-        std::string uri;
-        std::string rt;
-        std::string ri;
-
-        IOT_AirconResource aircon("/sec/aircon/0", {"x.com.samsung.da.device"}, {DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE});
-        uri = aircon.getUri(); rt = aircon.getTypes()[0]; ri = aircon.getInterfaces()[0];
-        if(aircon.registerResource(uri, rt, ri, OC_DISCOVERABLE) != OC_STACK_OK)
-            throw std::runtime_error("registerResource failed");
-        ri = aircon.getInterfaces()[1]; aircon.bindInterface(ri);
-        ri = aircon.getInterfaces()[2]; aircon.bindInterface(ri);
-
-        IOT_PowerResource power("/power/0", {"oic.r.power"}, {DEFAULT_INTERFACE});
-        uri = power.getUri(); rt = power.getTypes()[0]; ri = power.getInterfaces()[0];
-        if(power.registerResource(uri, rt, ri, OC_OBSERVABLE) != OC_STACK_OK)
-            throw std::runtime_error("registerResource failed");
-
-        aircon.addChildResource(&power);
+#ifdef __BUILD_HUB__
+        std::string uri, rt, ri;
+        IOT_HubResource hub("/sec/hub/0", {"device.hub"}, {DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE});
+        uri = hub.getUri(); rt = hub.getTypes()[0]; ri = hub.getInterfaces()[0];
+        if(hub.registerResource(uri, rt, ri, OC_DISCOVERABLE) != OC_STACK_OK)
+            throw std::runtime_error("register hub resource failed");
+        ri = hub.getInterfaces()[1]; hub.bindInterface(ri);
+        ri = hub.getInterfaces()[2]; hub.bindInterface(ri);
 
         ResourceHandles rhandles;
-        if(aircon.publishResource(rhandles, host, CT_ADAPTER_TCP) != OC_STACK_OK)
+        if(hub.publishResource(rhandles, enrollee->host(), CT_ADAPTER_TCP) != OC_STACK_OK)
             throw std::runtime_error("publishResource failed");
+#endif
 
 
         std::shared_ptr<OC::OCResource> report_res = nullptr;
@@ -129,11 +119,6 @@ void main_thread::routine()
                     "{\"status\":\"secured\",\"health\": 100}"
         };
 
-#ifdef __BUILD_HUB__
-        // TODO: Create HUB resource here
-#endif
-
-
         rmi_thread rmithread(host, device_id);
         if(!rmithread.start())
             throw std::runtime_error("publishResource failed");
@@ -146,16 +131,16 @@ void main_thread::routine()
 
             if(!report_res)
             {
-                write_log(  "[MAIN_THREADS] Try to find report resource\n");
+                write_log("[MAIN_THREADS] Try to find report resource\n");
                 try
                 {
                     report_res = IOT_Resource::findResource(host, OC_RSRVD_WELL_KNOWN_URI, CT_DEFAULT, 1, "core.security");
                 }
                 catch (std::exception& e)
                 {
-                    write_log(  "[MAIN_THREADS] Exception: %s\n", e.what());
-                    write_log(  "[MAIN_THREADS] Relogin\n", e.what());
 #ifndef __BUILD_PRIMITIVE__
+                    write_log("[MAIN_THREADS] Exception: %s\n", e.what());
+                    write_log("[MAIN_THREADS] Relogin\n", e.what());
                     enrollee->signIn();
 #endif
                 }
index c2aea03..4c284fd 100644 (file)
@@ -13,7 +13,9 @@ include_directories (
        ../nmdaemon
 )
 
-FILE(GLOB SRCS *.cpp ../iotivity_lib/IoT/*.cpp
+FILE(GLOB SRCS *.cpp
+       ../iotivity_lib/src/*.cpp
+       ../iotivity_lib/IoT/*.cpp
        ../nmdaemon/agentpolicyservice.cpp
        )
 
@@ -34,7 +36,7 @@ if ("${SCENARIO}" STREQUAL "PRIMITIVE")
        endif()
        target_link_libraries(${PROJECT_NAME} ${IOTIVITY_LIB_PROJECT_NAME} ${LINK_DLOG})
 else()
-       set (TEST_LINK_LIBRARIES ${TEST_LINK_LIBRARIES} ${CTRL_APP_LIB_PROJECT_NAME})
+        set (TEST_LINK_LIBRARIES ${TEST_LINK_LIBRARIES} ${CTRL_APP_LIB_PROJECT_NAME} dlog)
 endif()
 
 target_link_libraries(${PROJECT_NAME} ${TEST_LINK_LIBRARIES})
index dd8bcf9..ebfb9aa 100644 (file)
 #include <chrono>
 #include <jsoncpp/json/reader.h>
 
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "hub_client.h"
+
 using namespace NetworkManager;
 
 extern std::string cloud_host;
@@ -182,7 +186,7 @@ TEST_F(IoTDevManagerTest, device_discovery_ex)
     ASSERT_EQ(EC_OK, NM_getOwnedDevicesUUIDs(ctx, &dev_uuids));
     if(!dev_uuids)
     {
-        std::cout << "Repeat pwned devices not found" << std::endl << std::endl;
+        std::cout << "Repeat owned devices not found" << std::endl << std::endl;
     }
     else
     {
@@ -194,6 +198,21 @@ TEST_F(IoTDevManagerTest, device_discovery_ex)
 }
 
 /**
+ * Test checks hub resource discovery use case
+ * 1. Search for hub resource
+ * 2. Try to receive list of primitive devices
+ */
+TEST_F(IoTDevManagerTest, resource_hub_discovery)
+{
+    HubClient hub_client{cloud_host};
+    ASSERT_TRUE(hub_client);
+    std::string devices;
+    ASSERT_NO_THROW(devices = hub_client.getPrimitiveDevices(OC::QueryParamsMap()));
+    ASSERT_NE(devices, "");
+    std::cout << devices << std::endl;
+}
+
+/**
  * Part of device_discovery test for owning
  */
 TEST_F(IoTDevManagerTest, DISABLED_own_device)