4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
29 #include "cal_typedef.h"
30 #include "cal_internal.h"
32 #include "cal_inotify.h"
34 #include "cal_db_util.h"
36 #include "cal_db_query.h"
37 #include "cal_server_reminder.h"
39 #define CAL_SEARCH_LOOP_MAX 4
44 long long int alert_utime; /* to compare */
47 int type; /* utime, localtime */
49 int record; /* todo, event */
54 /* this api is necessary for repeat instance. */
55 static int _cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
57 int ret = CALENDAR_ERROR_NONE;
58 char query[CAL_DB_SQL_MAX_LEN] = {0};
59 cal_db_util_error_e dbret = CAL_DB_OK;
61 ret = cal_db_util_begin_trans();
62 if (CALENDAR_ERROR_NONE != ret)
64 ERR("cal_db_util_begin_trans() Fail");
65 return CALENDAR_ERROR_DB_FAILED;
68 DBG("alarm_id(%d)", alarm_id);
70 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
71 CAL_TABLE_ALARM, alarm_id);
73 dbret = cal_db_util_query_exec(query);
74 if (CAL_DB_OK != dbret) {
75 ERR("cal_db_util_query_exec() Fail(%d)", dbret);
76 SECURE("[%s]", query);
78 case CAL_DB_ERROR_NO_SPACE:
79 cal_db_util_end_trans(false);
80 return CALENDAR_ERROR_FILE_NO_SPACE;
82 cal_db_util_end_trans(false);
83 return CALENDAR_ERROR_DB_FAILED;
86 cal_db_util_end_trans(true);
87 return CALENDAR_ERROR_NONE;
90 static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
94 DBG("remove alarm id(%d)", alarm_id);
95 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
96 ret = alarmmgr_remove_alarm(alarm_id);
97 if (ret != ALARMMGR_RESULT_SUCCESS)
99 ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
102 return CALENDAR_ERROR_NONE;
105 static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
107 int ret = CALENDAR_ERROR_NONE;
108 char query[CAL_DB_SQL_MAX_LEN] = {0};
109 cal_db_util_error_e dbret = CAL_DB_OK;
111 ret = cal_db_util_begin_trans();
112 if (CALENDAR_ERROR_NONE != ret)
114 ERR("cal_db_util_begin_trans() Fail");
115 return CALENDAR_ERROR_DB_FAILED;
118 DBG("Update alarm_id(%d) in alarm table", alarm_id);
119 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
120 "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
121 CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
123 dbret = cal_db_util_query_exec(query);
124 if (CAL_DB_OK != dbret) {
125 ERR("cal_db_util_query_exec() Fail(%d)", dbret);
126 SECURE("[%s]", query);
128 case CAL_DB_ERROR_NO_SPACE:
129 cal_db_util_end_trans(false);
130 return CALENDAR_ERROR_FILE_NO_SPACE;
132 cal_db_util_end_trans(false);
133 return CALENDAR_ERROR_DB_FAILED;
136 cal_db_util_end_trans(true);
137 return CALENDAR_ERROR_NONE;
140 static long long int _cal_server_alarm_get_alert_utime(const char *field, int event_id, time_t current)
142 char query[CAL_DB_SQL_MAX_LEN] = {0};
143 snprintf(query, sizeof(query), "SELECT %s FROM %s "
144 "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
145 field, CAL_TABLE_NORMAL_INSTANCE, event_id, field, current, field);
147 sqlite3_stmt *stmt = NULL;
148 stmt = cal_db_util_query_prepare(query);
150 long long int utime = 0;
151 if (CAL_DB_ROW == cal_db_util_stmt_step(stmt))
152 utime = sqlite3_column_int(stmt, 0);
154 sqlite3_finalize(stmt);
158 static int _cal_server_alarm_get_alert_localtime(const char *field, int event_id, time_t current)
160 char query[CAL_DB_SQL_MAX_LEN] = {0};
163 localtime_r(¤t, &st);
164 time_t mod_current = timegm(&st);
165 snprintf(query, sizeof(query), "SELECT %s FROM %s "
166 "WHERE event_id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
167 field, CAL_TABLE_ALLDAY_INSTANCE, event_id, field, mod_current, field);
169 sqlite3_stmt *stmt = NULL;
170 stmt = cal_db_util_query_prepare(query);
172 const char *datetime = NULL;
173 if (CAL_DB_ROW == cal_db_util_stmt_step(stmt))
174 datetime = (const char *)sqlite3_column_text(stmt, 0);
176 if (NULL == datetime || '\0' == *datetime) {
177 ERR("Invalid datetime [%s]", datetime);
178 sqlite3_finalize(stmt);
182 int y = 0, m = 0, d = 0;
183 int h = 0, n = 0, s = 0;
184 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
185 sqlite3_finalize(stmt);
187 st.tm_year = y - 1900;
194 return (long long int)mktime(&st);
198 * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
199 * so, searching DB is neccessary to find alert time.
201 static int _cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
203 RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
205 char query[CAL_DB_SQL_MAX_LEN] = {0};
206 snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
207 "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.system_type, "
208 "B.type, B.dtstart_type, B.dtend_type "
209 "FROM %s as A, %s as B ON A.event_id = B.id WHERE alarm_id =%d ",
210 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
212 sqlite3_stmt *stmt = NULL;
213 stmt = cal_db_util_query_prepare(query);
214 RETVM_IF(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "cal_db_util_query_prepare() Fail");
220 long long int utime = 0;
221 const char *datetime = NULL;
224 int dtstart_type = 0;
228 if (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
230 event_id = sqlite3_column_int(stmt, index++);
231 unit = sqlite3_column_int(stmt, index++);
232 tick = sqlite3_column_int(stmt, index++);
233 type = sqlite3_column_int(stmt, index++);
234 utime = sqlite3_column_int64(stmt, index++);
235 datetime = (const char *)sqlite3_column_text(stmt, index++);
236 system_type = sqlite3_column_int(stmt, index++);
237 record_type = sqlite3_column_int(stmt, index++);
238 dtstart_type = sqlite3_column_int(stmt, index++);
239 dtend_type = sqlite3_column_int(stmt, index++);
242 if (NULL == tt_alert) {
243 ERR("Invalid parameter: tt_alert is NULL");
244 sqlite3_finalize(stmt);
245 return CALENDAR_ERROR_INVALID_PARAMETER;
248 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
249 if (CALENDAR_TIME_UTIME == type) {
253 int y = 0, m = 0, d = 0;
254 int h = 0, n = 0, s = 0;
255 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
257 st.tm_year = y - 1900;
263 *tt_alert = (long long int)mktime(&st);
264 DBG("datetime[%s] to %02d:%02d:%02d (%lld)", datetime, h, n, s, *tt_alert);
266 sqlite3_finalize(stmt);
267 return CALENDAR_ERROR_NONE;
269 sqlite3_finalize(stmt);
271 time_t current = time(NULL);
272 current += (tick * unit);
273 current -= 2; /* in case time passed */
275 switch (record_type) {
276 case CALENDAR_BOOK_TYPE_EVENT:
277 switch (dtstart_type) {
278 case CALENDAR_TIME_UTIME:
279 utime = _cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
282 case CALENDAR_TIME_LOCALTIME:
283 utime = _cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
288 case CALENDAR_BOOK_TYPE_TODO:
289 switch (dtend_type) {
290 case CALENDAR_TIME_UTIME:
291 utime = _cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
294 case CALENDAR_TIME_LOCALTIME:
295 utime = _cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
300 DBG("alert_time(%lld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, datetime, tick, unit);
302 *tt_alert = utime - (tick * unit);
303 return CALENDAR_ERROR_NONE;
306 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
308 char query_specific_utime[CAL_DB_SQL_MAX_LEN] = {0};
309 snprintf(query_specific_utime, sizeof(query_specific_utime),
310 // alarm utime(normal event + todo)
311 "SELECT event_id, remind_tick_unit, remind_tick, alarm_type, alarm_utime, alarm_datetime "
313 "WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
315 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
316 true == get_all ? "=" : ">",
318 true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
320 sqlite3_stmt *stmt = NULL;
321 stmt = cal_db_util_query_prepare(query_specific_utime);
323 ERR("cal_db_util_query_prepare() Fail");
324 SECURE("query[%s]", query_specific_utime);
328 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
329 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
331 ERR("calloc() Fail");
332 sqlite3_finalize(stmt);
337 ad->event_id = sqlite3_column_int(stmt, index++);
338 ad->unit = sqlite3_column_int(stmt, index++);
339 ad->tick = sqlite3_column_int(stmt, index++);
340 ad->type = sqlite3_column_int(stmt, index++);
341 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
342 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
343 *l = g_list_append(*l, ad);
344 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
345 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
346 ad->alert_utime = ad->time;
347 if (false == get_all) break;
349 sqlite3_finalize(stmt);
352 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
354 char query_specific_localtime[CAL_DB_SQL_MAX_LEN] = {0};
355 snprintf(query_specific_localtime, sizeof(query_specific_localtime),
356 "SELECT event_id, remind_tick_unit, remind_tick, "
357 "alarm_type, alarm_utime, alarm_datetime "
359 "WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
361 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
362 true == get_all ? "=" : ">",
364 true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
366 sqlite3_stmt *stmt = NULL;
367 stmt = cal_db_util_query_prepare(query_specific_localtime);
369 ERR("cal_db_util_query_prepare() Fail");
370 ERR("[%s]", query_specific_localtime);
374 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
375 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
377 ERR("calloc() Fail");
378 sqlite3_finalize(stmt);
383 ad->event_id = sqlite3_column_int(stmt, index++);
384 ad->unit = sqlite3_column_int(stmt, index++);
385 ad->tick = sqlite3_column_int(stmt, index++);
386 ad->type = sqlite3_column_int(stmt, index++);
387 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
388 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
389 *l = g_list_append(*l, ad);
390 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
391 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
393 int y = 0, m = 0, d = 0;
394 int h = 0, n = 0, s = 0;
395 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
398 st.tm_year = y - 1900;
404 ad->alert_utime = (long long int)mktime(&st);
405 if (false == get_all) break;
407 sqlite3_finalize(stmt);
410 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
412 char query_nonspecific_event_utime[CAL_DB_SQL_MAX_LEN] = {0};
417 snprintf(query_nonspecific_event_utime, sizeof(query_nonspecific_event_utime),
418 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtstart_utime, A.alarm_datetime "
419 "FROM %s as A, %s as B ON A.event_id = B.event_id "
420 "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
421 CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE,
422 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
423 true == get_all ? "=" : ">",
425 true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
427 sqlite3_stmt *stmt = NULL;
428 stmt = cal_db_util_query_prepare(query_nonspecific_event_utime);
430 ERR("cal_db_util_query_prepare() Fail");
431 ERR("[%s]", query_nonspecific_event_utime);
435 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
436 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
438 ERR("calloc() Fail");
439 sqlite3_finalize(stmt);
444 ad->event_id = sqlite3_column_int(stmt, index++);
445 ad->unit = sqlite3_column_int(stmt, index++);
446 ad->tick = sqlite3_column_int(stmt, index++);
447 ad->type = sqlite3_column_int(stmt, index++);
448 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
449 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
450 *l = g_list_append(*l, ad);
451 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
452 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
454 ad->alert_utime = ad->time - (ad->tick * ad->unit);
455 if (false == get_all) break;
457 sqlite3_finalize(stmt);
460 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
462 char query_nonspecific_event_localtime[CAL_DB_SQL_MAX_LEN] = {0};
467 snprintf(query_nonspecific_event_localtime, sizeof(query_nonspecific_event_localtime),
468 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtstart_datetime "
469 "FROM %s as A, %s as B ON A.event_id = B.event_id "
470 "WHERE A.remind_tick_unit >%d AND "
471 "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
472 CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE,
473 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
475 true == get_all ? "=" : ">",
476 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
477 sqlite3_stmt *stmt = NULL;
478 stmt = cal_db_util_query_prepare(query_nonspecific_event_localtime);
480 ERR("cal_db_util_query_prepare() Fail");
481 ERR("[%s]", query_nonspecific_event_localtime);
485 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
486 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
488 ERR("calloc() Fail");
489 sqlite3_finalize(stmt);
494 ad->event_id = sqlite3_column_int(stmt, index++);
495 ad->unit = sqlite3_column_int(stmt, index++);
496 ad->tick = sqlite3_column_int(stmt, index++);
497 ad->type = sqlite3_column_int(stmt, index++);
498 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
499 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
500 *l = g_list_append(*l, ad);
501 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
502 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
504 int y = 0, m = 0, d = 0;
505 int h = 0, n = 0, s = 0;
506 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
509 st.tm_year = y - 1900;
515 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
516 if (false == get_all) break;
518 sqlite3_finalize(stmt);
521 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
523 char query_nonspecific_todo_utime[CAL_DB_SQL_MAX_LEN] = {0};
528 snprintf(query_nonspecific_todo_utime, sizeof(query_nonspecific_todo_utime),
529 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtend_utime, A.alarm_datetime "
530 "FROM %s as A, %s as B ON A.event_id = B.id "
531 "WHERE A.remind_tick_unit >%d AND B.type =%d "
532 "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
533 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
534 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
535 true == get_all ? "=" : ">",
537 true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
539 sqlite3_stmt *stmt = NULL;
540 stmt = cal_db_util_query_prepare(query_nonspecific_todo_utime);
542 ERR("cal_db_util_query_prepare() Fail");
543 ERR("[%s]", query_nonspecific_todo_utime);
547 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
548 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
550 ERR("calloc() Fail");
551 sqlite3_finalize(stmt);
556 ad->event_id = sqlite3_column_int(stmt, index++);
557 ad->unit = sqlite3_column_int(stmt, index++);
558 ad->tick = sqlite3_column_int(stmt, index++);
559 ad->type = sqlite3_column_int(stmt, index++);
560 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
561 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
562 *l = g_list_append(*l, ad);
563 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
564 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
566 ad->alert_utime = ad->time - (ad->tick * ad->unit);
567 if (false == get_all) break;
569 sqlite3_finalize(stmt);
572 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
574 char query_nonspecific_todo_localtime[CAL_DB_SQL_MAX_LEN] = {0};
579 snprintf(query_nonspecific_todo_localtime, sizeof(query_nonspecific_todo_localtime),
580 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtend_datetime "
581 "FROM %s as A, %s as B ON A.event_id = B.id "
582 "WHERE A.remind_tick_unit >%d AND B.type =%d "
583 "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
584 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
585 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
587 true == get_all ? "=" : ">",
588 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
590 sqlite3_stmt *stmt = NULL;
591 stmt = cal_db_util_query_prepare(query_nonspecific_todo_localtime);
593 ERR("cal_db_util_query_prepare() Fail");
594 ERR("[%s]", query_nonspecific_todo_localtime);
598 while (CAL_DB_ROW == cal_db_util_stmt_step(stmt)) {
599 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
601 ERR("calloc() Fail");
602 sqlite3_finalize(stmt);
607 ad->event_id = sqlite3_column_int(stmt, index++);
608 ad->unit = sqlite3_column_int(stmt, index++);
609 ad->tick = sqlite3_column_int(stmt, index++);
610 ad->type = sqlite3_column_int(stmt, index++);
611 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
612 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
613 *l = g_list_append(*l, ad);
614 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
615 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
617 int y = 0, m = 0, d = 0;
618 int h = 0, n = 0, s = 0;
619 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
622 st.tm_year = y - 1900;
628 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
629 if (false == get_all) break;
631 sqlite3_finalize(stmt);
634 static int _cal_server_alarm_get_alert_list(time_t utime, GList **list)
637 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
640 struct tm st_local = {0};
641 localtime_r(&utime, &st_local);
642 char datetime[32] = {0};
643 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
644 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
645 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
646 DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
650 _cal_server_alarm_get_upcoming_specific_utime(utime, true, &l);
651 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, true, &l);
652 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, true, &l);
654 _cal_server_alarm_get_upcoming_specific_localtime(datetime, true, &l);
655 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, true, &l);
656 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, true, &l);
660 return CALENDAR_ERROR_NONE;
663 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
665 struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
666 struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
667 DBG("%lld) > (%lld)",p1->alert_utime, p2->alert_utime);
669 return p1->alert_utime < p2->alert_utime ? -1 : 1;
672 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
674 struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
675 DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
676 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
680 static int _cal_server_alarm_register(GList *alarm_list)
683 RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
685 int ret = CALENDAR_ERROR_NONE;
686 GList *l = g_list_first(alarm_list);
687 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
688 RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
690 /* clear all alarm which set by mine. */
691 ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
692 if (ret != ALARMMGR_RESULT_SUCCESS) {
693 ERR("alarmmgr_enum_alarm_ids() Fail");
697 time_t mod_time = (time_t)ad->alert_utime;
698 alarm_entry_t *alarm_info = NULL;
699 alarm_info = alarmmgr_create_alarm();
700 if (NULL == alarm_info)
702 ERR("Failed to create alarm");
703 return CALENDAR_ERROR_DB_FAILED;
706 struct tm st_alarm = {0};
708 switch (ad->system_type) {
709 case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
710 gmtime_r(&mod_time, &st_alarm);
715 localtime_r(&mod_time, &st_alarm);
719 alarm_date_t date = {0};
720 date.year = st_alarm.tm_year + 1900;
721 date.month = st_alarm.tm_mon + 1;
722 date.day = st_alarm.tm_mday;
723 date.hour = st_alarm.tm_hour;
724 date.min = st_alarm.tm_min;
725 date.sec = st_alarm.tm_sec;
726 alarmmgr_set_time(alarm_info, date);
727 DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
728 ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
729 ad->time, ad->datetime, ad->tick, ad->unit);
732 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
734 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
735 alarmmgr_free_alarm(alarm_info);
738 DBG("alarmmgr id (%d)", alarm_id);
739 _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
740 alarmmgr_free_alarm(alarm_info);
741 return CALENDAR_ERROR_NONE;
744 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
747 struct alarm_ud *au = (struct alarm_ud *)user_data;
749 RETV_IF(NULL == user_data, true);
752 ret = app_control_get_mime(app_control, &mime);
753 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
755 const char *reminder_mime = "application/x-tizen.calendar.reminder";
756 if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
757 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
763 GList *alarm_list = (GList *)user_data;
765 len = g_list_length(alarm_list);
767 DBG("len is 0, no alarm list");
771 app_control_h b = NULL;
772 app_control_create(&b);
773 app_control_set_operation(b, APP_CONTROL_OPERATION_DEFAULT);
774 app_control_set_app_id(b, package);
777 ids = calloc(len, sizeof(char *));
779 ERR("calloc() Fail");
780 app_control_destroy(b);
781 return CALENDAR_ERROR_DB_FAILED;
783 GList *l = g_list_first(alarm_list);
785 for (i = 0; i < len; i++) {
786 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
792 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
793 package, ad->time, ad->tick, ad->unit, ad->record);
795 char buf_event_id[128] = {0};
796 char buf_time[128] = {0};
797 char buf_tick[128] = {0};
798 char buf_unit[128] = {0};
799 char buf_record_type[128] = {0};
800 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
801 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
802 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
803 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
804 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
807 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
808 cal_server_reminder_add_callback_data(&p, "time", buf_time);
809 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
810 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
811 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
813 app_control_add_extra_data(b, buf_event_id, p); // key: id, value: id=4&time=123123&..
818 ids[i] = strdup(buf_event_id);
822 app_control_add_extra_data_array(b, "ids", (const char **)ids, len);
823 app_control_send_launch_request (b, NULL, NULL);
824 app_control_destroy(b);
826 for (i = 0; i < len; i++) {
835 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
837 RETM_IF(NULL == alarm_list, "No alarm list");
839 app_control_h app_control = NULL;
840 app_control_create(&app_control);
841 app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
842 app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
843 app_control_foreach_app_matched(app_control, __app_matched_cb, alarm_list);
844 app_control_destroy(app_control);
847 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
849 RETM_IF(NULL == alarm_list, "No alarm list");
851 GList *l = g_list_first(alarm_list);
853 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
859 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
860 ad->time, ad->tick, ad->unit, ad->record);
862 char buf_event_id[128] = {0};
863 char buf_time[128] = {0};
864 char buf_tick[128] = {0};
865 char buf_unit[128] = {0};
866 char buf_record_type[128] = {0};
867 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
868 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
869 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
870 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
871 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
874 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
875 cal_server_reminder_add_callback_data(&p, "time", buf_time);
876 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
877 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
878 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
879 cal_server_reminder_publish(p);
886 static int _cal_server_alarm_register_with_alarmmgr(time_t utime)
889 struct tm st_local = {0};
890 localtime_r(&utime, &st_local);
891 char datetime[32] = {0};
892 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
893 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
894 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
895 DBG("search alarm to register with given time (%ld) datetime[%s]", utime, datetime);
899 _cal_server_alarm_get_upcoming_specific_utime(utime, false, &l);
900 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, false, &l);
901 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, false, &l);
903 _cal_server_alarm_get_upcoming_specific_localtime(datetime, false, &l);
904 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, false, &l);
905 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, false, &l);
908 DBG("No alarm list");
909 return CALENDAR_ERROR_NONE;
912 l = g_list_sort(l, _cal_server_alarm_sort_cb);
913 g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
914 _cal_server_alarm_register(l);
918 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
923 return CALENDAR_ERROR_NONE;
926 static int _alert_cb(alarm_id_t alarm_id, void *data)
931 DBG("alarm_id (%ld)", alarm_id);
933 _cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
934 _cal_server_alarm_get_alert_list(tt_alert, &l);
935 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
936 _cal_server_alarm_noti_with_callback(l);
937 _cal_server_alarm_noti_with_control(l);
938 _cal_server_alarm_register_with_alarmmgr(tt_alert);
942 ////////////////////////////////////////////////////////////////////
943 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
949 t = vconf_keynode_get_int(node);
953 ret = vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, &t);
954 WARN_IF(0 < ret, "vconf_get_int() Fail");
959 _cal_server_alarm_register_with_alarmmgr(time(NULL));
963 DBG("system changed time(%ld)", t);
964 _cal_server_alarm_register_with_alarmmgr((time_t)t);
968 void _cal_server_alarm_set_timechange(void)
970 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
971 _cal_server_alarm_timechange_cb, NULL);
973 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
974 _cal_server_alarm_timechange_cb, NULL);
975 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
976 _cal_server_alarm_timechange_cb, NULL);
977 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
978 _cal_server_alarm_timechange_cb, NULL);
981 static void __changed_cb(const char* view_uri, void* data)
984 _cal_server_alarm_register_with_alarmmgr(time(NULL));
987 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
989 cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
990 cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
994 int cal_server_alarm(void)
999 _cal_server_alarm_set_timechange();
1000 _cal_server_alarm_set_inotify(__changed_cb);
1002 ret = alarmmgr_init("calendar-service");
1003 RETVM_IF(ret < 0, ret, "alarmmgr_init() Fail");
1005 ret = alarmmgr_set_cb(_alert_cb, NULL);
1006 RETVM_IF(ret < 0, ret, "alarmmgr_set_cb() Fail");
1008 _cal_server_alarm_register_with_alarmmgr(time(NULL));
1010 return CALENDAR_ERROR_NONE;