merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:17:39 +0000 (01:17 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:17:39 +0000 (01:17 +0900)
36 files changed:
CMakeLists.txt
calendar-service.manifest
calendar.pc
client/CMakeLists.txt
client/cal_client_db.c
client/cal_client_ipc.c
client/cal_client_reminder.c [moved from client/cal_client_alert.c with 65% similarity]
client/cal_client_reminder.h [new file with mode: 0644]
common/cal_internal.h
common/cal_mutex.c
common/cal_mutex.h
common/cal_record_event.c
common/cal_typedef.h
common/cal_vcalendar.c
common/cal_vcalendar_make.c
common/cal_vcalendar_parse.c
common/ipc/cal_ipc.h
common/ipc/cal_ipc_marshal.c
dft/src/dft_main.c
include/calendar_db.h
include/calendar_reminder.h
include/calendar_types2.h
native/cal_db.c
native/cal_db_instance.c
native/cal_db_plugin_event.c
native/cal_db_rrule.c
native/cal_db_util.c
native/cal_reminder.c
packaging/calendar-service.spec
schema/schema.sql
server/CMakeLists.txt
server/cal_server.c
server/cal_server_alarm.c
server/cal_server_ipc.c
server/cal_server_reminder.c [new file with mode: 0644]
server/cal_server_reminder.h [new file with mode: 0644]

index 6e59d2e..b185654 100755 (executable)
@@ -20,7 +20,7 @@ SET(VERSION "${VERSION_MAJOR}.1.14")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I${CMAKE_SOURCE_DIR}/include")
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util alarm-service icu-i18n appsvc)
+pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util alarm-service icu-i18n appsvc bundle)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index 8d0fe82..eacbd46 100644 (file)
@@ -16,6 +16,8 @@
                <filesystem path="/etc/rc.d/init.d/calendar-serviced.sh" label="_" exec_label="none" />
                <filesystem path="/etc/rc.d/rc3.d/S85calendar-serviced" label="_" exec_label="none" />
                <filesystem path="/etc/rc.d/rc5.d/S85calendar-serviced" label="_" exec_label="none" />
+               <filesystem path="/usr/lib/systemd/user/calendar.service" label="_" exec_label="none" />
+               <filesystem path="/usr/lib/systemd/user/tizen-middleware.target.wants/calendar.service" label="_" exec_label="none" />
        </assign>
        <request>
                <domain name="calendar-service" />
index 65f36aa..6969f74 100755 (executable)
@@ -8,6 +8,6 @@ includedir=${prefix}/include/calendar-service2
 Name: calendar-service2
 Description: calendar-service2 library
 Version: 0.1.8
-Requires: glib-2.0 alarm-service
+Requires: glib-2.0 alarm-service bundle
 Libs: -L${libdir} -lcalendar-service2
 Cflags: -I${includedir}
index 9a81f5c..f708919 100755 (executable)
@@ -11,7 +11,7 @@ SET(CALSVC2 calendar-service2)
 SET(SRCS
        cal_client_ipc.c
        cal_client_db.c
-    cal_client_alert.c
+    cal_client_reminder.c
        ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal.c
        ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_alarm.c
        ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_attendee.c
index 281b49b..9ed547c 100644 (file)
@@ -371,6 +371,7 @@ API int calendar_db_insert_record( calendar_record_h record, int* id )
 
     retvm_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
 
+    CAL_RECORD_RESET_COMMON((cal_record_s*)record);
     // make indata
     indata = pims_ipc_data_create(0);
     if (indata == NULL)
@@ -762,7 +763,7 @@ API int calendar_db_get_records_with_query( calendar_query_h query, int offset,
     return ret;
 }
 
-API int calendar_db_clean_after_sync( int calendar_book_id )
+API int calendar_db_clean_after_sync( int calendar_book_id, int calendar_db_version)
 {
     int ret = CALENDAR_ERROR_NONE;
     pims_ipc_data_h indata = NULL;
@@ -785,6 +786,13 @@ API int calendar_db_clean_after_sync( int calendar_book_id )
         CAL_IPC_DATA_FREE(indata);
         return ret;
     }
+    ret = _cal_ipc_marshal_int(calendar_db_version,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
 
     // ipc call
     if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_CLEAN_AFTER_SYNC, indata, &outdata) != 0)
index 1e4f6f1..7f16f38 100644 (file)
@@ -38,6 +38,7 @@
 #include "cal_ipc_marshal.h"
 
 #include "cal_client_ipc.h"
+#include "cal_client_reminder.h"
 
 static TLS pims_ipc_h calendar_ipc_thread = NULL;
 static pims_ipc_h calendar_ipc = NULL;
@@ -117,6 +118,10 @@ API int calendar_connect(void)
 
     _cal_view_initialize();
 
+    if (0 == calendar_connection_count)
+    {
+               _cal_client_reminder_create_for_subscribe();
+       }
     calendar_connection_count++;
     calendar_ipc = ipc_handle;
     _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
@@ -152,6 +157,10 @@ API int calendar_disconnect(void)
         _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
         return ret;
     }
+       else
+       {
+               _cal_client_reminder_destroy_for_subscribe();
+       }
 
     // ipc call
     if (pims_ipc_call(calendar_ipc, CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, indata, &outdata) != 0)
@@ -327,14 +336,17 @@ API int calendar_connect_with_flags(unsigned int flags)
         {
             int retry_time = 500;
             int i = 0;
-            for(i=0;i<6;i++)
+            for(i=0;i<9;i++)
             {
                 usleep(retry_time*1000);
                 ret = calendar_connect();
                 DBG("retry cnt=%d, ret=%x",(i+1), ret);
                 if (ret == CALENDAR_ERROR_NONE)
                     break;
-                retry_time *= 2;
+                if (i>6)
+                    retry_time += 30000;
+                else
+                    retry_time *= 2;
             }
 
         }
similarity index 65%
rename from client/cal_client_alert.c
rename to client/cal_client_reminder.c
index 5e35c81..3d525a5 100644 (file)
@@ -23,6 +23,7 @@
 #include "calendar_service.h"
 #include "calendar_db.h"
 #include "calendar_types2.h"
+#include "calendar_reminder.h"
 
 #include "cal_internal.h"
 #include "cal_typedef.h"
@@ -307,3 +308,177 @@ API int calendar_reminder_has_receiver(const char *pkgname)
 
     return ret;
 }
