{
_context_mgr = ctx_mgr;
-/* timer = new(std::nothrow) trigger_timer(_trigger); TODO
- IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");*/
+ timer = new(std::nothrow) trigger_timer();
+ IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");
return true;
}
{
if (subject.compare(TIMER_EVENT_SUBJECT) == 0) {
// option is event json in case of ON_TIME
-// return timer->subscribe(event);
- return ERR_NONE;
+ return timer->subscribe(option, listener);
}
int req_id = _subscribe(subject.c_str(), &option, listener);
int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener)
{
if (subject.compare(TIMER_EVENT_SUBJECT) == 0) {
-// return timer->unsubscribe(option);
- return ERR_NONE;
+ return timer->unsubscribe(option, listener);
}
int rid = find_sub(REQ_SUBSCRIBE, subject.c_str(), &option);
int ctx::context_monitor::read(std::string subject, json option, context_listener_iface* listener)
{
if (subject.compare(TIMER_CONDITION_SUBJECT) == 0) {
-// return timer->read(result); TODO
- return ERR_NONE;
+ return timer->read(listener);
}
int req_id = _read(subject.c_str(), &option, listener);
#include "action_manager.h"
#include "rule_evaluator.h"
#include "context_monitor.h"
+#include "timer_types.h"
#define CONTEXT_RULE_EVENT "event"
#define CONTEXT_RULE_CONDITION "condition"
int ctx::trigger_rule::start(void)
{
+ ctx::json time_option = EMPTY_JSON_OBJECT;
+ if (event->name.compare(TIMER_EVENT_SUBJECT) == 0) {
+ statement.get(NULL, CT_RULE_EVENT, &time_option);
+ }
+
// Subscribe event
- int error = ctx_monitor->subscribe(id, event->name, event->option, this);
+ int error = ctx_monitor->subscribe(id, event->name, (time_option == EMPTY_JSON_OBJECT)? event->option : time_option, this);
IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id);
return error;
int ctx::trigger_rule::stop(void)
{
+ ctx::json time_option = EMPTY_JSON_OBJECT;
+ if (event->name.compare(TIMER_EVENT_SUBJECT) == 0) {
+ statement.get(NULL, CT_RULE_EVENT, &time_option);
+ }
+
// Unsubscribe event
- int error = ctx_monitor->unsubscribe(id, event->name, event->option, this);
+ int error = ctx_monitor->unsubscribe(id, event->name, (time_option == EMPTY_JSON_OBJECT)? event->option : time_option, this);
IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
return error;
#include "rule_manager.h"
#include "context_monitor.h"
#include "rule.h"
+#include "timer.h"
#define RULE_TABLE "context_trigger_rule"
#define TEMPLATE_TABLE "context_trigger_template"
r_record.set(NULL, "creator_app_id", app_id);
}
r_record.set(NULL, "description", description);
+
+ // Handle timer event
+ ctx::trigger_timer::handle_timer_event(details);
+
r_record.set(NULL, "details", details.str());
ret = db_manager::insert_sync(RULE_TABLE, r_record, &rid);
IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert rule to db failed");
#include <context_mgr.h>
#include <context_trigger_types_internal.h>
#include "timer.h"
-#include "trigger.h"
#include "timer_types.h"
+#include "context_listener_iface.h"
#define MAX_HOUR 24
#define MAX_DAY 7
static int convert_string_to_day_of_week(std::string d)
{
int day = 0;
- d = d.substr(1, d.length() - 2);
if (d.compare(TIMER_SUN) == 0) {
day = SUN;
std::string key_op;
if (!day_info.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op)) {
- result = convert_string_to_day_of_week("\"" TIMER_EVERYDAY "\"");
+ result = convert_string_to_day_of_week(TIMER_EVERYDAY);
return result;
}
if (key_op.compare("and") == 0) {
- result = convert_string_to_day_of_week("\"" TIMER_EVERYDAY "\"");
+ result = convert_string_to_day_of_week(TIMER_EVERYDAY);
}
std::string tmp_d;
day_info.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &op);
if (op.compare("neq") == 0) {
- dow = convert_string_to_day_of_week("\"" TIMER_EVERYDAY "\"") & ~dow;
+ dow = convert_string_to_day_of_week(TIMER_EVERYDAY) & ~dow;
}
if (key_op.compare("and") == 0) {
memset(count, 0, sizeof(int) * MAX_DAY);
}
-ctx::trigger_timer::trigger_timer(ctx::context_trigger* tr)
- : trigger(tr)
+ctx::trigger_timer::trigger_timer()
{
submit_trigger_item();
}
result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, convert_day_of_week_to_string(day_of_week));
ctx::json dummy = NULL;
-// trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result); // TODO deliver event
+
+ for (listener_list_t::iterator it = listener_list.begin(); it != listener_list.end(); ++it) {
+ (*it)->on_event_received(TIMER_EVENT_SUBJECT, EMPTY_JSON_OBJECT, result);
+ }
}
-int ctx::trigger_timer::subscribe(ctx::json option)
+int ctx::trigger_timer::subscribe(ctx::json option, context_listener_iface* listener)
{
ctx::json day_info;
ctx::json time_info;
add(time, dow);
}
+ listener_list.push_back(listener);
+
return ERR_NONE;
}
-int ctx::trigger_timer::unsubscribe(ctx::json option)
+int ctx::trigger_timer::unsubscribe(ctx::json option, context_listener_iface* listener)
{
ctx::json day_info;
ctx::json time_info;
remove(time, dow);
}
+ listener_list.remove(listener);
+
return ERR_NONE;
}
-int ctx::trigger_timer::read(ctx::json* result)
+int ctx::trigger_timer::read(context_listener_iface* listener)
{
time_t rawtime;
struct tm timeinfo;
int minute_of_day = timeinfo.tm_hour * 60 + timeinfo.tm_min;
std::string day_of_week = convert_day_of_week_to_string(0x01 << timeinfo.tm_wday);
- (*result).set(NULL, TIMER_RESPONSE_KEY_DAY_OF_MONTH, day_of_month);
- (*result).set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, day_of_week);
- (*result).set(NULL, TIMER_RESPONSE_KEY_TIME_OF_DAY, minute_of_day);
+ ctx::json result;
+ result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_MONTH, day_of_month);
+ result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, day_of_week);
+ result.set(NULL, TIMER_RESPONSE_KEY_TIME_OF_DAY, minute_of_day);
+
+ _I("Time: %02d:%02d, Day of Week: %s, Day of Month: %d", timeinfo.tm_hour, timeinfo.tm_min, day_of_week.c_str(), day_of_month);
+
+ listener->on_condition_received(TIMER_CONDITION_SUBJECT, EMPTY_JSON_OBJECT, result);
return ERR_NONE;
}
{
return timer_state_map.empty();
}
+
+void ctx::trigger_timer::handle_timer_event(ctx::json& rule)
+{
+ ctx::json event;
+ rule.get(NULL, CT_RULE_EVENT, &event);
+
+ std::string e_name;
+ event.get(NULL, CT_RULE_EVENT_ITEM, &e_name);
+ if (e_name.compare(TIMER_EVENT_SUBJECT) != 0 ) {
+ return;
+ }
+
+ ctx::json day_info;
+ ctx::json it;
+ int dow;
+ for (int i = 0; event.get_array_elem(NULL, CT_RULE_DATA_ARR, i, &it); i++){
+ std::string key;
+ it.get(NULL, CT_RULE_DATA_KEY, &key);
+
+ if (key.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) {
+ dow = arrange_day_of_week(it);
+
+ day_info.set(NULL, CT_RULE_DATA_KEY, TIMER_RESPONSE_KEY_DAY_OF_WEEK);
+ day_info.set(NULL, CT_RULE_DATA_KEY_OPERATOR, "or");
+
+ for (int j = 0; j < MAX_DAY; j++) {
+ int d = 0x01 << j;
+ if (dow & d) {
+ std::string day = convert_day_of_week_to_string(d);
+ day_info.array_append(NULL, CT_RULE_DATA_VALUE_ARR, day);
+ day_info.array_append(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, "eq");
+ }
+ }
+ event.array_set_at(NULL, CT_RULE_DATA_ARR, i, day_info);
+ }
+
+ }
+
+ rule.set(NULL, CT_RULE_EVENT, event);
+}
namespace ctx {
- class context_trigger;
+ class context_listener_iface;
class trigger_timer : public timer_listener_iface {
private:
typedef std::map<int, ref_count_array_s> ref_count_map_t;
typedef std::map<int, timer_state_s> timer_state_map_t;
+ typedef std::list<context_listener_iface*> listener_list_t;
- ctx::context_trigger *trigger;
ref_count_map_t ref_count_map;
timer_state_map_t timer_state_map;
+ listener_list_t listener_list;
bool add(int minute, int day_of_week);
bool remove(int minute, int day_of_week);
bool on_timer_expired(int timer_id, void *user_data);
public:
- trigger_timer(ctx::context_trigger *tr);
+ trigger_timer();
~trigger_timer();
static void submit_trigger_item();
- int subscribe(ctx::json option);
- int unsubscribe(ctx::json option);
- int read(ctx::json* result);
+ int subscribe(ctx::json option, context_listener_iface* listener);
+ int unsubscribe(ctx::json option, context_listener_iface* listener);
+ int read(context_listener_iface* listener);
+
+ static void handle_timer_event(ctx::json& rule);
};
} /* namespace ctx */