Changed: now multiple hubs can be connected to one account. Refactored: ResportHandle...
authorLomtev Dmytro <d.lomtev@samsung.com>
Tue, 15 Aug 2017 08:54:36 +0000 (11:54 +0300)
committerLomtev Dmytro <d.lomtev@samsung.com>
Tue, 15 Aug 2017 08:54:36 +0000 (11:54 +0300)
17 files changed:
device_core/ctrl_app_lib/inc/hub_client.h
device_core/ctrl_app_lib/inc/securitycontext.h
device_core/ctrl_app_lib/src/securitycontext.cpp
device_core/iotivity_lib/inc/iotivity.h
device_core/iotivity_lib/inc/resource_callbacks.h
device_core/iotivity_lib/src/iotivity.cpp
device_core/iotivity_lib/src/resource_callbacks.cpp
device_core/nmdaemon/commandhandler.cpp
device_core/nmdaemon/hub_policy_resource.cpp
device_core/nmdaemon/main_thread.cpp
device_core/nmdaemon/main_thread.h
device_core/nmdaemon/reporthandler.h
device_core/nmdaemon/reporthandler_res.cpp [moved from device_core/nmdaemon/reporthandler.cpp with 81% similarity]
device_core/nmdaemon/reporthandler_res.h [new file with mode: 0644]
device_core/nmdaemon/reporthandlerfactory.cpp
device_core/nmdaemon/reporthandlermq.cpp [new file with mode: 0644]
device_core/nmdaemon/reporthandlermq.h [new file with mode: 0644]

index edcdee5..075602f 100644 (file)
@@ -27,6 +27,8 @@ class HubClient: public std::enable_shared_from_this<HubClient>
 public:
     static const std::string RESOURCE_TYPE;
 
+    typedef std::shared_ptr<HubClient> Ptr;
+
     /**
      * @brief Constructor
      * @param host [in] IoT Cloud host address
@@ -34,6 +36,21 @@ public:
     HubClient(const std::string& host);
 
     /**
+     * @brief Constructor
+     * @param hub_resource [in] resource tied wiith hub device
+     */
+    HubClient(std::shared_ptr<OC::OCResource> hub_resource) : resource(hub_resource)
+    {
+    }
+
+    /**
+     * @brief Copy constructor
+     */
+    HubClient(const HubClient& host) : resource(host.resource)
+    {
+    }
+
+    /**
      * @brief true if resource found and false otherwise
      */
     operator bool() const;
index ac2fb87..4f1fd82 100644 (file)
@@ -123,11 +123,7 @@ private:
     IoTDevicesMap unowned;
     PresenceHook presence_hook;
     std::mutex instance_mutex;
-    std::shared_ptr<OC::OCResource> notificationResource;
-    std::shared_ptr<ReportClient> reportClient;
-    std::shared_ptr<PolicyClient> policyClient;
-    std::shared_ptr<HubClient> hubClient;
-    std::mutex notificationMtx;
+    std::vector<HubClient::Ptr> hubs;
     std::string dsm_address;
 
     std::string user_login;
index e57b2a6..f5d2285 100644 (file)
@@ -13,6 +13,7 @@
 #include <chrono>
 #include <sstream>
 #include <iomanip>
+#include <future>
 #include "nmlib.h"
 #include "report_client.h"
 #include "policy_client.h"
@@ -42,63 +43,6 @@ const std::string NOTIF_FIND = "Notification findResource()";
 const std::string NOTIF_REQUEST = string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + NetworkManager::NOTIFICATION_TYPE;
 const std::string POLICY_TOPIC{"/srv/policy"};
 