+
+// for reminder callback
+
+typedef struct {
+       calendar_reminder_cb cb;
+       void *user_data;
+} callback_info_s;
+
+typedef struct {
+       char *view_uri;
+       GSList *callbacks;
+} subscribe_info_s;
+
+static pims_ipc_h __ipc = NULL;
+static GSList *__subscribe_list = NULL;
+
+int _cal_client_reminder_create_for_subscribe(void)
+{
+       _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+       if (!__ipc)
+       {
+               __ipc = pims_ipc_create_for_subscribe(CAL_IPC_SOCKET_PATH_FOR_SUBSCRIPTION);
+               if (!__ipc)
+               {
+                       ERR("pims_ipc_create_for_subscribe");
+                       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+                       return CALENDAR_ERROR_IPC;
+               }
+       }
+       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_client_reminder_destroy_for_subscribe(void)
+{
+       _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+
+       pims_ipc_destroy_for_subscribe(__ipc);
+       __ipc = NULL;
+
+       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+       return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_client_reminder_subscribe_callback(pims_ipc_h ipc, pims_ipc_data_h data, void *user_data)
+{
+       unsigned int size = 0;
+       const unsigned char *str = NULL;
+       int len = 0;
+       subscribe_info_s *info = user_data;
+
+       if (data)
+       {
+               len = (int)pims_ipc_data_get(data, &size);
+               if (0 == len)
+               {
+                       ERR("pims_ipc_data_get() failed");
+                       return;
+               }
+               str = (const unsigned char *)pims_ipc_data_get(data, &size);
+               if (!str)
+               {
+                       ERR("pims_ipc_data_get() failed");
+                       return;
+               }
+       }
+       if (info)
+       {
+               GSList *l = NULL;
+               for (l = info->callbacks; l; l = l->next)
+               {
+                       callback_info_s *cb_info = l->data;
+                       if (NULL == cb_info) continue;
+
+                       bundle *b = NULL;
+                       b = bundle_decode(str, len);
+                       if (b)
+                       {
+                               cb_info->cb(b, cb_info->user_data);
+                               bundle_free(b);
+                       }
+               }
+       }
+}
+
+API int calendar_reminder_add_cb(calendar_reminder_cb callback, void *user_data)
+{
+       GSList *it = NULL;
+       subscribe_info_s *info = NULL;
+       callback_info_s *cb_info = NULL;
+
+       _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+
+       for (it = __subscribe_list; it; it = it->next)
+       {
+               if (NULL == it->data) continue;
+
+               info = it->data;
+               if (strcmp(info->view_uri, CAL_NOTI_REMINDER_CAHNGED) == 0)
+                       break;
+               else
+                       info = NULL;
+       }
+       if (NULL == info)
+       {
+               info = calloc(1, sizeof(subscribe_info_s));
+               if (NULL == info)
+               {
+                       ERR("calloc() failed");
+                       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               if (pims_ipc_subscribe(__ipc, CAL_IPC_MODULE_FOR_SUBSCRIPTION, (char *)CAL_NOTI_REMINDER_CAHNGED,
+                                       __cal_client_reminder_subscribe_callback, (void *)info) != 0)
+               {
+                       ERR("pims_ipc_subscribe() failed");
+                       free(info);
+                       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+                       return CALENDAR_ERROR_IPC;
+               }
+               info->view_uri = strdup(CAL_NOTI_REMINDER_CAHNGED);
+               __subscribe_list = g_slist_append(__subscribe_list, info);
+       }
+
+       cb_info = calloc(1, sizeof(callback_info_s));
+       cb_info->user_data = user_data;
+       cb_info->cb = callback;
+       info->callbacks = g_slist_append(info->callbacks, cb_info);
+
+       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_reminder_remove_cb(calendar_reminder_cb callback, void *user_data)
+{
+       GSList *it = NULL;
+       subscribe_info_s *info = NULL;
+
+       _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+
+       for (it = __subscribe_list; it; it = it->next)
+       {
+               if (NULL == it->data) continue;
+
+               info = it->data;
+               if (strcmp(info->view_uri, CAL_NOTI_REMINDER_CAHNGED) == 0)
+                       break;
+               else
+                       info = NULL;
+       }
+       if (info)
+       {
+               GSList *l = NULL;
+               for (l = info->callbacks; l; l = l->next)
+               {
+                       callback_info_s *cb_info = l->data;
+                       if (callback == cb_info->cb && user_data == cb_info->user_data)
+                       {
+                               info->callbacks = g_slist_remove(info->callbacks, cb_info);
+                               break;
+                       }
+               }
+               if (g_slist_length(info->callbacks) == 0)
+               {
+                       __subscribe_list = g_slist_remove(__subscribe_list, info);
+                       free(info->view_uri);
+                       free(info);
+               }
+       }
+       _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_PUBSUB);
+       return CALENDAR_ERROR_NONE;
+}
+
+
diff --git a/client/cal_client_reminder.h b/client/cal_client_reminder.h
new file mode 100644 (file)
index 0000000..39ea4cf
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CAL_CLIENT_REMINDER_H__
+#define __CAL_CLIENT_REMINDER_H__
+
+int _cal_client_reminder_create_for_subscribe(void);
+
+#endif // __CAL_CLIENT_REMINDER_H__
index 36b9032..e34eb8a 100644 (file)
 #define WARN(fmt, arg...) SLOGW("%s:%d " fmt, __FUNCTION__, __LINE__, ##arg)
 #define ERR(fmt, arg...) SLOGE("%s:%d " fmt, __FUNCTION__, __LINE__, ##arg)
 #define DBG(fmt, arg...) SLOGD("%s:" fmt, __FUNCTION__, ##arg)
+#define VERBOSE(fmt, arg...) SLOGV(fmt, ##arg)
 
 //#define CAL_DEBUGGING
 #ifdef CAL_DEBUGGING
     #if defined(CAL_IPC_SERVER)
     #define CAL_FN_CALL DBG("SERVER:>>>>>>>>%s called", __FUNCTION__)
     #define CAL_FN_END DBG("SERVER:<<<<<<<<%s ended", __FUNCTION__)
+    #define CAL_FN_CALL_VERBOSE VERBOSE("SERVER:>>>>>>>>%s called", __FUNCTION__)
     #elif defined(CAL_IPC_CLIENT)
     #define CAL_FN_CALL DBG("CLIENT:>>>>>>>>%s called", __FUNCTION__)
     #define CAL_FN_END DBG("CLIENT:<<<<<<<<%s ended", __FUNCTION__)
+    #define CAL_FN_CALL_VERBOSE VERBOSE("CLIENT:>>>>>>>>%s called", __FUNCTION__)
     #else
     #define CAL_FN_CALL DBG(">>>>>>>>%s called", __FUNCTION__)
     #define CAL_FN_END DBG("<<<<<<<<%s ended", __FUNCTION__)
+    #define CAL_FN_CALL_VERBOSE VERBOSE(">>>>>>>>%s called", __FUNCTION__)
     #endif
 
     #if defined(CAL_IPC_SERVER)
     #define CAL_DBG(fmt, arg...) DBG("SERVER:%d " fmt, __LINE__, ##arg)
+    #define CAL_VERBOSE(fmt, arg...) VERBOSE("SERVER:%d " fmt, __LINE__, ##arg)
     #elif defined(CAL_IPC_CLIENT)
     #define CAL_DBG(fmt, arg...) DBG("CLIENT:%d " fmt, __LINE__, ##arg)
+    #define CAL_VERBOSE(fmt, arg...) VERBOSE("CLIENT:%d " fmt, __LINE__, ##arg)
     #else
     #define CAL_DBG(fmt, arg...) DBG("%d " fmt, __LINE__, ##arg)
+    #define CAL_VERBOSE(fmt, arg...) VERBOSE("%d " fmt, __LINE__, ##arg)
     #endif
 #else /* CAL_DEBUGGING */
 #define CAL_FN_CALL
index c4a89fa..08e6574 100644 (file)
@@ -27,6 +27,7 @@ static pthread_mutex_t __cal_property_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t __cal_connection_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t __cal_pims_ipc_call_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t __cal_inotify_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __cal_pims_ipc_pubsub_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static inline pthread_mutex_t* cts_mutex_get_mutex(int type)
 {
@@ -45,6 +46,9 @@ static inline pthread_mutex_t* cts_mutex_get_mutex(int type)
     case CAL_MUTEX_INOTIFY:
         ret_val = &__cal_inotify_mutex;
         break;
+       case CAL_MUTEX_PIMS_IPC_PUBSUB:
+               ret_val = &__cal_pims_ipc_pubsub_mutex;
+               break;
     default:
         ERR("unknown type(%d)", type);
         ret_val = NULL;
index 10866d3..c4f7ea5 100644 (file)
@@ -25,6 +25,7 @@ enum {
     CAL_MUTEX_PIMS_IPC_CALL,
     CAL_MUTEX_INOTIFY,
     CAL_MUTEX_PROPERTY_HASH,
+       CAL_MUTEX_PIMS_IPC_PUBSUB,
 };
 
 void _cal_mutex_lock(int type);
index ced7937..f3a21bb 100644 (file)
@@ -74,7 +74,7 @@ static void __cal_record_event_struct_init(cal_event_s *record)
 {
     memset(record,0,sizeof(cal_event_s));
 
-    record->meeting_status = CALENDAR_EVENT_STATUS_NONE;
+    record->meeting_status = CALENDAR_MEETING_STATUS_NOTMEETING;
     record->calendar_id = DEFAULT_EVENT_CALENDAR_BOOK_ID;
 
     record->index = CAL_INVALID_ID;
index 9742949..db1756b 100755 (executable)
@@ -30,6 +30,7 @@
 #define CAL_NOTI_EVENT_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_EVENT_CHANGED"
 #define CAL_NOTI_TODO_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_TODO_CHANGED"
 #define CAL_NOTI_CALENDAR_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_CALENDAR_CHANGED"
+#define CAL_NOTI_REMINDER_CAHNGED "reminder"
 
 /**
  * @enum cal_priority_e
index ba31633..85e8cd7 100644 (file)
@@ -225,6 +225,7 @@ API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_
                     fclose(file);
                     return CALENDAR_ERROR_INVALID_PARAMETER;
                 }
+                               calendar_list_next(list);
             }
 
             calendar_list_destroy(list, true);
index 0143640..baa650a 100644 (file)
@@ -230,13 +230,7 @@ static inline int __cal_vcalendar_make_created(cal_make_s *b, long long int t)
        return CALENDAR_ERROR_NONE;
 }
 
-static inline int __cal_vcalendar_make_description(cal_make_s *b, char *s)
-{
-       __cal_vcalendar_make_printf(b, "DESCRIPTION:", s);
-       return CALENDAR_ERROR_NONE;
-}
-
-static inline int __cal_vcalendar_make_dtstart(cal_make_s *b, calendar_time_s *caltime)
+static inline int __cal_vcalendar_make_dtstart(cal_make_s *b, char *tzid, calendar_time_s *caltime)
 {
        retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
 
@@ -250,18 +244,32 @@ static inline int __cal_vcalendar_make_dtstart(cal_make_s *b, calendar_time_s *c
        {
        case CALENDAR_TIME_UTIME:
         {
-            char* tmp_tzid = NULL;
-            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
-            if (tmp_tzid)
-            {
-                __cal_vcalendar_make_printf(b, "DTSTART:", tmp_tzid);
-                CAL_FREE(tmp_tzid);
-            }
+                       char* str_time = NULL;
+                       if (NULL != tzid && strlen(tzid) > 0)
+                       {
+                               str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       char buf[128] = {0};
+                                       snprintf(buf, sizeof(buf), "DTSTART;TZID=%s:", tzid);
+                                       __cal_vcalendar_make_printf(b, buf, str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
+                       else
+                       {
+                               str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       __cal_vcalendar_make_printf(b, "DTSTART:", str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
         }
                break;
 
        case CALENDAR_TIME_LOCALTIME:
-               __cal_vcalendar_make_printf(b, "DTSTART:",
+               __cal_vcalendar_make_printf(b, "DTSTART;VALUE=DATE:",
                                __cal_vcalendar_make_itos(caltime->time.date.year,
                                        caltime->time.date.month, caltime->time.date.mday));
                break;
@@ -282,12 +290,6 @@ static inline int __cal_vcalendar_make_last_mod(cal_make_s *b, long long int lli
        return CALENDAR_ERROR_NONE;
 }
 
-static inline int __cal_vcalendar_make_location(cal_make_s *b, char *s)
-{
-       __cal_vcalendar_make_printf(b, "LOCATION:", s);
-       return CALENDAR_ERROR_NONE;
-}
-
 int __cal_vcalendar_make_organizer(cal_make_s *b, char *cn, char *address)
 {
        int ret;
@@ -331,13 +333,7 @@ int __cal_vcalendar_make_dtstamp(cal_make_s *b, char *tzid)
        return CALENDAR_ERROR_NONE;
 }
 
-static inline int __cal_vcalendar_make_summary(cal_make_s *b, char *s)
-{
-       __cal_vcalendar_make_printf(b, "SUMMARY:", s);
-       return CALENDAR_ERROR_NONE;
-}
-
-static inline int __cal_vcalendar_make_dtend(cal_make_s *b, calendar_time_s *caltime)
+static inline int __cal_vcalendar_make_dtend(cal_make_s *b, char *tzid, calendar_time_s *caltime)
 {
        retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
 
@@ -351,18 +347,32 @@ static inline int __cal_vcalendar_make_dtend(cal_make_s *b, calendar_time_s *cal
        {
        case CALENDAR_TIME_UTIME:
         {
-            char *tmp_tzid = NULL;
-            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
-            if (tmp_tzid)
-            {
-                __cal_vcalendar_make_printf(b, "DTEND:", tmp_tzid);
-                CAL_FREE(tmp_tzid);
-            }
+                       char* str_time = NULL;
+                       if (NULL != tzid && strlen(tzid) > 0)
+                       {
+                               str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       char buf[128] = {0};
+                                       snprintf(buf, sizeof(buf), "DTEND;TZID=%s:", tzid);
+                                       __cal_vcalendar_make_printf(b, buf, str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
+                       else
+                       {
+                               str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       __cal_vcalendar_make_printf(b, "DTEND:", str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
         }
                break;
 
        case CALENDAR_TIME_LOCALTIME:
-               __cal_vcalendar_make_printf(b, "DTEND:",
+               __cal_vcalendar_make_printf(b, "DTEND;VALUE=DATE:",
                                __cal_vcalendar_make_itos(caltime->time.date.year,
                                        caltime->time.date.month, caltime->time.date.mday));
                break;
@@ -371,21 +381,41 @@ static inline int __cal_vcalendar_make_dtend(cal_make_s *b, calendar_time_s *cal
        return CALENDAR_ERROR_NONE;
 }
 
-static inline int __cal_vcalendar_make_due(cal_make_s *b, calendar_time_s *caltime)
+static inline int __cal_vcalendar_make_due(cal_make_s *b, char *tzid,  calendar_time_s *caltime)
 {
        retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
 
+       if (caltime->time.utime == CALENDAR_TODO_NO_DUE_DATE)
+       {
+               DBG("No due date");
+               return CALENDAR_ERROR_NONE;
+       }
+
        switch (caltime->type)
        {
        case CALENDAR_TIME_UTIME:
         {
-            char *tmp_tzid = NULL;
-            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
-            if (tmp_tzid)
-            {
-                __cal_vcalendar_make_printf(b, "DUE:", tmp_tzid);
-                CAL_FREE(tmp_tzid);
-            }
+                       char* str_time = NULL;
+                       if (NULL != tzid && strlen(tzid) > 0)
+                       {
+                               str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       char buf[128] = {0};
+                                       snprintf(buf, sizeof(buf), "DUE;TZID=%s:", tzid);
+                                       __cal_vcalendar_make_printf(b, buf, str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
+                       else
+                       {
+                               str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
+                               if (str_time)
+                               {
+                                       __cal_vcalendar_make_printf(b, "DUE:", str_time);
+                                       CAL_FREE(str_time);
+                               }
+                       }
         }
                break;
 
@@ -573,6 +603,119 @@ int __cal_vcalendar_make_audio(cal_make_s *b, calendar_record_h alarm)
        return CALENDAR_ERROR_NONE;
 }
 
+// ver 1.0 aalarm
+int __cal_vcalendar_make_aalarm(cal_make_s *b, calendar_record_h record, calendar_record_h alarm)
+{
+       int ret;
+       int type;
+       int tick, unit;
+       char *uri = NULL;
+       long long int utime;
+       calendar_time_s caltime = {0};
+       retvm_if(alarm == NULL, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid argument: alarm is NULL");
+
+       ret = calendar_record_get_uri_p(record, &uri);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_uri_p() failed");
+               return ret;
+       }
+
+       if (!strncmp(uri, _calendar_event._uri, strlen(_calendar_event._uri)))
+       {
+               type = CALENDAR_RECORD_TYPE_EVENT;
+       }
+       else if (!strncmp(uri, _calendar_todo._uri, strlen(_calendar_todo._uri)))
+       {
+               type = CALENDAR_RECORD_TYPE_TODO;
+       }
+       else
+       {
+               ERR("Invalid type(%s)", uri);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_int() failed");
+               return ret;
+       }
+       ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_int() failed");
+               return ret;
+       }
+
+       switch (unit)
+       {
+       case CALENDAR_ALARM_TIME_UNIT_SPECIFIC:
+               ret = calendar_record_get_lli(alarm, _calendar_alarm.time, &utime);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_get_lli() failed");
+                       return ret;
+               }
+               break;
+
+       default:
+               switch (type)
+               {
+               case CALENDAR_RECORD_TYPE_EVENT:
+                       ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
+                       if (CALENDAR_ERROR_NONE != ret)
+                       {
+                               ERR("calendar_record_get_caltime() failed");
+                               return ret;
+                       }
+                       switch (caltime.type)
+                       {
+                       case CALENDAR_TIME_UTIME:
+                               utime = caltime.time.utime - (tick * unit);
+                               break;
+
+                       case CALENDAR_TIME_LOCALTIME:
+                               utime = _cal_time_convert_itol(NULL, caltime.time.date.year,
+                                               caltime.time.date.month, caltime.time.date.mday, 0, 0, 0);
+                               utime -= (tick * unit);
+                               break;
+                       }
+                       break;
+
+               case CALENDAR_RECORD_TYPE_TODO:
+                       ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
+                       if (CALENDAR_ERROR_NONE != ret)
+                       {
+                               ERR("calendar_record_get_caltime() failed");
+                               return ret;
+                       }
+                       switch (caltime.type)
+                       {
+                       case CALENDAR_TIME_UTIME:
+                               utime = caltime.time.utime - (tick * unit);
+                               break;
+
+                       case CALENDAR_TIME_LOCALTIME:
+                               utime = _cal_time_convert_itol(NULL, caltime.time.date.year,
+                                               caltime.time.date.month, caltime.time.date.mday, 0, 0, 0);
+                               utime -= (tick * unit);
+                               break;
+                       }
+                       break;
+               }
+               break;
+       }
+
+       char *calstr = _cal_time_convert_ltos(NULL, utime);
+       DBG("[%s]", calstr);
+
+       ret = __cal_vcalendar_make_printf(b, "AALARM:", calstr);
+       CAL_FREE(calstr);
+
+       return CALENDAR_ERROR_NONE;
+}
+
 int __cal_vcalendar_make_alarm(cal_make_s *b, calendar_record_h alarm)
 {
        int ret;
@@ -594,6 +737,289 @@ int __cal_vcalendar_make_alarm(cal_make_s *b, calendar_record_h alarm)
        return CALENDAR_ERROR_NONE;
 }
 
+int __cal_vcalendar_make_rrule_append_mday(char *buf, char *mday)
+{
+       int i;
+       int num;
+       int length = 0;
+       char **t;
+       char *p;
+
+       if (NULL == buf || NULL == mday)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       t = g_strsplit(mday, ",", -1);
+       if (!t) {
+               ERR("g_strsplit failed");
+               g_strfreev(t);
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+       length = g_strv_length(t);
+       for (i = 0; i < length; i++)
+       {
+               p = t[i];
+               while (*p == ' ')
+               {
+                       p++;
+               }
+               num = atoi(p);
+               if (num > 0)
+               {
+                       strcat(buf, p);
+               }
+               else
+               {
+                       strcat(buf, p + 1);
+                       strcat(buf, "-");
+               }
+               strcat(buf, " ");
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_rrule_append_wday(char *buf, char *wday)
+{
+       int i, j;
+       int num, num_past;
+       int length = 0;
+       char **t;
+       char *p;
+       char buf_temp[8] = {0};
+
+       num_past = 0;
+       t = g_strsplit(wday, ",", -1);
+       if (!t) {
+               ERR("g_strsplit failed");
+               g_strfreev(t);
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+       length = g_strv_length(t);
+       for (i = 0; i < length; i++)
+       {
+               p = t[i];
+               while (*p == ' ') // del space
+               {
+                       p++;
+               }
+               j = 0; // get number
+               while (p[j] == '+' || p[j] == '-' || (p[j] >= '1' && p[j] <= '9'))
+               {
+                       j++;
+               }
+               if (j > 0)
+               {
+                       if (*p == '-')
+                       {
+                               snprintf(buf_temp, j, "%s", p + 1);
+                               num = atoi(buf_temp);
+                               if (0 == i)
+                               {
+                                       num_past = num;
+                                       strcat(buf, buf_temp);
+                                       strcat(buf, "-");
+                                       strcat(buf, " ");
+                               }
+                       }
+                       else
+                       {
+                               snprintf(buf_temp, j + 1, "%s", p);
+                               num = atoi(buf_temp);
+                               if (0 == i)
+                               {
+                                       num_past = num;
+                                       strcat(buf, buf_temp);
+                                       strcat(buf, " ");
+                               }
+                       }
+                       if (num_past == num)
+                       {
+                               strcat(buf, p + j);
+                               strcat(buf, " ");
+                       }
+                       else
+                       {
+                               ERR("Out of 1.0 spec");
+                       }
+                       DBG("%d num(%d) val[%s]", i, num, p + j);
+               }
+               else
+               {
+                       strcat(buf, p);
+                       strcat(buf, " ");
+               }
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_rrule_append_until(char *buf, calendar_record_h record)
+{
+       int ret;
+       int range_type = 0;
+       int count;
+       char *until_str = NULL;
+       char buf_range[256] = {0};
+       calendar_time_s caltime;
+
+       ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_int() failed");
+               return ret;
+       }
+
+       switch (range_type)
+       {
+       case CALENDAR_RANGE_COUNT:
+               ret = calendar_record_get_int(record, _calendar_event.count, &count);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_get_int() failed");
+                       return ret;
+               }
+               snprintf(buf_range, sizeof(buf_range), "#%d", count);
+               break;
+
+       case CALENDAR_RANGE_UNTIL:
+               memset(&caltime, 0x0, sizeof(calendar_time_s));
+               ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_get_caltime() failed");
+                       return ret;
+               }
+               switch (caltime.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       until_str = _cal_time_convert_ltos(NULL, caltime.time.utime);
+                       snprintf(buf_range, sizeof(buf_range), "%s", until_str);
+                       CAL_FREE(until_str);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       snprintf(buf_range, sizeof(buf_range), "%04d%02d%02dT000000Z",
+                                       caltime.time.date.year, caltime.time.date.month, caltime.time.date.mday);
+                       break;
+               }
+               break;
+
+       case CALENDAR_RANGE_NONE:
+               snprintf(buf_range, sizeof(buf_range), "#0");
+               break;
+       }
+       strcat(buf, buf_range);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_make_rrule_ver1(cal_make_s *b, calendar_record_h record)
+{
+       int ret;
+       int freq;
+       int interval = 0;
+       char *byyearday = NULL;
+       char *bymonth = NULL;
+       char *bymonthday = NULL;
+       char *byday = NULL;
+       char buf[512] = {0};
+
+       ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_int() failed");
+               return ret;
+       }
+       ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_int() failed");
+               return ret;
+       }
+       ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &byyearday);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+       ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &bymonth);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+       ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+       ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &bymonthday);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+
+       switch (freq) {
+       case CALENDAR_RECURRENCE_DAILY:
+               snprintf(buf, sizeof(buf), "D%d ", interval);
+               break;
+
+       case CALENDAR_RECURRENCE_WEEKLY:
+               snprintf(buf, sizeof(buf), "W%d ", interval);
+               __cal_vcalendar_make_rrule_append_wday(buf, byday);
+               break;
+
+       case CALENDAR_RECURRENCE_MONTHLY:
+               if (byday)
+               {
+                       snprintf(buf, sizeof(buf), "MP%d ", interval);
+                       __cal_vcalendar_make_rrule_append_wday(buf, byday);
+               }
+               else if (bymonthday)
+               {
+                       snprintf(buf, sizeof(buf), "MD%d ", interval);
+                       __cal_vcalendar_make_rrule_append_mday(buf, bymonthday);
+               }
+               else
+               {
+                       ERR("Invalid parameter");
+               }
+               break;
+
+       case CALENDAR_RECURRENCE_YEARLY:
+               if (bymonth)
+               {
+                       snprintf(buf, sizeof(buf), "YM%d ", interval);
+                       __cal_vcalendar_make_rrule_append_mday(buf, bymonth);
+               }
+               else if (byyearday)
+               {
+                       snprintf(buf, sizeof(buf), "YD%d ", interval);
+                       __cal_vcalendar_make_rrule_append_mday(buf, byyearday);
+               }
+               else
+               {
+                       ERR("Invalid parameter");
+               }
+               break;
+
+       default:
+               ERR("Invalid parameter");
+               break;
+       }
+
+       __cal_vcalendar_make_rrule_append_until(buf, record);
+
+       return __cal_vcalendar_make_printf(b, "RRULE:", buf);
+}
+
 static int __cal_vcalendar_make_rrule(cal_make_s *b, int freq, calendar_record_h record)
 {
        int ret;
@@ -625,75 +1051,66 @@ static int __cal_vcalendar_make_rrule(cal_make_s *b, int freq, calendar_record_h
        strcat(buf, ";INTERVAL=");
        strcat(buf, tmp);
 
-       ret = calendar_record_get_str(record, _calendar_event.bysecond, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.bysecond, &text);
        if (text) {
                strcat(buf, ";BYSECOND=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.byminute, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.byminute, &text);
        if (text) {
                strcat(buf, ";BYMINUTE=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.byhour, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.byhour, &text);
        if (text) {
                strcat(buf, ";BYHOUR=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.byday, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.byday, &text);
        if (text) {
                strcat(buf, ";BYDAY=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.bymonthday, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &text);
        if (text) {
                strcat(buf, ";BYMONTHDAY=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.byyearday, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &text);
        if (text) {
                strcat(buf, ";BYYEARDAY=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.byweekno, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.byweekno, &text);
        if (text) {
                strcat(buf, ";BYWEEKNO=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.bymonth, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &text);
        if (text) {
                strcat(buf, ";BYMONTH=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
-       ret = calendar_record_get_str(record, _calendar_event.bysetpos, &text);
+       ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &text);
        if (text) {
                strcat(buf, ";BYSETPOS=");
                strcat(buf, text);
-               CAL_FREE(text);
                text = NULL;
        }
 
@@ -765,12 +1182,74 @@ static int __cal_vcalendar_make_rrule(cal_make_s *b, int freq, calendar_record_h
        return __cal_vcalendar_make_printf(b, "RRULE:", buf);
 }
 /////////////////////////////////////////////////////////////////////////////
-int __cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
+
+int __cal_vcalendar_make_child_extended(cal_make_s *b, calendar_record_h child)
+{
+       int ret;
+       char *key = NULL;
+       char *value = NULL;
+       if (NULL == child)
+       {
+               ERR("Invalid argument: child is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = calendar_record_get_str_p(child, _calendar_extended_property.key, &key);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+       if (NULL == key || strncmp(key, "X-", strlen("X-")))
+       {
+               DBG("Not extended for vcalendar[%s]", key);
+               return CALENDAR_ERROR_NONE;
+       }
+
+       ret = calendar_record_get_str_p(child, _calendar_extended_property.value, &value);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed");
+               return ret;
+       }
+       ret = __cal_vcalendar_make_printf(b, key, value);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("__cal_vcalendar_make_printf() failed");
+               return ret;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_printf_str_p(calendar_record_h record, unsigned int property_id, cal_make_s *b, const char *property_str)
+{
+       int ret;
+       char *strval = NULL;
+
+       ret = calendar_record_get_str_p(record, property_id, &strval);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed(ret:%d): categories", ret);
+               return ret;
+       }
+       if (strval && (strlen(strval) > 0))
+       {
+               ret = __cal_vcalendar_make_printf(b, property_str, strval);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("__cal_vcalendar_make_printf() failed(ret:%d)", ret);
+                       return ret;
+               }
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_schedule(int version, cal_make_s *b, calendar_record_h record)
 {
        int ret;
        int freq;
        int intval;
-       long long int llival;
        char *strval = NULL;
        char *strval2 = NULL;
        calendar_time_s caltime = {0};
@@ -800,71 +1279,58 @@ int __cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
        ret = __cal_vcalendar_make_transp(b, intval);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
 
-       // created_time
+       // dtstart_type
        ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
        ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
        if (ret != CALENDAR_ERROR_NONE) {
                ERR("Failed to get start_time(%d)", ret);
                return -1;
        }
+       ret = __cal_vcalendar_make_dtstart(b, tzid, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get dtstart(%d)", ret);
+
 
+       // created_time
+/* keis want to skip for there potential error.
        ret = calendar_record_get_lli(record, _calendar_event.created_time, &llival);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get created_time(%d)", ret);
 
        ret = __cal_vcalendar_make_created(b, llival);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
+*/
 
        // description
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_event.description, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get description(%d)", ret);
-
-       if (strval) {
-               ret = __cal_vcalendar_make_description(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No description");
-       }
-
-       // dtstart_type
-       ret = __cal_vcalendar_make_dtstart(b, &caltime);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get dtstart(%d)", ret);
-
-       // TODO : geo
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.description, b, "DESCRIPTION:");
 
+       // rrule
        ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
-       DBG("freq(%d)", freq);
+       retvm_if(ret != CALENDAR_ERROR_NONE, ret,
+                       "Failed to get last_modified_time(%d)", ret);
        if (freq)
        {
-               __cal_vcalendar_make_rrule(b, freq, record);
+               switch (version)
+               {
+               case 1:
+                       ret = __cal_vcalendar_make_rrule_ver1(b, record);
+                       break;
+
+               default:
+                       __cal_vcalendar_make_rrule(b, freq, record);
+               }
        }
 
        // last_mod
+/* keis want to skip for there potential error.
        ret = calendar_record_get_lli(record, _calendar_event.last_modified_time, &llival);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get last_modified_time(%d)", ret);
 
        ret = __cal_vcalendar_make_last_mod(b, llival);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
+*/
        // location
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_event.location, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get location(%d)", ret);
-
-       if (strval) {
-               ret = __cal_vcalendar_make_location(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No location");
-       }
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.location, b, "LOCATION:");
 
        // organizer email
        strval = NULL;
@@ -897,54 +1363,36 @@ int __cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
        // TODO : seq
 
        // dtstamp
+/* keis want to skip for there potential error.
        ret = __cal_vcalendar_make_dtstamp(b, tzid);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
+*/
 
        // summary
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_event.summary, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get summary(%d)", ret);
-
-       if (strval) {
-               ret = __cal_vcalendar_make_summary(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No summary");
-       }
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.summary, b, "SUMMARY:");
 
        // dtend
        ret = calendar_record_get_caltime(record, _calendar_event.end_time, &caltime);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get end_time(%d)", ret);
 
-       ret = __cal_vcalendar_make_dtend(b, &caltime);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get dtstart(%d)", ret);
+       ret = __cal_vcalendar_make_dtend(b, tzid, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get end(%d)", ret);
+
+       // categories
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.categories, b, "CATEGORIES:");
+
+       // uid
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.uid, b, "UID:");
 
        // exdate
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_event.exdate, &strval);
-       if (CALENDAR_ERROR_NONE != ret)
-       {
-               ERR("calendar_record_get_str_p() failed(ret:%d): exdate", ret);
-               return ret;
-       }
-       if (strval)
-       {
-               ret = __cal_vcalendar_make_exdate(b, strval);
-               if (CALENDAR_ERROR_NONE != ret)
-               {
-                       ERR("__cal_vcalendar_make_exdate() failed(ret:%d)", ret);
-                       return ret;
-               }
-       }
+       __cal_vcalendar_make_printf_str_p(record, _calendar_event.exdate, b, "EXDATE:");
 
-       // attendee
        unsigned int count;
        calendar_record_h child = NULL;
 
+       // attendee
+       count = 0;
        ret = calendar_record_get_child_record_count(record,
                        _calendar_event.calendar_attendee, &count);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
@@ -967,37 +1415,74 @@ int __cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
        }
 
        // alarm
-       ret = calendar_record_get_child_record_count(record,
-                       _calendar_event.calendar_alarm, &count);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get child count(%d)", ret);
+       count = 0;
+       switch (version)
+       {
+       case 1:
+               // In ver 1.0, only first alarm will be dealt with.
+               ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
+               if (count > 0)
+               {
+                       ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, 0, &child);
+                       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
+
+                       ret = __cal_vcalendar_make_aalarm(b, record, child);
+                       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               }
+               else
+               {
+                       DBG("No alarm in ver1.0");
+               }
+               break;
+
+       default:
+               ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
+
+               while (count > 0)
+               {
+                       count--;
+                       ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, count, &child);
+                       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
+
+                       ret = __cal_vcalendar_make_alarm(b, child);
+                       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               }
+
+               if (count <= 0)
+               {
+                       DBG("No alarm in ver2.0");
+               }
+       }
+
+       // extended
+       count = 0;
+       ret = calendar_record_get_child_record_count(record, _calendar_event.extended, &count);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
 
        while (count > 0)
        {
                count--;
-               ret = calendar_record_get_child_record_at_p(record,
-                               _calendar_event.calendar_alarm, count, &child);
-               retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                               "Failed to get child alarm(%d)", ret);
+               ret = calendar_record_get_child_record_at_p(record, _calendar_event.extended, count, &child);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
 
