summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/cchecker/logic.h33
-rw-r--r--src/logic.cpp147
2 files changed, 171 insertions, 9 deletions
diff --git a/src/include/cchecker/logic.h b/src/include/cchecker/logic.h
index 3442890..1f42ab3 100644
--- a/src/include/cchecker/logic.h
+++ b/src/include/cchecker/logic.h
@@ -23,10 +23,12 @@
#ifndef CCHECKER_LOGIC_H
#define CCHECKER_LOGIC_H
+#include <condition_variable>
#include <gio/gio.h>
#include <string>
#include <vector>
#include <list>
+#include <thread>
#include <cchecker/app.h>
#include <cchecker/queue.h>
@@ -42,7 +44,8 @@ enum error_t {
REGISTER_CALLBACK_ERROR,
DBUS_ERROR,
PACKAGE_MANAGER_ERROR,
- DATABASE_ERROR
+ DATABASE_ERROR,
+ INTERNAL_ERROR
};
enum pkgmgr_event_t {
@@ -71,15 +74,19 @@ class Logic {
GVariant *parameters,
void *logic_ptr);
- private:
- //TODO: implement missing members
+ private:
error_t setup_db();
+ void load_database_to_buffer();
+
void check_ocsp(app_t &app);
void add_ocsp_url(const std::string &issuer, const std::string &url, int64_t date);
void pkgmanager_uninstall(const app_t &app);
void get_certs_from_signature(const std::string &signature, std::vector<std::string> &cert);
- void load_database_to_buffer();
+
+ void add_app_to_buffer(const app_t &app);
+ void remove_app_from_buffer(const app_t &app);
+
void pkgmgr_callback_internal(GVariant *parameters, pkgmgr_event_t event);
error_t register_dbus_signal_handler(GDBusProxy *proxy,
const char *name,
@@ -92,10 +99,28 @@ class Logic {
void *logic_ptr)
);
+ void process_all(void);
+ void process_queue(void);
+ void process_event(const event_t &event);
+ error_t process_buffer(void);
+
+ bool get_online(void) const;
+ void set_online(bool online);
+
+ bool get_should_exit(void) const;
+ void set_should_exit(void);
+
Queue m_queue;
std::list<app_t> m_buffer;
DB::SqlQuery *m_sqlquery;
+ bool m_was_setup_called;
+
bool m_is_online;
+ std::condition_variable m_to_process;
+ std::mutex m_mutex_cv;
+ std::thread m_thread;
+ bool m_should_exit;
+
GDBusProxy *m_proxy_connman;
GDBusProxy *m_proxy_pkgmgr_install;
GDBusProxy *m_proxy_pkgmgr_uninstall;
diff --git a/src/logic.cpp b/src/logic.cpp
index 8c25739..82059ac 100644
--- a/src/logic.cpp
+++ b/src/logic.cpp
@@ -38,6 +38,18 @@ const char *const TEPM_APP_ID = "temp#app_id";
Logic::~Logic(void)
{
LogDebug("Cert-checker cleaning.");
+
+ // wait and join processing thread
+ if (m_thread.joinable()) {
+ LogDebug("Waiting for join processing thread");
+ set_should_exit();
+ m_to_process.notify_one();
+ m_thread.join();
+ LogDebug("Processing thread joined");
+ }
+ else
+ LogDebug("No thread to join");
+
if (m_proxy_connman)
g_object_unref(m_proxy_connman);
if (m_proxy_pkgmgr_install)
@@ -49,12 +61,24 @@ Logic::~Logic(void)
Logic::Logic(void) :
m_sqlquery(NULL),
- m_is_online(false),
+ m_was_setup_called(false),
+ m_is_online(true),
+ m_should_exit(false),
m_proxy_connman(NULL),
m_proxy_pkgmgr_install(NULL),
m_proxy_pkgmgr_uninstall(NULL)
{}
+bool Logic::get_online() const
+{
+ return m_is_online;
+}
+
+void Logic::set_online(bool online)
+{
+ m_is_online = online;
+}
+
error_t Logic::setup_db()
{
// TODO: If database doesn't exist -should we create a new one?
@@ -75,6 +99,13 @@ error_t Logic::setup_db()
error_t Logic::setup()
{
+ // Check if setup was called
+ if (m_was_setup_called) {
+ LogError("You can call setup only once");
+ return INTERNAL_ERROR;
+ }
+ m_was_setup_called = true;
+
// Check if DB exists and create a new one if it doesn't
error_t err = setup_db();
if (err != NO_ERROR) {
@@ -82,6 +113,11 @@ error_t Logic::setup()
return err;
}
+ load_database_to_buffer();
+
+ // run process thread - thread will be waiting on condition variable
+ m_thread = std::thread(&Logic::process_all, this);
+
// FIXME: pkgmanager API signal handling was temporarily replaced
// by dbus API
@@ -121,8 +157,6 @@ error_t Logic::setup()
}
LogDebug("register connman event callback success");
- load_database_to_buffer();
-
return NO_ERROR;
}
@@ -243,6 +277,8 @@ void Logic::pkgmgr_callback_internal(GVariant *parameters,
", state: " << state << ", status: " << status);
m_queue.push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL));
}
+
+ m_to_process.notify_one();
}
else
LogDebug("Wrong state (" << std::string(state) << ") or status (" << std::string(status) << ")");
@@ -272,11 +308,13 @@ void Logic::connman_callback(GDBusProxy */*proxy*/,
if (params_str == "('State', <'online'>)") {
LogDebug("Device online");
- logic->m_is_online = true;
+ logic->set_online(true);
+
+ logic->m_to_process.notify_one();
}
else if (params_str == "('State', <'offline'>)") {
LogDebug("Device offline");
- logic->m_is_online = false;
+ logic->set_online(false);
}
}
@@ -307,4 +345,103 @@ void Logic::load_database_to_buffer()
m_sqlquery->get_app_list(m_buffer);
}
+/**
+ * This function should move all event from queue to the buffer
+ **/
+void Logic::process_queue(void)
+{
+ event_t event;
+ while(m_queue.pop_event(event)) {
+ process_event(event);
+ }
+}
+
+error_t Logic::process_buffer(void)
+{
+ // TODO: Implement
+ return NO_ERROR;
+}
+
+void Logic::process_all()
+{
+ //Check if should't exit
+ while (!get_should_exit()) {
+ std::unique_lock<std::mutex> lock(m_mutex_cv);
+
+ if (m_queue.empty()) {
+ LogDebug("Processing thread: waiting on condition");
+ m_to_process.wait(lock);
+ }
+ else
+ LogDebug("Processing thread: More events in queue - processing again");
+
+ LogDebug("Processing thread: running");
+
+ process_queue();
+ if (get_online())
+ process_buffer();
+ else
+ LogDebug("No network. Buffer won't be processed");
+
+ LogDebug("Processing done");
+ }
+
+ // should process queue just before exit
+ process_queue();
+}
+
+void Logic::process_event(const event_t &event)
+{
+ if (event.event_type == event_t::event_type_t::APP_INSTALL) {
+ // TODO: implement geting app signature, then getting certificates from app signature.
+ // TODO: implement add app to buffer and database
+ add_app_to_buffer(event.app);
+ }
+ else if (event.event_type == event_t::event_type_t::APP_UNINSTALL) {
+ remove_app_from_buffer(event.app);
+ }
+ else
+ LogError("Unknown event type");
+}
+
+void Logic::add_app_to_buffer(const app_t &app)
+{
+ // First add app to DB
+ if(!m_sqlquery->add_app_to_check_list(app)) {
+ LogError("Failed to add " << app.str() << "to database");
+ // We can do nothing about it. We can only log the error.
+ }
+
+ // Then add app to buffer
+ m_buffer.push_back(app);
+}
+
+void Logic::remove_app_from_buffer(const app_t &app)
+{
+ // First remove app from DB
+ m_sqlquery->remove_app_from_check_list(app);
+
+ // Then remove app from buffer
+ for (auto iter = m_buffer.begin(); iter != m_buffer.end(); ++iter) {
+ if (iter->app_id == app.app_id &&
+ iter->pkg_id == app.pkg_id &&
+ iter->uid == app.uid) {
+ LogDebug(iter->str() << " found in buffer - will be removed");
+ m_buffer.erase(iter);
+ break;
+ }
+ }
+}
+
+bool Logic::get_should_exit(void) const
+{
+ return m_should_exit;
+}
+
+void Logic::set_should_exit(void)
+{
+ m_should_exit = true;
+
+}
+
} //CCHECKER