-/**
- * @brief Check if resource client created and resource found
- */
-template<class ResourceClass>
-void checkResource(std::shared_ptr<ResourceClass>& sptr, const std::string& host)
-{
-    FN_VISIT
-    if (!sptr)
-    {
-        sptr = std::make_shared<ResourceClass>(host);
-    }
-
-    if (!bool(*(sptr)))
-    {
-        std::string error = ResourceClass::RESOURCE_TYPE + " resource not found.";
-        LOG_E(TAG, "%s", error.c_str());
-        sptr.reset();
-        throw NetworkManager::IoTInternalError(error);
-    }
-}
-
-/**
- * @brief Wrapper function to perform resource operations, if operation fails reource reseted.
- */
-template<class Callable, class Obj, typename... Args>
-void callResourceWithResetNonReturn(Callable fn, std::shared_ptr<Obj>& obj, Args&&... params)
-{
-    try
-    {
-        (obj.get()->*fn)(std::forward<Args>(params)...);
-    }
-    catch(std::exception& e)
-    {
-        NetworkManager::IoTivity::getInstance()->signIn();
-        obj.reset();
-        throw e;
-    }
-}
-
-/**
- * @brief Wrapper function to perform resource operations, if operation fails reource reseted.
- */
-template<class Callable, class Obj, typename... Args>
-auto callResourceWithResetReturn(Callable fn, std::shared_ptr<Obj>& obj, Args&&... params) -> decltype((std::declval<Obj>().*fn)(params...))
-{
-    try
-    {
-        return (obj.get()->*fn)(std::forward<Args>(params)...);
-    }
-    catch(std::exception& e)
-    {
-        NetworkManager::IoTivity::getInstance()->signIn();
-        obj.reset();
-        throw e;
-    }
-}
-
 } // namespace
 
 namespace NetworkManager
@@ -163,6 +107,14 @@ std::string SecurityContext::getAuthCode()
 const IoTDevicesMap& SecurityContext::getOwnedDevices()
 {
     FN_VISIT
+    auto hubs_finder = std::async(
+                std::launch::async,
+                &IoTivity::findResourceList,
+                iotivity,
+                true,
+                HubClient::RESOURCE_TYPE,
+                OC_RSRVD_WELL_KNOWN_URI,
+                CT_DEFAULT);
 
     RestService rest_service(dsm_address);
     owned = rest_service.getOwnedDevices(m_uid);
@@ -192,12 +144,20 @@ const IoTDevicesMap& SecurityContext::getOwnedDevices()
 
     try
     {
-        checkResource(hubClient, iotivity->host());
-        hubClient->getOwnedDevices(owned);
+        std::vector<std::shared_ptr<OC::OCResource>> hub_resources = hubs_finder.get();
+        hubs.clear();
+        for (auto hub_resource: hub_resources)
+        {
+            hubs.emplace_back(std::make_shared<HubClient>(hub_resource));
+        }
+
+        for (auto hub: hubs)
+        {
+            hub->getOwnedDevices(owned);
+        }
     }
     catch (std::exception& e)
     {
-        hubClient.reset();
         iotivity->signIn();
         LOG_E(TAG, "getOwnedDevices from Hub exception: %s", e.what());
     }
@@ -210,6 +170,15 @@ const IoTDevicesMap& SecurityContext::getUnOwnedDevices()
     FN_VISIT
     unowned.clear();
 
+    auto hubs_finder = std::async(
+                std::launch::async,
+                &IoTivity::findResourceList,
+                iotivity,
+                true,
+                HubClient::RESOURCE_TYPE,
+                OC_RSRVD_WELL_KNOWN_URI,
+                CT_DEFAULT);
+
     std::vector<IoTDevicePtr> found_devices = iotivity->findDevices(false, CT_ADAPTER_IP);
 
     for (auto found_device : found_devices)
@@ -232,13 +201,22 @@ const IoTDevicesMap& SecurityContext::getUnOwnedDevices()
 
     try
     {
-        LOG_D(TAG, "Request unowned devices from Hub");
-        checkResource(hubClient, iotivity->host());
-        hubClient->getUnownedDevices(unowned);
+        LOG_D(TAG, "Request unowned devices from Hubs");
+
+        std::vector<std::shared_ptr<OC::OCResource>> hub_resources = hubs_finder.get();
+        hubs.clear();
+        for (auto hub_resource: hub_resources)
+        {
+            hubs.emplace_back(std::make_shared<HubClient>(hub_resource));
+        }
+
+        for (auto hub: hubs)
+        {
+            hub->getUnownedDevices(unowned);
+        }
     }
     catch (std::exception& e)
     {
-        hubClient.reset();
         iotivity->signIn();
         LOG_E(TAG, "getUnOwnedDevices from Hub exception: %s", e.what());
     }
@@ -339,12 +317,6 @@ std::string SecurityContext::getDeviceReport(const std::string& uuid)
     RestService rest_service(dsm_address);
 
     return rest_service.getReports(uuid);
-
-//    FN_VISIT
-//    checkResource(reportClient, iotivity->host());
-//    QueryParamsMap qp{{"did", uuid}};
-
-//    return callResourceWithResetReturn(&ReportClient::getReport, reportClient, qp);
 }
 
 void SecurityContext::postReport(const std::string& report)