-               ret = __cal_vcalendar_make_alarm(b, child);
+               ret = __cal_vcalendar_make_child_extended(b, child);
                retv_if(ret != CALENDAR_ERROR_NONE, ret);
        }
 
        if (count <= 0)
        {
-               DBG("No alarm");
+               DBG("No extended");
        }
 
        return __cal_vcalendar_make_printf(b, "END:VEVENT", NULL);
 }
 
-int __cal_vcalendar_make_todo(cal_make_s *b, calendar_record_h record)
+int __cal_vcalendar_make_todo(int version, cal_make_s *b, calendar_record_h record)
 {
        int ret;
        int intval;
-       long long int llival;
-       char *strval = NULL;
        calendar_time_s caltime = {0};
        char *uri = NULL;
        char *tzid = NULL;
@@ -1017,64 +1502,45 @@ int __cal_vcalendar_make_todo(cal_make_s *b, calendar_record_h record)
        __cal_vcalendar_make_class(b, intval);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
 
-       // created_time
+       // dtstart_type
        ret = calendar_record_get_str_p(record, _calendar_todo.start_tzid, &tzid);
        ret = calendar_record_get_caltime(record, _calendar_todo.start_time, &caltime);
        if (ret != CALENDAR_ERROR_NONE) {
                ERR("Failed to get start_time(%d)", ret);
                return -1;
        }
+       ret = __cal_vcalendar_make_dtstart(b, tzid, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get dtstart(%d)", ret);
 
+       // created_time
+/* keis want to skip for there potential error.
        ret = calendar_record_get_lli(record, _calendar_todo.created_time, &llival);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get created_time(%d)", ret);
 
        ret = __cal_vcalendar_make_created(b, llival);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
+*/
 
        // description
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_todo.description, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get description(%d)", ret);
+       __cal_vcalendar_make_printf_str_p(record, _calendar_todo.description, b, "DESCRIPTION:");
 
-       if (strval) {
-               ret = __cal_vcalendar_make_description(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No description");
-       }
-
-       // dtstart_type
-       ret = __cal_vcalendar_make_dtstart(b, &caltime);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get dtstart(%d)", ret);
 
        // TODO : geo
 
        // last_mod
+/* keis want to skip for there potential error.
        ret = calendar_record_get_lli(record, _calendar_todo.last_modified_time, &llival);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get last_modified_time(%d)", ret);
 
        ret = __cal_vcalendar_make_last_mod(b, llival);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
+*/
 
        // location
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_todo.location, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get location(%d)", ret);
-
-       if (strval) {
-               ret = __cal_vcalendar_make_location(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No location");
-       }
+       __cal_vcalendar_make_printf_str_p(record, _calendar_todo.location, b, "LOCATION:");
 
        // priority
        ret = calendar_record_get_int(record, _calendar_todo.priority, &intval);
@@ -1088,77 +1554,173 @@ int __cal_vcalendar_make_todo(cal_make_s *b, calendar_record_h record)
        // TODO : seq
 
        // dtstamp
+/* keis want to skip for there potential error.
        ret = __cal_vcalendar_make_dtstamp(b, tzid);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
+*/
 
        // summary
-       strval = NULL;
-       ret = calendar_record_get_str_p(record, _calendar_todo.summary, &strval);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get summary(%d)", ret);
-
-       if (strval) {
-               ret = __cal_vcalendar_make_summary(b, strval);
-               retv_if(ret != CALENDAR_ERROR_NONE, ret);
-
-       } else {
-               DBG("No summary");
-       }
+       __cal_vcalendar_make_printf_str_p(record, _calendar_todo.summary, b, "SUMMARY:");
 
        // dtend
        ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
        retvm_if(ret != CALENDAR_ERROR_NONE, -1,
                        "Failed to get due_time(%d)", ret);
 
-       ret = __cal_vcalendar_make_due(b, &caltime);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "__cal_vcalendar_make_due() failed(%d)", ret);
+       ret = __cal_vcalendar_make_due(b, tzid, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "__cal_vcalendar_make_due() failed(%d)", ret);
+
+       // categories
+       __cal_vcalendar_make_printf_str_p(record, _calendar_todo.categories, b, "CATEGORIES:");
+
+       // uid
+       __cal_vcalendar_make_printf_str_p(record, _calendar_todo.uid, b, "UID:");
 
        // alarm
        unsigned int count;
        calendar_record_h child = NULL;
-       ret = calendar_record_get_child_record_count(record,
-                       _calendar_todo.calendar_alarm, &count);
-       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                       "Failed to get child count(%d)", ret);
+
+       switch (version)
+       {
+       case 1:
+               // In ver 1.0, only first alarm will be dealt with.
+               ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
+               if (count > 0)
+               {
+                       ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, 0, &child);
+                       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
+
+                       ret = __cal_vcalendar_make_aalarm(b, record, child);
+                       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               }
+               else
+               {
+                       DBG("No alarm in ver1.0");
+               }
+               break;
+
+       default:
+               ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
+
+               while (count > 0)
+               {
+                       count--;
+                       ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, count, &child);
+                       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
+
+                       ret = __cal_vcalendar_make_alarm(b, child);
+                       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               }
+
+               if (count <= 0)
+               {
+                       DBG("No alarm in ver2.0");
+               }
+       }
+
+       // extended
+       count = 0;
+       ret = calendar_record_get_child_record_count(record, _calendar_todo.extended, &count);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
 
        while (count > 0)
        {
                count--;
-               ret = calendar_record_get_child_record_at_p(record,
-                               _calendar_todo.calendar_alarm, count, &child);
-               retvm_if(ret != CALENDAR_ERROR_NONE, -1,
-                               "Failed to get child alarm(%d)", ret);
+               ret = calendar_record_get_child_record_at_p(record, _calendar_todo.extended, count, &child);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
 
-               ret = __cal_vcalendar_make_alarm(b, child);
+               ret = __cal_vcalendar_make_child_extended(b, child);
                retv_if(ret != CALENDAR_ERROR_NONE, ret);
        }
