Fixed to compare after conversion to localtime in alert_localtime logic
[platform/core/pim/calendar-service.git] / server / cal_server_alarm.c
index 426c8f3..3ee36be 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Calendar Service
  *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <stdlib.h>
-
-#include <appsvc.h>
+#include <sys/time.h>
+#include <unistd.h>
 #include <alarm.h>
 #include <vconf.h>
+#include <app.h>
 
+#include "calendar.h"
+#include "cal_typedef.h"
 #include "cal_internal.h"
-#include "calendar2.h"
 #include "cal_time.h"
-#include "cal_typedef.h"
 #include "cal_inotify.h"
-
 #include "cal_db_util.h"
 #include "cal_db.h"
 #include "cal_db_query.h"
-#include "cal_server_reminder.h"
+#include "cal_server_service.h"
+#include "cal_server_ondemand.h"
+#include "cal_server_dbus.h"
+#include "cal_server_alarm.h"
+
+#define CAL_SERVER_ALARM_THREAD_NAME "cal_server_alarm"
+
+GThread *_cal_server_alarm_thread = NULL;
+GCond _cal_server_alarm_cond;
+GMutex _cal_server_alarm_mutex;
+static bool server_killed = false;
+static bool signal_called = false;
+
+struct _alarm_data_s {
+       int event_id;
+       long long int alert_utime; /* to compare */
+       int unit;
+       int tick;
+       int type; /* utime, localtime */
+       long long int time;
+       int record; /* todo, event */
+       char datetime[CAL_STR_SHORT_LEN32];
+       int system_type;
+};
+
+struct alarm_ud {
+       GList *alarm_list;
+};
 
-static struct timeval stv; // check time
-static struct timeval etv; // check time
+/* this api is necessary for repeat instance. */
+static int cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       int ret = 0;
 
-static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id);
+       ret = cal_db_util_begin_trans();
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_begin_trans() Fail");
+               return CALENDAR_ERROR_DB_FAILED;
+               /* LCOV_EXCL_STOP */
+       }
+
+       DBG("alarm_id(%d)", alarm_id);
 
-static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
+       snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
+                       CAL_TABLE_ALARM, alarm_id);
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+       cal_db_util_end_trans(true);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
 {
        int ret;
 
        DBG("remove alarm id(%d)", alarm_id);
-       __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
+       cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
        ret = alarmmgr_remove_alarm(alarm_id);
-       if (ret != ALARMMGR_RESULT_SUCCESS)
-       {
-               ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               /* LCOV_EXCL_START */
+               ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
                return ret;
+               /* LCOV_EXCL_STOP */
        }
        return CALENDAR_ERROR_NONE;
 }
 
-struct _normal_data_s
+static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
 {
-       int id;
-       long long int alarm_utime;
-       int tick;
-       int unit;
-       int alarm_id;
-       int record_type;
-};
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       int ret = 0;
 