@@ -367,18 +339,11 @@ std::string SecurityContext::getPolicy(const std::string& uuid, const std::strin
     }
 
     return rest_service.getPolicy(uuid, agent);
-//    FN_VISIT
-//    checkResource(policyClient, iotivity->host());
-//    auto it = getIoTDevice(uuid);
-//    auto route = it->getRouting();
-
-//    return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, agent);
 }
 
 void SecurityContext::postPolicy(const std::string& uuid, const std::string& policy)
 {
     FN_VISIT
-//    checkResource(policyClient, iotivity->host());
     auto it = getIoTDevice(uuid);
     auto route = it->getRouting();
 
@@ -389,7 +354,6 @@ void SecurityContext::postPolicy(const std::string& uuid, const std::string& pol
     LOG_D(TAG, "Save policy for: %s with route %s", uuid.c_str(), route.c_str());
 
     iotivity->getMqHandler()->publish(POLICY_TOPIC, repr);
-//    callResourceWithResetNonReturn(&PolicyClient::postPolicy, policyClient, route, "", policy);
 }
 
 std::string SecurityContext::getAgentsList(const std::string& uuid)
@@ -404,13 +368,6 @@ std::string SecurityContext::getAgentsList(const std::string& uuid)
     RestService rest_service(dsm_address);
 
     return rest_service.getAgents(uuid);
-
-//    FN_VISIT
-//    checkResource(policyClient, iotivity->host());
-//    auto it = getIoTDevice(uuid);
-//    auto route = it->getRouting();
-
-//    return callResourceWithResetReturn(&PolicyClient::getPolicy, policyClient, route, "list");
 }
 
 IoTDevicePtr SecurityContext::getIoTDevice(const std::string& uuid)
index bcafa22..4f830c9 100644 (file)
@@ -87,6 +87,11 @@ public:
     void signOut();
 
     /**
+     * @brief delete device from IoTivity cloud
+     */
+    void deleteFromAccount();
+
+    /**
      * @brief cleanUp free memory occupied by IoTivity singletone instance
      */
     static void cleanUp();
index f339817..6c026c3 100644 (file)
@@ -95,6 +95,7 @@ struct FindResourceListCallback : public CallbackBase
 
     std::vector<std::shared_ptr<OC::OCResource>>& resources;
     OCConnectivityType conn_type;
