4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include "cal_internal.h"
27 #include "calendar2.h"
29 #include "cal_typedef.h"
30 #include "cal_inotify.h"
32 #include "cal_db_util.h"
34 #include "cal_db_query.h"
35 #include "cal_server_reminder.h"
37 static struct timeval stv; // check time
38 static struct timeval etv; // check time
40 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id);
42 static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
46 DBG("remove alarm id(%d)", alarm_id);
47 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
48 ret = alarmmgr_remove_alarm(alarm_id);
49 if (ret != ALARMMGR_RESULT_SUCCESS)
51 ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
54 return CALENDAR_ERROR_NONE;
60 long long int alarm_utime;
77 static int __cal_server_alarm_get_next_list_normal_event(long long int from_utime, long long int to_utime, GList **list, int *count)
80 char query[CAL_DB_SQL_MAX_LEN] = {0};
81 sqlite3_stmt *stmt = NULL;
83 DBG("searching normal event (%lld) ~ (%lld)", from_utime, to_utime);
85 snprintf(query, sizeof(query),
86 "SELECT A.event_id, B.alarm_time, "
87 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
88 "FROM %s as A, " // A is normal instance
89 "%s as B ON A.event_id = B.event_id, " // B is alarm
90 "%s as C ON B.event_id = C.id " // c is schedule
91 "WHERE C.has_alarm == 1 AND C.type = %d "
92 "AND B.remind_tick_unit = %d AND B.alarm_time = %lld "
94 "SELECT A.event_id, A.dtstart_utime - (B.remind_tick * B.remind_tick_unit), "
95 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
96 "FROM %s as A, " // A is normal instance
97 "%s as B ON A.event_id = B.event_id, " // B is alarm
98 "%s as C ON B.event_id = C.id " // c is schedule
99 "WHERE C.has_alarm = 1 AND C.type = %d "
100 "AND B.remind_tick_unit > %d "
101 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
102 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
103 "ORDER BY (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit))",
104 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
105 CALENDAR_BOOK_TYPE_EVENT,
106 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
107 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
108 CALENDAR_BOOK_TYPE_EVENT,
109 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
110 from_utime, to_utime);
112 stmt = _cal_db_util_query_prepare(query);
115 DBG("query[%s]", query);
116 ERR("_cal_db_util_query_prepare() Failed");
117 return CALENDAR_ERROR_DB_FAILED;
121 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
123 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
126 nd->id = sqlite3_column_int(stmt, index++);
127 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
128 nd->tick = sqlite3_column_int(stmt, index++);
129 nd->unit = sqlite3_column_int(stmt, index++);
130 nd->alarm_id = sqlite3_column_int(stmt, index++);
132 *list = g_list_append(*list, nd);
135 sqlite3_finalize(stmt);
136 return CALENDAR_ERROR_NONE;
139 static int __cal_server_alarm_get_next_list_normal_todo(long long int from_utime, long long int to_utime, GList **list, int *count)
142 char query[CAL_DB_SQL_MAX_LEN] = {0};
143 sqlite3_stmt *stmt = NULL;
145 DBG("searching normal todo (%lld) ~ (%lld)", from_utime, to_utime);
147 snprintf(query, sizeof(query),
148 "SELECT B.id, A.alarm_time, "
149 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
150 "FROM %s as A, " // A is alarm
151 "%s as B ON A.event_id = B.id " // B is schedule
152 "WHERE B.has_alarm == 1 AND B.type = %d "
153 "AND A.remind_tick_unit = %d AND A.alarm_time = %lld "
155 "SELECT B.id, B.dtend_utime - (A.remind_tick * A.remind_tick_unit), "
156 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
157 "FROM %s as A, " // A is alarm
158 "%s as B ON A.event_id = B.id " // B is schedule
159 "WHERE B.has_alarm = 1 AND B.type = %d "
160 "AND A.remind_tick_unit > %d "
161 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
162 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld "
163 "ORDER BY (B.dtend_utime - (A.remind_tick * A.remind_tick_unit))",
164 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
165 CALENDAR_BOOK_TYPE_TODO,
166 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
167 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
168 CALENDAR_BOOK_TYPE_TODO,
169 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
170 from_utime, to_utime);
172 stmt = _cal_db_util_query_prepare(query);
175 DBG("query[%s]", query);
176 ERR("_cal_db_util_query_prepare() Failed");
177 return CALENDAR_ERROR_DB_FAILED;
181 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
183 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
186 nd->id = sqlite3_column_int(stmt, index++);
187 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
188 nd->tick = sqlite3_column_int(stmt, index++);
189 nd->unit = sqlite3_column_int(stmt, index++);
190 nd->alarm_id = sqlite3_column_int(stmt, index++);
192 *list = g_list_append(*list, nd);
195 sqlite3_finalize(stmt);
196 return CALENDAR_ERROR_NONE;
199 static int __cal_server_alarm_get_next_list_allday_event(int from_datetime, int to_datetime, GList **list, int *count)
202 char query[CAL_DB_SQL_MAX_LEN] = {0};
203 sqlite3_stmt *stmt = NULL;
205 DBG("searching allday (%d) ~ (%d)", from_datetime, to_datetime);
207 snprintf(query, sizeof(query),
208 "SELECT A.event_id, B.alarm_time, "
209 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
210 "FROM %s as A, " // A is allday instance
211 "%s as B ON A.event_id = B.event_id, " // B is alarm
212 "%s as C ON B.event_id = C.id " // C is schedule
213 "WHERE C.has_alarm == 1 AND C.type = %d "
214 "AND B.remind_tick_unit = %d AND B.alarm_time = %d "
216 "SELECT A.event_id, A.dtstart_datetime, "
217 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
218 "FROM %s as A, " // A is allday instance
219 "%s as B ON A.event_id = B.event_id, " // B is alarm
220 "%s as C ON B.event_id = C.id " // C is schedule
221 "WHERE C.has_alarm = 1 AND C.type = %d "
222 "AND B.remind_tick_unit > %d "
223 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 > %d "
224 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 <= %d ",
225 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
226 CALENDAR_BOOK_TYPE_EVENT,
227 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
228 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
229 CALENDAR_BOOK_TYPE_EVENT,
230 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
231 from_datetime, to_datetime);
233 stmt = _cal_db_util_query_prepare(query);
236 DBG("query[%s]", query);
237 ERR("_cal_db_util_query_prepare() Failed");
238 return CALENDAR_ERROR_DB_FAILED;
242 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
244 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
247 ad->id = sqlite3_column_int(stmt, index++);
248 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
249 ad->tick = sqlite3_column_int(stmt, index++);
250 ad->unit = sqlite3_column_int(stmt, index++);
251 ad->alarm_id = sqlite3_column_int(stmt, index++);
253 *list = g_list_append(*list, ad);
256 sqlite3_finalize(stmt);
257 return CALENDAR_ERROR_NONE;
260 static int __cal_server_alarm_get_next_list_allday_todo(int from_datetime, int to_datetime, GList **list, int *count)
263 char query[CAL_DB_SQL_MAX_LEN] = {0};
264 sqlite3_stmt *stmt = NULL;
266 DBG("searching allday todo(%d) ~ (%d)", from_datetime, to_datetime);
268 snprintf(query, sizeof(query),
269 "SELECT A.event_id, A.alarm_time, "
270 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
271 "FROM %s as A, " // A is alarm
272 "%s as B ON A.event_id = B.id " // B is schedule
273 "WHERE B.has_alarm == 1 AND B.type = %d "
274 "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
276 "SELECT A.event_id, B.dtend_datetime, "
277 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
278 "FROM %s as A, " // A is alarm
279 "%s as B ON A.event_id = B.id " // B is schedule
280 "WHERE B.has_alarm = 1 AND B.type = %d "
281 "AND A.remind_tick_unit > %d "
282 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 > %d "
283 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 <= %d ",
284 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
285 CALENDAR_BOOK_TYPE_TODO,
286 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
287 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
288 CALENDAR_BOOK_TYPE_TODO,
289 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
290 from_datetime, to_datetime);
292 stmt = _cal_db_util_query_prepare(query);
295 DBG("query[%s]", query);
296 ERR("_cal_db_util_query_prepare() Failed");
297 return CALENDAR_ERROR_DB_FAILED;
301 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
303 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
306 ad->id = sqlite3_column_int(stmt, index++);
307 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
308 ad->tick = sqlite3_column_int(stmt, index++);
309 ad->unit = sqlite3_column_int(stmt, index++);
310 ad->alarm_id = sqlite3_column_int(stmt, index++);
312 *list = g_list_append(*list, ad);
315 sqlite3_finalize(stmt);
316 return CALENDAR_ERROR_NONE;
319 static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
321 char query[CAL_DB_SQL_MAX_LEN] = {0};
322 cal_db_util_error_e dbret = CAL_DB_OK;
324 DBG("Update alarm_id(%d) in alarm table", alarm_id);
325 snprintf(query, sizeof(query), "UPDATE %s SET "
327 "WHERE event_id = %d AND remind_tick = %d AND remind_tick_unit = %d",
330 event_id, tick, unit);
332 dbret = _cal_db_util_query_exec(query);
333 if (CAL_DB_OK != dbret)
335 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
338 case CAL_DB_ERROR_NO_SPACE:
339 return CALENDAR_ERROR_FILE_NO_SPACE;
341 return CALENDAR_ERROR_DB_FAILED;
345 return CALENDAR_ERROR_NONE;
348 static GFunc __cal_server_alarm_print_list_normal(gpointer data, gpointer user_data)
350 struct _normal_data_s *normal = (struct _normal_data_s *)data;
351 DBG("%02d:%lld", normal->id, normal->alarm_utime);
355 static GFunc __cal_server_alarm_print_list_allday_todo(gpointer data, gpointer user_data)
357 struct _allday_data_s *allday = (struct _allday_data_s *)data;
358 DBG("%02d:%d", allday->id, allday->alarm_datetime);
362 static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **normal_list, GList **allday_list)
365 char query[CAL_DB_SQL_MAX_LEN] = {0};
366 sqlite3_stmt *stmt = NULL;
367 struct _normal_data_s *nd;
368 struct _allday_data_s *ad;
370 snprintf(query, sizeof(query),
371 "SELECT A.type, A.dtstart_type, A.dtend_type, B.remind_tick, B.remind_tick_unit "
372 "FROM %s as A, " // schedule
373 "%s as B ON A.id = B.event_id " // alarm
374 "WHERE B.alarm_id = %d",
379 stmt = _cal_db_util_query_prepare(query);
382 DBG("query[%s]", query);
383 ERR("_cal_db_util_query_prepare() Failed");
384 return CALENDAR_ERROR_DB_FAILED;
388 int dtstart_type = 0;
392 if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
395 type = sqlite3_column_int(stmt, index++);
396 dtstart_type = sqlite3_column_int(stmt, index++);
397 dtend_type = sqlite3_column_int(stmt, index++);
398 tick = sqlite3_column_int(stmt, index++);
399 unit = sqlite3_column_int(stmt, index++);
405 sqlite3_finalize(stmt);
408 if ((type == CALENDAR_BOOK_TYPE_EVENT && dtstart_type == CALENDAR_TIME_UTIME)
409 || (type == CALENDAR_BOOK_TYPE_TODO && dtend_type == CALENDAR_TIME_UTIME))
411 long long int now_utime;
412 now_utime = _cal_time_get_now();
413 now_utime -= now_utime % 60;
415 snprintf(query, sizeof(query),
416 "SELECT A.event_id, A.dtstart_utime, "
417 "B.remind_tick, B.remind_tick_unit, "
419 "FROM %s as A, " // A is normal instance
420 "%s as B ON A.event_id = B.event_id, " // B is alarm
421 "%s as C ON B.event_id = C.id " // c is schedule
422 "WHERE C.has_alarm == 1 AND C.type = %d "
423 "AND B.remind_tick_unit = %d "
424 "AND B.alarm_time = %lld "
426 "SELECT A.event_id, A.dtstart_utime, "
427 "B.remind_tick, B.remind_tick_unit, "
429 "FROM %s as A, " // A is normal instance
430 "%s as B ON A.event_id = B.event_id, " // B is alarm
431 "%s as C ON B.event_id = C.id " // c is schedule
432 "WHERE C.has_alarm = 1 AND C.type = %d "
433 "AND B.remind_tick_unit > %d "
434 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
435 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
437 "SELECT B.id, B.dtend_utime, "
438 "A.remind_tick, A.remind_tick_unit, "
440 "FROM %s as A, " // A is alarm
441 "%s as B ON A.event_id = B.id " // B is schedule
442 "WHERE B.has_alarm == 1 AND B.type = %d "
443 "AND A.remind_tick_unit = %d "
444 "AND A.alarm_time = %lld "
446 "SELECT B.id, B.dtend_utime, "
447 "A.remind_tick, A.remind_tick_unit, "
449 "FROM %s as A, " // A is alarm
450 "%s as B ON A.event_id = B.id " // B is schedule
451 "WHERE B.has_alarm = 1 AND B.type = %d "
452 "AND A.remind_tick_unit > %d "
453 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
454 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld ",
455 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
456 CALENDAR_BOOK_TYPE_EVENT,
457 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
459 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
460 CALENDAR_BOOK_TYPE_EVENT,
461 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
462 now_utime, now_utime + 60,
463 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
464 CALENDAR_BOOK_TYPE_TODO,
465 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
467 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
468 CALENDAR_BOOK_TYPE_TODO,
469 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
470 now_utime, now_utime + 60);
472 stmt = _cal_db_util_query_prepare(query);
475 DBG("query[%s]", query);
476 ERR("_cal_db_util_query_prepare() Failed");
477 return CALENDAR_ERROR_DB_FAILED;
480 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
483 nd = calloc(1, sizeof(struct _normal_data_s));
484 nd->id = sqlite3_column_int(stmt, index++);
485 nd->alarm_utime = sqlite3_column_int64(stmt, index++); // dtstart, dtend
486 nd->tick = sqlite3_column_int(stmt, index++);
487 nd->unit = sqlite3_column_int(stmt, index++);
488 nd->record_type = sqlite3_column_int(stmt, index++); // event, todo
489 *normal_list = g_list_append(*normal_list, nd);
496 time_t now_timet = time(NULL);
497 struct tm start_tm = {0};
498 now_timet -= now_timet % 60;
499 gmtime_r(&now_timet, &start_tm);
500 now_datetime = (start_tm.tm_year + 1900) * 10000
501 + (start_tm.tm_mon + 1) * 100
502 + (start_tm.tm_mday);
504 snprintf(query, sizeof(query),
505 "SELECT A.event_id, A.dtstart_datetime, "
506 "B.remind_tick, B.remind_tick_unit, "
508 "FROM %s as A, " // A is allday instance
509 "%s as B ON A.event_id = B.event_id, " // B is alarm
510 "%s as C ON B.event_id = C.id " // C is schedule
511 "WHERE C.has_alarm == 1 AND C.type = %d "
512 "AND B.remind_tick_unit = %d "
513 "AND B.alarm_time = %d "
515 "SELECT A.event_id, A.dtstart_datetime, "
516 "B.remind_tick, B.remind_tick_unit, "
518 "FROM %s as A, " // A is allday instance
519 "%s as B ON A.event_id = B.event_id, " // B is alarm
520 "%s as C ON B.event_id = C.id " // C is schedule
521 "WHERE C.has_alarm = 1 AND C.type = %d "
522 "AND B.remind_tick_unit > %d "
523 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 = %d "
525 "SELECT A.event_id, B.dtend_datetime, "
526 "A.remind_tick, A.remind_tick_unit, "
528 "FROM %s as A, " // A is alarm
529 "%s as B ON A.event_id = B.id " // B is schedule
530 "WHERE B.has_alarm == 1 AND B.type = %d "
531 "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
533 "SELECT A.event_id, B.dtend_datetime, "
534 "A.remind_tick, A.remind_tick_unit, "
536 "FROM %s as A, " // A is alarm
537 "%s as B ON A.event_id = B.id " // B is schedule
538 "WHERE B.has_alarm = 1 AND B.type = %d "
539 "AND A.remind_tick_unit > %d "
540 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 = %d ",
541 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
542 CALENDAR_BOOK_TYPE_EVENT,
543 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
545 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
546 CALENDAR_BOOK_TYPE_EVENT,
547 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
549 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
550 CALENDAR_BOOK_TYPE_TODO,
551 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
553 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
554 CALENDAR_BOOK_TYPE_TODO,
555 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
558 stmt = _cal_db_util_query_prepare(query);
561 DBG("query[%s]", query);
562 ERR("_cal_db_util_query_prepare() Failed");
563 return CALENDAR_ERROR_DB_FAILED;
566 const unsigned char *temp;
567 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
570 ad = calloc(1, sizeof(struct _allday_data_s));
571 ad->id = sqlite3_column_int(stmt, index++);
572 temp = sqlite3_column_text(stmt, index++); // dtstart, dtend
573 ad->alarm_datetime = atoi((const char *)temp);
574 ad->tick = sqlite3_column_int(stmt, index++);
575 ad->unit = sqlite3_column_int(stmt, index++);
576 ad->record_type = sqlite3_column_int(stmt, index++);
577 *allday_list = g_list_append(*allday_list, ad);
580 sqlite3_finalize(stmt);
581 return CALENDAR_ERROR_NONE;
584 // this api is necessary for repeat instance.
585 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
587 char query[CAL_DB_SQL_MAX_LEN] = {0};
588 cal_db_util_error_e dbret = CAL_DB_OK;
590 DBG("alarm_id(%d)", alarm_id);
592 snprintf(query, sizeof(query),
593 "UPDATE %s SET alarm_id = 0 WHERE alarm_id = %d ",
594 CAL_TABLE_ALARM, alarm_id);
596 dbret = _cal_db_util_query_exec(query);
597 if (CAL_DB_OK != dbret)
599 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
602 case CAL_DB_ERROR_NO_SPACE:
603 return CALENDAR_ERROR_FILE_NO_SPACE;
605 return CALENDAR_ERROR_DB_FAILED;
609 return CALENDAR_ERROR_NONE;
612 static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit, char *type)
614 int ret = CALENDAR_ERROR_NONE;
616 char query[CAL_DB_SQL_MAX_LEN] = {0};
619 sqlite3_stmt *stmt = NULL;
620 cal_db_util_error_e dbret = CAL_DB_OK;
624 ERR("Invalid parameter: pkgname is NULL");
625 return CALENDAR_ERROR_INVALID_PARAMETER;
628 // get user key, value
629 snprintf(query, sizeof(query), "SELECT key, value FROM %s WHERE pkgname = '%s' ",
630 CAL_REMINDER_ALERT, pkgname);
631 stmt = _cal_db_util_query_prepare(query);
634 ERR("_cal_db_util_query_prepare() Failed");
635 return CALENDAR_ERROR_DB_FAILED;
638 while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
641 key = (const char *)sqlite3_column_text(stmt, index++);
642 value = (const char *)sqlite3_column_text(stmt, index++);
646 DBG("[%s][%s][%s][%s]", id, time, tick, unit);
650 appsvc_set_pkgname(b, pkgname);
651 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
652 if (key && value) appsvc_add_data(b, key, value);
653 appsvc_add_data(b, "id", id);
654 appsvc_add_data(b, "time", time);
655 appsvc_add_data(b, "tick", tick);
656 appsvc_add_data(b, "unit", unit);
657 appsvc_add_data(b, "type", type);
658 ret = appsvc_run_service(b, 0, NULL, NULL);
661 sqlite3_finalize(stmt);
663 // if no app, delete from the table
664 if (APPSVC_RET_ELAUNCH == ret)
666 DBG("Deleted no responce pkg[%s]", pkgname);
667 snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = '%s' ",
668 CAL_REMINDER_ALERT, pkgname);
669 dbret = _cal_db_util_query_exec(query);
670 if (CAL_DB_OK != dbret)
672 ERR("_cal_db_util_query_exec() failed(ret:%d)", ret);
675 case CAL_DB_ERROR_NO_SPACE:
676 return CALENDAR_ERROR_FILE_NO_SPACE;
678 return CALENDAR_ERROR_DB_FAILED;
683 return CALENDAR_ERROR_NONE;
686 static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit, char *type)
689 char query[CAL_DB_SQL_MAX_LEN] = {0};
690 sqlite3_stmt *stmt = NULL;
692 snprintf(query, sizeof(query), "SELECT pkgname FROM %s WHERE onoff = 1 ",
694 stmt = _cal_db_util_query_prepare(query);
697 ERR("_cal_db_util_query_prepare() Failed");
698 return CALENDAR_ERROR_DB_FAILED;
701 while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
704 const char *pkgname = (const char *)sqlite3_column_text(stmt, index++);
705 DBG("pkgname[%s]", pkgname);
706 __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit, type);
708 sqlite3_finalize(stmt);
710 return CALENDAR_ERROR_NONE;
713 static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list, GList *allday_list)
715 char buf_id[128] = {0};
716 char buf_time[128] = {0};
717 char buf_tick[128] = {0};
718 char buf_unit[128] = {0};
719 char buf_type[128] = {0};
722 l = g_list_first(normal_list);
723 if (NULL == l) DBG("normal list is NULL");
726 struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
727 snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
728 snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
729 snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
730 snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
731 snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
733 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
738 l = g_list_first(allday_list);
739 if (NULL == l) DBG("allday list is NULL");
742 struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
743 snprintf(buf_id, sizeof(buf_id), "%d", ad->id);
744 snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
745 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
746 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
747 snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
749 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
752 return CALENDAR_ERROR_NONE;
755 static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
759 struct _normal_data_s *nd;
761 GList *l = g_list_first(normal_list);
763 // try to save the first record.
764 // if alarm id exists, it means updated record is not earilier than already registerd one.
765 nd = (struct _normal_data_s *)l->data;
769 return CALENDAR_ERROR_DB_FAILED;
772 if (nd->alarm_id > 0)
774 DBG("Already registered this id");
775 return CALENDAR_ERROR_NONE;
778 DBG("new is earilier than registered.");
780 // clear all alarm which set by mine.
781 ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
782 if (ret != ALARMMGR_RESULT_SUCCESS)
784 ERR("alarmmgr_enum_alarm_ids() failed");
789 long long int mod_alarm_utime; // del seconds
790 mod_alarm_utime = nd->alarm_utime - (nd->alarm_utime % 60);
791 // ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(mod_alarm_utime - now_utime), 0, NULL, &alarm_id);
793 ///////////////////////////////////////
794 alarm_entry_t *alarm_info = NULL;
795 alarm_info = alarmmgr_create_alarm();
796 if (NULL == alarm_info)
798 ERR("Failed to create alarm");
799 return CALENDAR_ERROR_DB_FAILED;
802 tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
804 alarm_date_t alarm_date;
805 _cal_time_utoi(mod_alarm_utime, tzid,
806 &alarm_date.year, &alarm_date.month, &alarm_date.day,
807 &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
808 DBG("tzid[%s] datetime(%04d/%02d/%02d %02d:%02d:%02d", tzid,
809 alarm_date.year, alarm_date.month, alarm_date.day,
810 alarm_date.hour, alarm_date.min, alarm_date.sec);
812 alarmmgr_set_time(alarm_info, alarm_date);
813 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
814 if (tzid) free(tzid);
815 ///////////////////////////////////////
819 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
822 DBG("Get normal alarmmgr id (%d)", alarm_id);
823 __cal_server_alarm_update_alarm_id(alarm_id, nd->id, nd->tick, nd->unit);
825 return CALENDAR_ERROR_NONE;
828 static int __cal_server_alarm_register_next_allday(time_t now_timet, GList *allday_list)
832 struct _allday_data_s *ad;
835 GList *l = g_list_first(allday_list);
837 ad = (struct _allday_data_s *)l->data;
841 return CALENDAR_ERROR_DB_FAILED;
844 if (ad->alarm_id > 0)
846 DBG("Already registered this id");
847 return CALENDAR_ERROR_NONE;
850 DBG("new is earilier than registered.");
852 // clear all alarm which set by mine.
853 ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
854 if (ret != ALARMMGR_RESULT_SUCCESS)
856 ERR("alarmmgr_enum_alarm_ids() failed");
861 // ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(alarm_timet - (ad->tick * ad->unit) - now_timet), 0, NULL, &alarm_id);
863 ///////////////////////////////////////
864 alarm_entry_t *alarm_info = NULL;
865 alarm_info = alarmmgr_create_alarm();
866 if (NULL == alarm_info)
868 ERR("Failed to create alarm");
869 return CALENDAR_ERROR_DB_FAILED;
872 tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
874 alarm_date_t alarm_date;
875 _cal_time_utoi((long long int)(alarm_timet - (ad->tick * ad->unit)), tzid,
876 &alarm_date.year, &alarm_date.month, &alarm_date.day,
877 &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
878 alarmmgr_set_time(alarm_info, alarm_date);
879 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
880 if (tzid) free(tzid);
881 ///////////////////////////////////////
885 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
888 DBG("Get allday alarmmgr id (%d)", alarm_id);
889 __cal_server_alarm_update_alarm_id(alarm_id, ad->id, ad->tick, ad->unit);
891 return CALENDAR_ERROR_NONE;
894 static gint __cal_server_alarm_normal_sort_cb(gconstpointer a, gconstpointer b)
896 struct _normal_data_s *p1 = (struct _normal_data_s *)a;
897 struct _normal_data_s *p2 = (struct _normal_data_s *)b;
899 return p1->alarm_utime - p2->alarm_utime > 0 ? 1 : -1;
902 static gint __cal_server_alarm_allday_sort_cb(gconstpointer a, gconstpointer b)
904 struct _allday_data_s *p1 = (struct _allday_data_s *)a;
905 struct _allday_data_s *p2 = (struct _allday_data_s *)b;
907 return p1->alarm_datetime - p2->alarm_datetime > 0 ? 1 : -1;
910 static int __cal_server_alarm_register_with_alarmmgr(long long int now_utime)
912 GList *normal_list = NULL;
913 GList *allday_list = NULL;
918 gettimeofday(&stv, NULL); // check time
921 long long int from_utime, to_utime;
925 to_utime = now_utime - (now_utime % 60) + 60;
927 // searching 3months, next 6months, next 12months
928 for (loop_count = 1; loop_count < 4; loop_count++)
930 from_utime = to_utime;
931 to_utime = from_utime + (60 * 60 * 24 * 30 * 3 * loop_count);
932 __cal_server_alarm_get_next_list_normal_event(from_utime, to_utime, &normal_list, &event_count);
933 __cal_server_alarm_get_next_list_normal_todo(from_utime, to_utime, &normal_list, &todo_count);
934 if (event_count + todo_count > 0)
939 DBG("event count(%d) todo count(%d)", event_count, todo_count);
941 if (event_count + todo_count > 0)
943 normal_list = g_list_sort(normal_list, __cal_server_alarm_normal_sort_cb);
944 DBG("after sorting");
945 g_list_foreach(normal_list, (GFunc)__cal_server_alarm_print_list_normal, NULL);
946 __cal_server_alarm_register_next_normal(now_utime, normal_list);
951 g_list_free_full(normal_list, free);
958 time_t from_timet, to_timet;
959 int from_datetime, to_datetime;
960 struct tm datetime_tm;
961 now_timet = (time_t)now_utime;
965 to_timet = now_timet;
967 // searching 3months, next 6months, next 12months
968 for (loop_count = 1; loop_count < 4; loop_count++)
970 from_timet = to_timet;
971 gmtime_r(&from_timet, &datetime_tm);
972 from_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
974 to_timet = from_timet + (60 * 60 * 24 * 30 * 3 * loop_count);
975 gmtime_r(&to_timet, &datetime_tm);
976 to_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
978 __cal_server_alarm_get_next_list_allday_event(from_datetime, to_datetime, &allday_list, &event_count);
979 __cal_server_alarm_get_next_list_allday_todo(from_datetime, to_datetime, &allday_list, &todo_count);
981 if (event_count + todo_count > 0)
986 DBG("event count(%d) todo count(%d)", event_count, todo_count);
988 if (event_count + todo_count > 0)
990 allday_list = g_list_sort(allday_list, __cal_server_alarm_allday_sort_cb);
991 DBG("after sorting");
992 g_list_foreach(allday_list, (GFunc)__cal_server_alarm_print_list_allday_todo, NULL);
993 __cal_server_alarm_register_next_allday(now_timet, allday_list);
997 g_list_free_full(allday_list, free);
1002 gettimeofday(&etv, NULL);
1003 diff = ((int)etv.tv_sec *1000 + (int)etv.tv_usec/1000)
1004 -((int)stv.tv_sec *1000 + (int)stv.tv_usec/1000);
1005 DBG("registering time diff %ld(%d.%d)",diff, diff/1000, diff%1000); // time check
1009 static int __cal_server_alarm_callback(char *id, char *time, char *tick, char *unit, char *type)
1011 _cal_server_reminder_add_callback_data("id", id);
1012 _cal_server_reminder_add_callback_data("time", time);
1013 _cal_server_reminder_add_callback_data("tick", tick);
1014 _cal_server_reminder_add_callback_data("unit", unit);
1015 _cal_server_reminder_add_callback_data("type", type);
1017 return CALENDAR_ERROR_NONE;
1020 static int __cal_server_alarm_noti_callback(int alarm_id, GList *normal_list, GList *allday_list)
1022 char buf_id[128] = {0};
1023 char buf_time[128] = {0};
1024 char buf_tick[128] = {0};
1025 char buf_unit[128] = {0};
1026 char buf_type[128] = {0};
1029 l = g_list_first(normal_list);
1030 if (NULL == l) DBG("normal list is NULL");
1033 struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
1034 snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
1035 snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
1036 snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
1037 snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
1038 snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
1040 __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
1041 _cal_server_reminder_publish();
1046 l = g_list_first(allday_list);
1047 if (NULL == l) DBG("allday list is NULL");
1050 struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
1051 snprintf(buf_id, sizeof(buf_id), "%d", ad->id);
1052 snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
1053 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
1054 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
1055 snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
1057 __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
1058 _cal_server_reminder_publish();
1064 static int _alert_cb(alarm_id_t alarm_id, void *data)
1066 GList *normal_list = NULL;
1067 GList *allday_list = NULL;
1069 __cal_server_alarm_get_list_with_alarmmgr_id(alarm_id, &normal_list, &allday_list);
1070 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
1071 __cal_server_alarm_noti_with_appsvc(alarm_id, normal_list, allday_list);
1072 __cal_server_alarm_noti_callback(alarm_id, normal_list, allday_list);
1076 g_list_free_full(normal_list, free);
1081 g_list_free_full(allday_list, free);
1085 __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1089 ////////////////////////////////////////////////////////////////////
1090 static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
1094 t = vconf_keynode_get_int(node);
1098 vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, (int *)&t);
1101 DBG("systme changed time(%ld)", t);
1102 __cal_server_alarm_register_with_alarmmgr((long long int)t);
1105 int __cal_server_alarm_set_timechange(void)
1109 ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIMECHANGE,
1110 __cal_server_alarm_timechange_cb, NULL);
1113 ERR("vconf_ignore_key_changed() failed");
1116 return CALENDAR_ERROR_NONE;
1119 static void __changed_cb(const char* view_uri, void* data)
1121 __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1124 static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1126 _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
1127 _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
1131 int _cal_server_alarm(void)
1135 __cal_server_alarm_set_timechange();
1136 __cal_server_alarm_set_inotify(__changed_cb);
1138 ret = alarmmgr_init("calendar-service");
1139 retvm_if(ret < 0, ret, "alarmmgr_init() failed");
1141 ret = alarmmgr_set_cb(_alert_cb, NULL);
1142 retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
1144 __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1146 return CALENDAR_ERROR_NONE;