-struct _allday_data_s
-{
-       int id;
-       int alarm_datetime;
-       int tick;
-       int unit;
-       int alarm_id;
-       int record_type;
-};
-
-static int __cal_server_alarm_get_next_list_normal_event(long long int from_utime, long long int to_utime, GList **list, int *count)
-{
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-
-       DBG("searching normal event (%lld) ~ (%lld)", from_utime, to_utime);
-
-       snprintf(query, sizeof(query),
-                       "SELECT A.event_id, B.alarm_time, "
-                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
-                       "FROM %s as A, "                       // A is normal instance
-                       "%s as B ON A.event_id = B.event_id, " // B is alarm
-                       "%s as C ON B.event_id = C.id "        // c is schedule
-                       "WHERE C.has_alarm == 1 AND C.type = %d "
-                       "AND B.remind_tick_unit = %d AND B.alarm_time = %lld "
-                       "UNION "
-                       "SELECT A.event_id, A.dtstart_utime - (B.remind_tick * B.remind_tick_unit), "
-                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
-                       "FROM %s as A, "                       // A is normal instance
-                       "%s as B ON A.event_id = B.event_id, " // B is alarm
-                       "%s as C ON B.event_id = C.id "        // c is schedule
-                       "WHERE C.has_alarm = 1 AND C.type = %d "
-                       "AND B.remind_tick_unit > %d "
-                       "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
-                       "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
-                       "ORDER BY (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit))",
-                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
-                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       from_utime, to_utime);
-
-       stmt = _cal_db_util_query_prepare(query);
-       if (NULL == stmt)
-       {
-               DBG("query[%s]", query);
-               ERR("_cal_db_util_query_prepare() Failed");
+       ret = cal_db_util_begin_trans();
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_begin_trans() Fail");
                return CALENDAR_ERROR_DB_FAILED;
+               /* LCOV_EXCL_STOP */
        }
 
-       *count = 0;
-       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
-       {
-               struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
-
-               index = 0;
-               nd->id = sqlite3_column_int(stmt, index++);
-               nd->alarm_utime = sqlite3_column_int64(stmt, index++);
-               nd->tick = sqlite3_column_int(stmt, index++);
-               nd->unit = sqlite3_column_int(stmt, index++);
-               nd->alarm_id = sqlite3_column_int(stmt, index++);
-
-               *list = g_list_append(*list, nd);
-               (*count)++;
+       DBG("Update alarm_id(%d) in alarm table", alarm_id);
+       snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
+                       "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
+                       CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
        }
-       sqlite3_finalize(stmt);
+       cal_db_util_end_trans(true);
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_server_alarm_get_next_list_normal_todo(long long int from_utime, long long int to_utime, GList **list, int *count)
+static time_t _make_time(struct tm *time)
 {
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-
-       DBG("searching normal todo (%lld) ~ (%lld)", from_utime, to_utime);
-
-       snprintf(query, sizeof(query),
-                       "SELECT B.id, A.alarm_time, "
-                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
-                       "FROM %s as A, "                          // A is alarm
-                       "%s as B ON A.event_id = B.id "           // B is schedule
-                       "WHERE B.has_alarm == 1 AND B.type = %d "
-                       "AND A.remind_tick_unit = %d AND A.alarm_time = %lld "
-                       "UNION "
-                       "SELECT B.id, B.dtend_utime - (A.remind_tick * A.remind_tick_unit), "
-                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
-                       "FROM %s as A, "                          // A is alarm
-                       "%s as B ON A.event_id = B.id "           // B is schedule
-                       "WHERE B.has_alarm = 1 AND B.type = %d "
-                       "AND A.remind_tick_unit > %d "
-                       "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
-                       "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld "
-                       "ORDER BY (B.dtend_utime - (A.remind_tick * A.remind_tick_unit))",
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       from_utime, to_utime);
+       time_t utc = mktime(time);
 
-       stmt = _cal_db_util_query_prepare(query);
-       if (NULL == stmt)
-       {
-               DBG("query[%s]", query);
-               ERR("_cal_db_util_query_prepare() Failed");
-               return CALENDAR_ERROR_DB_FAILED;
+       /* If an error occurs when isdst is 1, retry it after chaning isdst is 0 */
+       if (utc < 0 && time->tm_isdst != 0 ) {
+               time->tm_isdst = 0;
+               utc = mktime(time);
        }
+       return utc;
+}
 
-       *count = 0;
-       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
-       {
-               struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
+static long long int _get_event_alert_utime(const char *field, int event_id, time_t current)
+{
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT %s FROM %s "
+                       "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
+                       field, CAL_TABLE_UTIME_INSTANCE, event_id, field, current, field);
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
 
-               index = 0;
-               nd->id = sqlite3_column_int(stmt, index++);
-               nd->alarm_utime = sqlite3_column_int64(stmt, index++);
-               nd->tick = sqlite3_column_int(stmt, index++);
-               nd->unit = sqlite3_column_int(stmt, index++);
-               nd->alarm_id = sqlite3_column_int(stmt, index++);
+       long long int utime = 0;
+       if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
+               utime = sqlite3_column_int(stmt, 0);
 
-               *list = g_list_append(*list, nd);
-               (*count)++;
-       }
        sqlite3_finalize(stmt);
-       return CALENDAR_ERROR_NONE;
+       return utime;
 }
 
-static int __cal_server_alarm_get_next_list_allday_event(int from_datetime, int to_datetime, GList **list, int *count)
+static int _get_event_alert_localtime(const char *field, int event_id, time_t current)
 {
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-
-       DBG("searching allday (%d) ~ (%d)", from_datetime, to_datetime);
-
-       snprintf(query, sizeof(query),
-                       "SELECT A.event_id, B.alarm_time, "
-                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
-                       "FROM %s as A, "                       // A is allday instance
-                       "%s as B ON A.event_id = B.event_id, " // B is alarm
-                       "%s as C ON B.event_id = C.id "        // C is schedule
-                       "WHERE C.has_alarm == 1 AND C.type = %d "
-                       "AND B.remind_tick_unit = %d AND B.alarm_time = %d "
-                       "UNION "
-                       "SELECT A.event_id, A.dtstart_datetime, "
-                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
-                       "FROM %s as A, "                       // A is allday instance
-                       "%s as B ON A.event_id = B.event_id, " // B is alarm
-                       "%s as C ON B.event_id = C.id "        // C is schedule
-                       "WHERE C.has_alarm = 1 AND C.type = %d "
-                       "AND B.remind_tick_unit > %d "
-                       "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 > %d "
-                       "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 <= %d ",
-                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
-                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       from_datetime, to_datetime);
-
-       stmt = _cal_db_util_query_prepare(query);
-       if (NULL == stmt)
-       {
-               DBG("query[%s]", query);
-               ERR("_cal_db_util_query_prepare() Failed");
-               return CALENDAR_ERROR_DB_FAILED;
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       struct tm st = {0};
+       struct tm now_s = {0};
+       char buf[256] = {0};
+
+       localtime_r(&current, &now_s);
+       snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d", (int)(now_s.tm_year + 1900),
+                               (int)(now_s.tm_mon + 1), (int)now_s.tm_mday, (int)now_s.tm_hour,
+                               (int)now_s.tm_min, (int)now_s.tm_sec);
+       DBG("Current time : (%s)", buf);
+
+       snprintf(query, sizeof(query), "SELECT %s FROM %s "
+                       "WHERE event_id=%d AND (strftime('%%s', %s) - strftime('%%s', '%s') > 0) ORDER BY %s LIMIT 1",
+                       field, CAL_TABLE_LOCALTIME_INSTANCE, event_id, field, buf, field);
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return ret;
+               /* LCOV_EXCL_STOP */
        }
 
-       *count = 0;
-       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
-       {
-               struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
+       const char *datetime = NULL;
+       if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
+               datetime = (const char *)sqlite3_column_text(stmt, 0);
 
-               index = 0;
-               ad->id = sqlite3_column_int(stmt, index++);
-               ad->alarm_datetime = sqlite3_column_int(stmt, index++);
-               ad->tick = sqlite3_column_int(stmt, index++);
-               ad->unit = sqlite3_column_int(stmt, index++);
-               ad->alarm_id = sqlite3_column_int(stmt, index++);
 
-               *list = g_list_append(*list, ad);
-               (*count)++;
+       if (NULL == datetime || '\0' == *datetime) {
+               /* LCOV_EXCL_START */
+               ERR("Invalid datetime [%s]", datetime);
+               sqlite3_finalize(stmt);
+               return 0;
+               /* LCOV_EXCL_STOP */
        }
+
+       int y = 0, m = 0, d = 0;
+       int h = 0, n = 0, s = 0;
+       sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
        sqlite3_finalize(stmt);
-       return CALENDAR_ERROR_NONE;
+
+       st.tm_year = y - 1900;
+       st.tm_mon = m - 1;
+       st.tm_mday = d;
+       st.tm_hour = h;
+       st.tm_min = n;
+       st.tm_sec = s;
+       st.tm_isdst = cal_time_is_dst_savings();
+
+       return (long long int)_make_time(&st);
 }
 
-static int __cal_server_alarm_get_next_list_allday_todo(int from_datetime, int to_datetime, GList **list, int *count)
+static int64_t _get_todo_alert_utime(const char *field, int id, time_t now_t)
 {
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-
-       DBG("searching allday todo(%d) ~ (%d)", from_datetime, to_datetime);
-
-       snprintf(query, sizeof(query),
-                       "SELECT A.event_id, A.alarm_time, "
-                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
-                       "FROM %s as A, "                // A is alarm
-                       "%s as B ON A.event_id = B.id " // B is schedule
-                       "WHERE B.has_alarm == 1 AND B.type = %d "
-                       "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
-                       "UNION "
-                       "SELECT A.event_id, B.dtend_datetime, "
-                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
-                       "FROM %s as A, "                // A is alarm
-                       "%s as B ON A.event_id = B.id " // B is schedule
-                       "WHERE B.has_alarm = 1 AND B.type = %d "
-                       "AND A.remind_tick_unit > %d "
-                       "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 > %d "
-                       "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 <= %d ",
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       from_datetime, to_datetime);
-
-       stmt = _cal_db_util_query_prepare(query);
-       if (NULL == stmt)
-       {
-               DBG("query[%s]", query);
-               ERR("_cal_db_util_query_prepare() Failed");
-               return CALENDAR_ERROR_DB_FAILED;
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT %s FROM "CAL_TABLE_SCHEDULE" "
+                       "WHERE id=%d AND %s>%ld ORDER BY %s LIMIT 1", field, id, field, now_t, field);
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return ret;
+               /* LCOV_EXCL_STOP */
        }
 
-       *count = 0;
-       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
-       {
-               struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
-
-               index = 0;
-               ad->id = sqlite3_column_int(stmt, index++);
-               ad->alarm_datetime = sqlite3_column_int(stmt, index++);
-               ad->tick = sqlite3_column_int(stmt, index++);
-               ad->unit = sqlite3_column_int(stmt, index++);
-               ad->alarm_id = sqlite3_column_int(stmt, index++);
-
-               *list = g_list_append(*list, ad);
-               (*count)++;
+       int64_t utime = 0;
+       ret = cal_db_util_stmt_step(stmt);
+       switch (ret) {
+       case CAL_SQLITE_ROW:
+               utime = (int64_t)sqlite3_column_int64(stmt, 0);
+               break;
+               /* LCOV_EXCL_START
+       case SQLITE_DONE:
+               ERR("No data");
+               break;*/ //Svace:371986
+       default:
+               ERR("Invalid return(%d)", ret);
+               break;
+               /* LCOV_EXCL_STOP */
        }
+
        sqlite3_finalize(stmt);
-       return CALENDAR_ERROR_NONE;
+       return utime;
 }
 
-static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
+static int _get_todo_alert_localtime(const char *field, int event_id, time_t current)
 {
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    cal_db_util_error_e dbret = CAL_DB_OK;
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       struct tm st = {0};
+       struct tm now_s = {0};
+       char buf[256] = {0};
+
+       localtime_r(&current, &now_s);
+       snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d", (int)(now_s.tm_year + 1900),
+                               (int)(now_s.tm_mon + 1), (int)now_s.tm_mday, (int)now_s.tm_hour,
+                               (int)now_s.tm_min, (int)now_s.tm_sec);
+       DBG("Current time : (%s)", buf);
+
+       snprintf(query, sizeof(query), "SELECT %s FROM %s "
+                       "WHERE id=%d AND (strftime('%%s', %s) - strftime('%%s', '%s') > 0) ORDER BY %s LIMIT 1",
+                       field, CAL_TABLE_SCHEDULE, event_id, field, buf, field);
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
 
-       DBG("Update alarm_id(%d) in alarm table", alarm_id);
-       snprintf(query, sizeof(query), "UPDATE %s SET "
-                       "alarm_id = %d "
-                       "WHERE event_id = %d AND remind_tick = %d AND remind_tick_unit = %d",
-                       CAL_TABLE_ALARM,
-                       alarm_id,
-                       event_id, tick, unit);
-
-       dbret = _cal_db_util_query_exec(query);
-       if (CAL_DB_OK != dbret)
-       {
-               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
-               switch (dbret)
-               {
-               case CAL_DB_ERROR_NO_SPACE:
-                       return CALENDAR_ERROR_FILE_NO_SPACE;
-               default:
-                       return CALENDAR_ERROR_DB_FAILED;
-               }
+       const char *datetime = NULL;
+       if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
+               datetime = (const char *)sqlite3_column_text(stmt, 0);
+
+       if (NULL == datetime || '\0' == *datetime) {
+               /* LCOV_EXCL_START */
+               ERR("Invalid datetime [%s]", datetime);
+               sqlite3_finalize(stmt);
+               return 0;
+               /* LCOV_EXCL_STOP */
        }
 
-       return CALENDAR_ERROR_NONE;
-}
+       int y = 0, m = 0, d = 0;
+       int h = 0, n = 0, s = 0;
+       sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
+       sqlite3_finalize(stmt);
 
-static GFunc __cal_server_alarm_print_list_normal(gpointer data, gpointer user_data)
-{
-       struct _normal_data_s *normal = (struct _normal_data_s *)data;
-       DBG("%02d:%lld", normal->id, normal->alarm_utime);
-       return 0;
-}
+       st.tm_year = y - 1900;
+       st.tm_mon = m - 1;
+       st.tm_mday = d;
+       st.tm_hour = h;
+       st.tm_min = n;
+       st.tm_sec = s;
+       st.tm_isdst = cal_time_is_dst_savings();
 
-static GFunc __cal_server_alarm_print_list_allday_todo(gpointer data, gpointer user_data)
-{
-       struct _allday_data_s *allday = (struct _allday_data_s *)data;
-       DBG("%02d:%d", allday->id, allday->alarm_datetime);
-       return 0;
+       return (long long int)_make_time(&st);
 }
-
-static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **normal_list, GList **allday_list)
+/*
+ * time(NULL) is not appropriate as parameter.
+ * 1 seconds could be flowed before calling function.(1 sec time diff)
+ * so, searching DB is neccessary to find alert time.
+ */
+static int cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
 {
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-       struct _normal_data_s *nd;
-       struct _allday_data_s *ad;
-
-       snprintf(query, sizeof(query),
-                       "SELECT A.type, A.dtstart_type, A.dtend_type, B.remind_tick, B.remind_tick_unit "
-                       "FROM %s as A, "                // schedule
-                       "%s as B ON A.id = B.event_id " // alarm
-                       "WHERE B.alarm_id = %d",
-                       CAL_TABLE_SCHEDULE,
-                       CAL_TABLE_ALARM,
-                       alarm_id);
-
-       stmt = _cal_db_util_query_prepare(query);
-       if (NULL == stmt)
-       {
-               DBG("query[%s]", query);
-               ERR("_cal_db_util_query_prepare() Failed");
-               return CALENDAR_ERROR_DB_FAILED;
+       int ret = 0;
+       RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
+                       "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.type, B.dtstart_type, "
+                       "B.dtend_type FROM %s as A, %s as B ON A.event_id =B.id WHERE alarm_id =%d ",
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return ret;
+               /* LCOV_EXCL_STOP */
        }
 
+       int event_id = 0;
+       int unit = 0;
+       int tick = 0;
        int type = 0;
+       long long int utime = 0;
+       const char *datetime = NULL;
+       int record_type = 0;
        int dtstart_type = 0;
        int dtend_type = 0;
-       int tick = 0;
-       int unit = 0;
-       if (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
-       {
-               index = 0;
-               type = sqlite3_column_int(stmt, index++);
-               dtstart_type = sqlite3_column_int(stmt, index++);
-               dtend_type = sqlite3_column_int(stmt, index++);
-               tick = sqlite3_column_int(stmt, index++);
-               unit = sqlite3_column_int(stmt, index++);
+       struct tm st = {0};
+
+       if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               event_id = sqlite3_column_int(stmt, 0);
+               unit = sqlite3_column_int(stmt, 1);
+               tick = sqlite3_column_int(stmt, 2);
+               type = sqlite3_column_int(stmt, 3);
+               utime = sqlite3_column_int64(stmt, 4);
+               datetime = (const char *)sqlite3_column_text(stmt, 5);
+               record_type = sqlite3_column_int(stmt, 6);
+               dtstart_type = sqlite3_column_int(stmt, 7);
+               dtend_type = sqlite3_column_int(stmt, 8);
        }
-       else
-       {
-               ERR("No record");
-       }
-       sqlite3_finalize(stmt);
-       stmt = NULL;
-
-       if ((type == CALENDAR_BOOK_TYPE_EVENT && dtstart_type == CALENDAR_TIME_UTIME)
-                       || (type == CALENDAR_BOOK_TYPE_TODO && dtend_type == CALENDAR_TIME_UTIME))
-       {
-               long long int now_utime;
-               now_utime = _cal_time_get_now();
-               now_utime -= now_utime % 60;
-
-               snprintf(query, sizeof(query),
-                               "SELECT A.event_id, A.dtstart_utime, "
-                               "B.remind_tick, B.remind_tick_unit, "
-                               "C.type "
-                               "FROM %s as A, "                       // A is normal instance
-                               "%s as B ON A.event_id = B.event_id, " // B is alarm
-                               "%s as C ON B.event_id = C.id "        // c is schedule
-                               "WHERE C.has_alarm == 1 AND C.type = %d "
-                               "AND B.remind_tick_unit = %d "
-                               "AND B.alarm_time = %lld "
-                               "UNION "
-                               "SELECT A.event_id, A.dtstart_utime, "
-                               "B.remind_tick, B.remind_tick_unit, "
-                               "C.type "
-                               "FROM %s as A, "                       // A is normal instance
-                               "%s as B ON A.event_id = B.event_id, " // B is alarm
-                               "%s as C ON B.event_id = C.id "        // c is schedule
-                               "WHERE C.has_alarm = 1 AND C.type = %d "
-                               "AND B.remind_tick_unit > %d "
-                               "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
-                               "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
-                               "UNION "
-                               "SELECT B.id, B.dtend_utime, "
-                               "A.remind_tick, A.remind_tick_unit, "
-                               "B.type "
-                               "FROM %s as A, "                          // A is alarm
-                               "%s as B ON A.event_id = B.id "           // B is schedule
-                               "WHERE B.has_alarm == 1 AND B.type = %d "
-                               "AND A.remind_tick_unit = %d "
-                               "AND A.alarm_time = %lld "
-                               "UNION "
-                               "SELECT B.id, B.dtend_utime, "
-                               "A.remind_tick, A.remind_tick_unit, "
-                               "B.type "
-                               "FROM %s as A, "                          // A is alarm
-                               "%s as B ON A.event_id = B.id "           // B is schedule
-                               "WHERE B.has_alarm = 1 AND B.type = %d "
-                               "AND A.remind_tick_unit > %d "
-                               "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
-                               "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld ",
-                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_utime,
-                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_utime, now_utime + 60,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_utime,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_utime, now_utime + 60);
-
-               stmt = _cal_db_util_query_prepare(query);
-               if (NULL == stmt)
-               {
-                       DBG("query[%s]", query);
-                       ERR("_cal_db_util_query_prepare() Failed");
-                       return CALENDAR_ERROR_DB_FAILED;
-               }
 
-               while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
-               {
-                       index = 0;
-                       nd = calloc(1, sizeof(struct _normal_data_s));
-                       nd->id = sqlite3_column_int(stmt, index++);
-                       nd->alarm_utime = sqlite3_column_int64(stmt, index++); // dtstart, dtend
-                       nd->tick = sqlite3_column_int(stmt, index++);
-                       nd->unit = sqlite3_column_int(stmt, index++);
-                       nd->record_type = sqlite3_column_int(stmt, index++); // event, todo
-                       *normal_list = g_list_append(*normal_list, nd);
-                       DBG("(%d)", nd->id);
+       if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
+               if (CALENDAR_TIME_UTIME == type) {
+                       *tt_alert = utime;
+               } else {
+                       int y = 0, m = 0, d = 0;
+                       int h = 0, n = 0, s = 0;
+                       if (datetime) {
+                               sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
+
+                               st.tm_year = y - 1900;
+                               st.tm_mon = m - 1;
+                               st.tm_mday = d;
+                               st.tm_hour = h;
+                               st.tm_min = n;
+                               st.tm_sec = s;
+                               st.tm_isdst = cal_time_is_dst_savings();
+                               *tt_alert = _make_time(&st);
+                               DBG("datetime[%s] to %02d:%02d:%02d (%ld)", datetime, h, n, s, *tt_alert);
+                       }
                }
+               sqlite3_finalize(stmt);
+               return CALENDAR_ERROR_NONE;
        }
-       else
-       {
-               int now_datetime;
-               time_t now_timet = time(NULL);
-               struct tm start_tm = {0};
-               now_timet -= now_timet % 60;
-               gmtime_r(&now_timet, &start_tm);
-               now_datetime = (start_tm.tm_year + 1900) * 10000
-                       + (start_tm.tm_mon + 1) * 100
-                       + (start_tm.tm_mday);
-
-               snprintf(query, sizeof(query),
-                               "SELECT A.event_id, A.dtstart_datetime, "
-                               "B.remind_tick, B.remind_tick_unit, "
-                               "C.type "
-                               "FROM %s as A, "                       // A is allday instance
-                               "%s as B ON A.event_id = B.event_id, " // B is alarm
-                               "%s as C ON B.event_id = C.id "        // C is schedule
-                               "WHERE C.has_alarm == 1 AND C.type = %d "
-                               "AND B.remind_tick_unit = %d "
-                               "AND B.alarm_time = %d "
-                               "UNION "
-                               "SELECT A.event_id, A.dtstart_datetime, "
-                               "B.remind_tick, B.remind_tick_unit, "
-                               "C.type "
-                               "FROM %s as A, "                       // A is allday instance
-                               "%s as B ON A.event_id = B.event_id, " // B is alarm
-                               "%s as C ON B.event_id = C.id "        // C is schedule
-                               "WHERE C.has_alarm = 1 AND C.type = %d "
-                               "AND B.remind_tick_unit > %d "
-                               "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 = %d "
-                               "UNION "
-                               "SELECT A.event_id, B.dtend_datetime, "
-                               "A.remind_tick, A.remind_tick_unit, "
-                               "B.type "
-                               "FROM %s as A, "                // A is alarm
-                               "%s as B ON A.event_id = B.id " // B is schedule
-                               "WHERE B.has_alarm == 1 AND B.type = %d "
-                               "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
-                               "UNION "
-                               "SELECT A.event_id, B.dtend_datetime, "
-                               "A.remind_tick, A.remind_tick_unit, "
-                               "B.type "
-                               "FROM %s as A, "                // A is alarm
-                               "%s as B ON A.event_id = B.id " // B is schedule
-                               "WHERE B.has_alarm = 1 AND B.type = %d "
-                               "AND A.remind_tick_unit > %d "
-                               "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 = %d ",
-                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_datetime,
-                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_EVENT,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_datetime,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_datetime,
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
-                       CALENDAR_BOOK_TYPE_TODO,
-                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
-                       now_datetime);
-
-               stmt = _cal_db_util_query_prepare(query);
-               if (NULL == stmt)
-               {
-                       DBG("query[%s]", query);
-                       ERR("_cal_db_util_query_prepare() Failed");
-                       return CALENDAR_ERROR_DB_FAILED;
+       sqlite3_finalize(stmt);
+
+       time_t current = time(NULL);
+
+       current += (tick * unit);
+       current -= 2; /* in case time passed */
+
+       switch (record_type) {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               switch (dtstart_type) {
+               case CALENDAR_TIME_UTIME:
+                       utime = _get_event_alert_utime("dtstart_utime", event_id, current);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       utime = _get_event_alert_localtime("dtstart_datetime", event_id, current);
+                       break;
                }
+               break;
 
-               const unsigned char *temp;
-               while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
-               {
-                       index = 0;
-                       ad = calloc(1, sizeof(struct _allday_data_s));
-                       ad->id = sqlite3_column_int(stmt, index++);
-                       temp = sqlite3_column_text(stmt, index++); // dtstart, dtend
-                       ad->alarm_datetime = atoi((const char *)temp);
-                       ad->tick = sqlite3_column_int(stmt, index++);
-                       ad->unit = sqlite3_column_int(stmt, index++);
-                       ad->record_type = sqlite3_column_int(stmt, index++);
-                       *allday_list = g_list_append(*allday_list, ad);
+       case CALENDAR_BOOK_TYPE_TODO:
+               switch (dtend_type) {
+               case CALENDAR_TIME_UTIME:
+                       utime = _get_todo_alert_utime("dtend_utime", event_id, current);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       utime = _get_todo_alert_localtime("dtend_datetime", event_id, current);
+                       break;
                }
+               break;
        }
-       sqlite3_finalize(stmt);
+       *tt_alert = utime - (tick * unit);
+
+       DBG("alert_time(%ld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, tick, unit);
+
        return CALENDAR_ERROR_NONE;
 }
 
-// this api is necessary for repeat instance.
-static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
+/*
+ * bool get_all is
+ * true : to get all alarms including same time event.
+ * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
+ * false : to get only one alarm to register in alarm-manager.
+ * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
+ */
+static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
 {
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    cal_db_util_error_e dbret = CAL_DB_OK;
-
-       DBG("alarm_id(%d)", alarm_id);
-
-       snprintf(query, sizeof(query),
-                       "UPDATE %s SET alarm_id = 0 WHERE alarm_id = %d ",
-                       CAL_TABLE_ALARM, alarm_id);
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, A.alarm_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
+                       "AND A.alarm_utime %s %ld %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
+                       true == get_all ? "=" : ">", utime,
+                       true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
 
-       dbret = _cal_db_util_query_exec(query);
-       if (CAL_DB_OK != dbret)
-       {
-               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
-               switch (dbret)
-               {
-               case CAL_DB_ERROR_NO_SPACE:
-                       return CALENDAR_ERROR_FILE_NO_SPACE;
-               default:
-                       return CALENDAR_ERROR_DB_FAILED;
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
                }
-       }
 
-       return CALENDAR_ERROR_NONE;
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+               ad->alert_utime = ad->time;
+               if (false == get_all) break;
+       }
+       sqlite3_finalize(stmt);
 }
 
-static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit, char *type)
+static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
 {
-       int ret = CALENDAR_ERROR_NONE;
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-       const char *key;
-       const char *value;
-    sqlite3_stmt *stmt = NULL;
-    cal_db_util_error_e dbret = CAL_DB_OK;
-
-       if (NULL == pkgname)
-       {
-               ERR("Invalid parameter: pkgname is NULL");
-               return CALENDAR_ERROR_INVALID_PARAMETER;
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, A.alarm_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
+                       "AND A.alarm_datetime %s '%s' %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
+                       true == get_all ? "=" : ">", datetime,
+                       true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
        }
 
-       // get user key, value
-       snprintf(query, sizeof(query), "SELECT key, value FROM %s WHERE pkgname = '%s' ",
-                       CAL_REMINDER_ALERT, pkgname);
-    stmt = _cal_db_util_query_prepare(query);
-    if (NULL == stmt)
-    {
-        ERR("_cal_db_util_query_prepare() Failed");
-        return CALENDAR_ERROR_DB_FAILED;
-    }
-
-    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
-    {
-               index = 0;
-               key = (const char *)sqlite3_column_text(stmt, index++);
-               value = (const char *)sqlite3_column_text(stmt, index++);
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
+               }
+
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+
+               int y = 0, m = 0, d = 0;
+               int h = 0, n = 0, s = 0;
+               sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
+
+               struct tm st = {0};
+               st.tm_year = y - 1900;
+               st.tm_mon = m -1;
+               st.tm_mday = d;
+               st.tm_hour = h;
+               st.tm_min = n;
+               st.tm_sec = s;
+               st.tm_isdst = cal_time_is_dst_savings();
+               ad->alert_utime = (long long int)_make_time(&st);
+               if (false == get_all) break;
        }
+       sqlite3_finalize(stmt);
+}
 
-       // run appsvc
-       DBG("[%s][%s][%s][%s]", id, time, tick, unit);
-
-       bundle *b;
-       b = bundle_create();
-       appsvc_set_pkgname(b, pkgname);
-       appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
-       if (key && value) appsvc_add_data(b, key, value);
-       appsvc_add_data(b, "id", id);
-       appsvc_add_data(b, "time", time);
-       appsvc_add_data(b, "tick", tick);
-       appsvc_add_data(b, "unit", unit);
-       appsvc_add_data(b, "type", type);
-       ret = appsvc_run_service(b, 0, NULL, NULL);
-       bundle_free(b);
+static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
+{
+       int ret = 0;
+       /*
+        * A:alarm
+        * B:utime
+        */
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
+                       "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_UTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
+                       "ON A.event_id = B.event_id AND B.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit > %d "
+                       "AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       true == get_all ? "=" : ">", utime,
+                       true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
+               }
 
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+
+               ad->alert_utime = ad->time - (ad->tick * ad->unit);
+               if (false == get_all) break;
+       }
        sqlite3_finalize(stmt);
+}
 
-       // if no app, delete from the table
-       if (APPSVC_RET_ELAUNCH == ret)
-       {
-               DBG("Deleted no responce pkg[%s]", pkgname);
-               snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = '%s' ",
-                               CAL_REMINDER_ALERT, pkgname);
-               dbret = _cal_db_util_query_exec(query);
-               if (CAL_DB_OK != dbret)
-               {
-                       ERR("_cal_db_util_query_exec() failed(ret:%d)", ret);
-                       switch (dbret)
-                       {
-                       case CAL_DB_ERROR_NO_SPACE:
-                               return CALENDAR_ERROR_FILE_NO_SPACE;
-                       default:
-                               return CALENDAR_ERROR_DB_FAILED;
-                       }
+static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
+{
+       int ret = 0;
+       /*
+        * A:alarm
+        * B:localtime
+        */
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
+                       "A.alarm_type, A.alarm_utime, B.dtstart_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_LOCALTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
+                       "ON A.event_id = B.event_id AND B.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit >%d AND "
+                       "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       datetime, true == get_all ? "=" : ">",
+                       true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
                }
 
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+
+               int y = 0, m = 0, d = 0;
+               int h = 0, n = 0, s = 0;
+               sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
+
+               struct tm st = {0};
+               st.tm_year = y - 1900;
+               st.tm_mon = m -1;
+               st.tm_mday = d;
+               st.tm_hour = h;
+               st.tm_min = n;
+               st.tm_sec = s;
+               st.tm_isdst = cal_time_is_dst_savings();
+               ad->alert_utime = (long long int)_make_time(&st) - (ad->tick * ad->unit);
+               if (false == get_all) break;
        }
-       return CALENDAR_ERROR_NONE;
+       sqlite3_finalize(stmt);
 }
 