+    std::string type;
 
     /**
      * @brief FindResourceListCallback constructor
@@ -103,8 +104,9 @@ struct FindResourceListCallback : public CallbackBase
      */
     FindResourceListCallback(
             std::vector<std::shared_ptr<OC::OCResource>>& resources,
-            const OCConnectivityType ct = OCConnectivityType::CT_DEFAULT)
-        : CallbackBase(), resources(resources), conn_type(ct) {}
+            const OCConnectivityType ct = OCConnectivityType::CT_DEFAULT,
+            const std::string& type = "")
+        : CallbackBase(), resources(resources), conn_type(ct), type(type) {}
 
     /**
      * @brief call - callback routine, called from iotivity framework
index de80934..88f18a2 100644 (file)
@@ -208,7 +208,7 @@ std::shared_ptr<OC::OCResource> IoTivity::findResource(bool cloud, const std::st
 std::vector<std::shared_ptr<OC::OCResource>> IoTivity::findResourceList(bool cloud, const std::string& type, const std::string& uri, OCConnectivityType con_type)
 {
     std::vector<std::shared_ptr<OC::OCResource>> resources;
-    FindResourceListCallback::Sptr callback = std::make_shared<FindResourceListCallback>(resources, con_type);
+    FindResourceListCallback::Sptr callback = std::make_shared<FindResourceListCallback>(resources, con_type, type);
     OCPlatform::findResourceList(cloud ? cloud_host : "", uri, con_type, bind_callback(callback, PH::_1));
 
     callback->wait_timeout();
@@ -427,6 +427,50 @@ void IoTivity::signOut()
         guardPostErrorCode(signOutCb->resultCode, SIGNOUT);
 }
 
+void IoTivity::deleteFromAccount()
+{
+    FN_VISIT
+    if (!signed_in)
+    {
+        return;
+    }
+    signed_in = false;
+
+    if (cloud_host.empty() || cloud_access_token.empty())
+    {
+        LOG_W(TAG, "SignOut without SignIn");
+        return;
+    }
+
+    if (!account_mgr)
+        throw IoTInternalError("No account manager", EC_IOTIVITY_ERROR);
+
+    auto deleteMutex = std::make_shared<std::mutex>();
+    weak_ptr<std::mutex> deleteMutexWptr(deleteMutex);
+    std::unique_lock<std::mutex> lock(*deleteMutex);
+    std::condition_variable cv;
+    bool called = false;
+    int code = OC_STACK_ERROR;
+
+    auto deleteCallback = [deleteMutexWptr, &cv, &called, &code] (const HeaderOptions&, const int ecode) {
+        if (auto mtx = deleteMutexWptr.lock())
+        {
+            called = true;
+            code = ecode;
+            cv.notify_all();
+        }
+    };
+
+    account_mgr->deleteDevice(cloud_access_token, getDeviceID(), deleteCallback);
+
+    cv.wait_for(lock, std::chrono::seconds(DEFAULT_TIMEOUT), [&called] { return called; });
+
+    if (!called || code > OC_STACK_RESOURCE_CHANGED)
+    {
+        throw IoTInternalError("Failed to delete device from account", EC_IOTIVITY_ERROR);
+    }
+}
+
 void IoTivity::devicePresenceHandle(
     const HeaderOptions& hOptions,
     const OCRepresentation& rep,
index 1606af6..2e8fc0a 100644 (file)
@@ -51,6 +51,22 @@ void FindResourceListCallback::call(std::weak_ptr<FindResourceListCallback> ctx,
 
         for (auto resource : found_resource)
         {
+            if (!p->type.empty())
+            {
+                auto res_types = resource->getResourceTypes();
+                bool found = false;
+                for (auto rt: res_types)
+                {
+                    if (p->type == rt)
+                    {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) continue;
+            }
+
             if (p->conn_type == CT_DEFAULT || (resource->connectivityType() & p->conn_type))
             {
                 p->resources.push_back(resource);
index 2e870c3..5979bec 100644 (file)
@@ -2,6 +2,9 @@
 #include "registration_mq.h"
 #include "device_commands.h"
 #include "application_service.h"
+#include "logging.h"
+
+#define TAG "nmdaemon"
 
 namespace NMD
 {
@@ -14,6 +17,7 @@ CommandHandler::CommandHandler(NetworkManager::IoTivity* iotivity,
                                WorkingMode wmode,
                                ThreadBase* main_thread)
     : m_iotivity(iotivity)
+    , m_hub(hub)
     , m_report_handler(report_handler)
     , m_policy_handler(policy_handler)
     , m_proxy_thread(proxy_thread)
@@ -76,16 +80,29 @@ void CommandHandler::unOwnTask()
 
     delete_config();
 
-    if (g_working_mode == WorkingMode::Hub)
+    try
+    {
+
+        if (g_working_mode == WorkingMode::Hub)
+        {
+            // disable hub to send found devices list
+            assert(m_hub);
+            m_hub->setEnabled(false);
+            clear_hub_cache();
+            m_report_handler->disable();
+            m_policy_handler->disable();
+            m_iotivity->unPublishAllResources();
+            m_hub->unownAll();
+        }
+
+        if (m_wmode != WorkingMode::Primitive)
+        {
+            m_iotivity->deleteFromAccount();
+        }
+    }
+    catch (std::exception& e)
     {
-        // disable hub to send found devices list
-        assert(m_hub);
-        m_hub->setEnabled(false);
-        clear_hub_cache();
-        m_report_handler->disable();
-        m_policy_handler->disable();
-        m_proxy_thread->addAction(std::async(std::launch::deferred, &NetworkManager::IoTivity::unPublishAllResources, m_iotivity));
-        m_proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::unownAll, m_hub.get()));
+        LOG_E(TAG, "Unpairing failed with exception: %s", e.what());
     }
 
     m_main_thread->stop();
index 223074e..4dd27c1 100644 (file)
@@ -207,7 +207,7 @@ void PolicyResource::observHandler(const HeaderOptions& /*head_options*/, const
         std::string policy;
         std::string value;
 