-
        if (count <= 0)
        {
-               DBG("No alarm");
+               DBG("No extended");
        }
 
        return __cal_vcalendar_make_printf(b, "END:VTODO", NULL);
 }
 
+int __cal_vcalendar_make_parent_extended(cal_make_s *b, calendar_list_h list, int *has_extended, int *version)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       GList *l = NULL;
+       cal_list_s *cal_list = (cal_list_s *)list;
+
+       if (NULL == list)
+       {
+               ERR("Invalid parameter: list is NULL");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       l = g_list_first(cal_list->record);
+       while (l)
+       {
+               char *uri = NULL;
+               calendar_record_h record = (calendar_record_h)l->data;
+               calendar_record_get_uri_p(record, &uri);
+               if (strncmp(uri, _calendar_extended_property._uri, strlen(_calendar_extended_property._uri)))
+               {
+                       l = g_list_next(l);
+                       continue;
+               }
+
+               *has_extended = 1;
+               cal_extended_s *extended = (cal_extended_s *)record;
+               if (NULL == extended)
+               {
+                       ERR("extended is NULL");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+               ret = __cal_vcalendar_make_printf(b, extended->key, extended->value);
+               DBG("extended key[%s] value[%s]", extended->key, extended->value);
+               if (!strncmp(extended->key, "VERSION", strlen("VERSION")))
+               {
+                       if (strstr(extended->value, "1.0"))
+                       {
+                               *version = 1;
+                       }
+                       else
+                       {
+                               *version = 2;
+                       }
+
+                       DBG("version (%s)", extended->value);
+                       break;
+               }
+               l = g_list_next(l);
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
 int _cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
 {
        int ret;
+       int version = 0;
+       int has_extended = 0;
        char *uri = NULL;
        calendar_record_h record;
 
        ret = __cal_vcalendar_make_printf(b, "BEGIN:VCALENDAR", NULL);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
 
-       ret = __cal_vcalendar_make_printf(b, "CALSCALE:GREGORIAN", NULL);
+       ret = __cal_vcalendar_make_parent_extended(b, list, &has_extended, &version);
        retv_if(ret != CALENDAR_ERROR_NONE, ret);
 
-       ret = __cal_vcalendar_make_printf(b, "PRODID:-//Samsung Electronics//Calendar//EN", NULL);
-       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       if (has_extended == 0)
+       {
+/* keis want to skip for there potential error.
+               ret = __cal_vcalendar_make_printf(b, "CALSCALE:GREGORIAN", NULL);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
 
-       ret = __cal_vcalendar_make_printf(b, "VERSION:2.0", NULL);
-       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               ret = __cal_vcalendar_make_printf(b, "PRODID:-//Samsung Electronics//Calendar//EN", NULL);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+*/
+
+               ret = __cal_vcalendar_make_printf(b, "VERSION:2.0", NULL);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
 
        ret = calendar_list_first(list);
        retvm_if(ret != CALENDAR_ERROR_NONE, ret,
@@ -1175,12 +1737,12 @@ int _cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
                ret = calendar_record_get_uri_p(record, &uri);
                if (!strcmp(uri, CALENDAR_VIEW_EVENT))
                {
-                       ret = __cal_vcalendar_make_schedule(b, record);
+                       ret = __cal_vcalendar_make_schedule(version, b, record);
 
                }
                else if (!strcmp(uri, CALENDAR_VIEW_TODO))
                {
-                       ret = __cal_vcalendar_make_todo(b, record);
+                       ret = __cal_vcalendar_make_todo(version, b, record);
 
                }
 
index 53113cc..a60ad8b 100644 (file)
@@ -45,7 +45,7 @@ struct _prop_func {
 
 struct _vcalendar_func {
        char *prop;
-       int (*func)(int ver, calendar_list_h list, calendar_record_h event, void *data);
+       int (*func)(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
 };
 
 struct _record_func {
@@ -54,8 +54,8 @@ struct _record_func {
 };
 
 char *_cal_vcalendar_parse_vcalendar(calendar_list_h *list_sch, void *data);
-char *_cal_vcalendar_parse_vevent(int ver, calendar_list_h *list_sch, void *data);
-char *_cal_vcalendar_parse_vtodo(int ver, calendar_list_h *list_sch, void *data);
+char *_cal_vcalendar_parse_vevent(int type, calendar_list_h *list_sch, void *data);
+char *_cal_vcalendar_parse_vtodo(int type, calendar_list_h *list_sch, void *data);
 char *_cal_vcalendar_parse_valarm(int type, calendar_record_h record, void *data);
 
 enum {
@@ -77,21 +77,21 @@ struct _prop_func _basic_funcs[VCAL_MAX] =
 //     {"METHOD", __cal_vcalendar_parse_method }
 };
 
-static int __cal_vcalendar_parse_dtstamp(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, void *data);
-static int __cal_vcalendar_parse_dtstart(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_created(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_description(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_last_mod(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_location(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_priority(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_status(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_summary(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_dtend(int ver, calendar_list_h list, calendar_record_h event, void *data);
-
-static int __cal_vcalendar_parse_completed(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_percent(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_dtstamp(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont);
+static int __cal_vcalendar_parse_dtstart(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_created(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_description(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_last_mod(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_location(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_priority(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_status(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_summary(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_rrule(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_dtend(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+
+static int __cal_vcalendar_parse_completed(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_percent(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
 
 enum {
        ATTENDEE_CUTYPE = 0x0,
@@ -132,9 +132,10 @@ struct _record_func _attendee_funcs[ATTENDEE_MAX] =
        { "DIR=", __cal_vcalendar_parse_attendee_dir }
 };
 
-static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_categories(int ver, calendar_list_h list, calendar_record_h event, void *data);
-static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_categories(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_aalarm(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont);
+static int __cal_vcalendar_parse_extended(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont);
 
 enum {
        VEVE_DTSTAMP = 0x0,
@@ -153,6 +154,7 @@ enum {
        VEVE_ATTENDEE,
        VEVE_CATEGORIES,
        VEVE_AALARM,    /* for ver 1.0 */
+       VEVE_EXTENDED,
        VEVE_MAX,
 };
 
@@ -174,6 +176,7 @@ struct _vcalendar_func _vevent_funcs[VEVE_MAX] =
        { "ATTENDEE", __cal_vcalendar_parse_attendee },
        { "CATEGORIES", __cal_vcalendar_parse_categories },
        { "AALARM", __cal_vcalendar_parse_aalarm },
+       { "X-", __cal_vcalendar_parse_extended },
 };
 
 static int __cal_vcalendar_parse_action(calendar_record_h alarm, void *data);
@@ -242,6 +245,7 @@ enum {
 //     VTODO_X_PROP,
 //     VTODO_IANA_PROP,
        VTODO_AALARM,   /* for ver 1.0 */
+       VTODO_EXTENDED,
        VTODO_MAX,
 };
 
@@ -261,6 +265,7 @@ struct _vcalendar_func _vtodo_funcs[VTODO_MAX] =
        { "SUMMARY", __cal_vcalendar_parse_summary },
        { "DUE", __cal_vcalendar_parse_dtend },
        { "AALARM", __cal_vcalendar_parse_aalarm },
+       { "X-", __cal_vcalendar_parse_extended },
 };
 
 static int __cal_vcalendar_parse_freq(calendar_record_h event, void *data);
@@ -427,25 +432,29 @@ int _cal_vcalendar_parse_unfolding(char *stream)
        retv_if(stream == NULL, CALENDAR_ERROR_INVALID_PARAMETER);
 
        p = stream;
-       while (*stream) {
-               if ('=' == *stream && '\r' == *(stream + 1) && '\n' == *(stream + 2))
+       while ('\0' != *p) {
+               if ('=' == *p && '\r' == *(p + 1) && '\n' == *(p + 2)) // ver 1.0
                {
-                       stream += 3;
+                       p += 3;
                }
-               else if ('\n' == *stream && ' ' == *(stream + 1))
+               else if ('=' == *p && '\n' == *(p + 1)) // ver 1.0 not spec but allow
                {
-                       stream += 2;
-                       p--;
+                       p += 2;
                }
-               else if ('\0' == *stream)
+               else if ('\r' == *p && '\n' == *(p + 1) && ' ' == *(p + 2)) // ver 2.0
                {
-                       DBG("break\n");
-                       break;
+                       p += 2;
                }
-               *p = *stream;
-               p++;
+               else if ('\n' == *p && ' ' == *(p + 1)) // ver 2.0 not spec but allow
+               {
+                       p += 1;
+               }
+               else
+               {
+               }
+               *stream = *p;
                stream++;
-
+               p++;
        }
        return CALENDAR_ERROR_NONE;
 }
@@ -509,8 +518,13 @@ char *_cal_vcalendar_parse_read_line(char *stream, char **prop, char **cont)
 
        while (*p) {
                switch (*p) {
+               case '\n': // not spec but allow
+                       p += 1 ;
+                       out = 1;
+                       break;
                case '\r':
                        if ('\n' == *(p + 1)) {
+                               p += 2;
                                out = 1;
                        }
                        break;
@@ -530,7 +544,6 @@ char *_cal_vcalendar_parse_read_line(char *stream, char **prop, char **cont)
        if (0 < i) {
                *cont = calloc(1, i);
                snprintf(*cont, i, "%s", q);
-               p += 2;
        } else {
                *prop = NULL;
                *cont = NULL;
@@ -554,32 +567,29 @@ static int __cal_vcalendar_parse_version(int *val, void *data)
        char *p = (char *)data;
 
        p++;
-       if (!strncmp(p, "1.0", strlen("1.0")))
+       DBG("version[%s]", p);
+       if (strstr(p, "1.0"))
        {
                DBG("version 1.0");
        }
-       else if (!strncmp(p, "2.0", strlen("2.0")))
-       {
-               DBG("version 2.0");
-       }
        else
        {
-               DBG("Invald version");
+               DBG("version 2.0");
        }
 
        return CALENDAR_ERROR_NONE;
 }
 
 /* vevnt */////////////////////////////////////////////////
-static int __cal_vcalendar_parse_dtstamp(int ver, calendar_list_h list, calendar_record_h event, void *data)
+static int __cal_vcalendar_parse_dtstamp(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont)
 {
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        p++;
 
@@ -598,6 +608,7 @@ static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_re
 static int __cal_vcalendar_parse_get_tzid_from_list(calendar_list_h list, const char *tzid, calendar_record_h *timezone)
 {
        GList *l = NULL;
+       int ret = 0;
 
        if (list == NULL || tzid == NULL)
        {
@@ -612,30 +623,32 @@ static int __cal_vcalendar_parse_get_tzid_from_list(calendar_list_h list, const
                char *uri = NULL;
                calendar_record_h record = (calendar_record_h)l->data;
                calendar_record_get_uri_p(record, &uri);
-               if (strncmp(uri, _calendar_timezone._uri, strlen(_calendar_timezone._uri)))
+               if (CALENDAR_ERROR_NONE == ret)
                {
-                       l = g_list_next(l);
-                       continue;
-               }
+                       if (strncmp(uri, _calendar_timezone._uri, strlen(_calendar_timezone._uri)))
+                       {
+                               l = g_list_next(l);
+                               continue;
+                       }
 
-               cal_timezone_s *tz = (cal_timezone_s *)record;
-               if (!strncmp(tz->standard_name, tzid, strlen(tzid)))
-               {
-                       DBG("Found same tzid[%s] in the list", tzid);
-                       *timezone = record;
-                       break;
+                       cal_timezone_s *tz = (cal_timezone_s *)record;
+                       if (!strncmp(tz->standard_name, tzid, strlen(tzid)))
+                       {
+                               DBG("Found same tzid[%s] in the list", tzid);
+                               *timezone = record;
+                               break;
+                       }
                }
-
                l = g_list_next(l);
        }
 
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_dtstart(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_dtstart(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
        int k = 0, j;
        char *tzid = NULL; // free after appling
        char buf[64] = {0, };
@@ -762,10 +775,10 @@ static int __cal_vcalendar_parse_dtstart(int type, calendar_list_h list, calenda
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_created(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_created(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        p++;
        switch (type)
@@ -819,16 +832,22 @@ static int __work_description_switch(int me, int mode, char *buf, int *charset,
        return mode;
 }
 
-static int __cal_vcalendar_parse_description(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_description(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
-       int i, j;
+       int i = 0, j;
        int ret;
        int len;
        int out;
        int mode;
        int charset, encoding;
        char buf[64] = {0};
-       char *p = (char *)data;
+       char *p = (char *)cont;
+
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
 
        i = j = 0;
        out = 0;
@@ -879,10 +898,10 @@ static int __cal_vcalendar_parse_description(int type, calendar_list_h list, cal
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_last_mod(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_last_mod(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        p++;
 
@@ -926,16 +945,22 @@ inline void __cal_vcalendar_parse_get_optional(char *p, int *encoding)
        }
 }
 
-static int __cal_vcalendar_parse_location(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_location(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
-       int i, j;
+       int i = 0, j;
        int ret;
        int len;
        int out;
        int mode;
        int charset, encoding;
        char buf[64] = {0};
-       char *p = (char *)data;
+       char *p = (char *)cont;
+
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
 
        i = j = 0;
        out = 0;
@@ -986,10 +1011,10 @@ static int __cal_vcalendar_parse_location(int type, calendar_list_h list, calend
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_priority(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_priority(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        p++;
        if (p[0] < '0' || p[0] > '9') {
@@ -1009,11 +1034,11 @@ static int __cal_vcalendar_parse_priority(int type, calendar_list_h list, calend
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_status(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_status(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
        int status;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        p++;
 
@@ -1073,16 +1098,22 @@ static int __cal_vcalendar_parse_status(int type, calendar_list_h list, calendar
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_summary(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_summary(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       int i, j;
+       int i = 0, j;
        int len;
        int out;
        int mode;
        int charset, encoding;
        char buf[64] = {0};
-       char *p = (char *)data;
+       char *p = (char *)cont;
+
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
 
        i = j = 0;
        out = 0;
@@ -1133,19 +1164,233 @@ static int __cal_vcalendar_parse_summary(int type, calendar_list_h list, calenda
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_record_h event, void *data)
+enum {
+       __RRULE_VER1_MODE_FREQ = 0x0,
+       __RRULE_VER1_MODE_NTH,
+       __RRULE_VER1_MODE_BY,
+       __RRULE_VER1_MODE_UNTIL,
+       __RRULE_VER1_MODE_OUT,
+};
+
+static int __cal_vcalendar_parse_rrule_ver1(calendar_record_h record, char *p)
+{
+       DBG("This is rrule for ver 1.0");
+       int ret;
+       int i, j;
+       int length;
+       int freq = CALENDAR_RECURRENCE_NONE;
+       int mode = 0; // 0:freq, 1:nth 2:bystr 3:range
+       int interval = 0;
+       unsigned int byint = 0; // 1:bymonthday 2:byday 3:bymonth 4:byyearday
+       int len;
+       int num = 0;
+       int y, mon, d, h, min, s;
+       char t1, z;
+       char **t;
+       char buf_by[256] = {0};
+       char buf[32] = {0};
+       calendar_time_s ut = {0};
+       cal_event_s *event = (cal_event_s *)record;
+
+       p++;
+       t = g_strsplit(p, " ", -1);
+       if (!t) {
+               ERR("g_strsplit failed");
+               g_strfreev(t);
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+       length = g_strv_length(t);
+       for (i = 0; i < length; i++)
+       {
+               if (t[i] == NULL || strlen(t[i]) == 0)
+               {
+                       continue;
+               }
+
+               switch (mode)
+               {
+               case __RRULE_VER1_MODE_FREQ: // freq
+                       mode = __RRULE_VER1_MODE_NTH;
+                       if (*t[i] == 'D')
+                       {
+                               DBG("CALENDAR_RECURRENCE_DAILY");
+                               freq = CALENDAR_RECURRENCE_DAILY;
+                               interval = strlen(t[i]) == 1 ? 1 : atoi(t[i] + 1);
+                               byint = _calendar_event.bymonthday;
+                       }
+                       else if (*t[i] == 'W')
+                       {
+                               DBG("CALENDAR_RECURRENCE_WEEKLY");
+                               freq = CALENDAR_RECURRENCE_WEEKLY;
+                               interval = strlen(t[i]) == 1 ? 1 : atoi(t[i] + 1);
+                               byint = _calendar_event.byday;
+                       }
+                       else if (*t[i] == 'M'&& *(t[i] + 1) == 'P')
+                       {
+                               DBG("CALENDAR_RECURRENCE_MONTHLY");
+                               freq = CALENDAR_RECURRENCE_MONTHLY;
+                               interval = strlen(t[i]) == 2 ? 1 : atoi(t[i] + 2);
+                               byint = _calendar_event.byday;
+                       }
+                       else if (*t[i] == 'M'&& *(t[i] + 1) == 'D')
+                       {
+                               DBG("CALENDAR_RECURRENCE_MONTHLY");
+                               freq = CALENDAR_RECURRENCE_MONTHLY;
+                               interval = strlen(t[i]) == 2 ? 1 : atoi(t[i] + 2);
+                               byint = _calendar_event.bymonthday;
+                       }
+                       else if (*t[i] == 'Y'&& *(t[i] + 1) == 'M')
+                       {
+                               DBG("CALENDAR_RECURRENCE_YEARLY");
+                               freq = CALENDAR_RECURRENCE_YEARLY;
+                               interval = strlen(t[i]) == 2 ? 1 : atoi(t[i] + 2);
+                               byint = _calendar_event.bymonth;
+                       }
+                       else if (*t[i] == 'Y'&& *(t[i] + 1) == 'D')
+                       {
+                               DBG("CALENDAR_RECURRENCE_YEARLY");
+                               freq = CALENDAR_RECURRENCE_YEARLY;
+                               interval = strlen(t[i]) == 2 ? 1 : atoi(t[i] + 2);
+                               byint = _calendar_event.byyearday;
+                       }
+                       else
+                       {
+                               ERR("Invalid ");
+                       }
+                       ret = _cal_record_set_int(record, _calendar_event.freq, freq);
+                       DBG("interval(%d)", interval);
+                       ret = _cal_record_set_int(record, _calendar_event.interval, interval);
+                       break;
+
+               case __RRULE_VER1_MODE_NTH: // num
+                       mode = __RRULE_VER1_MODE_BY;
+                       if (byint != _calendar_event.byday || *t[i] < '1' || *t[i] > '9')
+                       {
+                               DBG("No nth");
+                               i--;
+                               break;
+                       }
+
+                       num = 0;
+                       memset(buf, 0x0, sizeof(buf));
+                       len = strlen(t[i]);
+                       for (j = 0; j < len; j++)
+                       {
+                               if (*(t[i] + j) >= '1' && *(t[i] + j) <= '9')
+                               {
+                                       buf[j] = *(t[i] + j);
+                               }
+                               else if (*(t[i] + j) == '-')
+                               {
+                                       num = atoi(buf);
+                                       num *= -1;
+                               }
+                               else
+                               {
+                               }
+                       }
+                       DBG("nth(%d)", num);
+                       break;
+
+               case __RRULE_VER1_MODE_BY:
+                       mode = __RRULE_VER1_MODE_UNTIL;
+                       if (*t[i] == '#' || strlen(t[i]) > strlen("YYYYMMDD"))
+                       {
+                               DBG("No by");
+                               i--;
+                               break;
+                       }
+
+                       memset(buf, 0x0, sizeof(buf));
+                       if (num > 0)
+                       {
+                               snprintf(buf, sizeof(buf), "%d%s", num, t[i]);
+                       }
+                       else
+                       {
+                               snprintf(buf, sizeof(buf), "%s", t[i]);
+                       }
+
+                       strcat(buf_by, buf);
+                       break;
+
+               case __RRULE_VER1_MODE_UNTIL: // until
+                       mode = __RRULE_VER1_MODE_OUT; // out
+                       if (*t[i] == '#')
+                       {
+                               num = atoi(t[i] + 1);
+                               if (num == 0)
+                               {
+                                       DBG("CALENDAR_RANGE_NONE");
+                                       ret = _cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_NONE);
+                               }
+                               else
+                               {
+                                       DBG("CALENDAR_RANGE_COUNT(%d)", num);
+                                       ret = _cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_COUNT);
+                                       ret = _cal_record_set_int(record, _calendar_event.count, num);
+                               }
+                       }
+                       else
+                       {
+                               sscanf(t[i], "%4d%2d%2d%c%2d%2d%2d%c", &y, &mon, &d, &t1, &h, &min, &s, &z);
+                               switch (event->start.type)
+                               {
+                               case CALENDAR_TIME_UTIME:
+                                       ut.type = CALENDAR_TIME_UTIME;
+                                       ut.time.utime = _cal_time_convert_itol(event->start_tzid,
+                                                       y, mon, d, h, min, s);
+                                       DBG("CALENDAR_RANGE_UNTIL(%lld)", ut.time.utime);
+                                       break;
+                               case CALENDAR_TIME_LOCALTIME:
+                                       ut.type = CALENDAR_TIME_LOCALTIME;
+                                       ut.time.date.year = y;
+                                       ut.time.date.month = mon;
+                                       ut.time.date.mday = d;
+                                       DBG("CALENDAR_RANGE_UNTIL(%04d/%02d/%02d)", y, mon, d);
+                                       break;
+                               }
+                               ret = _cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
+                               ret = _cal_record_set_caltime(record, _calendar_event.until_time, ut);
+                       }
+                       break;
+
+               default:
+                       mode = __RRULE_VER1_MODE_OUT;
+                       break;
+               }
+
+               if (mode == __RRULE_VER1_MODE_OUT)
+               {
+                       break;
+               }
+       }
+       if (strlen(buf_by) > 0)
+       {
+               DBG("bystr[%s]", buf_by);
+               ret = _cal_record_set_str(record, byint, buf_by);
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_rrule(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
        int i, j, k;
        int mode;
        int version = 0;
        char buf[64] = {0};
-       char *tzid;
-       char *p = (char *)data;
+       char *p = (char *)cont;
 
        i = j = 0;
        mode = 0;
 
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
        if (strstr(p, "FREQ=")) {
                DBG("This is version 2");
                version = 2;
@@ -1156,7 +1401,7 @@ static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_r
 
        if (version == 2) {
                i = j = 0;
-               ret = _cal_record_set_int(event, _calendar_event.interval, 1);
+               ret = _cal_record_set_int(record, _calendar_event.interval, 1);
                /* this is for ver 2 */
                while (p[i] != '\0') {
                        DBG("[%c](%d)", p[i], i);
@@ -1170,7 +1415,7 @@ static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_r
 
                                for (k = 0; k < RRULE_MAX; k++) {
                                        if (!strncmp(buf, _rrule_funcs[k].prop, strlen(_rrule_funcs[k].prop))) {
-                                               _rrule_funcs[k].func(event, buf + strlen(_rrule_funcs[k].prop));
+                                               _rrule_funcs[k].func(record, buf + strlen(_rrule_funcs[k].prop));
                                                break;
                                        }
                                }
@@ -1189,186 +1434,23 @@ static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_r
                for (i = 0; i < RRULE_MAX; i++) {
                        if (!strncmp(buf, _rrule_funcs[i].prop, strlen(_rrule_funcs[i].prop))) {
                                version = 2;
-                               _rrule_funcs[i].func(event, buf + strlen(_rrule_funcs[i].prop));
+                               _rrule_funcs[i].func(record, buf + strlen(_rrule_funcs[i].prop));
                                break;
                        }
                }
                return CALENDAR_ERROR_NONE;
        }
 
-       /* this is for ver 1 */
-       int freq = 0;
-       int interval;
-       char by[64] = {0};
-       char _by[64] = {0};
-       char date[8] = {0};
-       int tmp;
-       int is_wday = 0;
-       int y, mon, d, h, min, s;
-       char t, z;
-       calendar_time_s stime;
-       i = 0;
-       mode = 0;
-       interval = 0;
-
-       ret = calendar_record_get_str(event, _calendar_event.start_tzid, &tzid);
-       ret = calendar_record_get_caltime(event, _calendar_event.start_time, &stime);
-
-       while (p[i] != '\0') {
-               switch (p[i]) {
-               case ':':
-               case ' ':
-                       if (mode == 0) {
-                               DBG("in mode 1");
-                               mode = 1;
-
-                       } else if (mode == 1) {
-                               DBG("in mode 2");
-                               mode = 2;
-                               buf[j] = '\0';
-                               if (buf[0] == 'D') {
-                                       freq = CALENDAR_RECURRENCE_DAILY;
-
-                               } else if (buf[0] == 'W') {
-                                       freq = CALENDAR_RECURRENCE_WEEKLY;
-
-                               } else if (buf[0] == 'M') {
-                                       freq = CALENDAR_RECURRENCE_MONTHLY;
-
-                               } else if (buf[0] == 'Y') {
-                                       freq = CALENDAR_RECURRENCE_YEARLY;
-
-                               } else {
-                                       freq = CALENDAR_RECURRENCE_NONE;
-
-                               }
-                               ret = _cal_record_set_int(event, _calendar_event.freq, freq);
-
-                               if (buf[1] >= '1' && buf[1] <= '9') {
-                                       interval = atoi(&buf[1]);
-                               } else {
-                                       interval = atoi(&buf[2]);
-                               }
-                               DBG("interval(%d)", interval);
-                               ret = _cal_record_set_int(event, _calendar_event.interval, interval);
-                               memset(buf, 0x0, sizeof(buf));
-
-                       } else {
-                               mode = 3;
-                               DBG("in mode 3");
-                               DBG("remained buf[%s]", buf);
-
-
-                               DBG("len(%d)", strlen(by));
-                               if (strlen(by) < 1) {
-                                       DBG("ret(%d)", atoi(buf));
-                                       if (buf[0] >= '1' && buf[0] <= '9') {
-                                               DBG("Set digit");
-                                               is_wday = 0;
-                                       } else {
-                                               DBG("Set wday [%s]", buf);
-                                               is_wday = 1;
-                                       }
-                                       DBG("1[%s][%s]", by, buf);
-                                       snprintf(_by, sizeof(by), "%s", buf);
-
-                               } else {
-                                       DBG("2[%s][%s]", by, buf);
-                                       snprintf(_by, sizeof(by), "%s %s", by, buf);
-                               }
-                               memcpy(by, _by, sizeof(_by));
-
-
-                               buf[j] = '\0';
-                               DBG("end statement[%s]", buf);
-                               DBG("freq(%d}", freq);
-                               switch (freq) {
-                               case CALENDAR_RECURRENCE_YEARLY:
-                                       ret = _cal_record_set_str(event, _calendar_event.bymonth, by);
-                                       _cal_time_ltoi(tzid, stime.time.utime, NULL, NULL, &tmp);
-                                       snprintf(date, sizeof(date), "%d", tmp);
-                                       ret = _cal_record_set_str(event, _calendar_event.bymonthday, date);
-                                       break;
-
-                               case CALENDAR_RECURRENCE_MONTHLY:
-                                       _cal_time_ltoi(tzid, stime.time.utime, NULL, &tmp, NULL);
-                                       snprintf(date, sizeof(date), "%d", tmp);
-                                       ret = _cal_record_set_str(event, _calendar_event.bymonth, date);
-
-                                       if (is_wday) {
-                                               ret = _cal_record_set_str(event, _calendar_event.byday, by);
-                                       } else {
-                                               ret = _cal_record_set_str(event, _calendar_event.bymonthday, by);
-                                       }
-                                       break;
-
-                               case CALENDAR_RECURRENCE_WEEKLY:
-                                       DBG("set weekly[%s]", by);
-                                       ret = _cal_record_set_str(event, _calendar_event.byday, by);
-                                       break;
-
-                               case CALENDAR_RECURRENCE_DAILY:
-                                       DBG("set daily[%s]", by);
-                                       ret = _cal_record_set_str(event, _calendar_event.byday, by);
-                                       break;
-                               default:
-                                       DBG("Nothing to set");
-                                       break;
-                               }
-                       }
-                       j = 0;
-                       memset(buf, 0x0, sizeof(buf));
-                       break;
-
-               default:
-                       buf[j] = p[i];
-                       j++;
-                       break;
-               }
-               i++;
-       }
-
-       DBG("freq(%d) interval(%d) by[%s]", freq, interval, by);
-
-       i = 0;
-       DBG("buf[%s]", buf);
-       calendar_time_s caltime = {0};
-       if (buf[i] == '#') {
-               if (buf[i + 1] == '0')
-               {
-                       DBG("count 0 and means endless");
-                       ret = _cal_record_set_int(event, _calendar_event.range_type,
-                                       CALENDAR_RANGE_NONE);
-               }
-               else
-               {
-                       DBG("until count [%s]", &buf[i+1]);
-                       ret = _cal_record_set_int(event, _calendar_event.range_type,
-                                       CALENDAR_RANGE_COUNT);
-                       ret = _cal_record_set_int(event, _calendar_event.count,
-                                       atoi(&buf[i+1]));
-               }
-
-       } else {
-               ret = _cal_record_set_int(event, _calendar_event.range_type,
-                               CALENDAR_RANGE_UNTIL);
-               DBG("untiltime[%s]", &buf[i]);
-               sscanf(&buf[i], "%4d%2d%2d%c%2d%2d%2d%c",
-                               &y, &mon, &d, &t, &h, &min, &s, &z);
-               caltime.type = CALENDAR_TIME_UTIME;
-               caltime.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
-               ret = _cal_record_set_caltime(event, _calendar_event.until_time, caltime);
-       }
-
-       CAL_FREE(tzid);
+       // for ver 1.0
+       __cal_vcalendar_parse_rrule_ver1(record, p);
 
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_dtend(int type, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_dtend(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
-       char *p = (char *)data;
+       char *p = (char *)cont;
        int k = 0, j;
        char buf[64] = {0, };
        char *tzid = NULL;
@@ -1491,12 +1573,12 @@ static int __cal_vcalendar_parse_dtend(int type, calendar_list_h list, calendar_
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_completed(int ver, calendar_list_h list, calendar_record_h event, void *data)
+static int __cal_vcalendar_parse_completed(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont)
 {
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_percent(int ver, calendar_list_h list, calendar_record_h event, void *data)
+static int __cal_vcalendar_parse_percent(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont)
 {
        return CALENDAR_ERROR_NONE;
 }
@@ -1595,11 +1677,11 @@ int _work_attendee_property(calendar_record_h attendee, char *buf)
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calendar_record_h event, void *data)
+static int __cal_vcalendar_parse_attendee(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont)
 {
        int ret;
        int i, j;
-       char *p = (char *)data;
+       char *p = (char *)cont;
        calendar_record_h attendee;
 
        ret = calendar_record_create(_calendar_attendee._uri, &attendee);
@@ -1611,6 +1693,12 @@ static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calenda
        int mode = 0;
        char buf[64] = {0};
 
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
        while (p[i] != '\0') {
                switch (p[i]) {
                case ':':
@@ -1662,9 +1750,9 @@ static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calenda
 }
 
 
-static int __cal_vcalendar_parse_categories(int ver, calendar_list_h list, calendar_record_h event, void *data)
+static int __cal_vcalendar_parse_categories(int type, calendar_list_h list, calendar_record_h event, char *prop, char *cont)
 {
-       char *p = (char *)data;
+       char *p = (char *)cont;
        int encoding = 0;
 
        while (*p != '\n' && *p != '\r' && *p != '\0') {
@@ -1693,7 +1781,70 @@ static int __cal_vcalendar_parse_categories(int ver, calendar_list_h list, calen
                        p++;
                }
        }
-       DBG("ver(%d)categories(%s)\n", ver, p);
+       DBG("type(%d)categories(%s)\n", type, p);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_extended(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
+{
+       int ret;
+       int id;
+       calendar_record_h extended = NULL;
+
+       ret = calendar_record_create(_calendar_extended_property._uri, &extended);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_create() failed");
+               return ret;
+       }
+
+       DBG("key[%s]value[%s]", prop, cont +1);
+       ret = calendar_record_set_str(extended, _calendar_extended_property.key, prop);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_set_str() failed");
+               return ret;
+       }
+       ret = calendar_record_set_str(extended, _calendar_extended_property.value, cont +1);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_set_str() failed");
+               return ret;
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = calendar_record_get_int(record, _calendar_event.id, &id);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_get_int() failed");
+                       return ret;
+               }
+               ret = calendar_record_add_child_record(record, _calendar_event.extended, extended);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_add_child_record() failed");
+                       return ret;
+               }
+               break;
+
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = calendar_record_get_int(record, _calendar_todo.id, &id);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_get_int() failed");
+                       return ret;
+               }
+               ret = calendar_record_add_child_record(record, _calendar_todo.extended, extended);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_add_child_record() failed");
+                       return ret;
+               }
+               break;
+       }
 
        return CALENDAR_ERROR_NONE;
 }
@@ -1712,7 +1863,7 @@ enum {
        __AALARM_REPEATCOUNT,
        __AALARM_AUDIOCONTENT,
 };
-static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_record_h record, void *data)
+static int __cal_vcalendar_parse_aalarm(int type, calendar_list_h list, calendar_record_h record, char *prop, char *cont)
 {
        int ret;
        int i = 0, j = 0;
@@ -1720,7 +1871,13 @@ static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_
        int y, mon, d, h, min, s;
        char t, z;
        char buf[64] = {0};
-       char *p = (char *)data;
+       char *p = (char *)cont;
+
+       if (p[i + 1] == '\0')
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
 
        while (p[i] != '\0')
        {
@@ -1781,6 +1938,11 @@ static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_
 
                case __AALARM_RUNTIME:
                        y = mon = d = h = min = s = 0;
+                       if (strlen(buf) < strlen("YYYYMMDD"))
+                       {
+                               ERR("Invalid until[%s]", buf);
+                               return CALENDAR_ERROR_INVALID_PARAMETER;
+                       }
                        sscanf(buf, "%04d%02d%02d%c%02d%02d%02d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
                        DBG("%d %d %d %d %d %d", y, mon, d, h, min, s);
                        break;
@@ -1809,7 +1971,7 @@ static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_
        int tick = 0, unit = 0;
        calendar_record_h alarm = NULL;
        calendar_time_s caltime = {0};
-       switch (ver)
+       switch (type)
        {
        case VCALENDAR_TYPE_VEVENT:
                ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
@@ -2233,7 +2395,7 @@ static int __cal_vcalendar_parse_until(calendar_record_h event, void *data)
        /* until value type has the same value as the dtstart */
        ret = _cal_record_set_int(event, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
 
-       ret = calendar_record_get_str(event, _calendar_event.start_tzid, &tzid);
+       ret = calendar_record_get_str_p(event, _calendar_event.start_tzid, &tzid);
        ret = calendar_record_get_caltime(event, _calendar_event.start_time, &stime);
        until.type = stime.type;
 
@@ -2252,7 +2414,6 @@ static int __cal_vcalendar_parse_until(calendar_record_h event, void *data)
                break;
        }
        ret = _cal_record_set_caltime(event, _calendar_event.until_time, until);
-       CAL_FREE(tzid);
 
        return CALENDAR_ERROR_NONE;
 }
@@ -2532,7 +2693,7 @@ static int __cal_vcalendar_parse_encoding(int *val, void *data)
 
 // end parse func////////////////////////////////////////////////////////////////
 
-char *_cal_vcalendar_parse_vevent(int ver, calendar_list_h *list_sch, void *data)
+char *_cal_vcalendar_parse_vevent(int type, calendar_list_h *list_sch, void *data)
 {
        DBG("[%s]", __func__);
        int i;
@@ -2562,7 +2723,7 @@ char *_cal_vcalendar_parse_vevent(int ver, calendar_list_h *list_sch, void *data
                } else {
                        for (i = 0; i < VEVE_MAX; i++) {
                                if (!strncmp(prop, _vevent_funcs[i].prop, strlen(_vevent_funcs[i].prop))) {
-                                       _vevent_funcs[i].func(ver, *list_sch, event, cont);
+                                       _vevent_funcs[i].func(type, *list_sch, event, prop, cont);
                                        break;
                                }
                        }
@@ -2612,7 +2773,7 @@ char *_cal_vcalendar_parse_vtodo(int type, calendar_list_h *list_sch, void *data
                } else {
                        for (i = 0; i < VTODO_MAX; i++) {
                                if (!strncmp(prop, _vtodo_funcs[i].prop, strlen(_vtodo_funcs[i].prop))) {
-                                       _vtodo_funcs[i].func(type, *list_sch, todo, cont);
+                                       _vtodo_funcs[i].func(type, *list_sch, todo, prop, cont);
                                        break;
                                }
                        }
@@ -2982,14 +3143,44 @@ char *_cal_vcalendar_parse_vcalendar(calendar_list_h *list, void *data)
                        break;
                }
 
-               if (!strncmp(prop, "PRODID", strlen("PRODID"))) {
-                       _basic_funcs[VCAL_PRODID].func(NULL, cont);
+               calendar_record_h extended = NULL;
+               ret = calendar_record_create(_calendar_extended_property._uri, &extended);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_create() failed");
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       break;
+               }
 
-               } else if (!strncmp(prop, "VERSION", strlen("VERSION"))) {
-                       _basic_funcs[VCAL_VERSION].func(NULL, cont);
+               ret = calendar_record_set_str(extended, _calendar_extended_property.key, prop);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_set_str() failed");
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       calendar_record_destroy(extended, true);
+                       break;
+               }
 
-               } else {
+               ret = calendar_record_set_str(extended, _calendar_extended_property.value, cont);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_set_str() failed");
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       calendar_record_destroy(extended, true);
+                       break;
+               }
 
+               ret = calendar_list_add(l, extended);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_set_str() failed");
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       calendar_record_destroy(extended, true);
+                       break;
                }
 
                CAL_FREE(prop);
index c67f2b5..ad3a92a 100644 (file)
 #ifndef __CAL_IPC_H__
 #define __CAL_IPC_H__
 
-#define CAL_IPC_SERVICE              "cal_svc_ipc"
-#define CAL_IPC_SOCKET_PATH          "/opt/usr/data/calendar-svc/."CAL_IPC_SERVICE
-#define CAL_IPC_MODULE               "cal_ipc_module"
+#define CAL_IPC_SERVICE                             "cal_svc_ipc"
+#define CAL_IPC_SOCKET_PATH                         "/opt/usr/data/calendar-svc/."CAL_IPC_SERVICE
+#define CAL_IPC_SOCKET_PATH_FOR_SUBSCRIPTION        "/opt/usr/data/calendar-svc/."CAL_IPC_SERVICE"_for_subscription"
+#define CAL_IPC_MODULE                              "cal_ipc_module"
+#define CAL_IPC_MODULE_FOR_SUBSCRIPTION             CAL_IPC_MODULE"_for_subscription"
 
 #define CAL_IPC_SERVER_CONNECT                      "connect"
 #define CAL_IPC_SERVER_DISCONNECT                   "disconnect"
index 7ac5984..dd4131c 100644 (file)
@@ -1106,7 +1106,8 @@ int _cal_ipc_unmarshal_list(const pims_ipc_data_h ipc_data, calendar_list_h* lis
     if (_cal_ipc_unmarshal_int(ipc_data,&(count)) != CALENDAR_ERROR_NONE)
     {
         ERR("_cal_ipc_unmarshal fail");
-        return CALENDAR_ERROR_INVALID_PARAMETER;
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
     }
 
     for(i=0;i<count;i++)
index 5868799..4d732af 100644 (file)
@@ -169,18 +169,55 @@ static int __dft_event_set_3(calendar_record_h event, int occurence, int status,
 {
        int ret;
 
+       switch (occurence)
+       {
+       case CALENDAR_RECURRENCE_NONE:
+       case CALENDAR_RECURRENCE_DAILY:
+       case CALENDAR_RECURRENCE_WEEKLY:
+       case CALENDAR_RECURRENCE_MONTHLY:
+       case CALENDAR_RECURRENCE_YEARLY:
+           break;
+       default:
+               printf("Out of range, so set CALENDAR_RECURRENCE_NONE\n");
+               occurence = CALENDAR_RECURRENCE_NONE;
+               break;
+       }
        ret = calendar_record_set_int(event, _calendar_event.count, occurence);
        if(CALENDAR_ERROR_NONE != ret)
        {
                printf("failed to set _calendar_event.count\n");
                return -1;
        }
+       switch (status)
+       {
+       case CALENDAR_EVENT_BUSY_STATUS_FREE:
+       case CALENDAR_EVENT_BUSY_STATUS_BUSY:
+       case CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE:
+       case CALENDAR_EVENT_BUSY_STATUS_TENTATIVE:
+               break;
+       default:
+               printf("Out of range, so set CALENDAR_EVENT_BUSY_STATUS_FREE\n");
+               status = CALENDAR_EVENT_BUSY_STATUS_FREE;
+               break;
+       }
        ret = calendar_record_set_int(event, _calendar_event.busy_status, status);
        if(CALENDAR_ERROR_NONE != ret)
        {
                printf("failed to set _calendar_event.busy_status\n");
                return -1;
        }
+
+       switch (sensitivity)
+       {
+       case CALENDAR_SENSITIVITY_PUBLIC:
+       case CALENDAR_SENSITIVITY_PRIVATE:
+       case CALENDAR_SENSITIVITY_CONFIDENTIAL:
+               break;
+       default:
+               printf("Out of range, so set CALENDAR_SENSITIVITY_PUBLIC\n");
+               sensitivity = CALENDAR_SENSITIVITY_PUBLIC;
+               break;
+       }
        ret = calendar_record_set_int(event, _calendar_event.sensitivity, sensitivity);
        if(CALENDAR_ERROR_NONE != ret)
        {
@@ -296,18 +333,57 @@ static int __dft_todo_set_3(calendar_record_h todo, int occurence, int status, i
 {
        int ret;
 
+       switch (occurence)
+       {
+       case CALENDAR_RECURRENCE_NONE:
+       case CALENDAR_RECURRENCE_DAILY:
+       case CALENDAR_RECURRENCE_WEEKLY:
+       case CALENDAR_RECURRENCE_MONTHLY:
+       case CALENDAR_RECURRENCE_YEARLY:
+           break;
+       default:
+               printf("Out of range, so set CALENDAR_RECURRENCE_NONE\n");
+               occurence = CALENDAR_RECURRENCE_NONE;
+               break;
+       }
        ret = calendar_record_set_int(todo, _calendar_todo.count, occurence);
        if(CALENDAR_ERROR_NONE != ret)
        {
                printf("failed to set _calendar_todo.count\n");
                return -1;
        }
+
+       switch (status)
+       {
+       case CALENDAR_TODO_STATUS_NONE:
+       case CALENDAR_TODO_STATUS_NEEDS_ACTION:
+       case CALENDAR_TODO_STATUS_COMPLETED:
+       case CALENDAR_TODO_STATUS_IN_PROCESS:
+       case CALENDAR_TODO_STATUS_CANCELED:
+               break;
+       default:
+               printf("Out of range, so set ALENDAR_TODO_STATUS_NEEDS_ACTION\n");
+               status = CALENDAR_TODO_STATUS_NEEDS_ACTION;
+               break;
+       }
        ret = calendar_record_set_int(todo, _calendar_todo.todo_status, status);
        if(CALENDAR_ERROR_NONE != ret)
        {
                printf("failed to set _calendar_todo.todo_status\n");
                return -1;
        }
+
+       switch (sensitivity)
+       {
+       case CALENDAR_SENSITIVITY_PUBLIC:
+       case CALENDAR_SENSITIVITY_PRIVATE:
+       case CALENDAR_SENSITIVITY_CONFIDENTIAL:
+               break;
+       default:
+               printf("Out of range, so set CALENDAR_SENSITIVITY_PUBLIC\n");
+               sensitivity = CALENDAR_SENSITIVITY_PUBLIC;
+               break;
+       }
        ret = calendar_record_set_int(todo, _calendar_todo.sensitivity, sensitivity);
        if(CALENDAR_ERROR_NONE != ret)
        {
index f784611..c787bea 100644 (file)
@@ -166,6 +166,7 @@ API int calendar_db_get_records_with_query( calendar_query_h query, int offset,
  * @brief       Cleans data after sync
  *
  * @param[in]   calendar_book_id                       The calendar book ID
+ * @param[in]   calendar_db_version         The calendar database version
  *
  * @return  0 on success, otherwise a negative error value.
  * @retval  #CALENDAR_ERROR_NONE                               Successful
@@ -177,7 +178,7 @@ API int calendar_db_get_records_with_query( calendar_query_h query, int offset,
  *
  * @see calendar_connect()
  */
-API int calendar_db_clean_after_sync( int calendar_book_id ); // calendar_svc_clean_after_sync  for EAS sync
+API int calendar_db_clean_after_sync( int calendar_book_id, int calendar_db_version ); // calendar_svc_clean_after_sync  for EAS sync
 
 /**
  * @brief       Gets records count of a specific view
index aa3b843..30de646 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __TIZEN_SOCAIL_CALENDAR_REMINDER_H__
 #define __TIZEN_SOCAIL_CALENDAR_REMINDER_H__
 
+#include <calendar_types2.h>
+
 #ifndef API
 #define API __attribute__ ((visibility("default")))
 #endif
@@ -100,7 +102,35 @@ API int calendar_reminder_deactivate_receiver(const char *pkgname);
  *
  * @see calendar_reminder_remove_receiver()
  */
-API bool calendar_reminder_has_receiver(const char *pkgname);
+API int calendar_reminder_has_receiver(const char *pkgname);
+
+/**
+ * @brief   Adds callback to get noti when alarm alerts.
+ *
+ * @param[in]   callback                           Callback to add.
+ * @param[in]   user_data                              The user data
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_cb()
+ */
+API int calendar_reminder_add_cb(calendar_reminder_cb callback, void *user_data);
+
+/**
+ * @brief   Removes callback to get noti when alarm alerts.
+ *
+ * @param[in]   callback                           Callback to remove.
+ * @param[in]   user_data                              The user data
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_add_cb()
+ */
+API int calendar_reminder_remove_cb(calendar_reminder_cb callback, void *user_data);
 
 /**
  * @}
index 1137755..5fe2ef5 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <tizen.h>
 #include <calendar_errors.h>
+#include <bundle.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -110,6 +111,16 @@ typedef void (*calendar_db_insert_result_cb)( int error, int* record_id_array, i
 typedef void (*calendar_db_changed_cb)(const char* view_uri, void* user_data);
 
 /**
+ * @brief       Called when alarm is alerted.
+ *
+ * @param[in]   b                      bundle
+ * @param[in]   user_data      The user data passed from the callback registration function
+ *
+ * @see calendar_db_add_changed_cb()
+ */
+typedef void (*calendar_reminder_cb)(bundle *b, void* user_data);
+
+/**
  * @brief Definition for calendar connect flag
  */
 #define CALENDAR_CONNECT_FLAG_NONE         0x00000000
index 695e6d3..6f958e4 100644 (file)
@@ -789,11 +789,12 @@ API int calendar_db_get_records_with_query( calendar_query_h query, int offset,
        return CALENDAR_ERROR_NONE;
 }
 
-API int calendar_db_clean_after_sync( int calendar_book_id )
+API int calendar_db_clean_after_sync( int calendar_book_id,  int calendar_db_version )
 {
     int ret;
     char query[CAL_DB_SQL_MIN_LEN] = {0};
     cal_db_util_error_e dbret = CAL_DB_OK;
+    int len = 0;
 
     retvm_if(calendar_book_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_id(%d) is Invalid", calendar_book_id);
 
@@ -802,10 +803,14 @@ API int calendar_db_clean_after_sync( int calendar_book_id )
     // !! please check rrule_table, alarm_table, attendee_table ..
 
     /* delete event table */
-    snprintf(query, sizeof(query), "DELETE FROM %s "
+    len = snprintf(query, sizeof(query), "DELETE FROM %s "
             "WHERE is_deleted = 1 AND calendar_id = %d",
             CAL_TABLE_SCHEDULE,
             calendar_book_id);
+    if (calendar_db_version > 0)
+    {
+        len = snprintf(query+len, sizeof(query)-len, " AND changed_ver <= %d", calendar_db_version);
+    }
 
     dbret = _cal_db_util_query_exec(query);
     CAL_DBG("%s",query);
index 5f4578b..e74ea36 100644 (file)
@@ -1775,13 +1775,21 @@ static int __cal_db_instance_publish_record_details(UCalendar *ucal, cal_event_s
                return CALENDAR_ERROR_INVALID_PARAMETER;
        }
 
-
        int duration = -1;
+       int exception_freq; // for exception
        long long int range = 0;
        calendar_time_s until = {0};
 
        __cal_db_instance_get_duration(ucal, &event->start, &event->end, &duration);
 
+       if (event->original_event_id > 0)
+       {
+               DBG("this is exception event so publish only one instance");
+               exception_freq = event->freq;
+               event->freq = CALENDAR_RECURRENCE_NONE;
+       }
+
+
        switch (event->range_type)
        {
        case CALENDAR_RANGE_COUNT:
@@ -1867,6 +1875,12 @@ static int __cal_db_instance_publish_record_details(UCalendar *ucal, cal_event_s
                __cal_db_instance_apply_setpos(event->index, &event->start, event, event->freq);
        }
 
+       if (event->original_event_id > 0)
+       {
+               DBG("return freq for exception event");
+               event->freq = exception_freq;
+       }
+
        return CALENDAR_ERROR_NONE;
 }
 
index bf4f071..780a049 100644 (file)
@@ -63,7 +63,7 @@ static int __cal_db_event_update_dirty(calendar_record_h record);
 bool __cal_db_event_check_changed_rrule(record);
 */
 static int __cal_db_event_exception_get_records(int original_id, GList **out_list);
-static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, calendar_list_h *hlist);
+static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, int calendar_id, calendar_list_h *hlist);
 static int __cal_db_event_exception_delete_with_id(int original_id);
 
 cal_db_plugin_cb_s _cal_db_event_plugin_cb = {
@@ -146,6 +146,34 @@ static int __cal_db_event_check_value_validation(cal_event_s *event)
        return CALENDAR_ERROR_NONE;
 }
 
+static int __cal_db_event_update_original_event_version(int original_event_id, int version)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       DBG("original_event(%d) changed_ver updated", original_event_id);
+       if (original_event_id > 0)
+       {
+               snprintf(query, sizeof(query), "UPDATE %s SET "
+                               "changed_ver = %d WHERE id = %d ",
+                               CAL_TABLE_SCHEDULE, version, original_event_id);
+
+               dbret = _cal_db_util_query_exec(query);
+               if(CAL_DB_DONE != dbret)
+               {
+                       ERR("_cal_db_util_query_exec() Failed");
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
 static int __cal_db_event_insert_record(calendar_record_h record, int* id)
 {
        int ret = -1;
@@ -350,6 +378,10 @@ static int __cal_db_event_insert_record(calendar_record_h record, int* id)
        event_id = _cal_db_util_last_insert_id();
        sqlite3_finalize(stmt);
 
+       // update parent event changed ver in case this event is exception mod
+       // which is original_event_id > 0
+       __cal_db_event_update_original_event_version(event->original_event_id, input_ver);
+
        calendar_record_get_int(record, _calendar_event.id, &tmp);
        _cal_record_set_int(record, _calendar_event.id, event_id);
        if (id)
@@ -389,18 +421,21 @@ static int __cal_db_event_insert_record(calendar_record_h record, int* id)
                DBG("No attendee");
        }
 
-       if (event->exception_list)
+       if (event->original_event_id < 0)
        {
-           DBG("insert exception");
-        list = NULL;
-        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event_id, &list);
-        ret = calendar_db_insert_records(list, NULL, NULL);
-        ret = calendar_list_destroy(list, false);
+               if (event->exception_list)
+               {
+                       DBG("insert exception");
+                       list = NULL;
+                       ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event_id, event->calendar_id, &list);
+                       ret = calendar_db_insert_records(list, NULL, NULL);
+                       ret = calendar_list_destroy(list, false);
+               }
+               else
+               {
+                       DBG("No exception");
+               }
        }
-    else
-    {
-        DBG("No exception");
-    }
 
        if (event->extended_list)
        {
@@ -534,6 +569,7 @@ static int __cal_db_event_update_record(calendar_record_h record)
        cal_db_util_error_e dbret = CAL_DB_OK;
        int has_alarm = 0;
        int timezone_id = 0;
+       int input_ver = 0;
 
        retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
 
@@ -550,6 +586,7 @@ static int __cal_db_event_update_record(calendar_record_h record)
     }
     has_alarm = _cal_db_alarm_has_alarm(event->alarm_list);
        _cal_time_get_timezone_from_table(event->start_tzid, NULL, &timezone_id);
+       input_ver = _cal_db_util_get_next_ver();
        snprintf(query, sizeof(query), "UPDATE %s SET "
                        "changed_ver = %d,"
                        "type = %d,"
@@ -598,7 +635,7 @@ static int __cal_db_event_update_record(calendar_record_h record)
                "sync_data4 = ? "
                        "WHERE id = %d;",
                CAL_TABLE_SCHEDULE,
-               _cal_db_util_get_next_ver(),
+               input_ver,
                CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
                event->event_status,
                event->priority,
@@ -724,6 +761,10 @@ static int __cal_db_event_update_record(calendar_record_h record)
        }
        sqlite3_finalize(stmt);
 
+       // update parent event changed ver in case this event is exception mod
+       // which is original_event_id > 0
+       __cal_db_event_update_original_event_version(event->original_event_id, input_ver);
+
        _cal_db_rrule_get_rrule_from_event(record, &rrule);
        _cal_db_rrule_update_record(event->index, rrule);
        CAL_FREE(rrule);
@@ -761,7 +802,7 @@ static int __cal_db_event_update_record(calendar_record_h record)
     {
         DBG("insert exception");
         list = NULL;
-        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event->index, &list);
+        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event->index, event->calendar_id, &list);
         if (ret == CALENDAR_ERROR_NONE)
         {
             calendar_db_insert_records(list, NULL, NULL);
@@ -786,6 +827,94 @@ static int __cal_db_event_update_record(calendar_record_h record)
        return CALENDAR_ERROR_NONE;
 }
 
+static int __cal_db_event_add_exdate(calendar_record_h record)
+{
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       cal_event_s *event = (cal_event_s *)record;
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (event->original_event_id < 0)
+       {
+               return CALENDAR_ERROR_NONE;
+       }
+       DBG("This is exception event");
+
+       // get exdate from original event.
+       snprintf(query, sizeof(query), "SELECT exdate FROM %s WHERE id = %d ",
+                       CAL_TABLE_SCHEDULE, event->original_event_id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       // add recurrence id to end of the exdate of original event.
+    const unsigned char *temp;
+       char *exdate = NULL;
+       if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+       {
+               temp = sqlite3_column_text(stmt, 1);
+               if (NULL == temp)
+               {
+                       exdate = strdup(event->recurrence_id);
+               }
+               else
+               {
+                       if (strstr((char *)temp, event->recurrence_id))
+                       {
+                               DBG("warn: recurrence id already is registered to exdate");
+                               sqlite3_finalize(stmt);
+                               return CALENDAR_ERROR_NONE;
+                       }
+                       exdate = strdup((char *)temp);
+                       strcat(exdate, event->recurrence_id);
+               }
+       }
+       else
+       {
+               DBG("Failed to get exdate: event_id(%d)", event->original_event_id);
+       }
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       // update exdate
+       DBG("update to recurrence id to exdate[%s]", exdate);
+       snprintf(query, sizeof(query), "UPDATE %s SET exdate = ? WHERE id = %d ",
+                       CAL_TABLE_SCHEDULE, event->original_event_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 index = 1;
+       _cal_db_util_stmt_bind_text(stmt, index, exdate);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+       if (CAL_DB_DONE != dbret) {
+               ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
 static int __cal_db_event_delete_record(int id)
 {
        int ret;
@@ -900,6 +1029,9 @@ static int __cal_db_event_delete_record(int id)
        retvm_if(ret != CALENDAR_ERROR_NONE, CALENDAR_ERROR_DB_FAILED,
                        "_cal_db_instance_discard_record() Failed(%d)", ret);
 
+       // start:add record to exdate if this record is exception mod.
+       __cal_db_event_add_exdate(record_event);
+
        ret = calendar_record_destroy(record_event, true);
        ret = calendar_record_destroy(record_calendar, true);
 
@@ -1410,6 +1542,7 @@ static int __cal_db_event_replace_record(calendar_record_h record, int id)
        cal_db_util_error_e dbret = CAL_DB_OK;
        int has_alarm = 0;
        int timezone_id = 0;
+       int input_ver = 0;
 
        retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
 
@@ -1419,6 +1552,7 @@ static int __cal_db_event_replace_record(calendar_record_h record, int id)
     }
     has_alarm = _cal_db_alarm_has_alarm(event->alarm_list);
        _cal_time_get_timezone_from_table(event->start_tzid, NULL, &timezone_id);
+       input_ver = _cal_db_util_get_next_ver();
        snprintf(query, sizeof(query), "UPDATE %s SET "
                        "changed_ver = %d,"
                        "type = %d,"
@@ -1467,7 +1601,7 @@ static int __cal_db_event_replace_record(calendar_record_h record, int id)
                "sync_data4 = ? "
                        "WHERE id = %d ",
                CAL_TABLE_SCHEDULE,
-               _cal_db_util_get_next_ver(),
+               input_ver,
                CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
                event->event_status,
                event->priority,
@@ -1593,6 +1727,10 @@ static int __cal_db_event_replace_record(calendar_record_h record, int id)
        }
        sqlite3_finalize(stmt);
 
+       // update parent event changed ver in case this event is exception mod
+       // which is original_event_id > 0
+       __cal_db_event_update_original_event_version(event->original_event_id, input_ver);
+
        _cal_db_rrule_get_rrule_from_event(record, &rrule);
        _cal_db_rrule_update_record(id, rrule);
        CAL_FREE(rrule);
@@ -1630,7 +1768,7 @@ static int __cal_db_event_replace_record(calendar_record_h record, int id)
     {
         DBG("insert exception");
         list = NULL;
-        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, id, &list);
+        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, id, event->calendar_id, &list);
         if (ret == CALENDAR_ERROR_NONE)
         {
             calendar_db_insert_records(list, NULL, NULL);
@@ -2590,7 +2728,7 @@ static int __cal_db_event_exception_get_records(int original_id, GList **out_lis
     return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, calendar_list_h *hlist)
+static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, int calendar_id, calendar_list_h *hlist)
 {
     int ret;
     GList *g = NULL;
@@ -2611,6 +2749,7 @@ static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id,
         if (exception)
         {
             ret = _cal_record_set_int(exception,_calendar_event.original_event_id, original_id);
+            ret = _cal_record_set_int(exception,_calendar_event.calendar_book_id, calendar_id);
             ret = calendar_list_add(h, exception);
 
         }
index c0286b8..39bfe5d 100644 (file)
@@ -249,7 +249,12 @@ int _cal_db_rrule_insert_record(int id, cal_rrule_s *rrule)
 
        DBG("[%s]", query);
        stmt = _cal_db_util_query_prepare(query);
-       retvm_if(stmt == NULL, CALENDAR_ERROR_DB_FAILED, "Failed to query prepare");
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
 
        index = 1;
 
@@ -412,24 +417,58 @@ int _cal_db_rrule_get_rrule(int id, cal_rrule_s **rrule)
        return CALENDAR_ERROR_NONE;
 }
 
-int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
+static int __cal_db_rrule_delete_record(int id)
 {
-       int dbret;
-       int index;
        char query[CAL_DB_SQL_MAX_LEN] = {0};
-       char until_datetime[32] = {0};
-       sqlite3_stmt *stmt = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
 
-       retvm_if(rrule == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
-                       "Invalid argument: rrule is NULL");
+       snprintf(query, sizeof(query),
+                       "DELETE FROM %s WHERE event_id = %d ",
+                       CAL_TABLE_RRULE, id);
 
-       if (rrule->freq == CALENDAR_RECURRENCE_NONE)
+       dbret = _cal_db_util_query_exec(query);
+       if(CAL_DB_DONE != dbret)
        {
-               DBG("freq is NONE");
-               return CALENDAR_ERROR_NONE;
+               ERR("_cal_db_util_query_exec() Failed");
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
        }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_rrule_has_record(int id, int *has_record)
+{
+       int ret;
+    int count = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT count(*) FROM %s WHERE event_id = %d ",
+                       CAL_TABLE_RRULE, id);
+
+       ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+
+       *has_record = count > 0 ? 1 : 0;
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char until_datetime[32] = {0};
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       sqlite3_stmt *stmt = NULL;
 
-       DBG("freq exist, so update rrule");
        snprintf(query, sizeof(query),
                        "UPDATE %s SET "
                        "freq = %d, "
@@ -460,13 +499,15 @@ int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
                        rrule->wkst,
                        id);
 
-       DBG("query[%s]", query);
        stmt = _cal_db_util_query_prepare(query);
-       retvm_if(stmt == NULL, CALENDAR_ERROR_DB_FAILED,
-                       "_cal_db_util_query_prepare() Failed");
-
-       index = 1;
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
 
+       int index = 1;
        if (CALENDAR_TIME_LOCALTIME == rrule->until_type)
        {
                snprintf(until_datetime, sizeof(until_datetime), "%04d%02d%02d",
@@ -523,7 +564,34 @@ int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
                        return CALENDAR_ERROR_DB_FAILED;
                }
        }
+       return CALENDAR_ERROR_NONE;
+}
 
+int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
+{
+       int has_record = 0;
+
+       retvm_if(rrule == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: rrule is NULL");
+
+       if (rrule->freq == CALENDAR_RECURRENCE_NONE)
+       {
+               DBG("freq is NONE");
+               __cal_db_rrule_delete_record(id);
+               return CALENDAR_ERROR_NONE;
+       }
+       else
+       {
+               __cal_db_rrule_has_record(id, &has_record);
+               if (has_record)
+               {
+                       __cal_db_rrule_update_record(id, rrule);
+               }
+               else
+               {
+                       _cal_db_rrule_insert_record(id, rrule);
+               }
+       }
        return CALENDAR_ERROR_NONE;
 }
 
index 1c3b7b5..a6c807a 100644 (file)
@@ -168,7 +168,8 @@ int _cal_db_util_query_get_first_int_result(const char *query, GSList *bind_text
        {
                ERR("sqlite3_step() failed(%d, %s).", ret, sqlite3_errmsg(calendar_db_handle));
                sqlite3_finalize(stmt);
-               if (SQLITE_DONE == ret) return CALENDAR_ERROR_DB_FAILED;
+               if (SQLITE_DONE == ret)
+                   return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
                return CALENDAR_ERROR_DB_FAILED;
        }
 
index 750b525..5cc71f1 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <stdlib.h>
 
+#include "calendar_reminder.h"
+
 #include "cal_internal.h"
 #include "cal_typedef.h"
 #include "cal_view.h"
@@ -249,3 +251,18 @@ API int calendar_reminder_has_receiver(const char *pkgname)
 
        return count > 0 ? true : false;
 }
+
+API int calendar_reminder_add_cb(calendar_reminder_cb callback, void *user_data)
+{
+       ERR("This API[%s] is not valid in native library.", __func__);
+       ERR("If you want to use this API, please use in client library.");
+       return CALENDAR_ERROR_NOT_PERMITTED;
+}
+
+API int calendar_reminder_remove_cb(calendar_reminder_cb callback, void *user_data)
+{
+       ERR("This API[%s] is not valid in native library.", __func__);
+       ERR("If you want to use this API, please use in client library.");
+       return CALENDAR_ERROR_NOT_PERMITTED;
+}
+
index edfd4b1..5d29d62 100644 (file)
@@ -1,7 +1,7 @@
 Name:       calendar-service
 Summary:    DB library for calendar
 Version:    0.1.14
-Release:    46
+Release:    84
 Group:      System/Libraries
 License:    Apache 2.0
 Source0:    %{name}-%{version}.tar.gz
@@ -22,6 +22,7 @@ BuildRequires: pkgconfig(appsvc)
 BuildRequires: pkgconfig(capi-base-common)
 BuildRequires: pkgconfig(contacts-service2)
 BuildRequires: pkgconfig(pims-ipc)
+BuildRequires: pkgconfig(bundle)
 
 %description
 DB library for calendar
index 8900e2a..1028bff 100755 (executable)
@@ -70,6 +70,7 @@ sync_data3 TEXT,
 sync_data4 TEXT
 );
 CREATE INDEX sch_idx1 ON schedule_table(type);
+CREATE INDEX sch_idx2 ON schedule_table(calendar_id);
 CREATE TRIGGER trg_sch_del AFTER DELETE ON schedule_table
  BEGIN
    DELETE FROM rrule_table WHERE event_id = old.id;
@@ -118,6 +119,8 @@ event_id INTEGER,
 dtstart_utime INTEGER,
 dtend_utime INTEGER
 );
+CREATE INDEX n_i_idx1 ON normal_instance_table(event_id, dtstart_utime);
+CREATE INDEX n_i_idx2 ON normal_instance_table(dtstart_utime);
 
 CREATE TABLE allday_instance_table
 (
@@ -125,6 +128,8 @@ event_id INTEGER,
 dtstart_datetime TEXT,
 dtend_datetime TEXT
 );
+CREATE INDEX a_i_idx1 ON allday_instance_table(event_id, dtstart_datetime);
+CREATE INDEX a_i_idx2 ON allday_instance_table(dtstart_datetime);
 
 CREATE TABLE attendee_table
 (
index c7704fd..93ffad2 100755 (executable)
@@ -87,6 +87,7 @@ ADD_EXECUTABLE(${DAEMON}
        cal_server.c
        cal_server_alarm.c
        cal_server_calendar_delete.c
+       cal_server_reminder.c
        )
 SET_TARGET_PROPERTIES(${DAEMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS})
 TARGET_LINK_LIBRARIES(${DAEMON} ${calserver_pkgs_LDFLAGS} ${LIBNAME})
index 2c72329..6f14920 100644 (file)
@@ -174,6 +174,9 @@ static int __server_main(void)
         return -1;
     }
 
+       // for subscribe
+       pims_ipc_svc_init_for_publish(CAL_IPC_SOCKET_PATH_FOR_SUBSCRIPTION, CAL_SECURITY_DEFAULT_PERMISSION, 0660);
+
     //loop = g_main_loop_new(NULL, FALSE);
 
     //calendar_alarm_init();
@@ -200,6 +203,7 @@ static int __server_main(void)
        _cal_inotify_finalize();
        calendar_disconnect();
 
+       pims_ipc_svc_deinit_for_publish();
     pims_ipc_svc_deinit();
 
     return 0;
index d54edec..de5e9ae 100644 (file)
@@ -32,6 +32,7 @@
 #include "cal_db_util.h"
 #include "cal_db.h"
 #include "cal_db_query.h"
+#include "cal_server_reminder.h"
 
 static struct timeval stv; // check time
 static struct timeval etv; // check time
@@ -60,6 +61,7 @@ struct _normal_data_s
        int tick;
        int unit;
        int alarm_id;
+       int record_type;
 };
 
 struct _allday_data_s
@@ -69,6 +71,7 @@ struct _allday_data_s
        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)
@@ -411,7 +414,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
 
                snprintf(query, sizeof(query),
                                "SELECT A.event_id, A.dtstart_utime, "
-                               "B.remind_tick, B.remind_tick_unit "
+                               "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
@@ -420,7 +424,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                                "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, "
+                               "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
@@ -430,7 +435,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                                "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 "
+                               "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 "
@@ -438,7 +444,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                                "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, "
+                               "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 "
@@ -478,6 +485,7 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                        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);
                }
@@ -495,7 +503,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
 
                snprintf(query, sizeof(query),
                                "SELECT A.event_id, A.dtstart_datetime, "
-                               "B.remind_tick, B.remind_tick_unit "
+                               "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
@@ -504,7 +513,8 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                                "AND B.alarm_time = %d "
                                "UNION "
                                "SELECT A.event_id, A.dtstart_datetime, "
-                               "B.remind_tick, B.remind_tick_unit "
+                               "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
@@ -513,14 +523,16 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                                "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 "
+                               "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 "
+                               "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 "
@@ -561,6 +573,7 @@ static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **no
                        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);
                }
        }
@@ -596,7 +609,7 @@ static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit)
+static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit, char *type)
 {
        int ret = CALENDAR_ERROR_NONE;
        int index;
@@ -637,10 +650,11 @@ static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id,
        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, "calendar-service/id", id);
-       appsvc_add_data(b, "calendar-service/time", time);
-       appsvc_add_data(b, "calendar-service/tick", tick);
-       appsvc_add_data(b, "calendar-service/unit", unit);
+       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);
 
@@ -669,7 +683,7 @@ static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id,
        return CALENDAR_ERROR_NONE;
 }
 
-static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit)
+static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit, char *type)
 {
        int index;
     char query[CAL_DB_SQL_MAX_LEN] = {0};
@@ -689,7 +703,7 @@ static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit
                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);
+               __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit, type);
        }
        sqlite3_finalize(stmt);
 
@@ -702,6 +716,7 @@ static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list,
        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);
@@ -713,8 +728,9 @@ static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list,
                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);
+               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
                l = g_list_next(l);
        }
 
@@ -728,11 +744,12 @@ static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list,
                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);
+               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
                l = g_list_next(l);
        }
-       return 0;
+       return CALENDAR_ERROR_NONE;
 }
 
 static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
@@ -949,6 +966,61 @@ static int __cal_server_alarm_register_with_alarmmgr(void)
        return 0;
 }
 
+static int __cal_server_alarm_callback(char *id, char *time, char *tick, char *unit, char *type)
+{
+       _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);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_noti_callback(int alarm_id, GList *normal_list, GList *allday_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;
+
+       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 int _alert_cb(alarm_id_t alarm_id, void *data)
 {
        GList *normal_list = NULL;
@@ -957,6 +1029,8 @@ static int _alert_cb(alarm_id_t alarm_id, void *data)
        __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);
index c2545eb..6526705 100644 (file)
@@ -618,6 +618,7 @@ void _cal_server_ipc_db_clean_after_sync(pims_ipc_h ipc, pims_ipc_data_h indata,
 {
     int ret = CALENDAR_ERROR_NONE;
     int calendar_book_id = 0;
+    int calendar_db_version = 0;
 
     if (indata)
     {
@@ -627,6 +628,12 @@ void _cal_server_ipc_db_clean_after_sync(pims_ipc_h ipc, pims_ipc_data_h indata,
             ERR("_cal_ipc_unmarshal_int fail");
             goto ERROR_RETURN;
         }
+        ret = _cal_ipc_unmarshal_int(indata,&calendar_db_version);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
     }
     else
     {
@@ -635,7 +642,7 @@ void _cal_server_ipc_db_clean_after_sync(pims_ipc_h ipc, pims_ipc_data_h indata,
         goto ERROR_RETURN;
     }
 
-    ret = calendar_db_clean_after_sync(calendar_book_id);
+    ret = calendar_db_clean_after_sync(calendar_book_id, calendar_db_version);
 
 ERROR_RETURN:
     if (outdata)
diff --git a/server/cal_server_reminder.c b/server/cal_server_reminder.c
new file mode 100644 (file)
index 0000000..ec4c54a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <bundle.h>
+#include <pims-ipc-svc.h>
+
+#include "calendar2.h"
+#include "cal_internal.h" // DBG
+#include "cal_typedef.h"
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_ipc.h"
+#include "cal_ipc_marshal.h"
+#include "cal_server_ipc.h"
+
+#define CAL_SUBSCRIBE_MAX_LEN 1024
+
+static __thread unsigned char *__reminder_changed_info = NULL;
+static __thread bundle *__b = NULL;
+static __thread int __bundle_len = 0;
+
+static gboolean __cal_server_reminder_publish_changes_with_data(unsigned char *data, int len)
+{
+       pims_ipc_data_h indata = NULL;
+       if (NULL == data)
+       {
+               ERR("Invalid parameter: data is NULL");
+               return true;
+       }
+
+       indata = pims_ipc_data_create(0);
+       if (NULL == indata)
+       {
+               ERR("pims_ipc_data_create() failed");
+               return false;
+       }
+       if (pims_ipc_data_put(indata, &len, sizeof(int)) != 0)
+       {
+               ERR("pims_ipc_data_put() failed");
+               return false;
+       }
+       if (pims_ipc_data_put(indata, data, len + 1) != 0)
+       {
+               ERR("pims_ipc_data_put() failed");
+               return false;
+       }
+       if (pims_ipc_svc_publish(CAL_IPC_MODULE_FOR_SUBSCRIPTION, (char *)CAL_NOTI_REMINDER_CAHNGED, indata) != 0)
+       {
+               ERR("pims_ipc_svc_publish() failed");
+               return false;
+       }
+       pims_ipc_data_destroy(indata);
+       return true;
+}
+
+void __cal_server_reminder_clear_changed_info(void)
+{
+       if (__reminder_changed_info)
+       {
+               bundle_free_encoded_rawdata(&__reminder_changed_info);
+               __reminder_changed_info = NULL;
+               __bundle_len = 0;
+       }
+}
+
+void _cal_server_reminder_publish(void)
+{
+       if (__b)
+       {
+               bundle_encode(__b, &__reminder_changed_info, &__bundle_len);
+               __cal_server_reminder_publish_changes_with_data(__reminder_changed_info, __bundle_len);
+               __cal_server_reminder_clear_changed_info();
+       }
+}
+
+void _cal_server_reminder_add_callback_data(char *key, char *value)
+{
+       if (NULL == __b)
+       {
+               __b = bundle_create();
+       }
+       bundle_add(__b, key, value);
+}
+
diff --git a/server/cal_server_reminder.h b/server/cal_server_reminder.h
new file mode 100644 (file)
index 0000000..d69efa6
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CAL_SERVER_REMINDER_H__
+#define __CAL_SERVER_REMINDER_H__
+
+void _cal_server_reminder_publish(void);
+void _cal_server_reminder_add_callback_data(char *key, char *value);
+
+#endif  //__CAL_SERVER_REMINDER_H__