summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:51:48 +0900
committerJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:51:48 +0900
commitd6aa47559c38d7e20d6d6a7a3671fa48ed58b9eb (patch)
tree5fbc758662a7866e32ec1adcfd9149c71987549e /src/plugins
parent8fe192a924f295972402d46141e39b86241a1441 (diff)
downloadoma-ds-agent-d6aa47559c38d7e20d6d6a7a3671fa48ed58b9eb.tar.gz
oma-ds-agent-d6aa47559c38d7e20d6d6a7a3671fa48ed58b9eb.tar.bz2
oma-ds-agent-d6aa47559c38d7e20d6d6a7a3671fa48ed58b9eb.zip
Tizen 2.1 base
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/CMakeLists.sub57
-rw-r--r--src/plugins/CMakeLists.txt3
-rwxr-xr-xsrc/plugins/ds-public/CMakeLists.txt11
-rwxr-xr-xsrc/plugins/ds-public/plain-text/CMakeLists.txt43
-rwxr-xr-xsrc/plugins/ds-public/plain-text/include/in_datastore_info_plain_text.h32
-rwxr-xr-xsrc/plugins/ds-public/plain-text/src/plugin_interface.c245
-rwxr-xr-xsrc/plugins/ds-public/vcard/CMakeLists.txt42
-rwxr-xr-xsrc/plugins/ds-public/vcard/include/encoding_util.h237
-rwxr-xr-xsrc/plugins/ds-public/vcard/include/in_datastore_info_vcard.h156
-rwxr-xr-xsrc/plugins/ds-public/vcard/include/plugin_spec.h65
-rwxr-xr-xsrc/plugins/ds-public/vcard/src/encoding_util.c814
-rwxr-xr-xsrc/plugins/ds-public/vcard/src/plugin_interface.c998
-rwxr-xr-xsrc/plugins/ds-public/xcalllog/CMakeLists.txt42
-rwxr-xr-xsrc/plugins/ds-public/xcalllog/include/encoding_util.h238
-rwxr-xr-xsrc/plugins/ds-public/xcalllog/include/plugin_spec.h33
-rwxr-xr-xsrc/plugins/ds-public/xcalllog/src/encoding_util.c812
-rwxr-xr-xsrc/plugins/ds-public/xcalllog/src/plugin_interface.c432
17 files changed, 4260 insertions, 0 deletions
diff --git a/src/plugins/CMakeLists.sub b/src/plugins/CMakeLists.sub
new file mode 100644
index 0000000..8040b54
--- /dev/null
+++ b/src/plugins/CMakeLists.sub
@@ -0,0 +1,57 @@
+
+
+#############################################
+#
+# Step 1. Set Variable and Build Dependency
+#
+
+# set lib name
+SET(LIBNAME "lib${PROJECT_NAME}")
+#SET(LIBDIR "${PREFIX}/lib")
+
+#############################################
+#
+# Step 2. Set Compile Environment
+#
+
+# set extra cflags from build dependency
+STRING(REPLACE ";" " " EXTRA_CFLAGS "${PLUGIN_CFLAGS}")
+
+# add include directories to the build.
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../../../include)
+
+# find all source files in a directory.
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRCS)
+
+#############################################
+#
+# Step 3. Set Link Environment
+#
+
+# add a library to the project using the specified source files.
+ADD_LIBRARY(${LIBNAME} SHARED ${SRCS})
+
+# link a target to given libraries from pkg-config.
+TARGET_LINK_LIBRARIES(${LIBNAME} ${PLUGIN_LDFLAGS})
+
+# sets additional compiler flags used to build sources within the target.
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+
+# override the default target name prefix (such as "lib")
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "")
+
+# specify the build version
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${VERSION})
+
+# specify the api version
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+
+#############################################
+#
+# Step 4. Install packages
+#
+
+# install library files
+INSTALL(TARGETS ${LIBNAME} DESTINATION ${LIBDIR})
+
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
new file mode 100644
index 0000000..b75a100
--- /dev/null
+++ b/src/plugins/CMakeLists.txt
@@ -0,0 +1,3 @@
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+
+ADD_SUBDIRECTORY(ds-public)
diff --git a/src/plugins/ds-public/CMakeLists.txt b/src/plugins/ds-public/CMakeLists.txt
new file mode 100755
index 0000000..63e1c2d
--- /dev/null
+++ b/src/plugins/ds-public/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+# set plguin name
+SET(PLUGIN_CATEGORY_NAME "ds-public")
+
+# set plugin install path
+SET(LIBDIR "${PREFIX}/lib/sync-agent/${PLUGIN_CATEGORY_NAME}")
+
+ADD_SUBDIRECTORY(plain-text)
+ADD_SUBDIRECTORY(vcard)
+ADD_SUBDIRECTORY(xcalllog)
+
diff --git a/src/plugins/ds-public/plain-text/CMakeLists.txt b/src/plugins/ds-public/plain-text/CMakeLists.txt
new file mode 100755
index 0000000..e940e6b
--- /dev/null
+++ b/src/plugins/ds-public/plain-text/CMakeLists.txt
@@ -0,0 +1,43 @@
+
+#############################################
+#
+# Step 1. Set Variable and Build Dependency
+#
+
+# set plguin name
+SET(PLUGIN_NAME "dc-plain-text")
+
+# set a name for the entire project
+PROJECT(plugin-${PLUGIN_NAME})
+
+# checks for build dependency modules : a pkg-config module for CMake
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${PLUGIN_NAME} REQUIRED
+ memo
+ glib-2.0
+ sync-agent
+ dlog
+ libwbxml2)
+
+#############################################
+#
+# Step 2. Set Compile Environment
+#
+
+# set extra cflags from build dependency
+SET(PLUGIN_CFLAGS "${dc-plain-text_CFLAGS}")
+
+#############################################
+#
+# Step 3. Set Link Environment
+#
+
+# link a target to given libraries from pkg-config.
+SET(PLUGIN_LDFLAGS "${dc-plain-text_LDFLAGS}")
+
+#############################################
+#
+# Step 4. Install packages
+#
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.sub) \ No newline at end of file
diff --git a/src/plugins/ds-public/plain-text/include/in_datastore_info_plain_text.h b/src/plugins/ds-public/plain-text/include/in_datastore_info_plain_text.h
new file mode 100755
index 0000000..7296840
--- /dev/null
+++ b/src/plugins/ds-public/plain-text/include/in_datastore_info_plain_text.h
@@ -0,0 +1,32 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 IN_DATASTORE_INFO_PLAIN_TEXT_H_
+#define IN_DATASTORE_INFO_PLAIN_TEXT_H_
+
+#define PLAIN_TEXT_TYPE "text/plain"
+#define PLAIN_TEXT_VERSION "1.0"
+
+typedef struct plain_text_field_list plain_text_field_list_s;
+struct plain_text_field_list {
+ int field_enum;
+ char *field_name;
+};
+
+static plain_text_field_list_s plain_text_field_list[] = { };
+
+#endif /* IN_DATASTORE_INFO_PLAIN_TEXT_H_ */
diff --git a/src/plugins/ds-public/plain-text/src/plugin_interface.c b/src/plugins/ds-public/plain-text/src/plugin_interface.c
new file mode 100755
index 0000000..2cc32d1
--- /dev/null
+++ b/src/plugins/ds-public/plain-text/src/plugin_interface.c
@@ -0,0 +1,245 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <memo-db.h>
+
+#include <sync_agent.h>
+
+#include "in_datastore_info_plain_text.h"
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef OMADS_AGENT_LOG
+#undef LOG_TAG
+#define LOG_TAG "PLUGIN_PLAIN_TEXT"
+#endif
+
+static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count);
+static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, plain_text_field_list_s * input_list);
+/*
+static sync_agent_da_return_e __convert_service_error_to_common_error(int err);
+*/
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_converter(const void *agent_data, void **service_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "agent_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ struct memo_data *temp_service_data = 0;
+ char *temp_agent_data = (char *)agent_data;
+
+ /* create item */
+ temp_service_data = memo_create_data();
+ if (temp_service_data == NULL) {
+ _DEBUG_INFO("[dc_plain_text_plugIn] memo_create_data() Fail!\n");
+ ret = SYNC_AGENT_DA_ERRORS;
+ *service_data = 0;
+ } else {
+ _DEBUG_INFO("[dc_plain_text_plugIn] memo_create_data() Success!\n");
+ temp_service_data->content = strdup(temp_agent_data); /* configuration item */
+ *service_data = (void *)temp_service_data;
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_replace_converter(void *old_service_data, const void *agent_data, void **new_service_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(old_service_data == NULL, SYNC_AGENT_DA_ERRORS, "old_service_data is NULL");
+ retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "agent_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ struct memo_data *temp_service_data = (struct memo_data *)old_service_data;
+ char *temp_agent_data = (char *)agent_data;
+
+ /* set item */
+ if (temp_service_data->has_doodle == 0) {
+ free(temp_service_data->content);
+ temp_service_data->content = strdup(temp_agent_data);
+ } else if (temp_service_data->comment != NULL) {
+ free(temp_service_data->comment);
+ temp_service_data->comment = strdup(temp_agent_data);
+ }
+ *new_service_data = (void *)temp_service_data;
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_reverse_converter(void *service_data, void **agent_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "service_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ char *temp_agent_data = 0;
+ struct memo_data *temp_service_data = (struct memo_data *)service_data;
+
+ /* deep copy */
+ if (temp_service_data == NULL) {
+ _DEBUG_INFO("[dc_plain_text_plugIn] Fail : no data !\n");
+ ret = SYNC_AGENT_DA_ERRORS;
+ *agent_data = 0;
+ } else if (temp_service_data->has_doodle == 0) {
+ _DEBUG_INFO("[dc_plain_text_plugIn] Success!\n");
+ temp_agent_data = strdup(temp_service_data->content);
+ *agent_data = (void *)temp_agent_data;
+ } else if (temp_service_data->comment != NULL) {
+ _DEBUG_INFO("[dc_plain_text_plugIn] Success!\n");
+ temp_agent_data = strdup(temp_service_data->comment);
+ *agent_data = (void *)temp_agent_data;
+ }
+
+ /* memory free */
+ if (temp_service_data != NULL)
+ memo_free_data(temp_service_data);
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API void *sync_agent_plugin_alloc_object()
+{
+ _DEBUG_INFO("[da_memo_plugIn] not implement !!");
+ return 0;
+}
+
+EXPORT_API int sync_agent_plugin_free_object(void *in_object)
+{
+ _DEBUG_INFO("[da_memo_plugIn] not implement !!");
+ return 0;
+}
+
+EXPORT_API void *sync_agent_plugin_set_value(void *in_object, int key, char *extension_key, void *value)
+{
+ _DEBUG_INFO("[da_memo_plugIn] not implement !!");
+ return 0;
+}
+
+EXPORT_API void *sync_agent_plugin_get_value(void *in_object, int key, char *extension_key)
+{
+ _DEBUG_INFO("[da_memo_plugIn] not implement !!");
+ return 0;
+}
+
+EXPORT_API sync_agent_plugin_object_info_s *sync_agent_plugin_get_obj_info()
+{
+ _EXTERN_FUNC_ENTER;
+
+ sync_agent_plugin_object_info_s *obj_info = (sync_agent_plugin_object_info_s *) calloc(1, sizeof(sync_agent_plugin_object_info_s));
+ if (obj_info == NULL) {
+ _DEBUG_INFO("CALLOC failed !!!");
+ return NULL;
+ }
+
+ obj_info->type = PLAIN_TEXT_TYPE;
+ obj_info->version = PLAIN_TEXT_VERSION;
+ obj_info->field_cnt = sizeof(plain_text_field_list) / sizeof(plain_text_field_list_s);
+
+ if (obj_info->field_cnt > 0)
+ if (_set_obj_field_info(&(obj_info->field_list), obj_info->field_cnt, plain_text_field_list) == 0)
+ return NULL;
+
+ _EXTERN_FUNC_EXIT;
+ return obj_info;
+}
+
+EXPORT_API int sync_agent_plugin_free_obj_info(sync_agent_plugin_object_info_s * obj_info)
+{
+ _EXTERN_FUNC_ENTER;
+
+ if (obj_info) {
+ if (obj_info->field_cnt > 0)
+ if (_free_obj_field_info(obj_info->field_list, obj_info->field_cnt) == 0)
+ return 0;
+
+ free(obj_info);
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count)
+{
+ _INNER_FUNC_ENTER;
+
+ int field_count = 0;
+ sync_agent_plugin_field_info_s *child = NULL;
+
+ if (field_list != NULL) {
+ for (field_count = 0; field_count < count; field_count++) {
+ child = field_list + field_count;
+ if (child->field_child_cnt > 0)
+ if (_free_obj_field_info(child->field_child_list, child->field_child_cnt) == 0)
+ return 0;
+ }
+ free(field_list);
+ }
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, plain_text_field_list_s * input_list)
+{
+ _INNER_FUNC_ENTER;
+
+ int field_count = 0;
+ sync_agent_plugin_field_info_s *child = NULL;
+
+ *field_list = (sync_agent_plugin_field_info_s *) calloc(count, sizeof(sync_agent_plugin_field_info_s));
+ if (*field_list == NULL) {
+ _DEBUG_ERROR("CALLOC failed !!!");
+ return 0;
+ }
+
+ for (field_count = 0; field_count < count; field_count++) {
+ child = (*field_list) + field_count;
+ child->field_name = input_list[field_count].field_name;
+ _DEBUG_TRACE("[%s]", child->field_name);
+ }
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+/*
+static sync_agent_da_return_e __convert_service_error_to_common_error(int err)
+{
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ _DEBUG_INFO("[da_memo_plugIn] Error Code : %d\n", err);
+
+ switch (err) {
+ default:
+ ret = SYNC_AGENT_DA_ERRORS;
+ break;
+ }
+
+ return ret;
+}
+*/
diff --git a/src/plugins/ds-public/vcard/CMakeLists.txt b/src/plugins/ds-public/vcard/CMakeLists.txt
new file mode 100755
index 0000000..bdd1871
--- /dev/null
+++ b/src/plugins/ds-public/vcard/CMakeLists.txt
@@ -0,0 +1,42 @@
+
+#############################################
+#
+# Step 1. Set Variable and Build Dependency
+#
+
+# set plguin name
+SET(PLUGIN_NAME "dc-vcard")
+
+# set a name for the entire project
+PROJECT(plugin-${PLUGIN_NAME})
+
+# checks for build dependency modules : a pkg-config module for CMake
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${PLUGIN_NAME} REQUIRED
+ contacts-service2
+ sync-agent
+ dlog
+ libwbxml2)
+
+#############################################
+#
+# Step 2. Set Compile Environment
+#
+
+# set extra cflags from build dependency
+SET(PLUGIN_CFLAGS "${dc-vcard_CFLAGS}")
+
+#############################################
+#
+# Step 3. Set Link Environment
+#
+
+# link a target to given libraries from pkg-config.
+SET(PLUGIN_LDFLAGS "${dc-vcard_LDFLAGS}")
+
+#############################################
+#
+# Step 4. Install packages
+#
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.sub) \ No newline at end of file
diff --git a/src/plugins/ds-public/vcard/include/encoding_util.h b/src/plugins/ds-public/vcard/include/encoding_util.h
new file mode 100755
index 0000000..19cdfad
--- /dev/null
+++ b/src/plugins/ds-public/vcard/include/encoding_util.h
@@ -0,0 +1,237 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 ENCODING_UTIL_H_
+#define ENCODING_UTIL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define QP_SIZE 76
+#define BASE64_SIZE 76
+
+typedef enum {
+ EN_TYPE_NONE = 0,
+ EN_TYPE_QUOTED_PRINTABLE,
+ EN_TYPE_BASE64
+} encoding_type_e;
+
+/* Quoted-Printable
+*
+* @example code
+int main()
+{
+char *src = "hello";
+char *encode_src;
+int encode_src_len = 0;
+char *decode_src;
+int decode_src_len = 0;
+
+int res = encode_qp(src, strlen(src), &encode_src, &encode_src_len);
+if (res != 0)
+fprintf(stdout, "encode src : %s ( %d ) \n", encode_src, encode_src_len);
+else
+fprintf(stdout, "%s\n", "encode error !!");
+
+res = decode_qp(encode_src, encode_src_len, &decode_src, &decode_src_len);
+if (res != 0)
+fprintf(stdout, "decode src : %s ( %d ) \n", decode_src, decode_src_len);
+else
+fprintf(stdout, "%s\n", "decode error !!");
+
+return 0;
+}
+
+*/
+
+/*
+* @brief encode original source ( encoding type : quoted-printable )
+* @param[in] src original source
+* @param[in] src_len length of original source
+* @param[out] en_src encoded source
+* @param[out] en_src_len length of encoded source
+* @return operation result
+* @retval 1 success
+* @retval 0 fail
+*/
+int encode_qp(char *src, int src_len, char **en_src, int *en_src_len);
+
+/*
+* @brief decode encoded source ( decoding type : quoted-printable )
+* @param[in] src encoded source
+* @param[in] src_len length of encoded source
+* @param[out] de_src decoded source ( original source )
+* @param[out] de_src_len length of decoded source
+* @return operation result
+* @retval 1 success
+* @retval 0 fail
+*/
+int decode_qp(char *src, int src_len, char **de_src, int *de_src_len);
+
+/* Base64
+*
+* @example code
+
+int main()
+{
+char *src = "hello";
+char *encode_src;
+int encode_src_len = 0;
+char *decode_src;
+int decode_src_len = 0;
+
+int res = encode_base64(src, strlen(src), &encode_src, &encode_src_len);
+if (res != 0)
+fprintf(stdout, "encode src : %s ( %d ) \n", encode_src, encode_src_len);
+else
+fprintf(stdout, "%s\n", "encode error !!");
+
+res = decode_base64(encode_src, encode_src_len, &decode_src, &decode_src_len);
+if (res != 0)
+fprintf(stdout, "decode src : %s ( %d ) \n", decode_src, decode_src_len);
+else
+fprintf(stdout, "%s\n", "decode error !!");
+
+return 0;
+}
+
+*/
+
+/*
+* @brief encode original source ( encoding type : base64 )
+* @param[in] src original source
+* @param[in] src_len length of original source
+* @param[out] en_src encoded source
+* @param[out] en_src_len length of encoded source
+* @return operation result
+* @retval 1 success
+* @retval 0 fail
+*/
+int encode_base64(char *src, int src_len, char **en_src, int *en_src_len);
+
+/*
+* @brief decode encoded source ( decoding type : base64 )
+* @param[in] src encoded source
+* @param[in] src_len length of encoded source
+* @param[out] de_src decoded source ( original source )
+* @param[out] de_src_len length of decoded source
+* @return operation result
+* @retval 1 success
+* @retval 0 fail
+*/
+int decode_base64(char *src, int src_len, char **de_src, int *de_src_len);
+
+/*
+* @brief make the decoding process
+* @param[in] src encoded source
+* @param[in] src_len length of encoded source
+* @param[out] de_src decoded source ( original source )
+* @param[out] de_src_len length of decoded source
+* @return operation result
+* @retval 1 success
+* @retval 0 fail
+*
+* @example code
+
+int main()
+{
+char *src = "..."; // decoded data
+int src_len = strlen(src);
+char *decode_src;
+int decode_src_len = 0;
+
+int res = proc_decoding(src, src_len, &decode_src, &decode_src_len);
+
+if (res != 0)
+fprintf(stdout, "decode src : \n%s\n", decode_src);
+else
+fprintf(stdout, "%s\n", "decode error !!");
+
+if (decode_src != NULL)
+free(decode_src);
+
+return 0;
+}
+*/
+int proc_decoding(const char *src, int src_len, char **de_src, int *de_src_len);
+
+/*
+* @brief encoded value is changed to the decoded value
+* @param[in] type encoding type
+* @param[in] value encoded value (end of string must be '\0' !!)
+* ex) =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+* @param[in] value_size length of encoded value
+* @param[out] decode_str decoded string
+* @param[out] decode_str_len length of decoded string
+* @return operation result
+* @ratval 1 success
+* @retval 0 fail
+*
+* @example code
+
+int main()
+{
+char *data = "..."; // ex) ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8
+encoding_type_e type = find_encoding_type((const char *)data);
+
+char *value = "..."; // ex) =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+int value_size = strlen(value);
+
+int decode_str_len = 0;
+char *decode_str = (char*)malloc(sizeof(char)*BUF_SIZE); // BUF_SIZE : user define
+if (decode_str == NULL) {
+// error process
+}
+memset(decode_str, 0x00, sizeof(char)*BUF_SIZE);
+
+int res = decode_value(type, value, data_size, &decode_str, &decode_str_len);
+
+if (res == 1) {
+// success process
+if (decode_str != NULL)
+free(decode_str);
+} else {
+// error process
+if (decode_str != NULL)
+free(decode_str);
+}
+
+return 0;
+}
+*/
+int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len);
+
+/*
+* @brief get encoding type for data
+* @param[in] data vobject data
+* @return encoding type
+* @ratval >= 1 success
+* @retval 0 fail
+*/
+encoding_type_e find_encoding_type(const char *data);
+
+/*
+* @brief check whether to exist this string, "ENCODING=" in the data
+* @param[in] data vobject data
+* @return operation result
+* @retval 1 exist
+* @retval 0 not exist
+*/
+int check_encoding_data(const char *data);
+
+#endif /* ENCODING_UTIL_H_ */
diff --git a/src/plugins/ds-public/vcard/include/in_datastore_info_vcard.h b/src/plugins/ds-public/vcard/include/in_datastore_info_vcard.h
new file mode 100755
index 0000000..54d1929
--- /dev/null
+++ b/src/plugins/ds-public/vcard/include/in_datastore_info_vcard.h
@@ -0,0 +1,156 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 IN_DATASTORE_INFO_VCARD_H_
+#define IN_DATASTORE_INFO_VCARD_H_
+
+#define VCARD_TYPE "text/x-vcard"
+#define VCARD_VERSION "2.1"
+
+typedef enum {
+ VCARD_FIELD_BEGIN = 10,
+ VCARD_FIELD_END,
+ VCARD_FIELD_VERSION,
+ VCARD_FIELD_FN,
+ VCARD_FIELD_N,
+ VCARD_FIELD_NICKNAME,
+ VCARD_FIELD_PHOTO,
+ VCARD_FIELD_BDAY,
+ VCARD_FIELD_ADR,
+ VCARD_FIELD_LABEL,
+ VCARD_FIELD_TEL,
+ VCARD_FIELD_EMAIL,
+ VCARD_FIELD_TITLE,
+ VCARD_FIELD_ROLE,
+ VCARD_FIELD_ORG,
+ VCARD_FIELD_NOTE,
+ VCARD_FIELD_REV,
+ VCARD_FIELD_UID,
+ VCARD_FIELD_URL,
+ VCARD_FIELD_X_ANNIVERSARY,
+ VCARD_FIELD_X_IRMC_LUID,
+
+} vcard_field_e;
+
+typedef enum {
+ VCARD_FIELD_ADR_DOM = 100,
+ VCARD_FIELD_ADR_INTL,
+ VCARD_FIELD_ADR_HOME,
+ VCARD_FIELD_ADR_WORK,
+ VCARD_FIELD_ADR_POSTAL,
+ VCARD_FIELD_ADR_PARCEL,
+ VCARD_FIELD_ADR_PREF,
+
+} vcard_field_adr_sub_e;
+
+typedef enum {
+ VCARD_FIELD_TEL_HOME = 200,
+ VCARD_FIELD_TEL_MSG,
+ VCARD_FIELD_TEL_WORK,
+ VCARD_FIELD_TEL_VOICE,
+ VCARD_FIELD_TEL_FAX,
+ VCARD_FIELD_TEL_CELL,
+ VCARD_FIELD_TEL_VIDEO,
+ VCARD_FIELD_TEL_PAGER,
+ VCARD_FIELD_TEL_BBS,
+ VCARD_FIELD_TEL_MODEM,
+ VCARD_FIELD_TEL_CAR,
+ VCARD_FIELD_TEL_ISDN,
+ VCARD_FIELD_TEL_PCS,
+ VCARD_FIELD_TEL_PREF,
+
+} vcard_field_tel_sub_e;
+
+typedef enum {
+ VCARD_FIELD_EMAIL_HOME = 300,
+ VCARD_FIELD_EMAIL_WORK,
+ VCARD_FIELD_EMAIL_PREF,
+
+} vcard_field_email_sub_e;
+
+typedef struct vcard_field_list vcard_field_list_s;
+struct vcard_field_list {
+ int field_enum;
+ char *field_name;
+};
+
+static vcard_field_list_s vcard_field_list[] = {
+ {VCARD_FIELD_BEGIN, "BEGIN"},
+ {VCARD_FIELD_END, "END"},
+ {VCARD_FIELD_VERSION, "VERSION"},
+ {VCARD_FIELD_FN, "FN"},
+ {VCARD_FIELD_N, "N"},
+ {VCARD_FIELD_NICKNAME, "NICKNAME"},
+ {VCARD_FIELD_PHOTO, "PHOTO"},
+ {VCARD_FIELD_BDAY, "BDAY"},
+ {VCARD_FIELD_ADR, "ADR"},
+ {VCARD_FIELD_LABEL, "LABEL"},
+ {VCARD_FIELD_TEL, "TEL"},
+ {VCARD_FIELD_EMAIL, "EMAIL"},
+ {VCARD_FIELD_TITLE, "TITLE"},
+ {VCARD_FIELD_ROLE, "ROLE"},
+ {VCARD_FIELD_ORG, "ORG"},
+ {VCARD_FIELD_NOTE, "NOTE"},
+ {VCARD_FIELD_REV, "REV"},
+ {VCARD_FIELD_UID, "UID"},
+ {VCARD_FIELD_URL, "URL"},
+ {VCARD_FIELD_X_ANNIVERSARY, "X-ANNIVERSARY"},
+ {VCARD_FIELD_X_IRMC_LUID, "X-IRMC-LUID"}
+};
+
+static vcard_field_list_s vcard_field_list_adr[] = {
+ {VCARD_FIELD_ADR_DOM, "DOM"},
+ {VCARD_FIELD_ADR_INTL, "INTL"},
+ {VCARD_FIELD_ADR_HOME, "HOME"},
+ {VCARD_FIELD_ADR_WORK, "WORK"},
+ {VCARD_FIELD_ADR_POSTAL, "POSTAL"},
+ {VCARD_FIELD_ADR_PARCEL, "PARCEL"},
+ {VCARD_FIELD_ADR_PREF, "PREF"}
+};
+
+static vcard_field_list_s vcard_field_list_tel[] = {
+ {VCARD_FIELD_TEL_HOME, "HOME"},
+ {VCARD_FIELD_TEL_MSG, "MSG"},
+ {VCARD_FIELD_TEL_WORK, "WORK"},
+ {VCARD_FIELD_TEL_VOICE, "VOICE"},
+ {VCARD_FIELD_TEL_FAX, "FAX"},
+ {VCARD_FIELD_TEL_CELL, "CELL"},
+ {VCARD_FIELD_TEL_VIDEO, "VIDEO"},
+ {VCARD_FIELD_TEL_PAGER, "PAGER"},
+ {VCARD_FIELD_TEL_BBS, "BBS"},
+ {VCARD_FIELD_TEL_MODEM, "MODEM"},
+ {VCARD_FIELD_TEL_CAR, "CAR"},
+ {VCARD_FIELD_TEL_ISDN, "ISDN"},
+ {VCARD_FIELD_TEL_PCS, "PCS"},
+ {VCARD_FIELD_TEL_PREF, "PREF"}
+};
+
+static vcard_field_list_s vcard_field_list_email[] = {
+ {VCARD_FIELD_EMAIL_HOME, "HOME"},
+ {VCARD_FIELD_EMAIL_WORK, "WORK"},
+ {VCARD_FIELD_EMAIL_PREF, "PREF"}
+};
+
+static vcard_field_list_s vcard_field_list_begin_end[] = {
+ {-1, "VCARD"}
+};
+
+static vcard_field_list_s vcard_field_list_version[] = {
+ {-1, VCARD_VERSION}
+};
+
+#endif /* IN_DATASTORE_INFO_VCARD_H_ */
diff --git a/src/plugins/ds-public/vcard/include/plugin_spec.h b/src/plugins/ds-public/vcard/include/plugin_spec.h
new file mode 100755
index 0000000..e6b1202
--- /dev/null
+++ b/src/plugins/ds-public/vcard/include/plugin_spec.h
@@ -0,0 +1,65 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 PLUGIN_SPEC_H_
+#define PLUGIN_SPEC_H_
+
+typedef enum {
+
+ VCARD_CONTENT_NO_TYPE = 0,
+ VCARD_CONTENT_EXTENSION = 1,
+ VCARD_CONTENT_FN = 2,
+ VCARD_CONTENT_N = 3,
+ VCARD_CONTENT_NICKNAME = 4,
+ VCARD_CONTENT_PHOTO = 5,
+ VCARD_CONTENT_BDAY = 6,
+ VCARD_CONTENT_ADR = 7,
+ VCARD_CONTENT_LABEL = 8,
+ VCARD_CONTENT_TEL = 9,
+ VCARD_CONTENT_EMAIL = 10,
+ VCARD_CONTENT_TITLE = 11,
+ VCARD_CONTENT_ROLE = 12,
+ VCARD_CONTENT_ORG = 13,
+ VCARD_CONTENT_NOTE = 14,
+ VCARD_CONTENT_REV = 15,
+ VCARD_CONTENT_UID = 16,
+ VCARD_CONTENT_URL = 17,
+ VCARD_CONTENT_X_ANNIVERSARY = 18,
+ VCARD_CONTENT_X_IRMC_LUID = 19,
+
+/*
+ VCARD_CONTENT_NAME,
+ VCARD_CONTENT_PROFILE,
+ VCARD_CONTENT_SOURCE,
+ VCARD_CONTENT_MAILER,
+ VCARD_CONTENT_TZ,
+ VCARD_CONTENT_GEO,
+ VCARD_CONTENT_LOGO,
+ VCARD_CONTENT_AGENT,
+ VCARD_CONTENT_CATEGORIES,
+ VCARD_CONTENT_PRODID,
+ VCARD_CONTENT_SORT-STRING,
+ VCARD_CONTENT_SOUND,
+ VCARD_CONTENT_VERSION,
+ VCARD_CONTENT_CLASS,
+ VCARD_CONTENT_KEY,
+ VCARD_CONTENT_X_CHILDREN,
+*/
+
+} vcard_value_type_e;
+
+#endif /* PLUGIN_SPEC_H_ */
diff --git a/src/plugins/ds-public/vcard/src/encoding_util.c b/src/plugins/ds-public/vcard/src/encoding_util.c
new file mode 100755
index 0000000..bf1d025
--- /dev/null
+++ b/src/plugins/ds-public/vcard/src/encoding_util.c
@@ -0,0 +1,814 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+
+#include <sync_agent.h>
+
+#include "encoding_util.h"
+
+#ifndef OMADS_AGENT_LOG
+#undef LOG_TAG
+#define LOG_TAG "ENCODING_UTIL"
+#endif
+
+#define TYPE_CHECK_BUF_SIZE 100 /* temporary definition */
+#define TEMP_BUFFER_SIZE 1024 /* temporary definition */
+
+/* BASE64 TABLE */
+static char base64_table[65] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
+ 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
+ '2', '3', '4', '5', '6', '7', '8', '9', '+',
+ '/', '='
+};
+
+/* Quoted-Printable */
+static char *_dec_to_hex(int dec);
+static int _hex_to_dec(char *hex);
+
+/* Base64 */
+static int _find_base(char ch);
+
+/*
+ * Quoted-Printable
+ */
+int encode_qp(char *src, int src_len, char **en_src, int *en_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ char *en_hex;
+ int i = 0;
+ int j = 0;
+ int size_cnt = 0;
+
+ /*encoded string length is three times longer than existing maximum string length */
+ int full_lenth = src_len * 3 + 1 + (int)(src_len * 3 / 76) * 3;
+ *en_src = (char *)malloc(sizeof(char) * full_lenth);
+ if (*en_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
+ return 0;
+ }
+ memset(*en_src, 0x00, src_len * 3 + 1);
+
+ _DEBUG_INFO("[encoding_util] src_len : %d\n", src_len);
+ for (i = 0; i < src_len; i++) {
+ /* _DEBUG_INFO("[encoding_util] i : %d\n", i); */
+ if (size_cnt >= QP_SIZE - 3) {
+ size_cnt = 0;
+ (*en_src)[j++] = 0x0A;
+ }
+
+ if ((src[i] >= 33 && src[i] <= 126) || (src[i] == 0x0A)) {
+ if (src[i] == 61) {
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ size_cnt += 3;
+ } else {
+ size_cnt++;
+ (*en_src)[j++] = src[i];
+ }
+ } else if (src[i] == 9 || src[i] == 32) {
+ if (src[i + 1] == 0x0A || src[i + 1] == '\0') { /* TAB or WhiteSpace */
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ size_cnt += 3;
+ } else {
+ size_cnt++;
+ (*en_src)[j++] = src[i];
+ }
+ } else {
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ _DEBUG_INFO("[encoding_util] en_src : %s\n", *en_src);
+ size_cnt += 3;
+ }
+ }
+
+ (*en_src)[j] = 0x00;
+ *en_src_len = size_cnt;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int decode_qp(char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ char hex[3];
+ char ch;
+ int dec = 0;
+ int is_space = 0;
+ int i = 0;
+ int j = 0;
+
+ *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
+ if (*de_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
+ return 0;
+ }
+ memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
+
+ while (src[i] != '\0') {
+ if (src[i] == 0x3D) { /* '=' */
+ /* check whiteSpace */
+ ch = src[++i];
+
+ /* '=' skip if next character is a TAB or WhiteSpace */
+ while (ch == 0x09 || ch == 0x20) {
+ is_space = 1;
+ ch = src[++i];
+
+ if (is_space == 1) {
+ is_space = 0;
+ continue;
+ }
+ }
+
+ /* '=' skip if next character is 3D which means '=' (encoding error case ??) */
+ while (ch == '3') {
+ ch = src[++i];
+
+ if (ch == 'D') {
+ ch = src[++i];
+ continue;
+ }
+ }
+
+ /* if next character is LF after '=' do doft line break
+ * encoded QP string on one line 76 character is allowed
+ */
+ if (ch == 0x0A) { /* LF */
+ i++;
+ continue;
+ }
+
+ hex[0] = src[i++];
+ hex[1] = src[i++];
+ hex[2] = '\0';
+
+ dec = _hex_to_dec(hex);
+
+ /* decoding error */
+ if (dec < 0) {
+ /* when error occur, restore the previous encoding message */
+ (*de_src)[j++] = 0x3D; /* '=' */
+ (*de_src)[j++] = hex[0];
+ (*de_src)[j++] = hex[1];
+ } else {
+ (*de_src)[j++] = dec;
+ }
+ } else if (src[i] > 0x7E) { /* encoding error */
+ i++; /* ignore that character */
+ } else {
+ (*de_src)[j++] = src[i++];
+ }
+ }
+
+ (*de_src)[j] = '\0';
+ *de_src_len = j;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+static char *_dec_to_hex(int dec)
+{
+ _INNER_FUNC_ENTER;
+
+ static char hex[3];
+ int i;
+ int ch;
+
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ ch = (dec & 0xF0) >> 4;
+ } else if (i == 1) {
+ ch = (dec & 0x0F);
+ }
+
+ if (ch >= 10) {
+ hex[i] = 'A' + ch - 10;
+ } else {
+ hex[i] = '0' + ch;
+ }
+ }
+
+ hex[i] = 0x00;
+
+ _DEBUG_TRACE("[encoding_util] hex : %s\n", hex);
+
+ _INNER_FUNC_EXIT;
+ return &hex[0];
+}
+
+static int _hex_to_dec(char *hex)
+{
+ _INNER_FUNC_ENTER;
+
+ int dec = 0;
+ int byte;
+ int i = 0;
+
+ for (i = 0; i < 2; i++) {
+ if (hex[i] >= '0' && hex[i] <= '9') {
+ byte = hex[i] - '0';
+ } else if (hex[i] >= 'A' && hex[i] <= 'F') {
+ byte = hex[i] - 'A' + 10;
+ } else if (hex[i] >= 'a' && hex[i] <= 'f') {
+ byte = hex[i] - 'a' + 10;
+ } else {
+ byte = -1;
+ }
+
+ if (byte < 0)
+ return -1;
+
+ dec += (i == 0) ? byte << 4 : byte;
+ }
+
+ _INNER_FUNC_EXIT;
+ return dec;
+}
+
+/*
+ * Base64
+ */
+int encode_base64(char *src, int src_len, char **en_src, int *en_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ int i = 0;
+ int j = 0;
+ int cnt = 0;
+ int ch = 0;
+ int size_cnt = 0;
+
+ *en_src = (char *)malloc(sizeof(char) * (src_len * 2));
+
+ if (*en_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
+ return 0;
+ }
+ memset(*en_src, 0x00, src_len * 2);
+
+ while (1) {
+ switch (cnt++) {
+ case 0:
+ {
+ if (i < src_len) {
+ ch = (src[i] & 0xFC) >> 2;
+ } else {
+ ch = -1;
+ }
+ }
+ break;
+
+ case 1:
+ {
+ if (i < src_len) {
+ if (i + 1 < src_len) {
+ ch = ((src[i] & 0x03) << 4) | ((src[i + 1] & 0xF0) >> 4);
+ } else {
+ ch = ((src[i] & 0x03) << 4);
+ }
+ } else {
+ ch = -1;
+ }
+ i++;
+ break;
+ }
+
+ case 2:
+ {
+ if (i < src_len) {
+ if (i + 1 < src_len) {
+ ch = ((src[i] & 0x0F) << 2) | ((src[i] & 0xC0) >> 6);
+ } else {
+ ch = ((src[i] & 0x0F) << 2);
+ }
+ } else {
+ ch = -1;
+ }
+ i++;
+ }
+ break;
+
+ case 3:
+ {
+ if (i < src_len) {
+ ch = (src[i] & 0x3F);
+ } else {
+ ch = -1;
+ }
+ i++;
+ cnt = 0;
+ }
+ break;
+ }
+
+ /*
+ if (ch >= 0 && ch <= 25) { // Upper Case Alphabet
+ (*en_src)[j++] = 'A' + ch;
+ } else if (ch >= 26 && ch <= 51) { // Lower Case Alphabet
+ (*en_src)[j++] = 'a' + ch - 26;
+ } else if (ch >= 52 && ch <= 61) { // Digit
+ (*en_src)[j++] = '0' + ch - 52;
+ } else if (ch == 62) {
+ (*en_src)[j++] = '+';
+ } else if (ch == 63) {
+ (*en_src)[j++] = '/';
+ } else if (ch == -1) {
+ (*en_src)[j++] = '='; // padding
+ }
+ */
+
+ if ((ch != -1) && (ch >= 0 && ch <= 64)) {
+ (*en_src)[j++] = base64_table[ch];
+ } else {
+ (*en_src)[j++] = base64_table[64]; /* padding */
+ }
+
+ size_cnt++;
+
+ if (j % 4 == 0) {
+ if (size_cnt == BASE64_SIZE) {
+ size_cnt = 0;
+ (*en_src)[j++] = 0x0A; /* soft line break */
+ }
+
+ if (i >= src_len)
+ break;
+ }
+ }
+
+ (*en_src)[j] = 0x00;
+ *en_src_len = j;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int decode_base64(char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ long tmp = 0; /* 4byte (using decoding) */
+ int i = 0;
+ int j = 0;
+ int cnt = 0;
+ int pad_cnt = 0;
+
+ /* de_src is enough for the src_len 3/4 size */
+ *de_src = (char *)malloc(sizeof(char) * (src_len));
+
+ if (*de_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
+ return 0;
+ }
+ memset(*de_src, 0x00, src_len);
+
+ while (src[i] != '\0') {
+ /*
+ if (isupper(src[i])) {
+ tmp = (tmp << 6) | (src[i] - 'A'); // Upper case : 0 ~ 25
+ } else if (islower(src[i])) {
+ tmp = (tmp << 6) | (src[i] - 'a' + 0x1A); // Lower case : 26(0x1A) ~ 51
+ } else if (isdigit(src[i])) {
+ tmp = (tmp << 6) | (src[i] - '0' + 0x34); // Number : 52(0x34) ~ 61
+ } else if (src[i] == '+') {
+ tmp = (tmp << 6) | 0x3E; // '+' : 62(0x3E)
+ } else if (src[i] == '/') {
+ tmp = (tmp << 6) | 0x3F; // '/' : 63(0x3F)
+ } else if (src[i] == '=') {
+ pad_cnt++;
+ tmp = (tmp << 6); // '=' : padding
+ } else {
+ tmp = (tmp << 6); // encoding error
+ f_DEBUG_INFO(stdout, "encoding error !! \n");
+ }
+ */
+
+ tmp = (tmp << 6) | (_find_base(src[i]));
+ if (tmp == 64) {
+ pad_cnt++;
+ } else if (tmp == -1) {
+ _DEBUG_ERROR("[encoding_util] encoding error \n");
+ }
+
+ if (++cnt >= 4) {
+ (*de_src)[j++] = (char)((tmp & 0x00FF0000) >> 16);
+ (*de_src)[j++] = (char)((tmp & 0x0000FF00) >> 8);
+ (*de_src)[j++] = (char)(tmp & 0x000000FF);
+
+ cnt = 0;
+ tmp = 0;
+
+ if (src[i + 1] == 0x0A) { /* soft line break */
+ i++;
+ }
+ }
+
+ i++;
+ }
+
+ (*de_src)[j - pad_cnt] = '\0';
+ *de_src_len = j - pad_cnt;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int proc_decoding(const char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ const char *reg_src = NULL;
+ reg_src = src;
+
+ _DEBUG_INFO("[encoding_util] << src >> \n%s\n", src);
+
+ *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
+ if (*de_src == NULL) {
+ _DEBUG_INFO("[encoding_util] malloc error !! \n");
+
+ return 0;
+ }
+ memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
+
+ char colon[] = ":";
+ char line_breaker[] = "\r\n";
+ char *start_decoding = NULL;
+ int data_size = 0;
+ int res = 0;
+ int de_temp_len = 0;
+ int len = 0;
+
+ _DEBUG_INFO("src len : %d", src_len);
+ char *de_temp = (char *)malloc(sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
+ if (de_temp == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ return 0;
+ }
+
+ while ((start_decoding = strstr(src, "ENCODING="))) {
+ char *colon_loc = strstr(start_decoding, colon); /* find ':''s location */
+ char *line_breaker_loc = NULL;
+ if (colon_loc != NULL) {
+ line_breaker_loc = strstr(colon_loc, line_breaker); /* find "\r\n"'s location */
+ } else {
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+ return 0;
+ }
+
+ /*
+ * if find "ENCODING=" do strcat data until ":" to de_src
+ */
+ data_size = (colon_loc + 1) - src; /* colon_loc + 1 ==> Until next character of ':' */
+
+ _DEBUG_INFO("data_size : %d", data_size);
+ char *temp = (char *)malloc(sizeof(char) * (data_size + 1));
+ if (temp == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+ memset(temp, 0x00, sizeof(char) * (data_size + 1));
+ memcpy(temp, src, data_size);
+ len = g_strlcat(*de_src, temp, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (temp != NULL)
+ free(temp);
+
+ return 0;
+ }
+
+ if (temp != NULL)
+ free(temp);
+
+ _DEBUG_INFO("[encoding_util] << *de_src >> \n %s\n", *de_src);
+
+ /*
+ * copy data from ":" until "\r\n"(actual encoding stream)
+ */
+ data_size = line_breaker_loc - colon_loc; /* from ':' until "\r\n" + '\0' */
+ char *value = (char *)malloc(sizeof(char) * (data_size + 1));
+ if (value == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+ memset(value, 0x00, sizeof(char) * (data_size + 1));
+ memcpy(value, ++colon_loc, data_size); /* from ':' until "\r\n" */
+ value[data_size] = '\0';
+ _DEBUG_INFO("value : %s, value_len : %d", value, strlen(value));
+
+ /*
+ * Get encoding type using data from "ENCODING=" to ":"
+ */
+ char type_check[TYPE_CHECK_BUF_SIZE] = { 0, };
+ int type_check_size = colon_loc - start_decoding;
+ strncpy(type_check, start_decoding, type_check_size);
+ _DEBUG_INFO("[encoding_util] type check : %s\n", type_check);
+ encoding_type_e type = find_encoding_type((const char *)type_check);
+
+ /*
+ * Process decoding by passing the actual value and encoding type to decode_value()
+ */
+ de_temp_len = 0;
+ memset(de_temp, 0x00, sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
+ res = decode_value(type, value, data_size, &de_temp, &de_temp_len);
+
+ if (res != 1) {
+ _DEBUG_ERROR("[encoding_util] decode_value error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (value != NULL)
+ free(value);
+
+ return 0;
+ }
+
+ /*
+ * Append decoded data to de_src
+ */
+ _DEBUG_INFO("[encoding_util] de_temp : %s\n", de_temp);
+ len = 0;
+ len = g_strlcat(*de_src, de_temp, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (value != NULL)
+ free(value);
+
+ return 0;
+ }
+
+ /*
+ * find "ENCODING=" since "\r\n" agina
+ */
+ src = line_breaker_loc;
+
+ if (value != NULL)
+ free(value);
+ }
+
+ len = 0;
+ len = g_strlcat(*de_src, src, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+
+ *de_src_len = strlen(*de_src);
+ _DEBUG_INFO("[encoding_util] changed src : \n%s ( %d ) \n", *de_src, *de_src_len);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int check_encoding_data(const char *data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ /*if (strstr(data, "ENCODING=") != NULL) {
+ _DEBUG_INFO("[encoding_util] exist encoding data !! \n");
+ return 1;
+ } else {
+ _DEBUG_INFO("[encoding_util] not exist encoding data !! \n");
+ return 0;
+ } */
+ _EXTERN_FUNC_EXIT;
+ return 0;
+}
+
+encoding_type_e find_encoding_type(const char *data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ encoding_type_e type = EN_TYPE_NONE;
+ if (strstr(data, "QUOTED-PRINTABLE") != NULL) {
+ _DEBUG_INFO("[encoding_util] type : QP\n");
+ type = EN_TYPE_QUOTED_PRINTABLE;
+ } else if (strstr(data, "BASE64") != NULL) {
+ _DEBUG_INFO("[encoding_util] type : BASE64\n");
+ type = EN_TYPE_BASE64;
+ } else {
+ _DEBUG_INFO("[encoding_util] not supported type !! \n");
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return type;
+}
+
+int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(value == NULL, 0, "[encoding_util] value is NULL\n");
+
+ int res = 1;
+ const char *start_pos = NULL;
+ const char *cursor = NULL;
+ int semi_cnt = 0;
+ int len = 0;
+
+ /*
+ * ex> value - =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+ */
+ cursor = value;
+ start_pos = value;
+
+ while (*cursor != '\0') {
+ if ((*cursor != ';') && (*cursor != '\r')) {
+ cursor++;
+ continue;
+ } else if (*cursor == ';') {
+ semi_cnt++;
+ }
+
+ int data_size = 0;
+ data_size = cursor - start_pos;
+
+ if (data_size == 0) {
+ cursor++;
+ start_pos++;
+ } else {
+ char *temp = (char *)malloc(sizeof(char) * (value_size + 1));
+ if (temp == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!");
+ return 0;
+ }
+ memset(temp, 0x00, sizeof(char) * (value_size + 1));
+ memcpy(temp, start_pos, data_size);
+
+ _DEBUG_INFO("[encoding_util] temp : %s \n", temp);
+
+ char *decoding = 0;
+ int decoding_len = 0;
+
+ switch (type) {
+ case EN_TYPE_QUOTED_PRINTABLE:
+ res = decode_qp(temp, data_size, &decoding, &decoding_len);
+ break;
+ case EN_TYPE_BASE64:
+ res = decode_base64(temp, data_size, &decoding, &decoding_len);
+ break;
+ default:
+ break;
+ }
+
+ if (temp != NULL)
+ free(temp);
+
+ _DEBUG_INFO("[encoding_util] decoding : %s ( %d )\n", decoding, decoding_len);
+
+ if (res != 1) {
+ _DEBUG_ERROR("[encoding_util] decoding error !! \n");
+
+ if (decoding != NULL)
+ free(decoding);
+
+ return 0;
+ } else {
+ _DEBUG_INFO("[encoding_util] decoding success !!");
+ if (decoding != NULL) {
+ len = g_strlcat(*decode_str, decoding, TEMP_BUFFER_SIZE);
+ if (len >= TEMP_BUFFER_SIZE) {
+ _DEBUG_ERROR("*decode_str buffer overflow !!");
+
+ if (decoding != NULL)
+ free(decoding);
+
+ return 0;
+ }
+ _DEBUG_INFO("[encoding_util] *decode_str : %s\n", *decode_str);
+ } else {
+ _DEBUG_ERROR("[encoding_util] decoding is NULL !!");
+ return 0;
+ }
+ }
+
+ if (decoding != NULL)
+ free(decoding);
+
+ cursor++;
+ start_pos = cursor;
+ }
+
+ if (semi_cnt > 0) {
+ int len = strlen(*decode_str);
+ (*decode_str)[len] = ';';
+ _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, strlen(*decode_str));
+ semi_cnt--;
+ }
+ }
+
+ *decode_str_len = strlen(*decode_str);
+
+ _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, *decode_str_len);
+
+ _EXTERN_FUNC_EXIT;
+ return res;
+}
+
+static int _find_base(char ch)
+{
+ _EXTERN_FUNC_ENTER;
+
+ int i = 0;
+ for (i = 0; i < 65; i++) {
+ if (base64_table[i] == ch) {
+ _DEBUG_INFO("[encoding_util] End !! \n");
+ return i;
+ }
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return -1;
+}
diff --git a/src/plugins/ds-public/vcard/src/plugin_interface.c b/src/plugins/ds-public/vcard/src/plugin_interface.c
new file mode 100755
index 0000000..5131f38
--- /dev/null
+++ b/src/plugins/ds-public/vcard/src/plugin_interface.c
@@ -0,0 +1,998 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdio.h>
+#include <contacts.h>
+#include <glib.h>
+
+#include <sync_agent.h>
+
+#include "plugin_spec.h"
+#include "in_datastore_info_vcard.h"
+#include "encoding_util.h"
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef OMADS_AGENT_LOG
+#undef LOG_TAG
+#define LOG_TAG "PLUGIN_VCARD"
+#endif
+
+static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count);
+static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, vcard_field_list_s * input_list);
+static char *_convert_key_name(int key);
+
+static int _get_content(const char *value, void *data);
+
+static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err);
+static char *_contacts_vcard_put_content(const char *vcard_stream, const char *content_type, const char *content_value);
+static int _contacts_vcard_get_content(const char *vcard_stream, const char *content_type, int (*fn) (const char *content_value, void *data), void *data);
+
+static void _contacts_struct_merge(contacts_record_h old, contacts_record_h new);
+static void __contacts_struct_property_merge(contacts_record_h old, contacts_record_h new);
+static void __contacts_struct_child_property_merge(unsigned int property_id, contacts_record_h old, contacts_record_h new);
+
+//static void _remove_vcard_field(CTSstruct *contact);
+//static void _remove_vcard_gslist_field(gpointer data, gpointer user_data);
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_converter(const void *agent_data, void **service_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+// retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
+//
+// sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+// int err = 0;
+// CTSstruct *temp_service_data = 0;
+//
+// /* decoding & convert */
+// _DEBUG_INFO("[dc_vcard_plugIn] agent data : %s\n", agent_data);
+// char *de_agent_data;
+// int src_len = strlen(agent_data);
+// int de_agent_data_len = 0;
+//
+// if (check_encoding_data(agent_data) == 1) {
+// err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
+// if (err == 0) {
+// _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
+// ret = SYNC_AGENT_DA_ERRORS;
+// return ret;
+// }
+//
+// err = contacts_svc_get_contact_from_vcard((const void *)de_agent_data, &temp_service_data);
+//
+// /*memory free */
+// if (de_agent_data != NULL)
+// free(de_agent_data);
+// } else {
+// err = contacts_svc_get_contact_from_vcard(agent_data, &temp_service_data);
+// }
+//
+// if (err < CTS_SUCCESS) {
+// _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Fail!\n");
+// ret = _convert_service_error_to_common_error(err);
+// *service_data = 0;
+// } else {
+// _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Success!\n");
+// *service_data = (void *)temp_service_data;
+// }
+
+ retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+ contacts_list_h list = NULL;
+ contacts_record_h record = NULL;
+ contacts_record_h cloned_record = NULL;
+
+ /* decoding & convert */
+ _DEBUG_INFO("[dc_vcard_plugIn] agent data : %s\n", agent_data);
+ char *de_agent_data;
+ int src_len = strlen(agent_data);
+ int de_agent_data_len = 0;
+
+ if (check_encoding_data(agent_data) == 1) {
+ err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
+ if (err == 0) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
+ ret = SYNC_AGENT_DA_ERRORS;
+ return ret;
+ }
+
+ err = contacts_vcard_parse_to_contacts(de_agent_data, &list);
+
+ /*memory free */
+ if (de_agent_data != NULL)
+ free(de_agent_data);
+ } else {
+ err = contacts_vcard_parse_to_contacts(agent_data, &list);
+ }
+
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *service_data = 0;
+ } else {
+ _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Success!\n");
+ err = contacts_list_get_current_record_p(list, &record);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_list_get_current_record_p() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *service_data = 0;
+ contacts_list_destroy(list, true);
+ return ret;
+ }
+
+ err = contacts_record_clone(record, &cloned_record);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_record_clone() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *service_data = 0;
+ contacts_list_destroy(list, true);
+ return ret;
+ }
+
+ *service_data = (void *)cloned_record;
+ contacts_list_destroy(list, true);
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_replace_converter(void *old_service_data, const void *agent_data, void **new_service_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+// retvm_if(old_service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] old_service_data is NULL");
+// retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
+//
+// sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+// int err = 0;
+// CTSstruct *temp_new_service_data = 0;
+// CTSstruct *temp_old_service_data = (CTSstruct *)old_service_data;
+//
+// /* 1. agent_data encoding check
+// * 2. decoding
+// * 3. copy to new_service_data
+// */
+// /* decoding */
+// char *de_agent_data;
+// int src_len = strlen(agent_data);
+// int de_agent_data_len = 0;
+//
+// if (check_encoding_data(agent_data) == 1) {
+// err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
+// if (err == 0) {
+// _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
+///* ret = SYNC_AGENT_DA_ERRORS;
+// return ret;*/
+// err = contacts_svc_get_contact_from_vcard(agent_data, &temp_new_service_data);
+// } else {
+// _DEBUG_INFO("[dc_vcard_plugIn] proc_decoding() Success l!\n");
+// err = contacts_svc_get_contact_from_vcard((const void *)de_agent_data, &temp_new_service_data);
+//
+// /*memory free */
+// if (de_agent_data != NULL)
+// free(de_agent_data);
+// }
+// } else {
+// err = contacts_svc_get_contact_from_vcard(agent_data, &temp_new_service_data);
+// }
+//
+// if (err < CTS_SUCCESS) {
+// _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Fail!\n");
+// ret = _convert_service_error_to_common_error(err);
+// *new_service_data = 0;
+//
+// /* memory free */
+// if (temp_old_service_data != NULL)
+// contacts_svc_struct_free(temp_old_service_data);
+//
+// } else {
+// _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Success!\n");
+// _remove_vcard_field(temp_old_service_data);
+// err = contacts_svc_struct_merge(temp_old_service_data, temp_new_service_data);
+// if (err < CTS_SUCCESS) {
+// _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_struct_merge() Fail!\n");
+// ret = _convert_service_error_to_common_error(err);
+// *new_service_data = 0;
+//
+// /* memory free */
+// if (temp_old_service_data != NULL)
+// contacts_svc_struct_free(temp_old_service_data);
+// } else {
+// _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_struct_merge() Success!\n");
+// *new_service_data = (void *)temp_old_service_data;
+// }
+// }
+//
+// /* memory free */
+// if (temp_new_service_data != NULL)
+// contacts_svc_struct_free(temp_new_service_data);
+
+ retvm_if(old_service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] old_service_data is NULL");
+ retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+ contacts_list_h list = NULL;
+
+ contacts_record_h temp_new_service_data = NULL;
+ contacts_record_h temp_old_service_data = (contacts_record_h) old_service_data;
+
+ /* 1. agent_data encoding check
+ * 2. decoding
+ * 3. copy to new_service_data
+ */
+ /* decoding */
+ char *de_agent_data;
+ int src_len = strlen(agent_data);
+ int de_agent_data_len = 0;
+
+ if (check_encoding_data(agent_data) == 1) {
+ err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
+ if (err == 0) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
+/* ret = SYNC_AGENT_DA_ERRORS;
+ return ret;*/
+ err = contacts_vcard_parse_to_contacts(agent_data, &list);
+ } else {
+ _DEBUG_INFO("[dc_vcard_plugIn] proc_decoding() Success l!\n");
+ err = contacts_vcard_parse_to_contacts(de_agent_data, &list);
+
+ /*memory free */
+ if (de_agent_data != NULL)
+ free(de_agent_data);
+ }
+ } else {
+ err = contacts_vcard_parse_to_contacts(agent_data, &list);
+ }
+
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *new_service_data = 0;
+
+ } else {
+ _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Success!\n");
+
+ err = contacts_list_get_current_record_p(list, &temp_new_service_data);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_list_get_current_record_p() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *new_service_data = 0;
+ goto DACI_FINISH;
+ }
+
+ _contacts_struct_merge(temp_old_service_data, temp_new_service_data);
+
+ *new_service_data = (void *)temp_old_service_data;
+ }
+
+ DACI_FINISH:
+
+ contacts_list_destroy(list, true);
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_reverse_converter(void *service_data, void **agent_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+// retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] service_data is NULL");
+//
+// sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+// int err = 0;
+// char *temp_agent_data = 0;
+// CTSstruct *temp_service_data = (CTSstruct *)service_data;
+//
+// /* Reverse_Converter */
+// err = contacts_svc_get_vcard_from_contact(temp_service_data, &temp_agent_data);
+// if (err < CTS_SUCCESS) {
+// _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_vcard_from_contact() Fail!\n");
+// ret = _convert_service_error_to_common_error(err);
+// *agent_data = 0;
+// } else {
+// _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_vcard_from_contact() Success!\n");
+// *agent_data = (void *)temp_agent_data;
+// }
+//
+// /* memory free */
+// if (temp_service_data != NULL)
+// contacts_svc_struct_free(temp_service_data);
+
+ retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] service_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+
+ char *temp_agent_data = 0;
+ contacts_record_h record = (contacts_record_h) service_data;
+
+ char *display_name = NULL;
+ int id;
+ contacts_record_get_str_p(record, _contacts_contact.display_name, &display_name);
+ contacts_record_get_int(record, _contacts_contact.id, &id);
+
+ _DEBUG_INFO("display_name = %s", display_name);
+ _DEBUG_INFO("id = %d", id);
+
+ /* Reverse_Converter */
+ err = contacts_vcard_make_from_contact(record, &temp_agent_data);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_make_from_contact() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *agent_data = 0;
+ } else {
+ _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_make_from_contact() Success!\n");
+ *agent_data = (void *)temp_agent_data;
+ _DEBUG_INFO("temp_agent_data = %s", temp_agent_data);
+ }
+
+ contacts_record_destroy(record, true);
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}
+
+EXPORT_API void *sync_agent_plugin_alloc_object()
+{
+ _EXTERN_FUNC_ENTER;
+
+ char *agent_data = "BEGIN:VCARD\r\n\
+VERSION:2.1\r\n\
+END:VCARD";
+
+ _EXTERN_FUNC_EXIT;
+ return (void *)agent_data;
+}
+
+EXPORT_API int sync_agent_plugin_free_object(void *in_object)
+{
+ _EXTERN_FUNC_ENTER;
+ _DEBUG_INFO("[dc_vcard_plugIn] Do nothing\n");
+
+ return 1;
+}
+
+EXPORT_API void *sync_agent_plugin_set_value(void *in_object, int key, char *extension_key, void *value)
+{
+ _EXTERN_FUNC_ENTER;
+
+ char *new_agent_data = 0;
+ char *key_name = 0;
+
+ if (key == VCARD_CONTENT_NO_TYPE)
+ return (void *)new_agent_data;
+ else if (key == VCARD_CONTENT_EXTENSION)
+ key_name = extension_key;
+ else
+ key_name = _convert_key_name(key);
+
+ new_agent_data = _contacts_vcard_put_content((const char *)in_object, (const char *)key_name, (const char *)value);
+
+ _EXTERN_FUNC_EXIT;
+ return (void *)new_agent_data;
+}
+
+EXPORT_API void *sync_agent_plugin_get_value(void *in_object, int key, char *extension_key)
+{
+ _EXTERN_FUNC_ENTER;
+
+ char data[5000] = { 0, }; /* hard coding : size 1000 */
+ char *key_name = 0;
+ int result;
+
+ if (key == VCARD_CONTENT_NO_TYPE)
+ return 0;
+ else if (key == VCARD_CONTENT_EXTENSION)
+ key_name = extension_key;
+ else
+ key_name = _convert_key_name(key);
+
+ result = _contacts_vcard_get_content((const char *)in_object, (const char *)key_name, _get_content, data);
+ if (result == 0) {
+ _EXTERN_FUNC_EXIT;
+ return 0;
+ }
+
+ _EXTERN_FUNC_EXIT;
+
+ if (strlen(data) == 0)
+ return 0;
+ else
+ return strdup(data);
+}
+
+EXPORT_API sync_agent_plugin_object_info_s *sync_agent_plugin_get_obj_info()
+{
+ _EXTERN_FUNC_ENTER;
+
+ sync_agent_plugin_object_info_s *obj_info = (sync_agent_plugin_object_info_s *) calloc(1, sizeof(sync_agent_plugin_object_info_s));
+ if (obj_info == NULL) {
+ _DEBUG_ERROR("CALLOC failed !!!");
+ return NULL;
+ }
+
+ obj_info->type = VCARD_TYPE;
+ obj_info->version = VCARD_VERSION;
+ obj_info->field_cnt = sizeof(vcard_field_list) / sizeof(vcard_field_list_s);
+
+ if (obj_info->field_cnt > 0)
+ if (_set_obj_field_info(&(obj_info->field_list), obj_info->field_cnt, vcard_field_list) == 0) {
+ /* for prevent */
+ if (obj_info != NULL)
+ free(obj_info);
+
+ return NULL;
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return obj_info;
+}
+
+EXPORT_API int sync_agent_plugin_free_obj_info(sync_agent_plugin_object_info_s * obj_info)
+{
+ _EXTERN_FUNC_ENTER;
+
+ if (obj_info != NULL) {
+ if (obj_info->field_cnt > 0)
+ if (_free_obj_field_info(obj_info->field_list, obj_info->field_cnt) == 0)
+ return 0;
+
+ free(obj_info);
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count)
+{
+ _INNER_FUNC_ENTER;
+
+ int field_count = 0;
+ sync_agent_plugin_field_info_s *child = NULL;
+
+ if (field_list != NULL) {
+ for (field_count = 0; field_count < count; field_count++) {
+ child = field_list + field_count;
+ if (child->field_child_cnt > 0)
+ if (_free_obj_field_info(child->field_child_list, child->field_child_cnt) == 0)
+ return 0;
+ }
+ free(field_list);
+ }
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, vcard_field_list_s * input_list)
+{
+ _INNER_FUNC_ENTER;
+
+ int field_count = 0;
+ sync_agent_plugin_field_info_s *child = NULL;
+
+ *field_list = (sync_agent_plugin_field_info_s *) calloc(count, sizeof(sync_agent_plugin_field_info_s));
+ if (*field_list == NULL) {
+ _DEBUG_ERROR("CALLOC failed !!!");
+ return 0;
+ }
+
+ for (field_count = 0; field_count < count; field_count++) {
+ child = (*field_list) + field_count;
+ child->field_name = input_list[field_count].field_name;
+ _DEBUG_TRACE("[%s]", child->field_name);
+
+ if (input_list[field_count].field_enum == VCARD_FIELD_BEGIN || input_list[field_count].field_enum == VCARD_FIELD_END) {
+ child->field_child_cnt = sizeof(vcard_field_list_begin_end) / sizeof(vcard_field_list_s);
+ _DEBUG_TRACE("----------");
+ _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_begin_end);
+ _DEBUG_TRACE("==========");
+ } else if (input_list[field_count].field_enum == VCARD_FIELD_VERSION) {
+ child->field_child_cnt = sizeof(vcard_field_list_version) / sizeof(vcard_field_list_s);
+ _DEBUG_TRACE("----------");
+ _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_version);
+ _DEBUG_TRACE("==========");
+ } else if (input_list[field_count].field_enum == VCARD_FIELD_ADR) {
+ child->field_child_cnt = sizeof(vcard_field_list_adr) / sizeof(vcard_field_list_s);
+ _DEBUG_TRACE("----------");
+ _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_adr);
+ _DEBUG_TRACE("==========");
+ } else if (input_list[field_count].field_enum == VCARD_FIELD_TEL) {
+ child->field_child_cnt = sizeof(vcard_field_list_tel) / sizeof(vcard_field_list_s);
+ _DEBUG_TRACE("----------");
+ _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_tel);
+ _DEBUG_TRACE("==========");
+ } else if (input_list[field_count].field_enum == VCARD_FIELD_EMAIL) {
+ child->field_child_cnt = sizeof(vcard_field_list_email) / sizeof(vcard_field_list_s);
+ _DEBUG_TRACE("----------");
+ _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_email);
+ _DEBUG_TRACE("==========");
+ }
+ }
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+static char *_convert_key_name(int key)
+{
+ _INNER_FUNC_ENTER;
+
+ char *key_name = 0;
+
+ switch (key) {
+ case VCARD_CONTENT_FN:
+ key_name = "FN";
+ break;
+ case VCARD_CONTENT_N:
+ key_name = "N";
+ break;
+ case VCARD_CONTENT_NICKNAME:
+ key_name = "NICKNAME";
+ break;
+ case VCARD_CONTENT_PHOTO:
+ key_name = "PHOTO";
+ break;
+ case VCARD_CONTENT_BDAY:
+ key_name = "BDAY";
+ break;
+ case VCARD_CONTENT_ADR:
+ key_name = "ADR";
+ break;
+ case VCARD_CONTENT_LABEL:
+ key_name = "LABEL";
+ break;
+ case VCARD_CONTENT_TEL:
+ key_name = "TEL";
+ break;
+ case VCARD_CONTENT_EMAIL:
+ key_name = "EMAIL";
+ break;
+ case VCARD_CONTENT_TITLE:
+ key_name = "TITLE";
+ break;
+ case VCARD_CONTENT_ROLE:
+ key_name = "ROLE";
+ break;
+ case VCARD_CONTENT_ORG:
+ key_name = "ORG";
+ break;
+ case VCARD_CONTENT_NOTE:
+ key_name = "NOTE";
+ break;
+ case VCARD_CONTENT_REV:
+ key_name = "REV";
+ break;
+ case VCARD_CONTENT_UID:
+ key_name = "UID";
+ break;
+ case VCARD_CONTENT_URL:
+ key_name = "URL";
+ break;
+ case VCARD_CONTENT_X_ANNIVERSARY:
+ key_name = "X-ANNIVERSARY";
+ break;
+ case VCARD_CONTENT_X_IRMC_LUID:
+ key_name = "X-IRMC-LUID";
+ break;
+ default:
+ break;
+ }
+
+ _INNER_FUNC_EXIT;
+ return key_name;
+}
+
+static int _get_content(const char *value, void *data)
+{
+ _INNER_FUNC_ENTER;
+
+ retvm_if(value == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] value is NULL");
+
+ const char *line_breaker = "\r";
+ char *colon_loc = 0;
+ char *line_breaker_loc = 0;
+ int data_size = 0;
+
+ colon_loc = (char *)value;
+ line_breaker_loc = strstr(colon_loc, line_breaker);
+ data_size = line_breaker_loc - colon_loc;
+ _DEBUG_TRACE("[dc_vcard_plugIn] value : %s", value);
+ _DEBUG_TRACE("[dc_vcard_plugIn] colon_loc : %s", colon_loc);
+ _DEBUG_TRACE("[dc_vcard_plugIn] line_breaker_loc : %s", line_breaker_loc);
+ _DEBUG_TRACE("[dc_vcard_plugIn] data_size : %d", data_size);
+
+ /* hard coding : size 5000 */
+ memcpy((char *)data, colon_loc, data_size);
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err)
+{
+ _INNER_FUNC_ENTER;
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ _DEBUG_TRACE("[da_contact_plugIn] Error Code : %d\n", err);
+
+ switch (err) {
+ case CONTACTS_ERROR_NONE:
+ ret = SYNC_AGENT_DA_SUCCESS;
+ break;
+ case CONTACTS_ERROR_OUT_OF_MEMORY:
+ ret = SYNC_AGENT_DA_ERR_MEMORY_FULL;
+ break;
+ case CONTACTS_ERROR_INVALID_PARAMETER:
+ ret = SYNC_AGENT_DA_ERR_INVALID_PARAMETER;
+ break;
+ case CONTACTS_ERROR_NO_DATA:
+ ret = SYNC_AGENT_DA_ERR_NO_DATA;
+ break;
+ case CONTACTS_ERROR_DB:
+ ret = SYNC_AGENT_DA_ERR_SERVICE_DB;
+ break;
+ case CONTACTS_ERROR_IPC:
+ ret = SYNC_AGENT_DA_ERR_SERVICE_IPC;
+ break;
+ default:
+ ret = SYNC_AGENT_DA_ERRORS;
+ break;
+ }
+
+ _INNER_FUNC_EXIT;
+
+ return ret;
+}
+
+static char *_contacts_vcard_put_content(const char *vcard_stream, const char *content_type, const char *content_value)
+{
+ _INNER_FUNC_ENTER;
+
+ int i, org_len, new_len;
+ char *new_stream, *cur;
+ const char *end_content = "END:VCARD";
+
+ retvm_if(NULL == vcard_stream, NULL, "vcard_stream is NULL");
+ retvm_if(NULL == content_type, NULL, "content_type is NULL");
+ retvm_if(NULL == content_value, NULL, "content_value is NULL");
+
+ org_len = strlen(vcard_stream);
+ new_len = org_len + strlen(content_type) + strlen(content_value) + 8;
+
+ new_stream = malloc(new_len);
+ retvm_if(NULL == new_stream, NULL, "malloc() Failed");
+
+ memcpy(new_stream, vcard_stream, org_len);
+
+ i = 1;
+ for (cur = new_stream + new_len - 1; cur; cur--) {
+ if (end_content[9 - i] == *cur) {
+ if (9 == i)
+ break;
+ i++;
+ continue;
+ } else {
+ i = 1;
+ }
+ }
+ if (9 != i) {
+ _DEBUG_ERROR("vcard_stream is invalid(%s)", vcard_stream);
+ free(new_stream);
+ _INNER_FUNC_EXIT;
+ return NULL;
+ }
+
+ cur += snprintf(cur, new_len - (cur - new_stream), "%s:", content_type);
+ cur = strncpy(cur, content_value, new_len - (cur - new_stream));
+ snprintf(cur, new_len - (cur - new_stream), "\r\n%s\r\n", end_content);
+
+ _INNER_FUNC_EXIT;
+
+ return new_stream;
+}
+
+static int _contacts_vcard_get_content(const char *vcard_stream, const char *content_type, int (*fn) (const char *content_value, void *data), void *data)
+{
+ _INNER_FUNC_ENTER;
+
+ int len, buf_size, type_len;
+ char *cursor, *found, *value;
+
+ retv_if(NULL == vcard_stream, 0);
+ retv_if(NULL == content_type, 0);
+ retv_if(NULL == fn, 0);
+
+ type_len = strlen(content_type);
+ value = malloc(1024);
+ retvm_if(NULL == value, 0, "malloc() Failed");
+ buf_size = 1024;
+
+ while ((found = strstr(vcard_stream, content_type))) {
+ if ((found != vcard_stream && '\n' != *(found - 1))
+ && ':' != *(found + type_len + 1))
+ continue;
+
+ cursor = found;
+ while (*cursor) {
+ if ('\r' == *cursor)
+ cursor++;
+ if ('\n' == *cursor) {
+ if (' ' != *(cursor + 1))
+ break;
+ }
+
+ cursor++;
+ }
+ len = cursor - found;
+ if (len < buf_size)
+ memcpy(value, found, len);
+ else {
+ value = realloc(value, len + 1);
+ if (value) {
+ buf_size = len + 1;
+ memcpy(value, found, len);
+ } else {
+ vcard_stream = found + type_len;
+ continue;
+ }
+ }
+ value[len] = '\0';
+ if (fn)
+ if (fn(value + type_len + 1, data)) {
+ free(value);
+ _INNER_FUNC_EXIT;
+ return 0;
+ }
+ vcard_stream = found + type_len;
+ }
+
+ free(value);
+
+ _INNER_FUNC_EXIT;
+ return 1;
+}
+
+static void _contacts_struct_merge(contacts_record_h old, contacts_record_h new)
+{
+ _INNER_FUNC_ENTER;
+
+ __contacts_struct_property_merge(old, new);
+
+ __contacts_struct_child_property_merge(_contacts_contact.name, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.image, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.company, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.note, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.number, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.email, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.event, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.messenger, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.address, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.url, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.nickname, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.profile, old, new);
+// __contacts_struct_child_property_merge(_contacts_contact.relationship, old, new);
+// __contacts_struct_child_property_merge(_contacts_contact.group_relation, old, new);
+ __contacts_struct_child_property_merge(_contacts_contact.extension, old, new);
+
+ _INNER_FUNC_EXIT;
+}
+
+static void __contacts_struct_property_merge(contacts_record_h old, contacts_record_h new)
+{
+ _INNER_FUNC_ENTER;
+
+// contacts_error_e err = CONTACTS_ERROR_NONE;
+//
+// char *ringtone_path = NULL;
+// char *image_thumbnail_path = NULL;
+// char *uid = NULL;
+// char *vibration = NULL;
+//
+// err = contacts_record_get_str_p(new, _contacts_contact.ringtone_path, &ringtone_path);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_get_str_p(ringtone_path) is failed");
+//
+// if (ringtone_path != NULL) {
+// _DEBUG_TRACE("ringtone_path = %s", ringtone_path);
+// err = contacts_record_set_str(old, _contacts_contact.ringtone_path, ringtone_path);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_set_str(%s) is failed", ringtone_path);
+// }
+//
+// err = contacts_record_get_str_p(new, _contacts_contact.image_thumbnail_path, &image_thumbnail_path);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_get_str_p(image_thumbnail_path) is failed");
+//
+// if (image_thumbnail_path != NULL) {
+// _DEBUG_TRACE("image_thumbnail_path = %s", image_thumbnail_path);
+// err = contacts_record_set_str(old, _contacts_contact.image_thumbnail_path, image_thumbnail_path);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_set_str(%s) is failed", image_thumbnail_path);
+// }
+//
+// err = contacts_record_get_str_p(new, _contacts_contact.uid, &uid);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_get_str_p(uid) is failed");
+//
+// if (uid != NULL) {
+// _DEBUG_TRACE("uid = %s", uid);
+// err = contacts_record_set_str(old, _contacts_contact.uid, uid);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_set_str(%s) is failed", uid);
+// }
+//
+// err = contacts_record_get_str_p(new, _contacts_contact.vibration, &vibration);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_get_str_p(vibration) is failed");
+//
+// if (vibration != NULL) {
+// _DEBUG_TRACE("vibration = %s", vibration);
+// err = contacts_record_set_str(old, _contacts_contact.vibration, vibration);
+// if (err != CONTACTS_ERROR_NONE)
+// _DEBUG_ERROR("contacts_record_set_str(%s) is failed", vibration);
+// }
+
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+
+ char *image_thumbnail_path = NULL;
+
+ err = contacts_record_get_str_p(new, _contacts_contact.image_thumbnail_path, &image_thumbnail_path);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_get_str_p(image_thumbnail_path) is failed");
+
+ if (image_thumbnail_path != NULL) {
+ _DEBUG_TRACE("image_thumbnail_path = %s", image_thumbnail_path);
+ err = contacts_record_set_str(old, _contacts_contact.image_thumbnail_path, image_thumbnail_path);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_set_str(%s) is failed", image_thumbnail_path);
+ }
+
+ _INNER_FUNC_EXIT;
+}
+
+static void __contacts_struct_child_property_merge(unsigned int property_id, contacts_record_h old, contacts_record_h new)
+{
+ _INNER_FUNC_ENTER;
+
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+
+ unsigned int old_count = 0;
+ unsigned int new_count = 0;
+
+ contacts_record_h old_record = NULL;
+ contacts_record_h new_record = NULL;
+ contacts_record_h new_cloned_record = NULL;
+
+ _DEBUG_TRACE("property_id = %d", property_id);
+
+ err = contacts_record_get_child_record_count(old, property_id, &old_count);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_get_child_record_count is failed");
+
+ _DEBUG_TRACE("old_count = %d", old_count);
+
+ int i;
+ for (i = 0; i < old_count; i++) {
+
+ err = contacts_record_get_child_record_at_p(old, property_id, 0, &old_record);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_get_child_record_at_p is failed");
+
+ err = contacts_record_remove_child_record(old, property_id, old_record);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_remove_child_record is failed");
+ }
+
+ err = contacts_record_get_child_record_count(new, property_id, &new_count);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_get_child_record_count is failed");
+
+ _DEBUG_TRACE("new_count = %d", new_count);
+
+ for (i = 0; i < new_count; i++) {
+
+ err = contacts_record_get_child_record_at_p(new, property_id, i, &new_record);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_get_child_record_at_p is failed");
+
+ err = contacts_record_clone(new_record, &new_cloned_record);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_clone is failed");
+
+ err = contacts_record_add_child_record(old, property_id, new_cloned_record);
+ if (err != CONTACTS_ERROR_NONE)
+ _DEBUG_ERROR("contacts_record_add_child_record is failed");
+ }
+
+ _INNER_FUNC_EXIT;
+}
+
+//static void _remove_vcard_field(CTSstruct *contact)
+//{
+// _INNER_FUNC_ENTER;
+//
+// GSList *numbers = 0, *email = 0, *event = 0, *postal = 0, *web = 0, *nick = 0;
+// CTSvalue *name = 0, *company = 0, *base = 0;
+//
+// /* free name */
+// contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, 0);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, 0);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_ADDITION_STR, 0);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_SUFFIX_STR, 0);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_PREFIX_STR, 0);
+// contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, 0);
+//
+// /* free company */
+// contacts_svc_struct_get_value(contact, CTS_VALUE_COMPANY, &company);
+// contacts_svc_value_set_str(company, CTS_COMPANY_VAL_NAME_STR, 0);
+// contacts_svc_value_set_str(company, CTS_COMPANY_VAL_DEPARTMENT_STR, 0);
+// contacts_svc_value_set_str(company, CTS_COMPANY_VAL_JOB_TITLE_STR, 0);
+// contacts_svc_value_set_str(company, CTS_COMPANY_VAL_ROLE_STR, 0);
+//
+// /* free base */
+// contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
+// contacts_svc_value_set_str(base, CTS_BASE_VAL_IMG_PATH_STR, 0);
+// //contacts_svc_value_set_str(base, CTS_BASE_VAL_FULL_IMG_PATH_STR, 0);
+// contacts_svc_value_set_str(base, CTS_NOTE_VAL_NOTE_STR, 0);
+//
+// /* free number */
+// contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &numbers);
+// g_slist_foreach(numbers, _remove_vcard_gslist_field, (gpointer) CTS_NUM_VAL_DELETE_BOOL);
+//
+// /* free email */
+// contacts_svc_struct_get_list(contact, CTS_CF_EMAIL_LIST, &email);
+// g_slist_foreach(email, _remove_vcard_gslist_field, (gpointer) CTS_EMAIL_VAL_DELETE_BOOL);
+//
+// /* free event */
+// contacts_svc_struct_get_list(contact, CTS_CF_EVENT_LIST, &event);
+// g_slist_foreach(event, _remove_vcard_gslist_field, (gpointer) CTS_EVENT_VAL_DELETE_BOOL);
+//
+// /* free postal */
+// contacts_svc_struct_get_list(contact, CTS_CF_POSTAL_ADDR_LIST, &postal);
+// g_slist_foreach(postal, _remove_vcard_gslist_field, (gpointer) CTS_POSTAL_VAL_DEFAULT_BOOL);
+//
+// /* free web */
+// contacts_svc_struct_get_list(contact, CTS_CF_WEB_ADDR_LIST, &web);
+// g_slist_foreach(web, _remove_vcard_gslist_field, (gpointer) CTS_WEB_VAL_DELETE_BOOL);
+//
+// /* free nick */
+// contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &nick);
+// g_slist_foreach(nick, _remove_vcard_gslist_field, (gpointer) CTS_NICKNAME_VAL_DELETE_BOOL);
+//
+// _INNER_FUNC_EXIT;
+//}
+//
+//static void _remove_vcard_gslist_field(gpointer data, gpointer user_data)
+//{
+// _INNER_FUNC_ENTER;
+//
+// contacts_svc_value_set_bool((CTSvalue *) data, (int)user_data, 1);
+//
+// _INNER_FUNC_EXIT;
+//}
diff --git a/src/plugins/ds-public/xcalllog/CMakeLists.txt b/src/plugins/ds-public/xcalllog/CMakeLists.txt
new file mode 100755
index 0000000..9e7305a
--- /dev/null
+++ b/src/plugins/ds-public/xcalllog/CMakeLists.txt
@@ -0,0 +1,42 @@
+
+#############################################
+#
+# Step 1. Set Variable and Build Dependency
+#
+
+# set plguin name
+SET(PLUGIN_NAME "dc-xcalllog")
+
+# set a name for the entire project
+PROJECT(plugin-${PLUGIN_NAME})
+
+# checks for build dependency modules : a pkg-config module for CMake
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${PLUGIN_NAME} REQUIRED
+ contacts-service2
+ sync-agent
+ dlog
+ libwbxml2)
+
+#############################################
+#
+# Step 2. Set Compile Environment
+#
+
+# set extra cflags from build dependency
+SET(PLUGIN_CFLAGS "${dc-xcalllog_CFLAGS}")
+
+#############################################
+#
+# Step 3. Set Link Environment
+#
+
+# link a target to given libraries from pkg-config.
+SET(PLUGIN_LDFLAGS "${dc-xcalllog_LDFLAGS}")
+
+#############################################
+#
+# Step 4. Install packages
+#
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.sub) \ No newline at end of file
diff --git a/src/plugins/ds-public/xcalllog/include/encoding_util.h b/src/plugins/ds-public/xcalllog/include/encoding_util.h
new file mode 100755
index 0000000..f55c5e8
--- /dev/null
+++ b/src/plugins/ds-public/xcalllog/include/encoding_util.h
@@ -0,0 +1,238 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 ENCODING_UTIL_H_
+#define ENCODING_UTIL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define QP_SIZE 76
+#define BASE64_SIZE 76
+
+typedef enum {
+ EN_TYPE_NONE = 0,
+ EN_TYPE_QUOTED_PRINTABLE,
+ EN_TYPE_BASE64
+} encoding_type_e;
+
+/* Quoted-Printable
+ *
+ * @example code
+int main()
+{
+ char *src = "hello";
+ char *encode_src;
+ int encode_src_len = 0;
+ char *decode_src;
+ int decode_src_len = 0;
+
+ int res = encode_qp(src, strlen(src), &encode_src, &encode_src_len);
+ if (res != 0)
+ fprintf(stdout, "encode src : %s ( %d ) \n", encode_src, encode_src_len);
+ else
+ fprintf(stdout, "%s\n", "encode error !!");
+
+ res = decode_qp(encode_src, encode_src_len, &decode_src, &decode_src_len);
+ if (res != 0)
+ fprintf(stdout, "decode src : %s ( %d ) \n", decode_src, decode_src_len);
+ else
+ fprintf(stdout, "%s\n", "decode error !!");
+
+ return 0;
+}
+
+ */
+
+/*
+ * @brief encode original source ( encoding type : quoted-printable )
+ * @param[in] src original source
+ * @param[in] src_len length of original source
+ * @param[out] en_src encoded source
+ * @param[out] en_src_len length of encoded source
+ * @return operation result
+ * @retval 1 success
+ * @retval 0 fail
+ */
+int encode_qp(char *src, int src_len, char **en_src, int *en_src_len);
+
+/*
+ * @brief decode encoded source ( decoding type : quoted-printable )
+ * @param[in] src encoded source
+ * @param[in] src_len length of encoded source
+ * @param[out] de_src decoded source ( original source )
+ * @param[out] de_src_len length of decoded source
+ * @return operation result
+ * @retval 1 success
+ * @retval 0 fail
+ */
+int decode_qp(char *src, int src_len, char **de_src, int *de_src_len);
+
+/* Base64
+ *
+ * @example code
+
+ int main()
+{
+ char *src = "hello";
+ char *encode_src;
+ int encode_src_len = 0;
+ char *decode_src;
+ int decode_src_len = 0;
+
+ int res = encode_base64(src, strlen(src), &encode_src, &encode_src_len);
+ if (res != 0)
+ fprintf(stdout, "encode src : %s ( %d ) \n", encode_src, encode_src_len);
+ else
+ fprintf(stdout, "%s\n", "encode error !!");
+
+ res = decode_base64(encode_src, encode_src_len, &decode_src, &decode_src_len);
+ if (res != 0)
+ fprintf(stdout, "decode src : %s ( %d ) \n", decode_src, decode_src_len);
+ else
+ fprintf(stdout, "%s\n", "decode error !!");
+
+ return 0;
+}
+
+ */
+
+/*
+ * @brief encode original source ( encoding type : base64 )
+ * @param[in] src original source
+ * @param[in] src_len length of original source
+ * @param[out] en_src encoded source
+ * @param[out] en_src_len length of encoded source
+ * @return operation result
+ * @retval 1 success
+ * @retval 0 fail
+ */
+int encode_base64(char *src, int src_len, char **en_src, int *en_src_len);
+
+/*
+ * @brief decode encoded source ( decoding type : base64 )
+ * @param[in] src encoded source
+ * @param[in] src_len length of encoded source
+ * @param[out] de_src decoded source ( original source )
+ * @param[out] de_src_len length of decoded source
+ * @return operation result
+ * @retval 1 success
+ * @retval 0 fail
+ */
+int decode_base64(char *src, int src_len, char **de_src, int *de_src_len);
+
+/*
+ * @brief make the decoding process
+ * @param[in] src encoded source
+ * @param[in] src_len length of encoded source
+ * @param[out] de_src decoded source ( original source )
+ * @param[out] de_src_len length of decoded source
+ * @return operation result
+ * @retval 1 success
+ * @retval 0 fail
+ *
+ * @example code
+
+int main()
+{
+ char *src = "..."; // decoded data
+ int src_len = strlen(src);
+ char *decode_src;
+ int decode_src_len = 0;
+
+ int res = proc_decoding(src, src_len, &decode_src, &decode_src_len);
+
+ if (res != 0)
+ fprintf(stdout, "decode src : \n%s\n", decode_src);
+ else
+ fprintf(stdout, "%s\n", "decode error !!");
+
+ if (decode_src != NULL)
+ free(decode_src);
+
+ return 0;
+}
+ */
+int proc_decoding(const char *src, int src_len, char **de_src, int *de_src_len);
+
+/*
+ * @brief encoded value is changed to the decoded value
+ * @param[in] type encoding type
+ * @param[in] value encoded value (end of string must be '\0' !!)
+ * ex) =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+ * @param[in] value_size length of encoded value
+ * @param[out] decode_str decoded string
+ * @param[out] decode_str_len length of decoded string
+ * @return operation result
+ * @ratval 1 success
+ * @retval 0 fail
+ *
+ * @example code
+
+int main()
+{
+ char *data = "..."; // ex) ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8
+ encoding_type_e type = find_encoding_type((const char *)data);
+
+ char *value = "..."; // ex) =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+ int value_size = strlen(value);
+
+ int decode_str_len = 0;
+ char *decode_str = (char*)malloc(sizeof(char)*BUF_SIZE); // BUF_SIZE : user define
+ if (decode_str == NULL) {
+ // error process
+ }
+ memset(decode_str, 0x00, sizeof(char)*BUF_SIZE);
+
+ int res = decode_value(type, value, data_size, &decode_str, &decode_str_len);
+
+ if (res == 1) {
+ // success process
+ if (decode_str != NULL)
+ free(decode_str);
+ } else {
+ // error process
+ if (decode_str != NULL)
+ free(decode_str);
+ }
+
+ return 0;
+}
+ */
+
+int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len);
+
+/*
+ * @brief get encoding type for data
+ * @param[in] data vobject data
+ * @return encoding type
+ * @ratval >= 1 success
+ * @retval 0 fail
+ */
+encoding_type_e find_encoding_type(const char *data);
+
+/*
+ * @brief check whether to exist this string, "ENCODING=" in the data
+ * @param[in] data vobject data
+ * @return operation result
+ * @retval 1 exist
+ * @retval 0 not exist
+ */
+int check_encoding_data(const char *data);
+
+#endif /* ENCODING_UTIL_H_ */
diff --git a/src/plugins/ds-public/xcalllog/include/plugin_spec.h b/src/plugins/ds-public/xcalllog/include/plugin_spec.h
new file mode 100755
index 0000000..cdc31df
--- /dev/null
+++ b/src/plugins/ds-public/xcalllog/include/plugin_spec.h
@@ -0,0 +1,33 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 PLUGIN_SPEC_H_
+#define PLUGIN_SPEC_H_
+
+typedef enum {
+
+ XCALLLOG_CONTENT_NO_TYPE = 0,
+ XCALLLOG_CONTENT_EXTENSION = 1,
+ XCALLLOG_CONTENT_FN = 2,
+ XCALLLOG_CONTENT_X_NUMBER = 3,
+ XCALLLOG_CONTENT_X_DATE = 4,
+ XCALLLOG_CONTENT_X_DURATION = 5,
+ XCALLLOG_CONTENT_X_CALLTYPE = 6,
+
+} xcallog_value_type_e;
+
+#endif /* PLUGIN_SPEC_H_ */
diff --git a/src/plugins/ds-public/xcalllog/src/encoding_util.c b/src/plugins/ds-public/xcalllog/src/encoding_util.c
new file mode 100755
index 0000000..d7823cb
--- /dev/null
+++ b/src/plugins/ds-public/xcalllog/src/encoding_util.c
@@ -0,0 +1,812 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+
+#include <sync_agent.h>
+
+#include "encoding_util.h"
+
+#ifndef OMADS_AGENT_LOG
+#undef LOG_TAG
+#define LOG_TAG "ENCODING_UTIL"
+#endif
+
+#define TYPE_CHECK_BUF_SIZE 100 /* temporary definition */
+#define TEMP_BUFFER_SIZE 1024 /* temporary definition */
+
+/* BASE64 TABLE */
+static char base64_table[65] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
+ 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
+ '2', '3', '4', '5', '6', '7', '8', '9', '+',
+ '/', '='
+};
+
+/* Quoted-Printable */
+static char *_dec_to_hex(int dec);
+static int _hex_to_dec(char *hex);
+
+/* Base64 */
+static int _find_base(char ch);
+
+/*
+ * Quoted-Printable
+ */
+int encode_qp(char *src, int src_len, char **en_src, int *en_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ char *en_hex;
+ int i = 0;
+ int j = 0;
+ int size_cnt = 0;
+
+ /*encoded string length is three times longer than existing maximum string length */
+ int full_lenth = src_len * 3 + 1 + (int)(src_len * 3 / 76) * 3;
+ *en_src = (char *)malloc(sizeof(char) * full_lenth);
+ if (*en_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
+ return 0;
+ }
+ memset(*en_src, 0x00, src_len * 3 + 1);
+
+ _DEBUG_INFO("[encoding_util] src_len : %d\n", src_len);
+ for (i = 0; i < src_len; i++) {
+ /* _DEBUG_INFO("[encoding_util] i : %d\n", i); */
+ if (size_cnt >= QP_SIZE - 3) {
+ size_cnt = 0;
+ (*en_src)[j++] = 0x0A;
+ }
+
+ if ((src[i] >= 33 && src[i] <= 126) || (src[i] == 0x0A)) {
+ if (src[i] == 61) {
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ size_cnt += 3;
+ } else {
+ size_cnt++;
+ (*en_src)[j++] = src[i];
+ }
+ } else if (src[i] == 9 || src[i] == 32) {
+ if (src[i + 1] == 0x0A || src[i + 1] == '\0') { /* TAB or WhiteSpace */
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ size_cnt += 3;
+ } else {
+ size_cnt++;
+ (*en_src)[j++] = src[i];
+ }
+ } else {
+ en_hex = _dec_to_hex(src[i]);
+ (*en_src)[j++] = 0x3D; /* '=' */
+ (*en_src)[j++] = en_hex[0];
+ (*en_src)[j++] = en_hex[1];
+ _DEBUG_INFO("[encoding_util] en_src : %s\n", *en_src);
+ size_cnt += 3;
+ }
+ }
+
+ (*en_src)[j] = 0x00;
+ *en_src_len = size_cnt;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int decode_qp(char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ char hex[3];
+ char ch;
+ int dec = 0;
+ int is_space = 0;
+ int i = 0;
+ int j = 0;
+
+ *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
+ if (*de_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
+ return 0;
+ }
+ memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
+
+ while (src[i] != '\0') {
+ if (src[i] == 0x3D) { /* '=' */
+ /* check whiteSpace */
+ ch = src[++i];
+
+ /* '=' skip if next character is a TAB or WhiteSpace */
+ while (ch == 0x09 || ch == 0x20) {
+ is_space = 1;
+ ch = src[++i];
+
+ if (is_space == 1) {
+ is_space = 0;
+ continue;
+ }
+ }
+
+ /* '=' skip if next character is 3D which means '=' (encoding error case ??) */
+ while (ch == '3') {
+ ch = src[++i];
+
+ if (ch == 'D') {
+ ch = src[++i];
+ continue;
+ }
+ }
+
+ /* if next character is LF after '=' do doft line break
+ * encoded QP string on one line 76 character is allowed
+ */
+ if (ch == 0x0A) { /* LF */
+ i++;
+ continue;
+ }
+
+ hex[0] = src[i++];
+ hex[1] = src[i++];
+ hex[2] = '\0';
+
+ dec = _hex_to_dec(hex);
+
+ /* decoding error */
+ if (dec < 0) {
+ /* when error occur, restore the previous encoding message */
+ (*de_src)[j++] = 0x3D; /* '=' */
+ (*de_src)[j++] = hex[0];
+ (*de_src)[j++] = hex[1];
+ } else {
+ (*de_src)[j++] = dec;
+ }
+ } else if (src[i] > 0x7E) { /* encoding error */
+ i++; /* ignore that character */
+ } else {
+ (*de_src)[j++] = src[i++];
+ }
+ }
+
+ (*de_src)[j] = '\0';
+ *de_src_len = j;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+static char *_dec_to_hex(int dec)
+{
+ _INNER_FUNC_ENTER;
+
+ static char hex[3];
+ int i;
+ int ch;
+
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ ch = (dec & 0xF0) >> 4;
+ } else if (i == 1) {
+ ch = (dec & 0x0F);
+ }
+
+ if (ch >= 10) {
+ hex[i] = 'A' + ch - 10;
+ } else {
+ hex[i] = '0' + ch;
+ }
+ }
+
+ hex[i] = 0x00;
+
+ _DEBUG_TRACE("[encoding_util] hex : %s\n", hex);
+
+ _INNER_FUNC_EXIT;
+ return &hex[0];
+}
+
+static int _hex_to_dec(char *hex)
+{
+ _INNER_FUNC_ENTER;
+
+ int dec = 0;
+ int byte;
+ int i = 0;
+
+ for (i = 0; i < 2; i++) {
+ if (hex[i] >= '0' && hex[i] <= '9') {
+ byte = hex[i] - '0';
+ } else if (hex[i] >= 'A' && hex[i] <= 'F') {
+ byte = hex[i] - 'A' + 10;
+ } else if (hex[i] >= 'a' && hex[i] <= 'f') {
+ byte = hex[i] - 'a' + 10;
+ } else {
+ byte = -1;
+ }
+
+ if (byte < 0)
+ return -1;
+
+ dec += (i == 0) ? byte << 4 : byte;
+ }
+
+ _INNER_FUNC_EXIT;
+ return dec;
+}
+
+/*
+ * Base64
+ */
+int encode_base64(char *src, int src_len, char **en_src, int *en_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ int i = 0;
+ int j = 0;
+ int cnt = 0;
+ int ch = 0;
+ int size_cnt = 0;
+
+ *en_src = (char *)malloc(sizeof(char) * (src_len * 2));
+
+ if (*en_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
+ return 0;
+ }
+ memset(*en_src, 0x00, src_len * 2);
+
+ while (1) {
+ switch (cnt++) {
+ case 0:
+ {
+ if (i < src_len) {
+ ch = (src[i] & 0xFC) >> 2;
+ } else {
+ ch = -1;
+ }
+ }
+ break;
+
+ case 1:
+ {
+ if (i < src_len) {
+ if (i + 1 < src_len) {
+ ch = ((src[i] & 0x03) << 4) | ((src[i + 1] & 0xF0) >> 4);
+ } else {
+ ch = ((src[i] & 0x03) << 4);
+ }
+ } else {
+ ch = -1;
+ }
+ i++;
+ break;
+ }
+
+ case 2:
+ {
+ if (i < src_len) {
+ if (i + 1 < src_len) {
+ ch = ((src[i] & 0x0F) << 2) | ((src[i] & 0xC0) >> 6);
+ } else {
+ ch = ((src[i] & 0x0F) << 2);
+ }
+ } else {
+ ch = -1;
+ }
+ i++;
+ }
+ break;
+
+ case 3:
+ {
+ if (i < src_len) {
+ ch = (src[i] & 0x3F);
+ } else {
+ ch = -1;
+ }
+ i++;
+ cnt = 0;
+ }
+ break;
+ }
+
+ /*
+ if (ch >= 0 && ch <= 25) { // Upper Case Alphabet
+ (*en_src)[j++] = 'A' + ch;
+ } else if (ch >= 26 && ch <= 51) { // Lower Case Alphabet
+ (*en_src)[j++] = 'a' + ch - 26;
+ } else if (ch >= 52 && ch <= 61) { // Digit
+ (*en_src)[j++] = '0' + ch - 52;
+ } else if (ch == 62) {
+ (*en_src)[j++] = '+';
+ } else if (ch == 63) {
+ (*en_src)[j++] = '/';
+ } else if (ch == -1) {
+ (*en_src)[j++] = '='; // padding
+ }
+ */
+
+ if (ch != -1) {
+ (*en_src)[j++] = base64_table[ch];
+ } else {
+ (*en_src)[j++] = base64_table[64]; /* padding */
+ }
+
+ size_cnt++;
+
+ if (j % 4 == 0) {
+ if (size_cnt == BASE64_SIZE) {
+ size_cnt = 0;
+ (*en_src)[j++] = 0x0A; /* soft line break */
+ }
+
+ if (i >= src_len)
+ break;
+ }
+ }
+
+ (*en_src)[j] = 0x00;
+ *en_src_len = j;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int decode_base64(char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ long tmp = 0; /* 4byte (using decoding) */
+ int i = 0;
+ int j = 0;
+ int cnt = 0;
+ int pad_cnt = 0;
+
+ /* de_src is enough for the src_len 3/4 size */
+ *de_src = (char *)malloc(sizeof(char) * (src_len));
+
+ if (*de_src == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
+ return 0;
+ }
+ memset(*de_src, 0x00, src_len);
+
+ while (src[i] != '\0') {
+ /*
+ if (isupper(src[i])) {
+ tmp = (tmp << 6) | (src[i] - 'A'); // Upper case : 0 ~ 25
+ } else if (islower(src[i])) {
+ tmp = (tmp << 6) | (src[i] - 'a' + 0x1A); // Lower case : 26(0x1A) ~ 51
+ } else if (isdigit(src[i])) {
+ tmp = (tmp << 6) | (src[i] - '0' + 0x34); // Number : 52(0x34) ~ 61
+ } else if (src[i] == '+') {
+ tmp = (tmp << 6) | 0x3E; // '+' : 62(0x3E)
+ } else if (src[i] == '/') {
+ tmp = (tmp << 6) | 0x3F; // '/' : 63(0x3F)
+ } else if (src[i] == '=') {
+ pad_cnt++;
+ tmp = (tmp << 6); // '=' : padding
+ } else {
+ tmp = (tmp << 6); // encoding error
+ _DEBUG_INFO("encoding error !! \n");
+ }
+ */
+
+ tmp = (tmp << 6) | (_find_base(src[i]));
+ if (tmp == 64) {
+ pad_cnt++;
+ } else if (tmp == -1) {
+ _DEBUG_ERROR("[encoding_util] encoding error \n");
+ }
+
+ if (++cnt >= 4) {
+ (*de_src)[j++] = (char)((tmp & 0x00FF0000) >> 16);
+ (*de_src)[j++] = (char)((tmp & 0x0000FF00) >> 8);
+ (*de_src)[j++] = (char)(tmp & 0x000000FF);
+
+ cnt = 0;
+ tmp = 0;
+
+ if (src[i + 1] == 0x0A) { /* soft line break */
+ i++;
+ }
+ }
+
+ i++;
+ }
+
+ (*de_src)[j - pad_cnt] = '\0';
+ *de_src_len = j - pad_cnt;
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int proc_decoding(const char *src, int src_len, char **de_src, int *de_src_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
+
+ const char *reg_src = NULL;
+ reg_src = src;
+
+ _DEBUG_INFO("[encoding_util] << src >> \n%s\n", src);
+
+ *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
+ if (*de_src == NULL) {
+ _DEBUG_INFO("[encoding_util] malloc error !! \n");
+
+ return 0;
+ }
+ memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
+
+ char colon[] = ":";
+ char line_breaker[] = "\r\n";
+ char *start_decoding = NULL;
+ int data_size = 0;
+ int res = 0;
+ int de_temp_len = 0;
+ int len = 0;
+
+ char *de_temp = (char *)malloc(sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
+ if (de_temp == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ return 0;
+ }
+
+ while ((start_decoding = strstr(src, "ENCODING="))) {
+ char *colon_loc = strstr(start_decoding, colon); /* find ':''s location */
+ char *line_breaker_loc = NULL;
+ if (colon_loc != NULL) {
+ line_breaker_loc = strstr(colon_loc, line_breaker); /* find "\r\n"'s location */
+ } else {
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+ return 0;
+ }
+
+ /*
+ * if find "ENCODING=" do strcat data until ":" to de_src
+ */
+ data_size = (colon_loc + 1) - src; /* colon_loc + 1 ==> Until next character of ':' */
+
+ char *temp = (char *)malloc(sizeof(char) * (data_size + 1));
+ if (temp == NULL) {
+ _DEBUG_ERROR("temp is null");
+ if (*de_src != NULL)
+ free(*de_src);
+
+ /* for prevent */
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+ memset(temp, 0x00, sizeof(char) * (data_size + 1));
+ memcpy(temp, src, data_size);
+
+ len = g_strlcat(*de_src, temp, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (temp != NULL)
+ free(temp);
+
+ return 0;
+ }
+
+ if (temp != NULL)
+ free(temp);
+
+ _DEBUG_INFO("[encoding_util] << *de_src >> \n %s\n", *de_src);
+
+ /*
+ * copy data from ":" until "\r\n"(actual encoding stream)
+ */
+ data_size = line_breaker_loc - colon_loc; /* from ':' until "\r\n" + '\0' */
+ char *value = (char *)malloc(sizeof(char) * (data_size + 1));
+ if (value == NULL) {
+ _DEBUG_ERROR("[encoding_util] malloc error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+ memset(value, 0x00, sizeof(char) * (data_size + 1));
+ memcpy(value, ++colon_loc, data_size); /* from ':' until "\r\n" */
+ value[data_size] = '\0';
+
+ /*
+ * Get encoding type using data from "ENCODING=" to ":"
+ */
+ char type_check[TYPE_CHECK_BUF_SIZE] = { 0, };
+ int type_check_size = colon_loc - start_decoding;
+ strncpy(type_check, start_decoding, type_check_size);
+ _DEBUG_INFO("[encoding_util] type check : %s\n", type_check);
+ encoding_type_e type = find_encoding_type((const char *)type_check);
+
+ /*
+ * Process decoding by passing the actual value and encoding type to decode_value()
+ */
+ de_temp_len = 0;
+ memset(de_temp, 0x00, sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
+
+ res = decode_value(type, value, data_size, &de_temp, &de_temp_len);
+
+ if (res != 1) {
+ _DEBUG_ERROR("[encoding_util] decode_value error !!\n");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (value != NULL)
+ free(value);
+
+ return 0;
+ }
+
+ /*
+ * Append decoded data to de_src
+ */
+ _DEBUG_INFO("[encoding_util] de_temp : %s\n", de_temp);
+ len = 0;
+ len = g_strlcat(*de_src, de_temp, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ if (value != NULL)
+ free(value);
+
+ return 0;
+ }
+
+ /*
+ * find "ENCODING=" since "\r\n" agina
+ */
+ src = line_breaker_loc;
+
+ if (value != NULL)
+ free(value);
+ }
+
+ /* Append remain character */
+ len = 0;
+ len = g_strlcat(*de_src, src, (src_len + 1));
+ if (len >= (src_len + 1)) {
+ _DEBUG_ERROR("*de_src buffer overflow !!");
+
+ if (*de_src != NULL)
+ free(*de_src);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ return 0;
+ }
+
+ *de_src_len = strlen(*de_src);
+ _DEBUG_INFO("[encoding_util] changed src : \n%s ( %d ) \n", *de_src, *de_src_len);
+
+ if (de_temp != NULL)
+ free(de_temp);
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+int check_encoding_data(const char *data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ if (strstr(data, "ENCODING=") != NULL) {
+ _DEBUG_INFO("[encoding_util] exist encoding data !! \n");
+ _EXTERN_FUNC_EXIT;
+ return 1;
+ } else {
+ _DEBUG_INFO("[encoding_util] not exist encoding data !! \n");
+ _EXTERN_FUNC_EXIT;
+ return 0;
+ }
+}
+
+encoding_type_e find_encoding_type(const char *data)
+{
+ _EXTERN_FUNC_ENTER;
+
+ encoding_type_e type = EN_TYPE_NONE;
+ if (strstr(data, "QUOTED-PRINTABLE") != NULL) {
+ _DEBUG_INFO("[encoding_util] type : QP\n");
+ type = EN_TYPE_QUOTED_PRINTABLE;
+ } else if (strstr(data, "BASE64") != NULL) {
+ _DEBUG_INFO("[encoding_util] type : BASE64\n");
+ type = EN_TYPE_BASE64;
+ } else {
+ _DEBUG_INFO("[encoding_util] not supported type !! \n");
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return type;
+}
+
+int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len)
+{
+ _EXTERN_FUNC_ENTER;
+
+ retvm_if(value == NULL, 0, "[encoding_util] value is NULL\n");
+
+ int res = 1;
+ const char *start_pos = NULL;
+ const char *cursor = NULL;
+ int semi_cnt = 0;
+ int len = 0;
+
+ /*
+ * ex> value - =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
+ */
+ cursor = value;
+ start_pos = value;
+
+ while (*cursor != '\0') {
+ if ((*cursor != ';') && (*cursor != '\r')) {
+ cursor++;
+ continue;
+ } else if (*cursor == ';') {
+ semi_cnt++;
+ }
+
+ int data_size = 0;
+ data_size = cursor - start_pos;
+
+ if (data_size == 0) {
+ cursor++;
+ start_pos++;
+ } else {
+ char *temp = (char *)malloc(sizeof(char) * (value_size + 1));
+ if (temp == NULL) {
+ _DEBUG_ERROR("MALLOC failed !!!");
+ res = 0;
+ return res;
+ }
+ memset(temp, 0x00, sizeof(char) * (value_size + 1));
+ memcpy(temp, start_pos, data_size);
+
+ _DEBUG_INFO("[encoding_util] temp : %s \n", temp);
+
+ char *decoding = NULL;
+ int decoding_len = 0;
+
+ switch (type) {
+ case EN_TYPE_QUOTED_PRINTABLE:
+ res = decode_qp(temp, data_size, &decoding, &decoding_len);
+ break;
+ case EN_TYPE_BASE64:
+ res = decode_base64(temp, data_size, &decoding, &decoding_len);
+ break;
+ default:
+ break;
+ }
+
+ if (temp != NULL)
+ free(temp);
+
+ _DEBUG_INFO("[encoding_util] decoding : %s ( %d )\n", decoding, decoding_len);
+
+ if (res != 1) {
+ _DEBUG_ERROR("[encoding_util] decoding error !! \n");
+
+ if (decoding != NULL)
+ free(decoding);
+
+ res = 0;
+ return res;
+ }
+
+ len = g_strlcat(*decode_str, decoding, TEMP_BUFFER_SIZE);
+ if (len >= TEMP_BUFFER_SIZE) {
+ _DEBUG_ERROR("*decode_str buffer overflow !!");
+
+ if (decoding != NULL)
+ free(decoding);
+
+ res = 0;
+ return res;
+ }
+
+ _DEBUG_INFO("[encoding_util] *decode_str : %s\n", *decode_str);
+
+ if (decoding != NULL)
+ free(decoding);
+
+ cursor++;
+ start_pos = cursor;
+ }
+
+ if (semi_cnt > 0) {
+ int len = strlen(*decode_str);
+ (*decode_str)[len] = ';';
+ _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, strlen(*decode_str));
+ semi_cnt--;
+ }
+ }
+
+ *decode_str_len = strlen(*decode_str);
+
+ _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, *decode_str_len);
+
+ _EXTERN_FUNC_EXIT;
+ return res;
+}
+
+static int _find_base(char ch)
+{
+ _EXTERN_FUNC_ENTER;
+
+ int i = 0;
+ for (i = 0; i < 65; i++) {
+ if (base64_table[i] == ch) {
+ _DEBUG_INFO("[encoding_util] End !! \n");
+ return i;
+ }
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return -1;
+}
diff --git a/src/plugins/ds-public/xcalllog/src/plugin_interface.c b/src/plugins/ds-public/xcalllog/src/plugin_interface.c
new file mode 100755
index 0000000..3ba4c05
--- /dev/null
+++ b/src/plugins/ds-public/xcalllog/src/plugin_interface.c
@@ -0,0 +1,432 @@
+/*
+ * oma-ds-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdio.h>
+#include <contacts.h>
+#include <glib.h>
+#include <time.h>
+
+#include <sync_agent.h>
+
+#include "plugin_spec.h"
+#include "encoding_util.h"
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef OMADS_AGENT_LOG
+#undef LOG_TAG
+#define LOG_TAG "PLUGIN_XCALLLOG"
+#endif
+
+static char *_convert_key_name(int key);
+static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err);
+
+static char *_convert_calllog_type(int type);
+static char *_convert_date(int date);
+static sync_agent_da_return_e _get_calllog_name(int contact_id, char **name);
+
+static char *_calllog_put_content(char *vcard_stream, char *content_type, char *content_value);
+
+static char *_convert_key_name(int key)
+{
+ _INNER_FUNC_ENTER;
+
+ char *key_name = 0;
+
+ switch (key) {
+ case XCALLLOG_CONTENT_FN:
+ key_name = "FN";
+ break;
+ case XCALLLOG_CONTENT_X_NUMBER:
+ key_name = "X-NUMBER";
+ break;
+ case XCALLLOG_CONTENT_X_DATE:
+ key_name = "X-DATE";
+ break;
+ case XCALLLOG_CONTENT_X_DURATION:
+ key_name = "X-DURATION";
+ break;
+ case XCALLLOG_CONTENT_X_CALLTYPE:
+ key_name = "X-CALLTYPE";
+ break;
+ default:
+ break;
+ }
+
+ _INNER_FUNC_EXIT;
+ return key_name;
+}
+
+static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err)
+{
+ _INNER_FUNC_ENTER;
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ _DEBUG_TRACE("[da_contact_plugIn] Error Code : %d\n", err);
+
+ switch (err) {
+ case CONTACTS_ERROR_NONE:
+ ret = SYNC_AGENT_DA_SUCCESS;
+ break;
+ case CONTACTS_ERROR_OUT_OF_MEMORY:
+ ret = SYNC_AGENT_DA_ERR_MEMORY_FULL;
+ break;
+ case CONTACTS_ERROR_INVALID_PARAMETER:
+ ret = SYNC_AGENT_DA_ERR_INVALID_PARAMETER;
+ break;
+ case CONTACTS_ERROR_NO_DATA:
+ ret = SYNC_AGENT_DA_ERR_NO_DATA;
+ break;
+ case CONTACTS_ERROR_DB:
+ ret = SYNC_AGENT_DA_ERR_SERVICE_DB;
+ break;
+ case CONTACTS_ERROR_IPC:
+ ret = SYNC_AGENT_DA_ERR_SERVICE_IPC;
+ break;
+ default:
+ ret = SYNC_AGENT_DA_ERRORS;
+ break;
+ }
+
+ _INNER_FUNC_EXIT;
+
+ return ret;
+}
+
+static char *_convert_calllog_type(int type)
+{
+ _INNER_FUNC_ENTER;
+
+ char *log_type = NULL;
+
+ switch (type) {
+ case 1: /*CTS_PLOG_TYPE_VOICE_INCOMMING */
+ case 3: /*CTS_PLOG_TYPE_VIDEO_INCOMMING */
+ log_type = "1";
+ break;
+ case 2: /*CTS_PLOG_TYPE_VOICE_OUTGOING */
+ case 4: /*CTS_PLOG_TYPE_VIDEO_OUTGOING */
+ log_type = "2";
+ break;
+ case 5: /*CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN */
+ case 6: /*CTS_PLOG_TYPE_VOICE_INCOMMING_SEEN */
+ case 7: /*CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN */
+ case 8: /*CTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN */
+ log_type = "3";
+ break;
+ }
+
+ _INNER_FUNC_EXIT;
+ return log_type;
+}
+
+static char *_convert_date(int time)
+{
+ _INNER_FUNC_ENTER;
+
+ char *date = (char *)calloc(17, sizeof(char));
+ if (date == NULL) {
+ _DEBUG_ERROR("CALLOC failed !!!");
+ return NULL;
+ }
+
+ struct tm *tm = localtime((time_t *) & time);
+
+ memset(date, 0, 17);
+
+ snprintf(date, 17, "%04ld%02d%02dT%02d%02d%02dZ", tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ _INNER_FUNC_EXIT;
+ return date;
+}
+
+static sync_agent_da_return_e _get_calllog_name(int contact_id, char **name)
+{
+ _INNER_FUNC_ENTER;
+
+// sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+// cts_error err = 0;
+// CTSstruct *item = 0;
+// CTSvalue *value = NULL;
+// char *first_name = NULL;
+// char *last_name = NULL;
+//
+// if (contact_id != 0) {
+// err = contacts_svc_get_contact(contact_id, &item);
+// if (err < CTS_SUCCESS) {
+// _DEBUG_ERROR("[da_xcalllog_plugIn] contacts_svc_get_contact() Fail!\n");
+// ret = _convert_service_error_to_common_error(err);
+// *name = 0;
+// } else {
+// _DEBUG_TRACE("[da_xcalllog_plugIn] contacts_svc_get_contact() Success!\n");
+//
+// contacts_svc_struct_get_value(item, CTS_CF_NAME_VALUE, &value);
+// first_name = (char *)contacts_svc_value_get_str(value, CTS_NAME_VAL_FIRST_STR);
+// _DEBUG_TRACE("name = %s", first_name);
+//
+// last_name = (char *)contacts_svc_value_get_str(value, CTS_NAME_VAL_LAST_STR);
+// _DEBUG_TRACE("name = %s", last_name);
+// *name = g_strdup_printf("%s %s", first_name, last_name);
+// }
+// } else
+// name = 0;
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+ contacts_record_h record = NULL;
+
+ if (contact_id != 0) {
+ err = contacts_db_get_record(_contacts_person_phone_log._uri, contact_id, &record);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[da_xcalllog_plugIn] contacts_db_get_record() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *name = 0;
+ } else {
+ _DEBUG_TRACE("[da_xcalllog_plugIn] contacts_db_get_record() Success!\n");
+
+ err = contacts_record_get_str(record, _contacts_person_phone_log.display_name, name);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[da_xcalllog_plugIn] contacts_db_get_record() Fail!\n");
+ ret = _convert_service_error_to_common_error(err);
+ *name = 0;
+ }
+ }
+ } else
+ name = 0;
+
+ _INNER_FUNC_EXIT;
+ return ret;
+}
+
+static char *_calllog_put_content(char *vcard_stream, char *content_type, char *content_value)
+{
+ _INNER_FUNC_ENTER;
+
+ retvm_if(vcard_stream == NULL, NULL, "vcard_stream is NULL\n");
+ retvm_if(content_type == NULL, NULL, "content_type is NULL\n");
+ retvm_if(content_value == NULL, NULL, "content_value is NULL\n");
+
+ char *new_stream = NULL;
+
+ new_stream = g_strdup_printf("%s%s:%s\r\n", vcard_stream, content_type, content_value);
+
+ _DEBUG_TRACE("old stream =%s", vcard_stream);
+ _DEBUG_TRACE("new stream =%s", new_stream);
+
+ free(vcard_stream);
+
+ _INNER_FUNC_EXIT;
+ return new_stream;
+}
+
+EXPORT_API void *sync_agent_plugin_alloc_object()
+{
+ _EXTERN_FUNC_ENTER;
+
+ char *agent_data = strdup("BEGIN:CALLLOG\r\n\
+");
+
+ _EXTERN_FUNC_EXIT;
+ return (void *)agent_data;
+}
+
+EXPORT_API void *sync_agent_plugin_set_value(void *in_object, int key, char *extension_key, void *value)
+{
+ _EXTERN_FUNC_ENTER;
+
+ char *new_agent_data = 0;
+ char *key_name = 0;
+
+ if (key == XCALLLOG_CONTENT_NO_TYPE)
+ return (void *)new_agent_data;
+ else if (key == XCALLLOG_CONTENT_EXTENSION)
+ key_name = extension_key;
+ else
+ key_name = _convert_key_name(key);
+
+ new_agent_data = _calllog_put_content(in_object, key_name, value);
+
+ _EXTERN_FUNC_EXIT;
+ return (void *)new_agent_data;
+}
+
+EXPORT_API int sync_agent_plugin_free_object(void *in_object)
+{
+ _EXTERN_FUNC_ENTER;
+ _DEBUG_INFO("[dc_xcalllog_plugIn] Do nothing\n");
+
+ _EXTERN_FUNC_EXIT;
+ return 1;
+}
+
+EXPORT_API sync_agent_da_return_e sync_agent_plugin_reverse_converter(void *service_data, void **agent_data)
+{
+ _EXTERN_FUNC_ENTER;
+
+// retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "service_data is NULL");
+//
+// sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+// CTSvalue *plog = (CTSvalue *) service_data;
+//
+// void *data = NULL;
+// char *duration = NULL;
+// char *log_type = NULL;
+// char *name = NULL;
+// char *date = NULL;
+//
+// /*date */
+// date = _convert_date(contacts_svc_value_get_int(plog, CTS_PLOG_VAL_LOG_TIME_INT));
+// if( date == NULL )
+// return SYNC_AGENT_DA_ERRORS;
+//
+// /*duration */
+// duration = g_strdup_printf("%d", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_DURATION_INT));
+//
+// /* type */
+// log_type = _convert_calllog_type(contacts_svc_value_get_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT));
+//
+// /*name */
+// ret = _get_calllog_name(contacts_svc_value_get_int(plog, CTS_PLOG_VAL_RELATED_ID_INT), &name);
+//
+// /*create default object */
+// data = sync_agent_alloc_object_plugin();
+//
+// data = sync_agent_set_value_plugin(data, XCALLLOG_CONTENT_X_NUMBER, NULL, (void *)contacts_svc_value_get_str(plog, CTS_PLOG_VAL_NUMBER_STR));
+// data = sync_agent_set_value_plugin(data, XCALLLOG_CONTENT_X_DATE, NULL, (void *)date);
+// data = sync_agent_set_value_plugin(data, XCALLLOG_CONTENT_X_DURATION, NULL, (void *)duration);
+//
+// if (name != NULL)
+// data = sync_agent_set_value_plugin(data, XCALLLOG_CONTENT_FN, NULL, name);
+//
+// data = sync_agent_set_value_plugin(data, XCALLLOG_CONTENT_X_CALLTYPE, NULL, log_type);
+//
+// *agent_data = g_strdup_printf("%sEND:CALLLOG", (char *)data);
+//
+// if (data != NULL)
+// free(data);
+//
+// if (duration != NULL)
+// free(duration);
+//
+// if (name != NULL)
+// free(name);
+//
+// if (date != NULL) {
+// free(date);
+// }
+
+ retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "service_data is NULL");
+
+ sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
+ contacts_error_e err = CONTACTS_ERROR_NONE;
+ contacts_record_h record = (contacts_record_h) service_data;
+
+ void *data = NULL;
+ char *duration = NULL;
+ char *log_type = NULL;
+ char *name = NULL;
+ char *date = NULL;
+
+ int log_time;
+ int temp_duration;
+ int temp_log_type;
+ int person_id;
+ char *number = NULL;
+
+ err = contacts_record_get_int(record, _contacts_phone_log.log_time, &log_time);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_xcalllog_plugIn] contacts_record_get_int is failed");
+ ret = _convert_service_error_to_common_error(err);
+ goto error;
+ }
+
+ err = contacts_record_get_int(record, _contacts_phone_log.extra_data1, &temp_duration);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_xcalllog_plugIn] contacts_record_get_int is failed");
+ ret = _convert_service_error_to_common_error(err);
+ goto error;
+ }
+
+ err = contacts_record_get_int(record, _contacts_phone_log.log_type, &temp_log_type);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_xcalllog_plugIn] contacts_record_get_int is failed");
+ ret = _convert_service_error_to_common_error(err);
+ goto error;
+ }
+
+ err = contacts_record_get_int(record, _contacts_phone_log.person_id, &person_id);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_xcalllog_plugIn] contacts_record_get_int is failed");
+ ret = _convert_service_error_to_common_error(err);
+ goto error;
+ }
+
+ err = contacts_record_get_str_p(record, _contacts_phone_log.address, &number);
+ if (err != CONTACTS_ERROR_NONE) {
+ _DEBUG_ERROR("[dc_xcalllog_plugIn] contacts_record_get_int is failed");
+ ret = _convert_service_error_to_common_error(err);
+ goto error;
+ }
+
+ /*date */
+ date = _convert_date(log_time);
+ if (date == NULL)
+ return SYNC_AGENT_DA_ERRORS;
+
+ /*duration */
+ duration = g_strdup_printf("%d", temp_duration);
+
+ /* type */
+ log_type = _convert_calllog_type(temp_log_type);
+
+ /*name */
+ ret = _get_calllog_name(person_id, &name);
+
+ /*create default object */
+ data = sync_agent_plugin_alloc_object();
+
+ data = sync_agent_plugin_set_value(data, XCALLLOG_CONTENT_X_NUMBER, NULL, (void *)number);
+ data = sync_agent_plugin_set_value(data, XCALLLOG_CONTENT_X_DATE, NULL, (void *)date);
+ data = sync_agent_plugin_set_value(data, XCALLLOG_CONTENT_X_DURATION, NULL, (void *)duration);
+
+ if (name != NULL)
+ data = sync_agent_plugin_set_value(data, XCALLLOG_CONTENT_FN, NULL, name);
+
+ data = sync_agent_plugin_set_value(data, XCALLLOG_CONTENT_X_CALLTYPE, NULL, log_type);
+
+ *agent_data = g_strdup_printf("%sEND:CALLLOG", (char *)data);
+
+ error:
+
+ if (data != NULL)
+ free(data);
+
+ if (duration != NULL)
+ free(duration);
+
+ if (name != NULL)
+ free(name);
+
+ if (date != NULL) {
+ free(date);
+ }
+
+ _EXTERN_FUNC_EXIT;
+ return ret;
+}