-        if (rep.getValue("did", value))
+        if (rep.getValue("duid", value))
         {
             did = value;
         }
index 5c1b7d5..d6d0d8d 100644 (file)
@@ -238,41 +238,4 @@ void MainThread::routine()
     g_running = false;
 }
 
-void MainThread::unregister_proc(IoTivity* iotivity,
-                                 std::shared_ptr<HubResource> hub,
-                                 std::shared_ptr<ReportHandler> report_handler,
-                                 std::shared_ptr<PolicyHandler> policy_handler,
-                                 std::shared_ptr<NotificationHandler> notification_handler,
-                                 std::shared_ptr<ProxyThread> proxy_thread)
-{
-    assert(iotivity);
-    assert(report_handler);
-    assert(policy_handler);
-    assert(notification_handler);
-    assert(proxy_thread);
-
-    // Device unregistration
-    if (g_working_mode != WorkingMode::Primitive)
-    {
-        RegistrationMQ::unreg(iotivity->getMqHandler(), iotivity->getDeviceID());
-    }
-
-    delete_config();
-
-    if (g_working_mode == WorkingMode::Hub)
-    {
-        // disable hub to send found devices list
-        assert(hub);
-        hub->setEnabled(false);
-        clear_hub_cache();
-        report_handler->disable();
-        policy_handler->disable();
-        notification_handler->disable();
-        proxy_thread->addAction(std::async(std::launch::deferred, &IoTivity::unPublishAllResources, iotivity));
-        proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::unownAll, hub.get()));
-    }
-
-    this->stop();
-}
-
 } // namespace NMD
index 9b82675..7bf413e 100644 (file)
@@ -37,13 +37,6 @@ public:
 \r
     virtual void routine();\r
 \r
-    void unregister_proc(NetworkManager::IoTivity* iotivity,\r
-                         std::shared_ptr<HubResource> hub,\r
-                         std::shared_ptr<ReportHandler> report_handler,\r
-                         std::shared_ptr<PolicyHandler> policy_handler,\r
-                         std::shared_ptr<NotificationHandler> notification_handler,\r
-                         std::shared_ptr<ProxyThread> proxy_thread);\r
-\r
 private:\r
     std::string m_device_name;\r
     std::string m_device_model;\r
index ac3b9b8..20e4a53 100644 (file)
@@ -2,9 +2,6 @@
 #define REPORTHANDLER_H
 
 #include <OCApi.h>
-#include <memory>
-#include "iotivity.h"
-#include <mutex>
 
 class ReportHandler
 {
@@ -31,36 +28,4 @@ protected:
     bool disabled;
 };
 
-class ReportHandlerRes: public ReportHandler
-{
-public:
-    /**
-     * @brief ReportHandlerRes constructor
-     * @param iotivity pointer to IoTivity instance
-     */
-    ReportHandlerRes(const std::string& server_id = "");
-
-    void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override;
-
-private:
-    std::shared_ptr<OC::OCResource> resource;
-    NetworkManager::IoTivity* iotivity;
-    std::string server_id;
-    void findResource();
-    std::mutex handler_mutex;
-};
-
-class ReportHandlerMQ: public ReportHandler
-{
-public:
-    void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override;
-
-private:
-    std::shared_ptr<OC::OCResource> resource;
-    NetworkManager::IoTivity* iotivity;
-    std::string server_id;
-    void findResource();
-    std::mutex handler_mutex;
-};
-
 #endif // REPORTHANDLER_H