-static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit, char *type)
+static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
 {
-       int index;
-    char query[CAL_DB_SQL_MAX_LEN] = {0};
-    sqlite3_stmt *stmt = NULL;
-
-       snprintf(query, sizeof(query), "SELECT pkgname FROM %s WHERE onoff = 1 ",
-                       CAL_REMINDER_ALERT);
-    stmt = _cal_db_util_query_prepare(query);
-    if (NULL == stmt)
-    {
-        ERR("_cal_db_util_query_prepare() Failed");
-        return CALENDAR_ERROR_DB_FAILED;
-    }
-
-    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
-    {
-               index = 0;
-               const char *pkgname = (const char *)sqlite3_column_text(stmt, index++);
-               DBG("pkgname[%s]", pkgname);
-               __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit, type);
+       int ret = 0;
+       /*
+        * A:alarm
+        * S:todo(utime)
+        */
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, S.dtend_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE A.remind_tick_unit > %d AND S.type = %d "
+                       "AND (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
+                       true == get_all ? "=" : ">", utime,
+                       true == get_all ? "" : "ORDER BY (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
        }
-       sqlite3_finalize(stmt);
 
-       return CALENDAR_ERROR_NONE;
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
+               }
+
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+
+               ad->alert_utime = ad->time - (ad->tick * ad->unit);
+               if (false == get_all) break;
+       }
+       sqlite3_finalize(stmt);
 }
 
