#include <types_internal.h>
#include <json.h>
#include <context_trigger_types_internal.h>
+#include "trigger.h"
#include "../access_control/privilege.h"
#include "context_monitor.h"
-#include "fact_reader.h"
+#include "fact_request.h"
#include "timer_types.h"
-static ctx::fact_reader *reader = NULL;
+static int last_rid;
+static int last_err;
+static ctx::json last_data_read;
+
+ctx::context_manager_impl *ctx::context_monitor::_context_mgr = NULL;
+
+static int generate_req_id()
+{
+ static int req_id = 0;
+
+ if (++req_id < 0) {
+ // Overflow handling
+ req_id = 1;
+ }
+
+ return req_id;
+}
ctx::context_monitor::context_monitor()
{
delete timer;
}
-bool ctx::context_monitor::init(ctx::fact_reader* fr, ctx::context_trigger* tr)
+bool ctx::context_monitor::init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr)
{
- reader = fr;
- trigger = tr;
- timer = new(std::nothrow) trigger_timer(trigger);
+ _context_mgr = ctx_mgr;
+ _trigger = tr;
+
+ timer = new(std::nothrow) trigger_timer(_trigger);
IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");
return true;
ctx::json eoption = NULL;
event.get(NULL, CT_RULE_EVENT_OPTION, &eoption);
- int req_id = reader->subscribe(subject.c_str(), &eoption, true);
+ int req_id = _subscribe(subject.c_str(), &eoption, true);
IF_FAIL_RETURN_TAG(req_id > 0, ERR_OPERATION_FAILED, _E, "Subscribe event failed");
_D(YELLOW("Subscribe event(rule%d). req%d"), rule_id, req_id);
- request_map[rule_id] = req_id;
- read_req_cnt_map[req_id]++;
return ERR_NONE;
}
+int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wait_response)
+{
+ IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
+
+ int rid = find_sub(subject, option);
+ if (rid > 0) {
+ increase_sub(rid);
+ _D("Duplicated request for %s", subject);
+ return rid;
+ }
+
+ rid = generate_req_id();
+
+ fact_request *req = new(std::nothrow) fact_request(REQ_SUBSCRIBE,
+ rid, subject, option ? option->str().c_str() : NULL, wait_response ? this : NULL);
+ IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
+
+ send_request(req); //TODO: what happens if the request actually takes more time than the timeout
+ add_sub(rid, subject, option);
+
+ IF_FAIL_RETURN_TAG(wait_response, rid, _D, "Ignoring response for %s", subject);
+
+ if (last_err != ERR_NONE) {
+ remove_sub(rid);
+ _E("Subscription request failed: %#x", last_err);
+ return -1;
+ }
+
+ return rid;
+}
+
int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option)
{
if (subject.compare(TIMER_EVENT_SUBJECT) == 0) {
return timer->unsubscribe(option);
}
- _D(YELLOW("Unsubscribe event(rule%d). req%d"), rule_id, request_map[rule_id]);
- int req_id = request_map[rule_id];
- request_map.erase(rule_id);
+ ctx::json eoption = NULL;
+ option.get(NULL, CT_RULE_EVENT_OPTION, &eoption);
- read_req_cnt_map[req_id]--;
- if (read_req_cnt_map[req_id] == 0) {
- reader->unsubscribe(subject.c_str(), req_id);
- read_req_cnt_map.erase(req_id);
+ int rid = find_sub(subject.c_str(), &eoption);
+ if (rid < 0) {
+ _D("Invalid unsubscribe request");
+ return ERR_INVALID_PARAMETER;
}
+ if (decrease_sub(rid) <= 0) {
+ _unsubscribe(subject.c_str(), rid);
+ }
+ _D(YELLOW("Unsubscribe event(rule%d). req%d"), rule_id, rid);
+
return ERR_NONE;
}
+void ctx::context_monitor::_unsubscribe(const char *subject, int subscription_id)
+{
+ fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, subscription_id, subject, NULL, NULL);
+ IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
+
+ send_request(req);
+ remove_sub(subscription_id);
+}
+
+bool ctx::context_monitor::send_request(fact_request* req)
+{
+ _context_mgr->assign_request(req);
+ return false;
+}
+
int ctx::context_monitor::read(std::string subject, json option, ctx::json* result)
{
bool ret;
}
context_fact fact;
- ret = reader->read(subject.c_str(), &option, fact);
+ ret = _read(subject.c_str(), &option, fact);
IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Read fact failed");
*result = fact.get_data();
return ERR_NONE;
}
+bool ctx::context_monitor::_read(const char* subject, json* option, context_fact& fact)
+{
+ IF_FAIL_RETURN(subject, false);
+
+ int rid = generate_req_id();
+
+ fact_request *req = new(std::nothrow) fact_request(REQ_READ_SYNC,
+ rid, subject, option ? option->str().c_str() : NULL, this);
+ IF_FAIL_RETURN_TAG(req, false, _E, "Memory allocation failed");
+
+ send_request(req);
+
+ if (last_err != ERR_NONE) {
+ _E("Read request failed: %#x", last_err);
+ return false;
+ }
+
+ fact.set_req_id(rid);
+ fact.set_subject(subject);
+ fact.set_data(last_data_read);
+ last_data_read = EMPTY_JSON_OBJECT;
+
+ return true;
+}
+
bool ctx::context_monitor::is_supported(std::string subject)
{
if (subject.compare(TIMER_EVENT_SUBJECT) == 0
return true;
}
- return reader->is_supported(subject.c_str());
+ return _context_mgr->is_supported(subject.c_str());
}
bool ctx::context_monitor::is_allowed(const char *client, const char *subject)
if (STR_EQ(subject, TIMER_CONDITION_SUBJECT))
return true;
- return reader->is_allowed(client, subject);
+ //TODO: re-implement this in the proper 3.0 style
+ //return _context_mgr->is_allowed(client, subject);
+ return true;
+}
+
+bool ctx::context_monitor::get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options)
+{
+ return _context_mgr->pop_trigger_item(subject, operation, attributes, options);
+}
+
+int ctx::context_monitor::find_sub(const char* subject, json* option)
+{
+ json opt_j;
+ if (option) {
+ opt_j = *option;
+ }
+
+ for (subscr_map_t::iterator it = subscr_map.begin(); it != subscr_map.end(); ++it) {
+ if ((*(it->second)).subject == subject && (*(it->second)).option == opt_j) {
+ return it->first;
+ }
+ }
+
+ return -1;
+}
+
+bool ctx::context_monitor::add_sub(int sid, const char* subject, json* option)
+{
+ subscr_info_s *info = new(std::nothrow) subscr_info_s(sid, subject, option);
+ IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+
+ subscr_map[sid] = info;
+
+ return true;
+}
+
+void ctx::context_monitor::remove_sub(const char* subject, json* option)
+{
+ json opt_j;
+ if (option) {
+ opt_j = *option;
+ }
+
+ for (subscr_map_t::iterator it = subscr_map.begin(); it != subscr_map.end(); ++it) {
+ if ((*(it->second)).subject == subject && (*(it->second)).option == opt_j) {
+ delete it->second;
+ subscr_map.erase(it);
+ return;
+ }
+ }
+}
+
+void ctx::context_monitor::remove_sub(int sid)
+{
+ subscr_map.erase(sid);
+
+ return;
+}
+
+int ctx::context_monitor::increase_sub(int sid)
+{
+ subscr_map_t::iterator it = subscr_map.find(sid);
+
+ subscr_info_s* info = it->second;
+ info->cnt++;
+
+ return info->cnt;
+}
+
+int ctx::context_monitor::decrease_sub(int sid)
+{
+ subscr_map_t::iterator it = subscr_map.find(sid);
+
+ subscr_info_s* info = it->second;
+ info->cnt--;
+
+ return info->cnt;
+}
+
+void ctx::context_monitor::reply_result(int req_id, int error, json* request_result, json* fact)
+{
+ _D("Request result received: %d", req_id);
+ last_rid = req_id;
+ last_err = error;
+ last_data_read = (fact ? *fact : EMPTY_JSON_OBJECT);
+}
+
+void ctx::context_monitor::publish_fact(int req_id, int error, const char* subject, json* option, json* fact)
+{
+ _D(YELLOW("Fact received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
+
+ // TODO: deliver fact to each rule instance
+
+ // TODO Remove
+ _trigger->push_fact(req_id, error, subject, *option, *fact);
}
#ifndef __CONTEXT_MONITOR_H__
#define __CONTEXT_MONITOR_H__
+#include <list>
#include <map>
+#include <json.h>
+#include "../context_mgr_impl.h"
+#include "fact.h"
#include "timer.h"
namespace ctx {
class json;
- class fact_reader;
class context_fact;
+ class fact_request;
class context_monitor {
public:
context_monitor();
~context_monitor();
- bool init(ctx::fact_reader* fr, ctx::context_trigger* tr);
+ bool init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr);
int subscribe(int rule_id, std::string subject, ctx::json event);
int unsubscribe(int rule_id, std::string subject, ctx::json option);
bool is_supported(std::string subject);
bool is_allowed(const char *client, const char *subject);
+ void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL);
+ void publish_fact(int req_id, int error, const char *subject, json *option, json *fact);
+
+ bool get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options);
+
private:
- std::map<int, int> request_map; // <rule_id, fact_read_req_id>
- std::map<int, int> read_req_cnt_map; // <fact_read_req_id, count>
- ctx::context_trigger* trigger;
+ int _subscribe(const char* subject, json* option, bool wait_response);
+ void _unsubscribe(const char *subject, int subscription_id);
+ bool _read(const char *subject, json *option, context_fact& fact);
+
+ ctx::context_trigger* _trigger;
ctx::trigger_timer* timer;
+ static context_manager_impl *_context_mgr;
+
+ struct subscr_info_s {
+ int sid;
+ int cnt;
+ std::string subject;
+ ctx::json option;
+ subscr_info_s(int id, const char *subj, ctx::json *opt)
+ : sid(id), cnt(1), subject(subj)
+ {
+ if (opt)
+ option = *opt;
+ }
+ };
+
+ typedef std::map<int, subscr_info_s*> subscr_map_t;
+ subscr_map_t subscr_map;
+
+ int find_sub(const char *subject, json *option);
+ bool add_sub(int sid, const char *subject, json *option);
+ void remove_sub(const char *subject, json *option);
+ void remove_sub(int sid);
+ int increase_sub(int sid);
+ int decrease_sub(int sid);
+ static bool send_request(fact_request* req);
}; /* class context_monitor */
} /* namespace ctx */
+++ /dev/null
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <scope_mutex.h>
-#include "trigger.h"
-#include "fact_request.h"
-#include "fact_reader.h"
-
-#define COND_END_TIME(T) (g_get_monotonic_time() + (T) * G_TIME_SPAN_SECOND)
-#define SUBSCRIBE_TIMEOUT 3
-#define READ_TIMEOUT 10
-
-static GMutex request_mutex;
-static GCond request_cond;
-static int last_rid;
-static int last_err;
-static ctx::json last_data_read;
-
-ctx::context_manager_impl *ctx::fact_reader::_context_mgr = NULL;
-ctx::context_trigger *ctx::fact_reader::_trigger = NULL;
-
-static int generate_req_id()
-{
- static int req_id = 0;
-
- if (++req_id < 0) {
- // Overflow handling
- req_id = 1;
- }
-
- return req_id;
-}
-
-ctx::fact_reader::fact_reader(context_manager_impl* mgr, context_trigger* trigger)
-{
- _context_mgr = mgr;
- _trigger = trigger;
-}
-
-ctx::fact_reader::~fact_reader()
-{
- for (subscr_list_t::iterator it = subscr_list.begin(); it != subscr_list.end(); ++it) {
- delete *it;
- }
- subscr_list.clear();
-}
-
-int ctx::fact_reader::find_sub(const char* subject, json* option)
-{
- json opt_j;
- if (option) {
- opt_j = *option;
- }
-
- for (subscr_list_t::iterator it = subscr_list.begin(); it != subscr_list.end(); ++it) {
- if ((*it)->subject == subject && (*it)->option == opt_j) {
- return (*it)->sid;
- }
- }
-
- return -1;
-}
-
-bool ctx::fact_reader::add_sub(int sid, const char* subject, json* option)
-{
- subscr_info_s *info = new(std::nothrow) subscr_info_s(sid, subject, option);
- IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
-
- subscr_list.push_back(info);
- return true;
-}
-
-void ctx::fact_reader::remove_sub(const char* subject, json* option)
-{
- json opt_j;
- if (option) {
- opt_j = *option;
- }
-
- for (subscr_list_t::iterator it = subscr_list.begin(); it != subscr_list.end(); ++it) {
- if ((*it)->subject == subject && (*it)->option == opt_j) {
- delete *it;
- subscr_list.erase(it);
- return;
- }
- }
-}
-
-void ctx::fact_reader::remove_sub(int sid)
-{
- for (subscr_list_t::iterator it = subscr_list.begin(); it != subscr_list.end(); ++it) {
- if ((*it)->sid == sid) {
- delete *it;
- subscr_list.erase(it);
- return;
- }
- }
-}
-
-gboolean ctx::fact_reader::send_request(gpointer data)
-{
- fact_request *req = static_cast<fact_request*>(data);
- _context_mgr->assign_request(req);
- return FALSE;
-}
-
-bool ctx::fact_reader::is_supported(const char* subject)
-{
- return _context_mgr->is_supported(subject);
-}
-
-bool ctx::fact_reader::is_allowed(const char *client, const char *subject)
-{
- //TODO: re-implement this in the proper 3.0 style
- //return _context_mgr->is_allowed(client, subject);
- return true;
-}
-
-bool ctx::fact_reader::get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options)
-{
- return _context_mgr->pop_trigger_item(subject, operation, attributes, options);
-}
-
-int ctx::fact_reader::subscribe(const char* subject, json* option, bool wait_response)
-{
- IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
-
- ctx::scope_mutex sm(&request_mutex);
-
- int rid = find_sub(subject, option);
- if (rid > 0) {
- _D("Duplicated request for %s", subject);
- return rid;
- }
-
- rid = generate_req_id();
-
- fact_request *req = new(std::nothrow) fact_request(REQ_SUBSCRIBE,
- rid, subject, option ? option->str().c_str() : NULL, wait_response ? this : NULL);
- IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
-
- g_idle_add(send_request, req);
- add_sub(rid, subject, option);
-
- IF_FAIL_RETURN_TAG(wait_response, rid, _D, "Ignoring response for %s", subject);
-
- while (last_rid != rid) {
- if (!g_cond_wait_until(&request_cond, &request_mutex, COND_END_TIME(SUBSCRIBE_TIMEOUT))) {
- _E("Timeout: subject %s", subject);
- //TODO: what happens if the request actually takes more time than the timeout
- remove_sub(rid);
- return -1;
- }
- }
-
- if (last_err != ERR_NONE) {
- remove_sub(rid);
- _E("Subscription request failed: %#x", last_err);
- return -1;
- }
-
- return rid;
-}
-
-void ctx::fact_reader::unsubscribe(const char* subject, json* option)
-{
- IF_FAIL_VOID(subject);
-
- ctx::scope_mutex sm(&request_mutex);
-
- int rid = find_sub(subject, option);
- IF_FAIL_VOID_TAG(rid > 0, _W, "Unknown subscription for %s", subject);
-
- unsubscribe(subject, rid);
-}
-
-void ctx::fact_reader::unsubscribe(const char *subject, int subscription_id)
-{
- fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, subscription_id, subject, NULL, NULL);
- IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
-
- g_idle_add(send_request, req);
- remove_sub(subscription_id);
-}
-
-bool ctx::fact_reader::read(const char* subject, json* option, context_fact& fact)
-{
- IF_FAIL_RETURN(subject, false);
-
- ctx::scope_mutex sm(&request_mutex);
-
- int rid = generate_req_id();
-
- fact_request *req = new(std::nothrow) fact_request(REQ_READ_SYNC,
- rid, subject, option ? option->str().c_str() : NULL, this);
- IF_FAIL_RETURN_TAG(req, false, _E, "Memory allocation failed");
-
- g_idle_add(send_request, req);
-
- while (last_rid != rid) {
- if (!g_cond_wait_until(&request_cond, &request_mutex, COND_END_TIME(READ_TIMEOUT))) {
- _E("Timeout: subject %s", subject);
- //TODO: what happens if the request actually takes more time than the timeout
- return false;
- }
- }
-
- if (last_err != ERR_NONE) {
- _E("Read request failed: %#x", last_err);
- return false;
- }
-
- fact.set_req_id(rid);
- fact.set_subject(subject);
- fact.set_data(last_data_read);
- last_data_read = EMPTY_JSON_OBJECT;
-
- return true;
-}
-
-void ctx::fact_reader::reply_result(int req_id, int error, json* request_result, json* fact)
-{
- ctx::scope_mutex sm(&request_mutex);
-
- last_rid = req_id;
- last_err = error;
- last_data_read = (fact ? *fact : EMPTY_JSON_OBJECT);
-
- g_cond_signal(&request_cond);
-}
-
-void ctx::fact_reader::publish_fact(int req_id, int error, const char* subject, json* option, json* fact)
-{
- _trigger->push_fact(req_id, error, subject, *option, *fact);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CONTEXT_FACT_READER_H__
-#define __CONTEXT_FACT_READER_H__
-
-#include <list>
-#include <json.h>
-#include "../context_mgr_impl.h"
-#include "fact.h"
-
-namespace ctx {
-
- class context_trigger;
-
- class fact_reader {
- public:
- fact_reader(context_manager_impl *mgr, context_trigger *trigger);
- ~fact_reader();
-
- bool is_supported(const char *subject);
- bool is_allowed(const char *client, const char *subject);
- bool get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options);
-
- int subscribe(const char *subject, json *option, bool wait_response = false);
- void unsubscribe(const char *subject, json *option);
- void unsubscribe(const char *subject, int subscription_id);
- bool read(const char *subject, json *option, context_fact& fact);
-
- void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL);
- void publish_fact(int req_id, int error, const char *subject, json *option, json *fact);
-
- private:
- static context_manager_impl *_context_mgr;
- static context_trigger *_trigger;
-
- struct subscr_info_s {
- int sid;
- std::string subject;
- ctx::json option;
- subscr_info_s(int id, const char *subj, ctx::json *opt)
- : sid(id), subject(subj)
- {
- if (opt)
- option = *opt;
- }
- };
-
- typedef std::list<subscr_info_s*> subscr_list_t;
- subscr_list_t subscr_list;
-
- int find_sub(const char *subject, json *option);
- bool add_sub(int sid, const char *subject, json *option);
- void remove_sub(const char *subject, json *option);
- void remove_sub(int sid);
-
- static gboolean send_request(gpointer data);
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_FACT_READER_H__ */
#include <types_internal.h>
#include "fact_request.h"
-ctx::fact_request::fact_request(int type, int req_id, const char* subj, const char* desc, fact_reader* reader)
+ctx::fact_request::fact_request(int type, int req_id, const char* subj, const char* desc, context_monitor* ctx_monitor)
: request_info(type, req_id, subj, desc)
- , _reader(reader)
+ , _ctx_monitor(ctx_monitor)
, replied(false)
{
}
bool ctx::fact_request::reply(int error)
{
- IF_FAIL_RETURN(!replied && _reader, true);
- _reader->reply_result(_req_id, error);
+ IF_FAIL_RETURN(!replied && _ctx_monitor, true);
+ _ctx_monitor->reply_result(_req_id, error);
return (replied = true);
}
bool ctx::fact_request::reply(int error, ctx::json& request_result)
{
- IF_FAIL_RETURN(!replied && _reader, true);
+ IF_FAIL_RETURN(!replied && _ctx_monitor, true);
IF_FAIL_RETURN(_type != REQ_READ_SYNC, true);
- _reader->reply_result(_req_id, error, &request_result);
+ _ctx_monitor->reply_result(_req_id, error, &request_result);
return (replied = true);
}
bool ctx::fact_request::reply(int error, ctx::json& request_result, ctx::json& data_read)
{
- IF_FAIL_RETURN(!replied && _reader, true);
- _reader->reply_result(_req_id, error, &request_result, &data_read);
+ IF_FAIL_RETURN(!replied && _ctx_monitor, true);
+ _ctx_monitor->reply_result(_req_id, error, &request_result, &data_read);
return (replied = true);
}
bool ctx::fact_request::publish(int error, ctx::json& data)
{
- IF_FAIL_RETURN(_reader, true);
- _reader->publish_fact(_req_id, error, _subject.c_str(), &get_description(), &data);
+ IF_FAIL_RETURN(_ctx_monitor, true);
+ _ctx_monitor->publish_fact(_req_id, error, _subject.c_str(), &get_description(), &data);
return true;
}
#ifndef __CONTEXT_TRIGGER_FACT_REQUEST_H__
#define __CONTEXT_TRIGGER_FACT_REQUEST_H__
-#include "fact_reader.h"
+#include "context_monitor.h"
#include "../request.h"
namespace ctx {
class fact_request : public request_info {
public:
- fact_request(int type, int req_id, const char* subj, const char* desc, fact_reader* reader);
+ fact_request(int type, int req_id, const char* subj, const char* desc, context_monitor* ctx_monitor);
~fact_request();
const char* get_client();
bool publish(int error, ctx::json& data);
private:
- fact_reader *_reader;
+ context_monitor *_ctx_monitor;
bool replied;
};
#include <db_mgr.h>
#include "../dbus_server_impl.h"
#include <app_manager.h>
-#include "fact_reader.h"
#include "rule_manager.h"
#include "script_generator.h"
#include "trigger.h"
destroy_clips();
}
-bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::fact_reader* fr)
+bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr)
{
bool ret;
int error;
clips_h = NULL;
trigger = tr;
- ret = c_monitor.init(fr, tr);
+ ret = c_monitor.init(ctx_mgr, tr);
IF_FAIL_RETURN_TAG(ret, false, _E, "Context monitor initialization failed");
// Create tables into db (rule, event, condition, action, template)
ret = db_manager::execute_sync(FOREIGN_KEYS_ON, &record);
IF_FAIL_RETURN_TAG(ret, false, _E, "Foreign keys on failed");
- apply_templates(fr);
+ apply_templates();
if (get_uninstalled_app() > 0) {
error = clear_rule_of_uninstalled_app(true);
return ret;
}
-void ctx::rule_manager::apply_templates(ctx::fact_reader *fr)
+void ctx::rule_manager::apply_templates(void)
{
std::string subject;
int operation;
std::string q_update;
std::string q_insert = "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options) VALUES";
- while (fr->get_fact_definition(subject, operation, attributes, options)) {
+ while (c_monitor.get_fact_definition(subject, operation, attributes, options)) {
_D("Subject: %s, Ops: %d", subject.c_str(), operation);
_J("Attr", attributes);
_J("Opt", options);
class json;
class context_trigger;
- class fact_reader;
class rule_manager {
public:
rule_manager();
~rule_manager();
- bool init(ctx::context_trigger* tr, ctx::fact_reader* fr);
+ bool init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr);
int add_rule(std::string creator, const char* app_id, ctx::json rule, ctx::json* rule_id);
int remove_rule(int rule_id);
int enable_rule(int rule_id);
clips_handler* clips_h;
context_monitor c_monitor;
- void apply_templates(ctx::fact_reader *fr);
+ void apply_templates(void);
bool reenable_rule(void);
int verify_rule(ctx::json& rule, const char* app_id);
int64_t get_duplicated_rule_id(std::string creator, ctx::json& rule);
#include <types_internal.h>
#include <context_trigger_types_internal.h>
-#include "fact_reader.h"
#include "trigger.h"
#include "rule_manager.h"
ctx::context_trigger::context_trigger()
- : _reader(NULL)
{
}
{
}
-bool ctx::context_trigger::init(ctx::context_manager_impl* mgr)
+bool ctx::context_trigger::init(ctx::context_manager_impl* ctx_mgr)
{
// Do the necessary initialization process.
// This function is called from the main thread during the service launching process.
- _reader = new(std::nothrow) fact_reader(mgr, this);
- IF_FAIL_RETURN_TAG(_reader, false, _E, "Memory allocation failed");
-
- _D("Starting Context Trigger Thread");
- IF_FAIL_RETURN(start(), false);
-
- push_thread_event(ETYPE_INITIALIZE, NULL);
+ _D("Context Trigger Init");
+ process_initialize(ctx_mgr);
return true;
}
void ctx::context_trigger::release()
{
- _D("Stopping Context Trigger Thread");
- stop();
-
// Release the occupied resources.
// This function is called from the main thread during the service termination process.
- delete _reader;
- _reader = NULL;
+ _D("Context Trigger Release");
delete rule_mgr;
rule_mgr = NULL;
}
-void ctx::context_trigger::on_thread_event_popped(int type, void* data)
-{
- switch (type) {
- case ETYPE_REQUEST:
- IF_FAIL_VOID(data);
- process_request(static_cast<request_info*>(data));
- break;
- case ETYPE_FACT:
- IF_FAIL_VOID(data);
- process_fact(static_cast<context_fact*>(data));
- break;
- case ETYPE_INITIALIZE:
- process_initialize();
- break;
- default:
- _W("Unknown event type");
- return;
- }
-
- delete_thread_event(type, data);
-}
-
-void ctx::context_trigger::delete_thread_event(int type, void* data)
-{
- IF_FAIL_VOID(data);
-
- switch (type) {
- case ETYPE_REQUEST:
- {
- std::string subject = static_cast<ctx::request_info*>(data)->get_subject();
- if (subject != CONTEXT_TRIGGER_SUBJECT_ENABLE) {
- delete (static_cast<request_info*>(data));
- }
- }
- return;
- case ETYPE_FACT:
- delete (static_cast<context_fact*>(data));
- return;
- case ETYPE_INITIALIZE:
- return;
- default:
- _W("Unknown event type");
- return;
- }
-}
-
bool ctx::context_trigger::assign_request(ctx::request_info* request)
{
std::string subject = request->get_subject();
return false;
}
- push_thread_event(ETYPE_REQUEST, request);
+ process_request(request);
return true;
}
}
}
+// TODO remove
void ctx::context_trigger::push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data)
{
context_fact *fact = new(std::nothrow) context_fact(req_id, error, subject, option, data);
IF_FAIL_VOID_TAG(fact, _E, "Memory allocation failed");
- push_thread_event(ETYPE_FACT, fact);
+ process_fact(fact);
+
}
+// TODO: remove
void ctx::context_trigger::process_fact(ctx::context_fact* fact)
{
// Process the context fact.
rule_mgr->on_event_received(fact->get_subject(), fact->get_option(), fact->get_data());
}
-void ctx::context_trigger::process_initialize(void)
+void ctx::context_trigger::process_initialize(ctx::context_manager_impl* mgr)
{
rule_mgr = new(std::nothrow) rule_manager();
IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed");
- bool ret = rule_mgr->init(this, _reader);
+ bool ret = rule_mgr->init(this, mgr);
if (!ret) {
_E("Context trigger initialization failed.");
raise(SIGTERM);
#ifndef __CONTEXT_CONTEXT_TRIGGER_H__
#define __CONTEXT_CONTEXT_TRIGGER_H__
-#include <event_driven.h>
#include "../request.h"
#include "fact.h"
namespace ctx {
- class fact_reader;
class rule_manager;
class client_request;
class context_manager_impl;
- class context_trigger : public event_driven_thread {
+ class context_trigger {
public:
context_trigger();
~context_trigger();
- bool init(ctx::context_manager_impl* mgr);
+ bool init(ctx::context_manager_impl* ctx_mgr);
void release();
bool assign_request(ctx::request_info* request);
- void push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data);
+ void push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data); // TODO remove
private:
- enum event_type_e {
- ETYPE_REQUEST = 1, // A request received from a client
- ETYPE_FACT, // A context fact received from a CA
- ETYPE_INITIALIZE, // Initialization
- };
-
- ctx::fact_reader *_reader;
-
- void on_thread_event_popped(int type, void* data);
- void delete_thread_event(int type, void* data);
-
void process_request(ctx::request_info* request);
void process_fact(ctx::context_fact* fact);
- void process_initialize(void);
+ void process_initialize(ctx::context_manager_impl* mgr);
void add_rule(ctx::request_info* request);
void remove_rule(ctx::request_info* request);