diff options
Diffstat (limited to 'src/plugins')
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; +} |