2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <types_internal.h>
20 #include <scope_mutex.h>
21 #include <timer_mgr.h>
24 #include "timer_types.h"
25 #include <context_mgr.h>
30 using namespace ctx::timer_manager;
31 static GMutex timer_mutex;
33 ctx::trigger_timer::ref_count_array_s::ref_count_array_s()
35 memset(count, 0, sizeof(int) * MAX_DAY);
38 ctx::trigger_timer::trigger_timer(ctx::context_trigger* tr)
41 submit_trigger_item();
44 ctx::trigger_timer::~trigger_timer()
49 void ctx::trigger_timer::submit_trigger_item()
51 context_manager::register_trigger_item(TIMER_EVENT_SUBJECT, OPS_SUBSCRIBE,
53 "\"TimeOfDay\":{\"type\":\"integer\",\"min\":0,\"max\":1439},"
54 "\"DayOfWeek\":{\"type\":\"string\",\"values\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\",\"Weekday\",\"Weekend\"]}"
58 context_manager::register_trigger_item(TIMER_CONDITION_SUBJECT, OPS_READ,
60 "\"TimeOfDay\":{\"type\":\"integer\",\"min\":0,\"max\":1439},"
61 "\"DayOfWeek\":{\"type\":\"string\",\"values\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\",\"Weekday\",\"Weekend\"]},"
62 "\"DayOfMonth\":{\"type\":\"integer\",\"min\":1,\"max\":31}"
68 int ctx::trigger_timer::merge_day_of_week(int* ref_cnt)
72 for (int d = 0; d < MAX_DAY; ++d) {
74 day_of_week |= (0x01 << d);
81 bool ctx::trigger_timer::add(int minute, int day_of_week)
83 IF_FAIL_RETURN_TAG(minute >=0 && minute < 1440 &&
84 day_of_week > 0 && day_of_week <= timer_manager::EVERYDAY,
85 false, _E, "Invalid parameter");
87 ctx::scope_mutex sm(&timer_mutex);
89 ref_count_array_s &ref = ref_count_map[minute];
91 for (int d = 0; d < MAX_DAY; ++d) {
92 if ((day_of_week & (0x01 << d)) != 0) {
97 return reset_timer(minute);
100 bool ctx::trigger_timer::remove(int minute, int day_of_week)
102 IF_FAIL_RETURN_TAG(minute >=0 && minute < 1440 &&
103 day_of_week > 0 && day_of_week <= timer_manager::EVERYDAY,
104 false, _E, "Invalid parameter");
106 ctx::scope_mutex sm(&timer_mutex);
108 ref_count_array_s &ref = ref_count_map[minute];
110 for (int d = 0; d < MAX_DAY; ++d) {
111 if ((day_of_week & (0x01 << d)) != 0 && ref.count[d] > 0) {
116 return reset_timer(minute);
119 bool ctx::trigger_timer::reset_timer(int minute)
121 int day_of_week = merge_day_of_week(ref_count_map[minute].count);
122 timer_state_s &timer = timer_state_map[minute];
124 if (day_of_week == timer.day_of_week) {
125 /* Necessary timers are already running... */
129 if (day_of_week == 0 && timer.timer_id > 0) {
130 /* Turn off the timer at hour, if it is not necessray anymore. */
131 timer_manager::remove(timer.timer_id);
132 timer_state_map.erase(minute);
133 ref_count_map.erase(minute);
137 if (timer.timer_id > 0) {
138 /* Turn off the current timer, to set a new one. */
139 timer_manager::remove(timer.timer_id);
141 timer.day_of_week = 0;
144 /* Create a new timer, w.r.t. the new day_of_week value. */
146 int m = minute - h * 60;
147 int tid = timer_manager::set_at(h, m, day_of_week, this);
148 IF_FAIL_RETURN_TAG(tid > 0, false, _E, "Timer setting failed");
150 timer.timer_id = tid;
151 timer.day_of_week = day_of_week;
156 void ctx::trigger_timer::clear()
158 ctx::scope_mutex sm(&timer_mutex);
160 for (timer_state_map_t::iterator it = timer_state_map.begin(); it != timer_state_map.end(); ++it) {
161 if (it->second.timer_id > 0) {
162 timer_manager::remove(it->second.timer_id);
166 timer_state_map.clear();
167 ref_count_map.clear();
170 bool ctx::trigger_timer::on_timer_expired(int timer_id, void* user_data)
177 localtime_r(&rawtime, &timeinfo);
179 int hour = timeinfo.tm_hour;
180 int min = timeinfo.tm_min;
181 int day_of_week = (0x01 << timeinfo.tm_wday);
183 on_timer_expired(hour, min, day_of_week);
188 void ctx::trigger_timer::on_timer_expired(int hour, int min, int day_of_week)
190 _I("Time: %02d:%02d, Day of Week: %#x", hour, min, day_of_week);
193 result.set(NULL, TIMER_RESPONSE_KEY_TIME_OF_DAY, hour * 60 + min);
194 result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, convert_day_of_week_to_string(day_of_week));
196 ctx::json dummy = NULL;
197 trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result);
200 int ctx::trigger_timer::get_day_of_month()
207 localtime_r(&rawtime, &timeinfo);
209 int day_of_month = timeinfo.tm_mday;
214 std::string ctx::trigger_timer::get_day_of_week()
221 localtime_r(&rawtime, &timeinfo);
223 int day_of_week = (0x01 << timeinfo.tm_wday);
225 return convert_day_of_week_to_string(day_of_week);
228 int ctx::trigger_timer::get_minute_of_day()
235 localtime_r(&rawtime, &timeinfo);
237 int hour = timeinfo.tm_hour;
238 int minute = timeinfo.tm_min;
240 return hour * 60 + minute;
243 int ctx::trigger_timer::convert_string_to_day_of_week(std::string d)
246 d = d.substr(1, d.length() - 2);
248 if (d.compare(TIMER_SUN) == 0) {
250 } else if (d.compare(TIMER_MON) == 0) {
252 } else if (d.compare(TIMER_TUE) == 0) {
254 } else if (d.compare(TIMER_WED) == 0) {
256 } else if (d.compare(TIMER_THU) == 0) {
258 } else if (d.compare(TIMER_FRI) == 0) {
260 } else if (d.compare(TIMER_SAT) == 0) {
262 } else if (d.compare(TIMER_WEEKDAY) == 0) {
264 } else if (d.compare(TIMER_WEEKEND) == 0) {
266 } else if (d.compare(TIMER_EVERYDAY) == 0) {
273 std::string ctx::trigger_timer::convert_day_of_week_to_string(int d)
279 } else if (d == MON) {
281 } else if (d == TUE) {
283 } else if (d == WED) {
285 } else if (d == THU) {
287 } else if (d == FRI) {
289 } else if (d == SAT) {
291 } else if (d == WEEKDAY) {
293 } else if (d == WEEKEND) {
295 } else if (d == EVERYDAY) {
296 day = TIMER_EVERYDAY;
302 bool ctx::trigger_timer::empty()
304 return timer_state_map.empty();