-static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list, GList *allday_list)
+static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
 {
-       char buf_id[128] = {0};
-       char buf_time[128] = {0};
-       char buf_tick[128] = {0};
-       char buf_unit[128] = {0};
-       char buf_type[128] = {0};
-       GList *l = NULL;
-
-       l = g_list_first(normal_list);
-       if (NULL == l) DBG("normal list is NULL");
-       while (l)
-       {
-               struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
-               snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
-               snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
-               snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
-               snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
-               snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
-
-               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
-               l = g_list_next(l);
+       int ret = 0;
+       /*
+        * A:alarm
+        * B:todo(localtime)
+        */
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
+                       "A.alarm_type,A.alarm_utime,B.dtend_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as B ON A.event_id = B.id "
+                       "WHERE A.remind_tick_unit >%d AND B.type =%d "
+                       "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
+                       datetime, true == get_all ? "=" : ">",
+                       true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
+
+       sqlite3_stmt *stmt = NULL;
+       ret = cal_db_util_query_prepare(query, &stmt);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_prepare() Fail(%d)", ret);
+               SECURE("query[%s]", query);
+               return;
+               /* LCOV_EXCL_STOP */
        }
 
-       l = NULL;
-       l = g_list_first(allday_list);
-       if (NULL == l) DBG("allday list is NULL");
-       while (l)
-       {
-               struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
-               snprintf(buf_id, sizeof(buf_id), "%d",  ad->id);
-               snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
-               snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
-               snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
-               snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
-
-               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
-               l = g_list_next(l);
+       while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
+               struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
+               if (NULL == ad) {
+                       /* LCOV_EXCL_START */
+                       ERR("calloc() Fail");
+                       sqlite3_finalize(stmt);
+                       return;
+                       /* LCOV_EXCL_STOP */
+               }
+
+               ad->event_id = sqlite3_column_int(stmt, 0);
+               ad->unit = sqlite3_column_int(stmt, 1);
+               ad->tick = sqlite3_column_int(stmt, 2);
+               ad->type = sqlite3_column_int(stmt, 3);
+               ad->time = (long long int)sqlite3_column_int64(stmt, 4);
+               snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
+               *l = g_list_append(*l, ad);
+               DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
+                               ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
+
+               int y = 0, m = 0, d = 0;
+               int h = 0, n = 0, s = 0;
+               sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
+
+               struct tm st = {0};
+               st.tm_year = y - 1900;
+               st.tm_mon = m -1;
+               st.tm_mday = d;
+               st.tm_hour = h;
+               st.tm_min = n;
+               st.tm_sec = s;
+               st.tm_isdst = cal_time_is_dst_savings();
+               ad->alert_utime = (long long int)_make_time(&st) - (ad->tick * ad->unit);
+               if (false == get_all) break;
        }
-       return CALENDAR_ERROR_NONE;
+       sqlite3_finalize(stmt);
 }
 
