DRAFT : [SECIOTSRK-352] Implement API for uninstall app command from server
authori.metelytsia <i.metelytsia@samsung.com>
Fri, 28 Jul 2017 11:21:40 +0000 (14:21 +0300)
committeri.metelytsia <i.metelytsia@samsung.com>
Fri, 28 Jul 2017 11:22:20 +0000 (14:22 +0300)
14 files changed:
device_core/nmdaemon/application_service.cpp [new file with mode: 0644]
device_core/nmdaemon/application_service.h [new file with mode: 0644]
device_core/nmdaemon/audit_trail_client.cpp
device_core/nmdaemon/audit_trail_client.h
device_core/nmdaemon/main_thread.cpp
device_core/nmdaemon/main_thread.h
device_core/nmdaemon/notification_handler.cpp [new file with mode: 0644]
device_core/nmdaemon/notification_handler.h [new file with mode: 0644]
device_core/nmdaemon/notification_handler_factory.cpp [new file with mode: 0644]
device_core/nmdaemon/notification_handler_factory.h [new file with mode: 0644]
device_core/nmdaemon/notification_handler_mq.cpp [new file with mode: 0644]
device_core/nmdaemon/notification_handler_mq.h [new file with mode: 0644]
device_core/nmdaemon/notification_handler_res.cpp [new file with mode: 0644]
device_core/nmdaemon/notification_handler_res.h [new file with mode: 0644]