similarity index 81%
rename from device_core/nmdaemon/reporthandler.cpp
rename to device_core/nmdaemon/reporthandler_res.cpp
index 779e437..104f5a9 100644 (file)
@@ -1,8 +1,6 @@
-#include "reporthandler.h"
-#include <iostream>
 #include "logging.h"
 #include "iot_resource.h"
-#include "OCPlatform.h"
+#include "reporthandler_res.h"
 
 #define TAG "nmdaemon"
 
@@ -14,8 +12,7 @@ namespace
 const std::string REPORT_RESOURCE_TYPE{"core.security"};
 }
 
-ReportHandlerRes::ReportHandlerRes(const std::string& server_id)
-    : server_id(server_id)
+ReportHandlerRes::ReportHandlerRes(const std::string& server_id) : server_id(server_id)
 {
     iotivity = NetworkManager::IoTivity::getInstance();
 }
@@ -64,7 +61,3 @@ void ReportHandlerRes::findResource()
     }
 }
 
-void ReportHandlerMQ::pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) {
-    if (disabled) return;
-    NetworkManager::IoTivity::getInstance()->getMqHandler()->publish("/srv/report", rep);
-}
diff --git a/device_core/nmdaemon/reporthandler_res.h b/device_core/nmdaemon/reporthandler_res.h
new file mode 100644 (file)
index 0000000..aad5938
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef REPORTHANDLERRES_H
+#define REPORTHANDLERRES_H
+
+#include <mutex>
+#include "iotivity.h"
+#include "reporthandler.h"
+
+class ReportHandlerRes: public ReportHandler
+{
+public:
+    /**
+     * @brief ReportHandlerRes constructor
+     * @param iotivity pointer to IoTivity instance
+     */
+    ReportHandlerRes(const std::string& server_id = "");
+
+    void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override;
+
+private:
+
+    void findResource();
+
+    std::shared_ptr<OC::OCResource> resource;
+    NetworkManager::IoTivity* iotivity;
+    std::string server_id;
+    std::mutex handler_mutex;
+};
+
+#endif // REPORTHANDLERRES_H
index 5f2ff88..87796bc 100644 (file)
@@ -1,4 +1,6 @@
 #include "reporthandler.h"
+#include "reporthandler_res.h"
+#include "reporthandlermq.h"
 #include "reporthandlerfactory.h"
 
 std::shared_ptr<ReportHandler> ReportHandlerFactory::createWithResource(const std::string& sid)
diff --git a/device_core/nmdaemon/reporthandlermq.cpp b/device_core/nmdaemon/reporthandlermq.cpp
new file mode 100644 (file)
index 0000000..990aba7
--- /dev/null
@@ -0,0 +1,15 @@
+#include "reporthandlermq.h"
+#include "logging.h"
+
+#define TAG "nmdaemon"
+
+namespace
+{
+const std::string POST_REPORT_MQ{"/srv/report"};
+}
+
+void ReportHandlerMQ::pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& /*params*/) {
+    if (disabled) return;
+
+    NetworkManager::IoTivity::getInstance()->getMqHandler()->publish(POST_REPORT_MQ, rep);
+}
diff --git a/device_core/nmdaemon/reporthandlermq.h b/device_core/nmdaemon/reporthandlermq.h
new file mode 100644 (file)
index 0000000..2b0ac96
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef REPORTHANDLERMQ_H
+#define REPORTHANDLERMQ_H
+
+#include <mutex>
+#include "iotivity.h"
+#include "reporthandler.h"
+
+class ReportHandlerMQ: public ReportHandler
+{
+public:
+    void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override;
+
+private:
+
+    void findResource();
+
+    OC::OCResource::Ptr resource;
+    NetworkManager::IoTivity* iotivity;
+    std::string server_id;
+    std::mutex handler_mutex;
+};
+
+#endif // REPORTHANDLERMQ_H