-static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
+static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
 {
-       int ret;
-       int alarm_id;
-       struct _normal_data_s *nd;
+       int ret = 0;
+       CAL_FN_CALL();
+       RET_IF(NULL == out_l);
 
-       GList *l = g_list_first(normal_list);
+       tzset();
+       struct tm st_local = {0};
+       localtime_r(&utime, &st_local);
 
-       // try to save the first record.
-       // if alarm id exists, it means updated record is not earilier than already registerd one.
-       nd = (struct _normal_data_s *)l->data;
-       if (NULL == nd)
-       {
-               ERR("No data");
-               return CALENDAR_ERROR_DB_FAILED;
-       }
+       char datetime[CAL_STR_SHORT_LEN32] = {0};
+       ret = snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
+                       st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
+                       st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
 
-       if (nd->alarm_id > 0)
-       {
-               DBG("Already registered this id");
-               return CALENDAR_ERROR_NONE;
+       if(ret < 0){
+               WARN("datetime is truncated (%s)",datetime);
        }
 
-       DBG("new is earilier than registered.");
+       DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
 
-       // clear all alarm which set by mine.
-       ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
-       if (ret != ALARMMGR_RESULT_SUCCESS)
-       {
-               ERR("alarmmgr_enum_alarm_ids() failed");
-               return ret;
-       }
+       GList *l = NULL;
 
-       // register new list
-       long long int mod_alarm_utime; // del seconds
-       mod_alarm_utime = nd->alarm_utime - (nd->alarm_utime % 60);
-//     ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(mod_alarm_utime - now_utime), 0, NULL, &alarm_id);
+       _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
+       _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
+       _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
 
-///////////////////////////////////////
-       alarm_entry_t *alarm_info = NULL;
-       alarm_info = alarmmgr_create_alarm();
-       if (NULL == alarm_info)
-       {
-               ERR("Failed to create alarm");
-               return CALENDAR_ERROR_DB_FAILED;
-       }
-       char *tzid = NULL;
-       tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
-
-       alarm_date_t alarm_date;
-       _cal_time_utoi(mod_alarm_utime, tzid,
-                       &alarm_date.year, &alarm_date.month, &alarm_date.day,
-                       &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
-       DBG("tzid[%s] datetime(%04d/%02d/%02d %02d:%02d:%02d", tzid,
-                       alarm_date.year, alarm_date.month, alarm_date.day,
-                       alarm_date.hour, alarm_date.min, alarm_date.sec);
-
-       alarmmgr_set_time(alarm_info, alarm_date);
-       ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
-       if (tzid) free(tzid);
-///////////////////////////////////////
+       _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
+       _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
+       _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
 
-       if (ret < 0)
-       {
-               ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
-               return ret;
-       }
-       DBG("Get normal alarmmgr id (%d)", alarm_id);
-       __cal_server_alarm_update_alarm_id(alarm_id, nd->id, nd->tick, nd->unit);
+       *out_l = l;
+}
 
-       return CALENDAR_ERROR_NONE;
+static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
+{
+       struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
+       struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
+       DBG("%lld) > (%lld)", p1->alert_utime, p2->alert_utime);
+
+       return p1->alert_utime < p2->alert_utime ? -1 : 1;
 }
 
-static int __cal_server_alarm_register_next_allday(time_t now_timet, GList *allday_list)
+static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
 {
-       int ret;
-       int alarm_id;
-       struct _allday_data_s *ad;
-       time_t alarm_timet;
-
-       GList *l = g_list_first(allday_list);
-       alarm_id = 0;
-       ad = (struct _allday_data_s *)l->data;
-       if (NULL == ad)
-       {
-               ERR("No data");
-               return CALENDAR_ERROR_DB_FAILED;
-       }
+       struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
+       DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s] alert_utime[%lld]",
+                       ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime, ad->alert_utime);
+       return 0;
+}
 