diff --git a/device_core/nmdaemon/application_service.cpp b/device_core/nmdaemon/application_service.cpp
new file mode 100644 (file)
index 0000000..78abe2c
--- /dev/null
@@ -0,0 +1,53 @@
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <linux/limits.h>
+#include <cassert>
+
+#include "application_service.h"
+
+namespace NMD
+{
+
+int ApplicationService::install(const std::string& package_path_name)
+{
+    std::string cmd{"rpm -Uvih --nodeps --force "};
+    cmd.append(package_path_name).append(" > /dev/null");
+    return system(cmd.c_str());
+}
+
+int ApplicationService::uninstall(const std::string& package_name)
+{
+    std::string cmd{"rpm -e "};
+    cmd.append(package_name).append(" > /dev/null");
+    return system(cmd.c_str());
+}
+
+std::string ApplicationService::find_package_by_app_name(const std::string& app_name)
+{
+    std::string res;
+
+    std::string cmd{"rpm -qa | grep "};
+    cmd.append(app_name);
+
+    FILE* fp = popen(cmd.c_str(), "r");
+    if(fp)
+    {
+        char p[PATH_MAX];
+        while(fgets(p, PATH_MAX, fp) != NULL)
+        {
+            std::string s{p};
+            if(s.find(app_name) != std::string::npos)
+            {
+                res = s;
+                break;
+            }
+        }
+
+        pclose(fp);
+    }
+
+    return res;
+}
+
+} // namespace NMD
diff --git a/device_core/nmdaemon/application_service.h b/device_core/nmdaemon/application_service.h
new file mode 100644 (file)
index 0000000..34d8da5
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __APPLICATION_SERVICE_H__
+#define __APPLICATION_SERVICE_H__
+
+#include <string>
+
+namespace NMD
+{
+
+/**
+ * @brief The ApplicationService class is designed to install and maintain software
+ */
+class ApplicationService
+{
+public:
+
+    /**
+     * @brief Install package
+     * @details This API can be used to install RPM package
+     * @param package_path_name [in] RPM package full pathname
+     * @return 0 if success
+     */
+    static int install(const std::string& package_path_name);
+
+    /**
+     * @brief Uninstall package
+     * @details This API can be used to uninstall RPM package
+     * @param package_name [in] RPM package name
+     * @return 0 if success
+     */
+    static int uninstall(const std::string& package_name);
+
+    /**
+     * @brief Find package by application name
+     * @details This API can be used to identify package name
+     * @param app_name [in] application name
+     * @return package name or empty string
+     */
+    static std::string find_package_by_app_name(const std::string& app_name);
+
+};
+
+} // namespace NMD
+
+#endif /* __APPLICATION_SERVICE_H__ */
index 4e24c81..cff23a6 100644 (file)
@@ -43,8 +43,19 @@ AuditTrailClient::~AuditTrailClient()
 
 bool AuditTrailClient::start_dac_auditing()
 {
-    return ((audit_trail_enable_dac(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
-            (audit_trail_add_dac_cb(m_audit_trail, logCallback, (void*)this, &m_dac_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    bool res = false;
+
+    try
+    {
+        res = ((audit_trail_enable_dac(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
+               (audit_trail_add_dac_cb(m_audit_trail, logCallback, (void*)this, &m_dac_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    }
+    catch(...)
+    {
+        res = false;
+    }
+
+    return res;
 }
 
 void AuditTrailClient::stop_dac_auditing()
@@ -54,8 +65,19 @@ void AuditTrailClient::stop_dac_auditing()
 
 bool AuditTrailClient::start_mac_auditing()
 {
-    return ((audit_trail_enable_mac(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
-            (audit_trail_add_mac_cb(m_audit_trail, logCallback, (void*)this, &m_mac_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    bool res = false;
+
+    try
+    {
+        res = ((audit_trail_enable_mac(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
+               (audit_trail_add_mac_cb(m_audit_trail, logCallback, (void*)this, &m_mac_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    }
+    catch(...)
+    {
+        res = false;
+    }
+
+    return res;
 }
 
 void AuditTrailClient::stop_mac_auditing()
@@ -65,8 +87,19 @@ void AuditTrailClient::stop_mac_auditing()
 
 bool AuditTrailClient::start_syscall_auditing()
 {
-    return ((audit_trail_enable_syscall(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
-            (audit_trail_add_syscall_cb(m_audit_trail, logCallback, (void*)this, &m_syscall_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    bool res = false;
+
+    try
+    {
+        res = ((audit_trail_enable_syscall(m_audit_trail, true) == AUDIT_TRAIL_ERROR_NONE) &&
+               (audit_trail_add_syscall_cb(m_audit_trail, logCallback, (void*)this, &m_syscall_cb_id) == AUDIT_TRAIL_ERROR_NONE));
+    }
+    catch(...)
+    {
+        res = false;
+    }
+
+    return res;
 }
 
 void AuditTrailClient::stop_syscall_auditing()
@@ -74,9 +107,11 @@ void AuditTrailClient::stop_syscall_auditing()
     audit_trail_remove_syscall_cb(m_audit_trail, m_syscall_cb_id);
 }
 
-bool AuditTrailClient::start_auditing()
+void AuditTrailClient::start_auditing()
 {
-    return (start_dac_auditing() && start_mac_auditing() && start_syscall_auditing());
+    start_dac_auditing();
+    start_mac_auditing();
+    start_syscall_auditing();
 }
 
 void AuditTrailClient::stop_auditing()
index bac23e8..0015622 100644 (file)
@@ -80,7 +80,7 @@ public:
      * @brief Start DAC, MAC and system calls auditing
      * @details This API can be used to start to collect logs
      */
-    bool start_auditing();
+    void start_auditing();
 
     /**
      * @brief Stop DAC, MAC and system calls auditing
index 2ced3a5..710049c 100644 (file)
@@ -7,6 +7,7 @@
 #include "easysetup_server.h"
 #include "reporthandlerfactory.h"
 #include "policyhandlerfactory.h"
+#include "notification_handler_factory.h"
 #include "hub_report_resource.h"
 #include "hub_policy_resource.h"
 #include "iot_policy_enforce.h"
@@ -104,6 +105,7 @@ void MainThread::routine()
         std::shared_ptr<PolicyResource> policy_hub_resource;
         std::shared_ptr<ReportHandler> report_handler;
         std::shared_ptr<PolicyHandler> policy_handler;
+        std::shared_ptr<NotificationHandler> notification_handler;
         ResourceHandles rhandles;
 
         write_log(  "[MAIN_THREADS] Config : \n\thost[%s] \n\tauth_provider[%s] \n\tauth_code[%s] \n\tuid[%s] \n\taccess_token[%s] \n\tdevice_id[%s]\n",
@@ -123,19 +125,27 @@ void MainThread::routine()
         {
             report_handler = ReportHandlerFactory::createWithMQ();
             policy_handler = PolicyHandlerFactory::createWithMQ();
+            notification_handler = NotificationHandlerFactory::createWithMQ();
         }
         else
         {
             report_handler = ReportHandlerFactory::createWithResource(config.ssid);
             policy_handler = PolicyHandlerFactory::createWithResource(config.ssid);
+            notification_handler = NotificationHandlerFactory::createWithResource(config.ssid);
         }
 
-        while (!policy_handler->init())
+        while(!policy_handler->init())
         {
             write_log("[MAIN_THREADS] Policy resource not found\n");
             std::this_thread::sleep_for(std::chrono::seconds(10));
         }
 
+        while(!notification_handler->init())
+        {
+            write_log("[MAIN_THREADS] Notification resource not found\n");
+            std::this_thread::sleep_for(std::chrono::seconds(10));
+        }
+
         proxy_thread = std::make_shared<ProxyThread>();
         proxy_thread->start();
 
@@ -157,11 +167,11 @@ void MainThread::routine()
             policy_hub_resource->registerResource();
         }
 
-        ControlResource control([this, &hub, &proxy_thread, iotivity, &policy_handler, &report_handler](const std::string& state)
+        ControlResource control([this, &hub, &proxy_thread, iotivity, &policy_handler, &report_handler, &notification_handler](const std::string& state)
         {
             if(state == "unown")
             {
-                proxy_thread->addAction(std::async(std::launch::deferred, &MainThread::unregister_proc, this, iotivity, hub, report_handler, policy_handler, proxy_thread));
+                proxy_thread->addAction(std::async(std::launch::deferred, &MainThread::unregister_proc, this, iotivity, hub, report_handler, policy_handler, notification_handler, proxy_thread));
             }
         });
 
@@ -214,6 +224,10 @@ void MainThread::routine()
     {
         write_log("[MAIN_THREADS] error - %s\n", _e.what());
     }
+    catch(...)
+    {
+        write_log("[MAIN_THREADS] error\n");
+    }
 
     write_log("[MAIN_THREADS] stopped\n");
     g_running = false;
@@ -223,12 +237,14 @@ 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(hub);
     assert(report_handler);
     assert(policy_handler);
+    assert(notification_handler);
     assert(proxy_thread);
 
     // Device unregistration
@@ -243,6 +259,7 @@ void MainThread::unregister_proc(IoTivity* iotivity,
         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()));
     }
index 2221e86..e036693 100644 (file)
@@ -6,6 +6,7 @@
 #include "hub_resource.h"\r
 #include "reporthandlerfactory.h"\r
 #include "policyhandlerfactory.h"\r
+#include "notification_handler_factory.h"\r
 #include "proxythread.h"\r
 #include "thread_base.h"\r
 \r
@@ -40,6 +41,7 @@ public:
                          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
diff --git a/device_core/nmdaemon/notification_handler.cpp b/device_core/nmdaemon/notification_handler.cpp
new file mode 100644 (file)
index 0000000..14c81a8
--- /dev/null
@@ -0,0 +1,46 @@
+#include <iostream>
+
+#include "iotivity.h"
+#include "logging.h"
+#include "iotutils.h"
+
+#include "notification_handler.h"
+
+#define TAG "nmdaemon"
+
+using namespace OC;
+
+namespace NMD
+{
+
+void NotificationHandler::observeCallback(const HeaderOptions& head_options, const OCRepresentation& rep, const int& ecode, const int& seq_number)
+{
+    std::cout << "========== NotificationHandler::observeCallback" << std::endl;
+    NetworkManager::printRepresentation(rep);
+
+#if 0
+    if (ecode == OC_STACK_OK)
+    {
+        std::string policy = rep.getValue<std::string>("policy");
+        std::string did = rep.getValue<std::string>("did");
+        LOG_D(TAG, "[Recieved Policy for %s]\n%s\n", did.c_str(), policy.c_str());
+        const std::string& device_id = NetworkManager::IoTivity::getInstance()->getDeviceID();
+
+        if (did == device_id)
+        {
+            iot::core::PolicyEnforce::GetInstance().ParsePolicy(policy);
+        }
+        else if (callback)
+        {
+            callback(head_options, rep, ecode, seq_number);
+        }
+    }
+    else
+    {
+        LOG_D(TAG, "[NotificationHandler] Observe error: %d", ecode);
+    }
+#endif
+
+}
+
+} // namespace NMD
diff --git a/device_core/nmdaemon/notification_handler.h b/device_core/nmdaemon/notification_handler.h
new file mode 100644 (file)
index 0000000..835aebd
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __NOTIFICATION_HANDLER_H__
+#define __NOTIFICATION_HANDLER_H__
+
+#include <OCApi.h>
+
+namespace NMD
+{
+
+/**
+ * @brief The NotificationHandler class is designed for handling notification from server
+ */
+class NotificationHandler
+{
+public:
+
+    /**
+     * @brief observeCallback notification resource observe callback
+     * @param head_options [in] COAP headers
+     * @param rep [in] notification representation
+     * @param ecode [in] error code
+     * @param seq_number [in] oserve message sequence number
+     */
+    void observeCallback(const OC::HeaderOptions& head_options, const OC::OCRepresentation& rep, const int& ecode, const int& seq_number);
+
+    /**
+     * @brief init make startup initialization
+     * @return true on success
+     */
+    virtual bool init() = 0;
+
+    /**
+     * @brief Shut down notification handling
+     */
+    void disable()
+    {
+        disabled = true;
+    }
+
+    virtual ~NotificationHandler() {};
+
+protected:
+
+    bool disabled = false;
+};
+
+} // namespace NMD
+
+#endif /* __NOTIFICATION_HANDLER_H__ */
diff --git a/device_core/nmdaemon/notification_handler_factory.cpp b/device_core/nmdaemon/notification_handler_factory.cpp
new file mode 100644 (file)
index 0000000..81fd738
--- /dev/null
@@ -0,0 +1,21 @@
+#include <iostream>
+
+#include "notification_handler_res.h"
+#include "notification_handler_mq.h"
+
+#include "notification_handler_factory.h"
+
+namespace NMD
+{
+
+std::shared_ptr<NotificationHandler> NotificationHandlerFactory::createWithResource(const std::string& sid)
+{
+    return std::make_shared<NotificationHandlerRes>(sid);
+}
+
+std::shared_ptr<NotificationHandler> NotificationHandlerFactory::createWithMQ()
+{
+    return std::make_shared<NotificationHandlerMQ>();
+}
+
+} // namespace NMD
diff --git a/device_core/nmdaemon/notification_handler_factory.h b/device_core/nmdaemon/notification_handler_factory.h
new file mode 100644 (file)
index 0000000..e3fd87c
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __NOTIFICATION_HANDLER_FACTORY_H__
+#define __NOTIFICATION_HANDLER_FACTORY_H__
+
+#include <memory>
+
+#include "notification_handler.h"
+
+namespace NMD
+{
+
+/**
+ * @brief Factory class for NotificationHandler
+ */
+class NotificationHandlerFactory
+{
+public:
+    /**
+     * @brief createWithResource creates NotificationHandler using resource layer for communication
+     * @param sid [in] optional server id (with id used for primitive devices)
+     * @return handler shared pointer
+     */
+    static std::shared_ptr<NotificationHandler> createWithResource(const std::string& sid = "");
+
+    /**
+     * @brief createWithMQ creates NotificationHandler using Message Queue layer for communication
+     * @return handler shared pointer
+     */
+    static std::shared_ptr<NotificationHandler> createWithMQ();
+};
+
+} // namespace NMD
+
+#endif // __NOTIFICATION_HANDLER_FACTORY_H__
diff --git a/device_core/nmdaemon/notification_handler_mq.cpp b/device_core/nmdaemon/notification_handler_mq.cpp
new file mode 100644 (file)
index 0000000..7e6689b
--- /dev/null
@@ -0,0 +1,30 @@
+#include <iostream>
+
+#include "iotivity.h"
+#include "logging.h"
+
+#include "notification_handler_mq.h"
+
+#define TAG "nmdaemon"
+
+using namespace OC;
+
+namespace PH = std::placeholders;
+
+namespace NMD
+{
+
+bool NotificationHandlerMQ::init()
+{
+    auto iotivity = NetworkManager::IoTivity::getInstance();
+    auto handler = iotivity->getMqHandler();
+    std::string parentTopic = "/" + iotivity->getCloudAuthId();
+    handler->getTopic(parentTopic);
+    std::string topic = parentTopic + "/notification";
+    handler->subscribe(topic, std::bind(&NotificationHandler::observeCallback, this, PH::_1, PH::_2, PH::_3, PH::_4));
+
+    LOG_D(TAG, "Suscribed to topic [%s]", topic.c_str());
+    return true;
+}
+
+} // namespace NMD
diff --git a/device_core/nmdaemon/notification_handler_mq.h b/device_core/nmdaemon/notification_handler_mq.h
new file mode 100644 (file)
index 0000000..26473d8
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __NOTIFICATION_HANDLER_MQ_H__
+#define __NOTIFICATION_HANDLER_MQ_H__
+
+#include "notification_handler.h"
+
+namespace NMD
+{
+
+/**
+ * @brief The NotificationHandler class is designed for handling MQ notification
+ */
+class NotificationHandlerMQ : public NotificationHandler
+{
+public:
+
+    /**
+     * @brief init make startup initialization
+     * @return true on success
+     */
+    bool init() override;
+};
+
+} // namespace NMD
+
+#endif /* __NOTIFICATION_HANDLER_MQ_H__ */
diff --git a/device_core/nmdaemon/notification_handler_res.cpp b/device_core/nmdaemon/notification_handler_res.cpp
new file mode 100644 (file)
index 0000000..0cae744
--- /dev/null
@@ -0,0 +1,70 @@
+#include <iostream>
+
+#include "iotivity.h"
+#include "iot_resource.h"
+#include "logging.h"
+
+#include "notification_handler_res.h"
+
+#define TAG "nmdaemon"
+
+using namespace OC;
+using namespace NetworkManager;
+
+namespace PH = std::placeholders;
+
+namespace
+{
+const std::string NOTIFICATION_RESOURCE_TYPE{"core.notification"};
+}
+
+namespace NMD
+{
+
+NotificationHandlerRes::NotificationHandlerRes(const std::string& server_id)
+    : sid(server_id), resource(nullptr)
+{
+}
+
+bool NotificationHandlerRes::init()
+{
+    return findResource();
+}
+
+bool NotificationHandlerRes::findResource()
+{
+    auto iotivity = NetworkManager::IoTivity::getInstance();
+
+    resource = iotivity->findResource(iotivity->host(), NOTIFICATION_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
+
+    if (!resource)
+    {
+        if (iotivity->isConnected())
+        {
+
+            try
+            {
+                iotivity->signIn();
+                resource = iotivity->findResource(iotivity->host(), NOTIFICATION_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid);
+            }
+            catch (std::exception& e)
+            {
+                LOG_E(TAG, "IoTivity error: %s", e.what());
+            }
+        }
+    }
+
+    if(resource)
+    {
+        QueryParamsMap query{{"did", iotivity->getDeviceID()}};
+        resource->observe(ObserveType::Observe, query, std::bind(&NotificationHandlerRes::observeCallback, this, PH::_1, PH::_2, PH::_3, PH::_4));
+    }
+    else
+    {
+        LOG_D(TAG, "[RMI_THREADS] Notification resource not found");
+    }
+
+    return bool(resource);
+}
+
+} // namespace NMD
diff --git a/device_core/nmdaemon/notification_handler_res.h b/device_core/nmdaemon/notification_handler_res.h
new file mode 100644 (file)
index 0000000..7a135d2
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __NOTIFICATION_HANDLER_RES_H__
+#define __NOTIFICATION_HANDLER_RES_H__
+
+#include "iotivity.h"
+#include "iot_resource.h"
+
+#include "notification_handler.h"
+
+namespace NMD
+{
+
+/**
+ * @brief The NotificationHandler class is designed for handling IoT notification
+ */
+class NotificationHandlerRes: public NotificationHandler
+{
+public:
+    /**
+     * @brief CTOR
+     * @param server_id [in]
+     */
+    NotificationHandlerRes(const std::string& server_id = "");
+
+    bool init() override;
+
+protected:
+    std::string sid;
+    std::shared_ptr<OC::OCResource> resource;
+
+    /**
+     * @brief findResource starting search of notification resource on server
+     * @return true on success
+     */
+    bool findResource();
+};
+
+} // namespace NMD
+
+#endif /* __NOTIFICATION_HANDLER_RES_H__ */