-       if (ad->alarm_id > 0)
-       {
-               DBG("Already registered this id");
-               return CALENDAR_ERROR_NONE;
-       }
+static int _cal_server_alarm_register(GList *alarm_list)
+{
+       CAL_FN_CALL();
+       RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
 
-       DBG("new is earilier than registered.");
+       int ret = CALENDAR_ERROR_NONE;
+       GList *l = g_list_first(alarm_list);
+       RETV_IF(NULL == l, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
+       RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
 
-       // clear all alarm which set by mine.
-       ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
-       if (ret != ALARMMGR_RESULT_SUCCESS)
-       {
-               ERR("alarmmgr_enum_alarm_ids() failed");
+       /* clear all alarm which set by mine. */
+       ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               /* LCOV_EXCL_START */
+               ERR("alarmmgr_enum_alarm_ids() Fail");
                return ret;
+               /* LCOV_EXCL_STOP */
        }
 
-       // register new list
-//     ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(alarm_timet - (ad->tick * ad->unit) - now_timet), 0, NULL, &alarm_id);
-
-///////////////////////////////////////
+       time_t mod_time = (time_t)ad->alert_utime;
        alarm_entry_t *alarm_info = NULL;
        alarm_info = alarmmgr_create_alarm();
-       if (NULL == alarm_info)
-       {
+       if (NULL == alarm_info) {
+               /* LCOV_EXCL_START */
                ERR("Failed to create alarm");
                return CALENDAR_ERROR_DB_FAILED;
+               /* LCOV_EXCL_STOP */
+       }
+       tzset();
+       struct tm st_alarm = {0};
+
+       switch (ad->system_type) {
+       case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
+               gmtime_r(&mod_time, &st_alarm);
+               break;
+
+       default:
+               tzset();
+               localtime_r(&mod_time, &st_alarm);
+               break;
        }
-       char *tzid = NULL;
-       tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
-
-       alarm_date_t alarm_date;
-       _cal_time_utoi((long long int)(alarm_timet - (ad->tick * ad->unit)), tzid,
-                       &alarm_date.year, &alarm_date.month, &alarm_date.day,
-                       &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
-       alarmmgr_set_time(alarm_info, alarm_date);
-       ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
-       if (tzid) free(tzid);
-///////////////////////////////////////
 
-       if (ret < 0)
-       {
-               ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
+       alarm_date_t date = {0};
+       date.year = st_alarm.tm_year + 1900;
+       date.month = st_alarm.tm_mon + 1;
+       date.day = st_alarm.tm_mday;
+       date.hour = st_alarm.tm_hour;
+       date.min = st_alarm.tm_min;
+       date.sec = st_alarm.tm_sec;
+       alarmmgr_set_time(alarm_info, date);
+       DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
+                       ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
+                       ad->time, ad->datetime, ad->tick, ad->unit);
+
+       int alarm_id = 0;
+       ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
+       if (ret < 0) {
+               /* LCOV_EXCL_START */
+               ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
+               alarmmgr_free_alarm(alarm_info);
                return ret;
+               /* LCOV_EXCL_STOP */
        }
-       DBG("Get allday alarmmgr id (%d)", alarm_id);
-       __cal_server_alarm_update_alarm_id(alarm_id, ad->id, ad->tick, ad->unit);
-
+       DBG("alarmmgr id (%d)", alarm_id);
+       _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
+       alarmmgr_free_alarm(alarm_info);
        return CALENDAR_ERROR_NONE;
 }
 
-static gint __cal_server_alarm_normal_sort_cb(gconstpointer a, gconstpointer b)
+static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
 {
-       struct _normal_data_s *p1 = (struct _normal_data_s *)a;
-       struct _normal_data_s *p2 = (struct _normal_data_s *)b;
+       CAL_FN_CALL();
 
-       return p1->alarm_utime - p2->alarm_utime > 0 ? 1 : -1;
-}
+       int ret = 0;
+       int i;
 
-static gint __cal_server_alarm_allday_sort_cb(gconstpointer a, gconstpointer b)
-{
-       struct _allday_data_s *p1 = (struct _allday_data_s *)a;
-       struct _allday_data_s *p2 = (struct _allday_data_s *)b;
+       RETV_IF(NULL == user_data, true);
 
-       return p1->alarm_datetime - p2->alarm_datetime > 0 ? 1 : -1;
-}
+       char *mime = NULL;
+       ret = app_control_get_mime(app_control, &mime);
+       RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
 
-static int __cal_server_alarm_register_with_alarmmgr(long long int now_utime)
-{
-       GList *normal_list = NULL;
-       GList *allday_list = NULL;
-       int event_count;
-       int todo_count;
-       int loop_count;
-
-       gettimeofday(&stv, NULL); // check time
-
-       // for normal
-       long long int from_utime, to_utime;
-
-       event_count = 0;
-       todo_count = 0;
-       to_utime = now_utime - (now_utime %  60) + 60;
-
-       // searching 3months, next 6months, next 12months
-       for (loop_count = 1; loop_count < 4; loop_count++)
-       {
-               from_utime = to_utime;
-               to_utime = from_utime + (60 * 60 * 24 * 30 * 3 * loop_count);
-               __cal_server_alarm_get_next_list_normal_event(from_utime, to_utime, &normal_list, &event_count);
-               __cal_server_alarm_get_next_list_normal_todo(from_utime, to_utime, &normal_list, &todo_count);
-               if (event_count + todo_count > 0)
-               {
-                       break;
-               }
+       const char *reminder_mime = "application/x-tizen.calendar.reminder";
+       if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
+               DBG("get mime[%s] is not [%s]", mime, reminder_mime);
+               free(mime);
+               return true;
+       }
+       free(mime);
+
+       struct alarm_ud *au = (struct alarm_ud *)user_data;
+       GList *alarm_list = au->alarm_list;
+       if (NULL == alarm_list) {
+               /* LCOV_EXCL_START */
+               ERR("No list");
+               return true;
+               /* LCOV_EXCL_STOP */
+       }
+       int len = 0;
+       len = g_list_length(alarm_list);
+       if (0 == len) {
+               DBG("len is 0, no alarm list");
+               return true;
        }
-       DBG("event count(%d) todo count(%d)", event_count, todo_count);
-
-       if (event_count + todo_count > 0)
-       {
-               normal_list = g_list_sort(normal_list, __cal_server_alarm_normal_sort_cb);
-               DBG("after sorting");
-               g_list_foreach(normal_list, (GFunc)__cal_server_alarm_print_list_normal, NULL);
-               __cal_server_alarm_register_next_normal(now_utime, normal_list);
 
+       app_control_h ac = NULL;
+       ret = app_control_create(&ac);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_create() Fail(%d)", ret);
+               return true;
+               /* LCOV_EXCL_STOP */
+       }
+       ret = app_control_set_operation(ac,  APP_CONTROL_OPERATION_DEFAULT);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_create() Fail(%d)", ret);
+               app_control_destroy(ac);
+               return true;
+               /* LCOV_EXCL_STOP */
        }
-       if (normal_list)
-       {
-               g_list_free_full(normal_list, free);
-               normal_list = NULL;
+       ret = app_control_set_app_id(ac, package);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_set_app_id() Fail(%d)", ret);
+               app_control_destroy(ac);
+               return true;
+               /* LCOV_EXCL_STOP */
        }
 
-       // for allday
-       DBG("allday");
-       time_t now_timet;
-       time_t from_timet, to_timet;
-       int from_datetime, to_datetime;
-       struct tm datetime_tm;
-       now_timet = (time_t)now_utime;
-
-       event_count = 0;
-       todo_count = 0;
-       to_timet = now_timet;
-
-       // searching 3months, next 6months, next 12months
-       for (loop_count = 1; loop_count < 4; loop_count++)
-       {
-               from_timet = to_timet;
-               gmtime_r(&from_timet, &datetime_tm);
-               from_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
-
-               to_timet = from_timet + (60 * 60 * 24 * 30 * 3 * loop_count);
-               gmtime_r(&to_timet, &datetime_tm);
-               to_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
-
-               __cal_server_alarm_get_next_list_allday_event(from_datetime, to_datetime, &allday_list, &event_count);
-               __cal_server_alarm_get_next_list_allday_todo(from_datetime, to_datetime, &allday_list, &todo_count);
-
-               if (event_count + todo_count > 0)
-               {
+       char **ids = NULL;
+       ids = calloc(len, sizeof(char *));
+       if (NULL == ids) {
+               /* LCOV_EXCL_START */
+               ERR("calloc() Fail");
+               app_control_destroy(ac);
+               return true;
+               /* LCOV_EXCL_STOP */
+       }
+       GList *cursor = g_list_first(alarm_list);
+       for (i = 0; i < len; i++) {
+               if (NULL == cursor) {
+                       ERR("cursor is NULL");
                        break;
                }
+               struct _alarm_data_s *ad = (struct _alarm_data_s *)cursor->data;
+               if (NULL == ad) {
+                       WARN("No data");
+                       cursor = g_list_next(cursor);
+                       continue;
+               }
+               DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
+                               package, ad->time, ad->tick, ad->unit, ad->record);
+
+               int slen = 0;
+               char extra[CAL_STR_MIDDLE_LEN] = {0};
+               slen = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
+               slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%lld", "time", ad->time);
+               slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "tick", ad->tick);
+               slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "unit", ad->unit);
+               slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "type", ad->record);
+
+               /*
+                * key: id, value: id=4&time=123123&..
+                */
+               char buf_id[CAL_STR_MIDDLE_LEN] = {0};
+               snprintf(buf_id, sizeof(buf_id), "%d", ad->event_id);
+               app_control_add_extra_data(ac, buf_id, extra);
+               DBG("value[%s] id[%s]", extra, buf_id);
+
+               /* append ids */
+               ids[i] = strdup(buf_id);
+
+               cursor = g_list_next(cursor);
        }
-       DBG("event count(%d) todo count(%d)", event_count, todo_count);
-
-       if (event_count + todo_count > 0)
-       {
-               allday_list = g_list_sort(allday_list, __cal_server_alarm_allday_sort_cb);
-               DBG("after sorting");
-               g_list_foreach(allday_list, (GFunc)__cal_server_alarm_print_list_allday_todo, NULL);
-               __cal_server_alarm_register_next_allday(now_timet, allday_list);
-       }
-       if (allday_list)
-       {
-               g_list_free_full(allday_list, free);
-               allday_list = NULL;
+       app_control_add_extra_data_array(ac, "ids", (const char **)ids, len);
+       app_control_send_launch_request(ac, NULL, NULL);
+       app_control_destroy(ac);
+
+       for (i = 0; i < len; i++) {
+               free(ids[i]);
+               ids[i] = NULL;
        }
+       free(ids);
 
-       int diff;
-       gettimeofday(&etv, NULL);
-       diff = ((int)etv.tv_sec *1000 + (int)etv.tv_usec/1000)
-               -((int)stv.tv_sec *1000 + (int)stv.tv_usec/1000);
-       DBG("registering time diff %ld(%d.%d)",diff, diff/1000, diff%1000); // time check
-       return 0;
+       return true;
 }
 
-static int __cal_server_alarm_callback(char *id, char *time, char *tick, char *unit, char *type)
+static void _cal_server_alarm_noti_with_control(GList *alarm_list)
 {
-       _cal_server_reminder_add_callback_data("id", id);
-       _cal_server_reminder_add_callback_data("time", time);
-       _cal_server_reminder_add_callback_data("tick", tick);
-       _cal_server_reminder_add_callback_data("unit", unit);
-       _cal_server_reminder_add_callback_data("type", type);
+       CAL_FN_CALL();
+
+       int ret = 0;
+       RETM_IF(NULL == alarm_list, "No alarm list");
+
+       app_control_h app_control = NULL;
+       ret = app_control_create(&app_control);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_create() Fail(%d)", ret);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+       ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_set_operation() Fail(%d)", ret);
+               app_control_destroy(app_control);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+       ret = app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_set_mime() Fail(%d)", ret);
+               app_control_destroy(app_control);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
 
-       return CALENDAR_ERROR_NONE;
+       struct alarm_ud *au = calloc(1, sizeof(struct alarm_ud));
+       if (NULL == au) {
+               /* LCOV_EXCL_START */
+               ERR("calloc() Fail");
+               app_control_destroy(app_control);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+       au->alarm_list = alarm_list;
+       ret = app_control_foreach_app_matched(app_control, __app_matched_cb, au);
+       if (APP_CONTROL_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("app_control_foreach_app_matched() Fail(%d)", ret);
+               free(au);
+               app_control_destroy(app_control);
+               return;
+               /* LCOV_EXCL_STOP */
+       }
+       free(au);
+       app_control_destroy(app_control);
 }
 
-static int __cal_server_alarm_noti_callback(int alarm_id, GList *normal_list, GList *allday_list)
+static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
 {
-       char buf_id[128] = {0};
-       char buf_time[128] = {0};
-       char buf_tick[128] = {0};
-       char buf_unit[128] = {0};
-       char buf_type[128] = {0};
-       GList *l = NULL;
+       RETM_IF(NULL == alarm_list, "No alarm list");
+
+       GList *l = g_list_first(alarm_list);
+       while (l) {
+               struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
+               if (NULL == ad) {
+                       WARN("No data");
+                       l = g_list_next(l);
+                       continue;
+               }
+               DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
+                               ad->time, ad->tick, ad->unit, ad->record);
+
+               int len = 0;
+               char extra[CAL_STR_MIDDLE_LEN] = {0};
+               len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
+               len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
+               len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
+               len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
+               len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
+               cal_dbus_publish_reminder(len, extra);
 
-       l = g_list_first(normal_list);
-       if (NULL == l) DBG("normal list is NULL");
-       while (l)
-       {
-               struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
-               snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
-               snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
-               snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
-               snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
-               snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
-
-               __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
-               _cal_server_reminder_publish();
                l = g_list_next(l);
        }
+}
 
-       l = NULL;
-       l = g_list_first(allday_list);
-       if (NULL == l) DBG("allday list is NULL");
-       while (l)
-       {
-               struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
-               snprintf(buf_id, sizeof(buf_id), "%d",  ad->id);
-               snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
-               snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
-               snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
-               snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
-
-               __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
-               _cal_server_reminder_publish();
-               l = g_list_next(l);
-       }
-       return 0;
+static void cal_server_alarm_register_next_alarm(time_t utime)
+{
+       CAL_FN_CALL();
+
+       GList *l = NULL;
+       _cal_server_alarm_get_latest(utime, false, &l);
+       if (NULL == l)
+               return;
+
+       l = g_list_sort(l, _cal_server_alarm_sort_cb);
+       g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
+       _cal_server_alarm_register(l);
+
+       g_list_free_full(l, free);
 }
 
-static int _alert_cb(alarm_id_t alarm_id, void *data)
+static void cal_server_alarm_alert(time_t tt_alert)
 {
-       GList *normal_list = NULL;
-       GList *allday_list = NULL;
-
-       __cal_server_alarm_get_list_with_alarmmgr_id(alarm_id, &normal_list, &allday_list);
-       __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
-       __cal_server_alarm_noti_with_appsvc(alarm_id, normal_list, allday_list);
-       __cal_server_alarm_noti_callback(alarm_id, normal_list, allday_list);
-
-       if (normal_list)
-       {
-               g_list_free_full(normal_list, free);
-               normal_list = NULL;
-       }
-       if (allday_list)
-       {
-               g_list_free_full(allday_list, free);
-               allday_list = NULL;
-       }
+       GList *l = NULL;
+       _cal_server_alarm_get_latest(tt_alert, true, &l);
+       if (NULL == l)
+               return;
 
-       __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
-       return 0;
+       _cal_server_alarm_noti_with_callback(l);
+       _cal_server_alarm_noti_with_control(l);
+       g_list_free_full(l, free);
 }
 
-////////////////////////////////////////////////////////////////////
-static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
+static int _alert_cb(alarm_id_t alarm_id, void *data)
 {
-       time_t t;
-       if (node) {
-               t = vconf_keynode_get_int(node);
-       }
-       else
-       {
-               vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, (int *)&t);
-       }
+       CAL_FN_CALL();
+       DBG("alarm_id (%d)", (int)alarm_id);
+
+       time_t tt_alert = 0;
+       cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
+       cal_server_alarm_alert(tt_alert);
+       cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
+       cal_server_alarm_start();
+       return 0;
+}
 
-       DBG("systme changed time(%ld)", t);
-       __cal_server_alarm_register_with_alarmmgr((long long int)t);
+static void _timechanged_cb(keynode_t *node, void *data)
+{
+       cal_server_alarm_alert(time(NULL));
+       cal_server_alarm_start();
 }
 
-int __cal_server_alarm_set_timechange(void)
+static void _cal_server_alarm_set_timechange(void)
 {
-       int ret;
+       vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, _timechanged_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, _timechanged_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE, _timechanged_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT, _timechanged_cb, NULL);
+}
 
-       ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIMECHANGE,
-                       __cal_server_alarm_timechange_cb, NULL);
-       if (ret < 0)
-       {
-               ERR("vconf_ignore_key_changed() failed");
-               return ret;
-       }
-       return CALENDAR_ERROR_NONE;
+static void _cal_server_alarm_unset_timechange(void)
+{
+       vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, _timechanged_cb);
+       vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, _timechanged_cb);
+       vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE, _timechanged_cb);
+       vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT, _timechanged_cb);
 }
 
-static void __changed_cb(const char* view_uri, void* data)
+static void _changed_cb(const char* view_uri, void* data)
 {
-       __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
+       DBG("Receive alarm change signal");
+       cal_server_alarm_start();
 }
 
-static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
+static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
 {
-       _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
-       _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
+       cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_FILE_EVENT, callback, NULL);
+       cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_FILE_TODO, callback, NULL);
        return 0;
 }
 
-int _cal_server_alarm(void)
+static void _cal_server_alarm_unset_inotify(calendar_db_changed_cb callback)
 {
-       int ret;
+       cal_inotify_unsubscribe(CAL_NOTI_FILE_EVENT, callback, NULL);
+       cal_inotify_unsubscribe(CAL_NOTI_FILE_TODO, callback, NULL);
+}
 
-       __cal_server_alarm_set_timechange();
-       __cal_server_alarm_set_inotify(__changed_cb);
+static int cal_server_alarm_init(void)
+{
+       int ret = 0;
 
-       ret = alarmmgr_init("calendar-service");
-       retvm_if(ret < 0, ret, "alarmmgr_init() failed");
+       _cal_server_alarm_set_timechange();
+       _cal_server_alarm_set_inotify(_changed_cb);
 
        ret = alarmmgr_set_cb(_alert_cb, NULL);
-       retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
+       if (ret < 0) {
+               /* LCOV_EXCL_START */
+               ERR("alarmmgr_set_cb() Fail(%d)", ret);
+               return CALENDAR_ERROR_SYSTEM;
+               /* LCOV_EXCL_STOP */
+       }
 
-       __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
+       ret = alarmmgr_init("calendar-service");
+       if (ret < 0) {
+               /* LCOV_EXCL_START */
+               ERR("alarmmgr_init() Fail(%d)", ret);
+               return CALENDAR_ERROR_SYSTEM;
+               /* LCOV_EXCL_STOP */
+       }
 
        return CALENDAR_ERROR_NONE;
 }
 
+static gpointer _cal_server_alarm_main(gpointer user_data)
+{
+       DBG("thread alarm: start");
+
+       int ret = 0;
+       bool is_initialized = false;
+
+       while (1) {
+               g_mutex_lock(&_cal_server_alarm_mutex);
+               /*
+                * While syncing with contacts,
+                * because calendar-service could be stopped by on-demand,
+                * holding on-demand is needed.
+                */
+               cal_server_ondemand_hold();
+
+               do {
+                       if (false == is_initialized) {
+                               ret = cal_server_alarm_init();
+                               if (CALENDAR_ERROR_NONE != ret) {
+                                       /* LCOV_EXCL_START */
+                                       ERR("cal_server_alarm_init() Fail(%d)", ret);
+                                       break;
+                                       /* LCOV_EXCL_STOP */
+                               }
+                               DBG("thread alarm: init");
+                               is_initialized = true;
+                       }
+
+                       ret = cal_connect();
+                       if (CALENDAR_ERROR_NONE != ret) {
+                               /* LCOV_EXCL_START */
+                               ERR("cal_connect() Fail(%d)", ret);
+                               break;
+                               /* LCOV_EXCL_STOP */
+                       }
+
+                       cal_server_alarm_register_next_alarm(time(NULL));
+                       cal_disconnect();
+
+               } while (0);
+
+               cal_server_ondemand_release();
+               cal_server_ondemand_start();
+
+               DBG("thread alarm: wait");
+               while (false == signal_called)
+                       g_cond_wait(&_cal_server_alarm_cond, &_cal_server_alarm_mutex);
+               signal_called = false;
+               g_mutex_unlock(&_cal_server_alarm_mutex);
+
+               if (server_killed)
+                       break;
+       }
+       DBG("thread alarm: end");
+       g_thread_exit(NULL);
+
+       return NULL;
+}
+
+void cal_server_alarm_send_signal(void)
+{
+       g_mutex_lock(&_cal_server_alarm_mutex);
+       signal_called = true;
+       g_cond_signal(&_cal_server_alarm_cond);
+       g_mutex_unlock(&_cal_server_alarm_mutex);
+}
+
+void cal_server_alarm_start(void)
+{
+       CAL_FN_CALL();
+
+       if (NULL == _cal_server_alarm_thread) {
+               g_mutex_init(&_cal_server_alarm_mutex);
+               g_cond_init(&_cal_server_alarm_cond);
+               _cal_server_alarm_thread = g_thread_new(CAL_SERVER_ALARM_THREAD_NAME,
+                               _cal_server_alarm_main, NULL);
+       }
+       cal_server_alarm_send_signal();
+}
+
+static void cal_server_alarm_deinit(void)
+{
+       alarmmgr_fini();
+       _cal_server_alarm_unset_inotify(_changed_cb);
+       _cal_server_alarm_unset_timechange();
+}
+
+void cal_server_alarm_end(void)
+{
+       CAL_FN_CALL();
+
+       server_killed = true;
+
+       cal_server_alarm_deinit();
+       cal_server_alarm_send_signal();
+
+       g_cond_clear(&_cal_server_alarm_cond);
+       g_thread_join(_cal_server_alarm_thread);
+       g_thread_unref(_cal_server_alarm_thread);
+       _cal_server_alarm_thread = NULL;
+}