diff options
Diffstat (limited to 'src/agent/service-engine/se_sync.c')
-rwxr-xr-x | src/agent/service-engine/se_sync.c | 3245 |
1 files changed, 3245 insertions, 0 deletions
diff --git a/src/agent/service-engine/se_sync.c b/src/agent/service-engine/se_sync.c new file mode 100755 index 0000000..c946921 --- /dev/null +++ b/src/agent/service-engine/se_sync.c @@ -0,0 +1,3245 @@ +/* + * 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. + */ + +/** + * @SE_Sync.c + * @version 0.1 + * @brief This file is the source file of implementation of functions which process sync request, auto configure etc.. + */ + +#include <sys/time.h> + +#include <sync_agent.h> +#include <plugin/plugin_slp_device.h> + +#include "service-engine/se_sync.h" +#include "service-engine/se_storage.h" +#include "service-engine/se_common.h" +#include "service-engine/se_notification.h" +#include "service-adapter/sa_common_interface.h" +#include "common/common_util.h" +#include "common/common_define_internal.h" + +#ifndef OMADS_AGENT_LOG +#undef LOG_TAG +#define LOG_TAG "OMA_DS_SE" +#endif + +static se_error_type_e _session_process(int account_id, alert_type_e server_sync_type, sync_progress_e process, sync_error_e error); +static se_error_type_e __process_update(int account_id, alert_type_e server_sync_type, sync_progress_status_e progress_status, operation_type_e operation_type, int content_type, bool is_from_server, bool need_to_save, sync_result_s * sync_result); +static se_error_type_e _write_sync_data(int account_id, alert_type_e alert_type, sync_session_result_e sync_session_result, int last_session_time, int only_from_client); +static se_error_type_e ___write_sync_resource_info(int account_id, int content_type, int last_session_time, int only_from_client, sync_result_s * client_sync_result, sync_result_s * server_sync_result); + +static se_error_type_e __init_datastore_info_array(int account_id); +static se_error_type_e ___set_datastore_info_array(int account_id, char *config_key, service_type_e content_type); +static se_error_type_e ___generate_datastore_info(int account_id, service_type_e content_type, datastore_s ** datastore); +static se_error_type_e __init_datastore_info(int account_id, service_type_e content_type, datastore_s ** datastore); +static se_error_type_e ___set_datastore_config(int account_id, int content_type, datastore_s ** datastore); +static se_error_type_e __get_sync_type(int account_id, alert_type_e * sync_type); + +static se_error_type_e __on_synchronising_account(int account_id); +static se_error_type_e _off_synchronising_account(int account_id); + +static se_error_type_e __on_resume_flag(int account_id); +static se_error_type_e _off_resume_flag(int account_id); + +static se_error_type_e _assemble_changed_datastores(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj); +static se_error_type_e _prepare_pre_sync(int account_id, char *sync_mode, san_package_s * san_package, alert_type_e * sync_type); +static se_error_type_e __set_config_based_on_sync_mode(int account_id, char *sync_mode, san_package_s * san_package); +static se_error_type_e _execute_pre_sync(int account_id, int session_time, pre_sync_return_obj_s * pre_sync_return_obj, alert_type_e * server_sync_type); +static se_error_type_e __execute_pre_sync_set_server_id(int account_id, char *dev_id); +static se_error_type_e __execute_pre_sync_datastore(int account_id, int session_time, GList * datastore_info, alert_type_e * server_sync_type); +static se_error_type_e _execute_sync(int account_id, alert_type_e client_sync_type, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj); +static se_error_type_e __execute_sync_arrange_changelog(int account_id, alert_type_e sync_type, GList * status); +static se_error_type_e __execute_sync_status(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj); +static se_error_type_e __execute_sync_change(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj); +static se_error_type_e _update_sync_result(int account_id); + +static command_result_e ___convert_return_status(sync_agent_da_return_e da_err); +static char *__convert_cttype_str(int itemTypeId); +static int ___convert_sync_type_value(char *sync_type_str); +static char *__convert_sync_type_str(alert_type_e sync_type); +static char *___convert_sync_progress_status_str(sync_progress_status_e progress_status); +static char *___convert_operation_type_str(operation_type_e operation_type); +static char *_convert_sync_progress_str(sync_progress_e process); +static char *_convert_sync_error_str(sync_error_e error); +static se_error_type_e _check_low_battery(); +static se_error_type_e _open_services(); +static se_error_type_e _close_services(); + +static inline long myclock() +{ + struct timeval tv; + gettimeofday(&tv, 0); + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +static se_error_type_e _session_process(int account_id, alert_type_e server_sync_type, sync_progress_e process, sync_error_e error) +{ + _INNER_FUNC_ENTER; + + char *profileDirName = NULL; + se_error_type_e err = SE_INTERNAL_OK; + bool result; + + result = get_config(account_id, DEFINE_CONFIG_KEY_PROFILE_DIR_NAME, &profileDirName); + if (result == false) { + _DEBUG_ERROR("failed in get_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + if (profileDirName != NULL) { + err = session_process(profileDirName, server_sync_type, process, error); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to send noti"); + goto error; + } + } + + error: + if (profileDirName != NULL) + free(profileDirName); + + _INNER_FUNC_EXIT; + + return err; +} + +static se_error_type_e __process_update(int account_id, alert_type_e server_sync_type, sync_progress_status_e progress_status, operation_type_e operation_type, int content_type, bool is_from_server, bool need_to_save, sync_result_s * sync_result) +{ + _INNER_FUNC_ENTER; + + _DEBUG_VERBOSE("account_id =%d, progress_status = %d, operation_type = %d, content_type = %d, isFromServer = %d, needToSave = %d ", account_id, progress_status, operation_type, content_type, is_from_server, need_to_save); + _DEBUG_VERBOSE("numberOfChange = %d, received_count = %d, syncCount = %d", sync_result->number_of_change, sync_result->received_count, sync_result->add_count + sync_result->replace_count + sync_result->delete_count); + + se_error_type_e err = SE_INTERNAL_OK; + char *profileDirName = NULL; + char *uri = NULL; + char *sync_type = NULL; + char *operation = NULL; + char *progress = NULL; + + bool result; + result = get_config(account_id, DEFINE_CONFIG_KEY_PROFILE_DIR_NAME, &profileDirName); + if (result == false) { + _DEBUG_ERROR("failed in get_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + /* do not need to send update noti to ui */ + if (profileDirName == NULL) { + _DEBUG_VERBOSE("profileDirName is NULL"); + goto error; + } + + if (need_to_save == true) { + err = write_sync_statistics(account_id, content_type, is_from_server, sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in writeSyncStatistics"); + goto error; + } + } + + sync_type = __convert_sync_type_str(server_sync_type); + + progress = ___convert_sync_progress_status_str(progress_status); + + operation = ___convert_operation_type_str(operation_type); + + if (sync_type == NULL || progress == NULL || operation == NULL) { + err = SE_INTERNAL_NOT_DEFINED; + goto error; + } + + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (datastoreinfo_per_content_type[content_type]->source != NULL) + uri = strdup(datastoreinfo_per_content_type[content_type]->source); + } + + err = send_noti_process_update(profileDirName, sync_type, uri, progress, operation, is_from_server, 0, 0, sync_result->number_of_change, sync_result->add_count + sync_result->replace_count + sync_result->delete_count); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in send_noti_process_update"); + goto error; + } + + error: + + if (profileDirName != NULL) + free(profileDirName); + + if (uri != NULL) + free(uri); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _write_sync_data(int account_id, alert_type_e alert_type, sync_session_result_e sync_session_result, int last_session_time, int only_from_client) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + err = write_profile_data(account_id, alert_type, sync_session_result, last_session_time, only_from_client); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in writeProfileData"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e ___write_sync_resource_info(int account_id, int content_type, int last_session_time, int only_from_client, sync_result_s * client_sync_result, sync_result_s * server_sync_result) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + err = write_sync_resource_info(account_id, content_type, last_session_time, only_from_client, client_sync_result, server_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in write_sync_resource_info"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __init_datastore_info_array(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + err = ___set_datastore_info_array(account_id, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CONTACTS, TYPE_CONTACT); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in set_datastoreinfo_array"); + goto error; + } + + err = ___set_datastore_info_array(account_id, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALENDAR, TYPE_CALENDAR); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in set_datastoreinfo_array"); + goto error; + } + + err = ___set_datastore_info_array(account_id, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_MEMO, TYPE_MEMO); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in set_datastoreinfo_array"); + goto error; + } + + err = ___set_datastore_info_array(account_id, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALLLOG, TYPE_CALLLOG); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in set_datastoreinfo_array"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e ___set_datastore_info_array(int account_id, char *config_key, service_type_e content_type) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + datastore_s *datastore_info = NULL; + bool result; + char *value = NULL; + + result = get_config(account_id, config_key, &value); + if (result == true) { + if (strcmp(value, "1") == 0) { + err = ___generate_datastore_info(account_id, content_type, &datastore_info); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to create or init datastore_info"); + datastoreinfo_per_content_type[content_type] = NULL; + goto error; + } + datastoreinfo_per_content_type[content_type] = datastore_info; + } + + } else + datastoreinfo_per_content_type[content_type] = NULL; + + error: + + if (value != NULL) + free(value); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e ___generate_datastore_info(int account_id, service_type_e content_type, datastore_s ** datastore) +{ + _INNER_FUNC_ENTER; + _DEBUG_VERBOSE("content_type=[%d]\n", content_type); + + se_error_type_e err = SE_INTERNAL_OK; + char *clientLastAnchor = NULL; + char *clientNextAnchor = NULL; + char *serverLastAnchor = NULL; + + sync_agent_da_return_e da_err = SYNC_AGENT_DA_ERRORS; + + sync_result_s *pSyncResult = NULL; + datastore_s *temp_datastore = NULL; + err = ___set_datastore_config(account_id, content_type, &temp_datastore); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in set_datastore_config"); + goto error; + } + + GList *anchor_list = NULL; + sync_agent_da_get_last_anchor_list_query_s query; + query.option = SYNC_AGENT_DA_GET_LAST_ANCHOR_LIST_OPTION_ITEM_TYPE_ID; + query.account_id = account_id; + query.item_type_id = temp_datastore->datastore_id; + + da_err = sync_agent_get_last_anchor_list(&query, &anchor_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_last_anchor_list !!"); + goto error; + } + + if (g_list_length(anchor_list) > 0) { + GList *last_anchor_info = g_list_nth(anchor_list, g_list_length(anchor_list) - 1); + clientLastAnchor = ((sync_agent_da_last_anchor_s *) (last_anchor_info->data))->last_anchor_client; + serverLastAnchor = ((sync_agent_da_last_anchor_s *) (last_anchor_info->data))->last_anchor_server; + } else { + sync_agent_da_last_anchor_s lastAnchor_daci; + + lastAnchor_daci.account_id = account_id; + lastAnchor_daci.data_store_id = temp_datastore->datastore_id; + lastAnchor_daci.last_anchor_server = NULL; + lastAnchor_daci.last_anchor_client = NULL; + lastAnchor_daci.access_name = "Engine"; + + da_err = sync_agent_add_last_anchor(&lastAnchor_daci); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("da_add_last_anchor_internal is failed %d", da_err); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + + clientNextAnchor = g_strdup_printf("%ld", time(NULL)); + + _DEBUG_VERBOSE("clientLastAnchor = %s\n", clientLastAnchor); + _DEBUG_VERBOSE("serverLastAnchor = %s\n", serverLastAnchor); + _DEBUG_VERBOSE("clientNextAnchor = %s\n", clientNextAnchor); + + /*slow sync if managed anchor info not exist.. (first sync) */ + if (clientLastAnchor == NULL) + set_datastore_client_anchor(temp_datastore, clientNextAnchor, clientNextAnchor); + else + set_datastore_client_anchor(temp_datastore, clientLastAnchor, clientNextAnchor); + + set_datastore_server_anchor(temp_datastore, serverLastAnchor, NULL); + + pSyncResult = create_sync_result(); + if (pSyncResult == NULL) { + _DEBUG_ERROR("create_syncResult is failed"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + temp_datastore->client_sync_result = pSyncResult; + + pSyncResult = create_sync_result(); + if (pSyncResult == NULL) { + _DEBUG_ERROR("create_syncResult is failed"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + temp_datastore->server_sync_result = pSyncResult; + + *datastore = temp_datastore; + temp_datastore = NULL; + + error: + + if (clientNextAnchor != NULL) + free(clientNextAnchor); + + if (temp_datastore != NULL) + free_datastore(temp_datastore); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __init_datastore_info(int account_id, service_type_e content_type, datastore_s ** datastore) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + char *sourceDatastore = NULL; + char key[128]; + datastore_s *temp_datastore = NULL; + sync_result_s *pSyncResult = NULL; + + bool result; + switch (content_type) { + case TYPE_CONTACT: + snprintf(key, sizeof(key), "%s_%s", DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CONTACTS, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_SOURCE); + break; + case TYPE_CALENDAR: + snprintf(key, sizeof(key), "%s_%s", DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALENDAR, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_SOURCE); + break; + case TYPE_MEMO: + snprintf(key, sizeof(key), "%s_%s", DEFINE_CONFIG_KEY_PROFILE_CATEGORY_MEMO, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_SOURCE); + break; + case TYPE_CALLLOG: + snprintf(key, sizeof(key), "%s_%s", DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALLLOG, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_SOURCE); + break; + default: + _DEBUG_VERBOSE("unknown content type = %d", content_type); + goto error; + } + + _DEBUG_ERROR("content_type = %d", content_type); + _DEBUG_ERROR("key = %s", key); + result = get_config(account_id, key, &sourceDatastore); + if (result == false) { + _DEBUG_ERROR("failed in get_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + temp_datastore = create_datastore(NULL, sourceDatastore); + if (temp_datastore == NULL) { + _DEBUG_ERROR("failed to create_Datastore"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + pSyncResult = create_sync_result(); + if (pSyncResult == NULL) { + _DEBUG_ERROR("create_syncResult is failed"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + temp_datastore->client_sync_result = pSyncResult; + + pSyncResult = create_sync_result(); + if (pSyncResult == NULL) { + _DEBUG_ERROR("create_syncResult is failed"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + temp_datastore->server_sync_result = pSyncResult; + + *datastore = temp_datastore; + temp_datastore = NULL; + + error: + if (sourceDatastore != NULL) + free(sourceDatastore); + + if (temp_datastore != NULL) + free_datastore(temp_datastore); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e ___set_datastore_config(int account_id, int content_type, datastore_s ** datastore) +{ + _INNER_FUNC_ENTER; + + datastore_s *temp_datastore = NULL; + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + char *contentType = NULL; + + char sourceDatastore_key[128]; + char targetDatastore_key[128]; + char id_key[128]; + char pw_key[128]; + + char *sourceDatastore = NULL; + char *targetDatastore = NULL; + char *sync_type = NULL; + char *id = NULL; + char *pw = NULL; + + alert_type_e alert_type = ALERT_UNKNOWN; + + GList *config_list = NULL; + GList *iter = NULL; + sync_agent_da_config_s *config_data = NULL; + + int folder_type_id = 0; + switch (content_type) { + case TYPE_CONTACT: + { + folder_type_id = 0; + contentType = DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CONTACTS; + } + break; + case TYPE_CALENDAR: + { + folder_type_id = 0; + contentType = DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALENDAR; + } + break; + case TYPE_MEMO: + { + folder_type_id = 0; + contentType = DEFINE_CONFIG_KEY_PROFILE_CATEGORY_MEMO; + } + break; + case TYPE_CALLLOG: + { + folder_type_id = 0; + contentType = DEFINE_CONFIG_KEY_PROFILE_CATEGORY_CALLLOG; + } + break; + default: + _DEBUG_VERBOSE("unknown content type = %d", content_type); + err = SE_INTERNAL_ERROR; + goto error; + } + + snprintf(sourceDatastore_key, sizeof(sourceDatastore_key), "%s_%s", contentType, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_SOURCE); + snprintf(targetDatastore_key, sizeof(targetDatastore_key), "%s_%s", contentType, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_TARGET); + snprintf(id_key, sizeof(id_key), "%s_%s", contentType, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_ID); + snprintf(pw_key, sizeof(id_key), "%s_%s", contentType, DEFINE_CONFIG_KEY_PROFILE_CATEGORY_PASSWORD); + + da_err = sync_agent_get_config_list(account_id, &config_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + for (iter = config_list; iter != NULL; iter = g_list_next(iter)) { + config_data = (sync_agent_da_config_s *) iter->data; + + if (config_data != NULL) { + if (config_data->key != NULL) { + if (strcmp(config_data->key, sourceDatastore_key) == 0) { + if (config_data->value != NULL) + sourceDatastore = strdup(config_data->value); + } + + if (strcmp(config_data->key, targetDatastore_key) == 0) { + if (config_data->value != NULL) + targetDatastore = strdup(config_data->value); + } + + if (strcmp(config_data->key, DEFINE_CONFIG_KEY_PROFILE_CLIENT_SYNC_TYPE) == 0) { + if (config_data->value != NULL) + sync_type = strdup(config_data->value); + } + + if (strcmp(config_data->key, id_key) == 0) { + if (config_data->value != NULL) + id = strdup(config_data->value); + } + + if (strcmp(config_data->key, pw_key) == 0) { + if (config_data->value != NULL) + pw = strdup(config_data->value); + } + } + } + } + + if (sync_type != NULL) { + alert_type = ___convert_sync_type_value(sync_type); + } else { + _DEBUG_ERROR("sync_type is NULL !"); + err = SE_INTERNAL_ERROR; + goto error; + } + + _DEBUG_VERBOSE("get_Config result sourceDatastore= %s ", sourceDatastore); + _DEBUG_VERBOSE("get_Config result targetDatastore= %s ", targetDatastore); + _DEBUG_VERBOSE("get_Config result alert_type= %s ", sync_type); + _DEBUG_VERBOSE("get_Config result id= %s ", id); + _DEBUG_VERBOSE("get_Config result pw= %s ", pw); + + temp_datastore = create_datastore(targetDatastore, sourceDatastore); + if (temp_datastore == NULL) { + _DEBUG_ERROR("temp_datastore is NULL"); + err = SE_INTERNAL_ERROR; + goto error; + } + + set_datastore_content_type_info(temp_datastore, content_type, folder_type_id); + set_datastore_account_info(temp_datastore, id, pw); + set_datastore_client_sync_type(temp_datastore, alert_type); + + *datastore = temp_datastore; + temp_datastore = NULL; + + error: + + if (sourceDatastore != NULL) + free(sourceDatastore); + + if (targetDatastore != NULL) + free(targetDatastore); + + if (sync_type != NULL) + free(sync_type); + + if (id != NULL) + free(id); + + if (pw != NULL) + free(pw); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __get_sync_type(int account_id, alert_type_e * alert_type) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + char *sync_type = NULL; + + bool result = get_config(account_id, DEFINE_CONFIG_KEY_PROFILE_CLIENT_SYNC_TYPE, &sync_type); + if (result == false) { + _DEBUG_ERROR("failed in get_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + *alert_type = ___convert_sync_type_value(sync_type); + + error: + + if (sync_type != NULL) + free(sync_type); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __on_synchronising_account(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + bool result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_SYNCHRONISING, "1", "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _off_synchronising_account(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + bool result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_SYNCHRONISING, "0", "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __on_resume_flag(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + bool result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_RESUME, "1", "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _off_resume_flag(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + bool result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_RESUME, "0", "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _assemble_changed_datastores(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + changed_datastore_s *pChangedDatastore = NULL; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + int content_type; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (!datastoreinfo_per_content_type[content_type]->client_sync_type) + continue; + + if (datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_SLOW_SYNC + || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_CLIENT || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_CLIENT_BY_SERVER) { + + if (content_type == TYPE_CALLLOG) { + _DEBUG_TRACE("sync_agent_refresh_item_tbl_from_service for call log"); + sync_agent_refresh_item_tbl_from_service(account_id, datastoreinfo_per_content_type[content_type]->datastore_id); + } + + GList *item_list = NULL; + sync_agent_da_get_item_list_query_s query; + query.option = SYNC_AGENT_DA_GET_ITEM_LIST_OPTION_ACCOUNT_ID; + query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_get_item_list(account_id, &query, &item_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_list !!"); + } + + pChangedDatastore = create_changed_datastore(datastoreinfo_per_content_type[content_type]->source, datastoreinfo_per_content_type[content_type]->target, 1, g_list_length(item_list)); + + if (pChangedDatastore == NULL) { + sync_agent_free_item_list(item_list); + _DEBUG_ERROR("failed in create_ChangedDatastore"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + if (g_list_length(item_list) > 0) { + GList *iter = NULL; + sync_agent_da_item_s *iter_data; + for (iter = item_list; iter != NULL; iter = g_list_next(iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_item_s *) (iter->data); + if (iter_data != NULL) { + char *cttype = __convert_cttype_str(iter_data->data_store_id); + changed_item_s *pChanged = create_changed_item(CHANGE_ADD, iter_data->item_id); + if (pChanged == NULL) { + sync_agent_free_item_list(item_list); + _DEBUG_ERROR("failed in create_ChangedDatastore"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + set_changed_item_content_type(pChanged, cttype); + set_changed_item_index_of_datastore(pChanged, content_type); + + add_changed_datastore_changed_item(pChangedDatastore, pChanged); + } else { + _DEBUG_ERROR("iter_data is NULL !!"); + sync_agent_free_item_list(item_list); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + } + + sync_agent_free_item_list(item_list); + } + + GList *item_id_list = NULL; + + sync_agent_da_get_item_id_list_query_s item_id_query = {0,}; + item_id_query.option = SYNC_AGENT_DA_GET_ITEM_ID_LIST_OPTION_OPERATION_ID_N_ITEM_TYPE_ID; + item_id_query.account_id = account_id; + item_id_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + item_id_query.operation_id = SYNC_AGENT_DA_CHANGE_OPERATION_DELETE; + + da_err = sync_agent_get_item_id_list(&item_id_query, &item_id_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_id_list !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + GList *item_id_iter = NULL; + char *item_id; + + if (g_list_length(item_id_list) > 0) { + for (item_id_iter = item_id_list; item_id_iter != NULL; item_id_iter = g_list_next(item_id_iter)) { + item_id = NULL; + item_id = (char *)(item_id_iter->data); + + da_err = sync_agent_delete_item(item_id, 1); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_item !!"); + sync_agent_free_item_id_list(item_id_list); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + } + + sync_agent_free_item_id_list(item_id_list); + + /*delete changelog data by account id and datastore id */ + sync_agent_da_delete_changelog_query_s delete_ch_query = {0,}; + delete_ch_query.option = SYNC_AGENT_DA_DELETE_CHANGELOG_OPTION_ITEM_TYPE_ID; + delete_ch_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_delete_changelog(account_id, &delete_ch_query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_changelog !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } else if (datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_TWO_WAY + || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_TWO_WAY_BY_SERVER + || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_ONE_WAY_FROM_CLIENT || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER) { + _DEBUG_TRACE("server sync type is ALERT_TYPE [%d]", datastoreinfo_per_content_type[content_type]->server_sync_type); + + /*on resume flag into agent DB */ + err = __on_resume_flag(account_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __on_resume_flag"); + goto error; + } + + if (content_type == TYPE_CALLLOG) { + _DEBUG_TRACE("sync_agent_construct_item_tbl_from_service for call log"); + sync_agent_construct_item_tbl_from_service(account_id, content_type); + } + + /*from changelog */ + GList *item_info_list = NULL; + sync_agent_da_get_changelog_list_query_s get_ch_query; + get_ch_query.option = SYNC_AGENT_DA_GET_CHANGELOG_LIST_OPTION_ITEM_TYPE_ID; + get_ch_query.account_id = account_id; + get_ch_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_get_changelog_list(&get_ch_query, &item_info_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_changelog_list !!"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + pChangedDatastore = create_changed_datastore(datastoreinfo_per_content_type[content_type]->source, datastoreinfo_per_content_type[content_type]->target, 1, g_list_length(item_info_list)); + + if (pChangedDatastore == NULL) { + sync_agent_free_changelog_list(item_info_list); + _DEBUG_ERROR("failed in create_ChangedDatastore"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + /*gathering changelog info */ + if (g_list_length(item_info_list) > 0) { + char *cttype = __convert_cttype_str(datastoreinfo_per_content_type[content_type]->datastore_id); + + GList *item_info_iter = NULL; + sync_agent_da_item_changelog_s *iter_data; + + for (item_info_iter = item_info_list; item_info_iter != NULL; item_info_iter = g_list_next(item_info_iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_item_changelog_s *) (item_info_iter->data); + + if (iter_data != NULL) { + changed_item_s *pChanged = create_changed_item(iter_data->operation_id - 300, iter_data->item_id); + if (pChanged == NULL) { + sync_agent_free_changelog_list(item_info_list); + _DEBUG_ERROR("failed in create_ChangedDatastore"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + set_changed_item_content_type(pChanged, cttype); + set_changed_item_index_of_datastore(pChanged, content_type); + add_changed_datastore_changed_item(pChangedDatastore, pChanged); + } else { + sync_agent_free_changelog_list(item_info_list); + _DEBUG_ERROR("iter_data is NULL !!"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + } + + int *itemTypeIdList = (int *)calloc(1, sizeof(int)); + if (itemTypeIdList == NULL) { + _DEBUG_ERROR("failed in da_set_item_changelog_wait_status_internal"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + itemTypeIdList[0] = datastoreinfo_per_content_type[content_type]->datastore_id; + + sync_agent_da_update_changelog_query_s query; + query.option = SYNC_AGENT_DA_UPDATE_CHANGELOG_OPTION_WAIT_STATUS; + query.folder_id_list = NULL; + query.folder_id_count = 0; + query.item_type_id_list = itemTypeIdList; + query.item_type_id_count = 1; + + da_err = sync_agent_update_changelog(account_id, &query); + + sync_agent_free_changelog_list(item_info_list); + + if (itemTypeIdList != NULL) + free(itemTypeIdList); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_update_changelog !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + } else if (datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_ONE_WAY_FROM_SERVER + || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_ONE_WAY_FROM_SERVER_BY_SERVER + || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_SERVER || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_SERVER_BY_SERVER) { + + if (datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_ONE_WAY_FROM_SERVER) { + /*on resume flag into agent DB */ + err = __on_resume_flag(account_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __on_resume_flag"); + goto error; + } + } + + /*MUST create empty changedDatastore.. */ + pChangedDatastore = create_changed_datastore(datastoreinfo_per_content_type[content_type]->source, datastoreinfo_per_content_type[content_type]->target, 1, 0); + if (pChangedDatastore == NULL) { + _DEBUG_ERROR("pChangedDatastore is NULL"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + if (datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_SERVER || datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_REFRESH_FROM_SERVER_BY_SERVER) { + + /*_DEBUG_TRACE("sync_agent_refresh_item_tbl_from_service"); + sync_agent_refresh_item_tbl_from_service(account_id, datastoreinfo_per_content_type[content_type]->plugin_type);*/ + + /* Delete All item (include changelog), before adapting server item data… */ + _DEBUG_TRACE("sync_agent_begin_service = %d", datastoreinfo_per_content_type[content_type]->datastore_id); + sync_agent_begin_service(datastoreinfo_per_content_type[content_type]->datastore_id); + sync_agent_begin_transaction(); + + /*delete service item data */ + sync_agent_da_delete_service_item_query_s query; + query.content_type = datastoreinfo_per_content_type[content_type]->datastore_id; + query.account_id = account_id; + + da_err = sync_agent_query_delete_service_items(&query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + + sync_agent_end_service(datastoreinfo_per_content_type[content_type]->datastore_id, 0); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_ROLLBACK); + + _DEBUG_ERROR("failed in sync_agent_query_delete_service_items()"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + _DEBUG_TRACE("da_get_item_by_account_id_internal"); + /*get all item by account id */ + GList *item_list = NULL; + sync_agent_da_get_item_list_query_s get_item_query; + get_item_query.option = SYNC_AGENT_DA_GET_ITEM_LIST_OPTION_ACCOUNT_ID; + get_item_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_get_item_list(account_id, &get_item_query, &item_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_list !!"); + } + _DEBUG_TRACE("item_cnt = %d", g_list_length(item_list)); + + GList *item_iter = NULL; + sync_agent_da_item_s *item_iter_data; + for (item_iter = item_list; item_iter != NULL; item_iter = g_list_next(item_iter)) { + item_iter_data = NULL; + item_iter_data = (sync_agent_da_item_s *) (item_iter->data); + + GList *mapping_list = NULL; + sync_agent_da_get_item_list_query_s mapping_query; + mapping_query.option = SYNC_AGENT_DA_GET_ITEM_LIST_OPTION_SERVICE_ID_MAPPING; + mapping_query.item_id = item_iter_data->item_id; + + da_err = sync_agent_get_item_list(account_id, &mapping_query, &mapping_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_list !!"); + } + + _DEBUG_TRACE("acc_cnt = %d", g_list_length(mapping_list)); + + GList *mapping_iter = NULL; + sync_agent_da_item_s *mapping_iter_data; + + for (mapping_iter = mapping_list; mapping_iter != NULL; mapping_iter = g_list_next(mapping_iter)) { + mapping_iter_data = NULL; + mapping_iter_data = (sync_agent_da_item_s *) (mapping_iter->data); + da_err = sync_agent_delete_item(mapping_iter_data->item_id, 1); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_item !!"); + } + } + + sync_agent_free_item_list(mapping_list); + } + + /*delete changelog data by account id and datastore id */ + _DEBUG_TRACE("da_delete_item_changelog_by_item_type_id_internal = %d", datastoreinfo_per_content_type[content_type]->datastore_id); + + sync_agent_da_delete_changelog_query_s delete_ch_query; + delete_ch_query.option = SYNC_AGENT_DA_DELETE_CHANGELOG_OPTION_ITEM_TYPE_ID; + delete_ch_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_delete_changelog(account_id, &delete_ch_query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + + sync_agent_free_item_list(item_list); + + sync_agent_end_service(datastoreinfo_per_content_type[content_type]->datastore_id, 0); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_ROLLBACK); + + _DEBUG_ERROR("failed in sync_agent_delete_changelog !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + /*delete item from item_tbl */ + _DEBUG_TRACE("da_delete_item_by_item_type_id_internal = %d", datastoreinfo_per_content_type[content_type]->datastore_id); + sync_agent_da_delete_item_query_s delete_item_query; + delete_item_query.option = SYNC_AGENT_DA_DELETE_ITEM_OPTION_ITEM_TYPE_ID; + delete_item_query.account_id = account_id; + delete_item_query.item_type_id = datastoreinfo_per_content_type[content_type]->datastore_id; + + da_err = sync_agent_query_delete_item(&delete_item_query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + sync_agent_free_item_list(item_list); + + sync_agent_end_service(datastoreinfo_per_content_type[content_type]->datastore_id, 0); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_ROLLBACK); + + _DEBUG_ERROR("failed in sync_agent_query_delete_item !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + _DEBUG_TRACE("sync_agent_end_service = %d", datastoreinfo_per_content_type[content_type]->datastore_id); + sync_agent_end_service(datastoreinfo_per_content_type[content_type]->datastore_id, 1); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_COMMIT); + sync_agent_free_item_list(item_list); + } + } + if (datastoreinfo_per_content_type[content_type]->client_sync_type) { + (*sync_obj)->changed_datastore = g_list_append((*sync_obj)->changed_datastore, pChangedDatastore); + + /* for prevent */ + if (pChangedDatastore != NULL) { + set_number_of_change(datastoreinfo_per_content_type[content_type]->client_sync_result, pChangedDatastore->number_of_changes); + } else { + _DEBUG_ERROR("pChangedDatastore is NULL !"); + } + + operation_type_e operation_type; + if (datastoreinfo_per_content_type[content_type]->client_sync_result->number_of_change == 0) + operation_type = OPERATION_NOOP; + else + operation_type = OPERATION_ADD; + err = __process_update(account_id, server_sync_type, SYNC_PROGRESS_SUCCESS, operation_type, content_type, false, false, datastoreinfo_per_content_type[content_type]->client_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("Failed in process_update"); + goto error; + } + } + } + } + + _INNER_FUNC_EXIT; + return err; + + error: + + if (pChangedDatastore != NULL) { + free_changed_datastore(pChangedDatastore); + pChangedDatastore = NULL; + } + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _prepare_pre_sync(int account_id, char *sync_mode, san_package_s * san_package, alert_type_e * sync_type) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + /*set synchronising flag into agent DB */ + err = __on_synchronising_account(account_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __on_synchronising_account"); + goto error; + } + + /*get sync type */ + err = __get_sync_type(account_id, sync_type); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __get_sync_type"); + goto error; + } + + /*init datastore_info_array */ + err = __init_datastore_info_array(account_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __init_datastore_info_array"); + goto error; + } + + /*set config based on sync mode */ + err = __set_config_based_on_sync_mode(account_id, sync_mode, san_package); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __set_config_based_on_sync_mode"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __set_config_based_on_sync_mode(int account_id, char *sync_mode, san_package_s * san_package) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + int content_type; + + if (strcmp(sync_mode, DEFINE_SYNC_MODE_PUSH) == 0) { + if (san_package != NULL) { + int count = san_package->cnt_sync_alerts; + _DEBUG_TRACE("count = %d", count); + int i; + for (i = 0; i < count; i++) { + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + + if (datastoreinfo_per_content_type[content_type] != NULL) { + _DEBUG_TRACE("datastoreinfo_per_content_type[content_type]->target = %s", datastoreinfo_per_content_type[content_type]->target); + if (datastoreinfo_per_content_type[content_type]->target == NULL) + continue; + + if (strcmp(san_package->sync_alerts[i].server_uri, datastoreinfo_per_content_type[content_type]->target) == 0) { + datastoreinfo_per_content_type[content_type]->client_sync_type = san_package->sync_alerts[i].sync_type; + _DEBUG_TRACE("san_package->syncAlerts[i].sync_type = %d", san_package->sync_alerts[i].sync_type); + } else + datastoreinfo_per_content_type[content_type]->client_sync_type = ALERT_UNKNOWN; + } + } + } + } + } + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _execute_pre_sync(int account_id, int session_time, pre_sync_return_obj_s * pre_sync_return_obj, alert_type_e * server_sync_type) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + /*if there is no alert command from server check it and goto fail_part */ + if (g_list_length(pre_sync_return_obj->datastore_info) == 0) { + _DEBUG_TRACE("alert command list from server is empty"); + err = SE_INTERNAL_MISCONFIGURATION; + goto error; + } + + err = __execute_pre_sync_set_server_id(account_id, pre_sync_return_obj->dev_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __set_server_id"); + goto error; + } + + err = __execute_pre_sync_datastore(account_id, session_time, pre_sync_return_obj->datastore_info, server_sync_type); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __process_datastore"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; + +} + +static se_error_type_e __execute_pre_sync_set_server_id(int account_id, char *dev_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + bool result; + char *value = NULL; + + if (dev_id != NULL) { + result = get_config(account_id, DEFINE_CONFIG_KEY_PROFILE_SERVER_ID, &value); + if (result == true) { + if (value != NULL) { + if (strcmp(value, dev_id) == 0) { + /* OK */ + } else { + result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_SERVER_ID, dev_id, "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + } else { + result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_SERVER_ID, dev_id, "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + } else { + _DEBUG_ERROR("failed in get_Config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + error: + + if (value != NULL) { + free(value); + value = NULL; + } + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __execute_pre_sync_datastore(int account_id, int session_time, GList * datastore_info, alert_type_e * server_sync_type) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + int result; + + bool changeSyncType = false; + alert_type_e sync_type = ALERT_UNKNOWN; + + int content_type; + GList *serverDatastore_iter = NULL; + datastore_info_s *serverDatastoreInfo = NULL; + bool existInServerDatastore; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + existInServerDatastore = false; + + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (datastoreinfo_per_content_type[content_type]->client_sync_type) { + _DEBUG_VERBOSE("datastoreinfo_per_content_type[%d]->client_sync_type = %d", content_type, datastoreinfo_per_content_type[content_type]->client_sync_type); + + for (serverDatastore_iter = datastore_info; serverDatastore_iter != NULL; serverDatastore_iter = g_list_next(serverDatastore_iter)) { + serverDatastoreInfo = serverDatastore_iter->data; + + if (strcmp(serverDatastoreInfo->source, datastoreinfo_per_content_type[content_type]->target) == 0) { + existInServerDatastore = true; + + if (serverDatastoreInfo->next_anchor != NULL) + datastoreinfo_per_content_type[content_type]->next_anchor_server = strdup(serverDatastoreInfo->next_anchor); + + datastoreinfo_per_content_type[content_type]->server_sync_type = serverDatastoreInfo->sync_type; + + if (datastoreinfo_per_content_type[content_type]->client_sync_type != datastoreinfo_per_content_type[content_type]->server_sync_type) { + changeSyncType = true; + sync_type = datastoreinfo_per_content_type[content_type]->server_sync_type; + } + + _DEBUG_VERBOSE("datastoreinfo_per_content_type[%d]->server_sync_type = %d", content_type, datastoreinfo_per_content_type[content_type]->server_sync_type); + + if (datastoreinfo_per_content_type[content_type]->last_anchor_server) { + /*if (strcmp(datastoreinfo_per_content_type[content_type]->lastAnchorServer, serverDatastoreInfo->lastAnchor) != 0) { + free(datastoreinfo_per_content_type[content_type]->lastAnchorServer); + datastoreinfo_per_content_type[content_type]->lastAnchorServer = NULL; + datastoreinfo_per_content_type[content_type]->server_sync_type == ALERT_SLOW_SYNC; + } */ + } else { + /* When first synchronize, lastAnchorServer is NULL... + if (datastoreinfo_per_content_type[content_type]->server_sync_type != ALERT_SLOW_SYNC + && datastoreinfo_per_content_type[content_type]->server_sync_type != ALERT_REFRESH_FROM_CLIENT + && datastoreinfo_per_content_type[content_type]->server_sync_type != ALERT_REFRESH_FROM_CLIENT_BY_SERVER + && datastoreinfo_per_content_type[content_type]->server_sync_type != ALERT_REFRESH_FROM_SERVER + && datastoreinfo_per_content_type[content_type]->server_sync_type != ALERT_REFRESH_FROM_SERVER_BY_SERVER) { + _DEBUG_VERBOSE("sync_agent_refresh_item_tbl_from_service"); + sync_agent_refresh_item_tbl_from_service(account_id, datastoreinfo_per_content_type[content_type]->plugin_type); + } */ + } + break; + } + } + + if (!existInServerDatastore) { + /* datastore config is wrong this datastore is not going to contain sync process from now */ + err = __process_update(account_id, ALERT_UNKNOWN, SYNC_FAILED_DB_CONFIG, OPERATION_NOOP, content_type, false, true, datastoreinfo_per_content_type[content_type]->client_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to process_update"); + goto error; + } + + err = __process_update(account_id, ALERT_UNKNOWN, SYNC_FAILED_DB_CONFIG, OPERATION_NOOP, content_type, true, true, datastoreinfo_per_content_type[content_type]->server_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to process_update"); + goto error; + } + + /* set fail into result (both client and server) */ + if (datastoreinfo_per_content_type[content_type]->client_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->client_sync_result->session_result = SYNC_SESSION_FAILED; + if (datastoreinfo_per_content_type[content_type]->server_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->server_sync_result->session_result = SYNC_SESSION_FAILED; + + err = ___write_sync_resource_info(account_id, content_type, session_time, 0, datastoreinfo_per_content_type[content_type]->client_sync_result, datastoreinfo_per_content_type[content_type]->server_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to write_SyncResourceInfo"); + goto error; + } + + free_datastore(datastoreinfo_per_content_type[content_type]); + datastoreinfo_per_content_type[content_type] = NULL; + + datastore_s *datastore = NULL; + err = __init_datastore_info(account_id, content_type, &datastore); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to init_datastore_info"); + goto error; + } + + datastoreinfo_per_content_type[content_type] = datastore; + } + } + } + } + + if (changeSyncType) { + *server_sync_type = sync_type; + result = set_config_str(account_id, DEFINE_CONFIG_KEY_PROFILE_SERVER_SYNC_TYPE, __convert_sync_type_str(sync_type), "string", "SE"); + if (result == false) { + _DEBUG_ERROR("failed in set_config"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _execute_sync(int account_id, alert_type_e client_sync_type, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + if (client_sync_type == ALERT_TWO_WAY || client_sync_type == ALERT_TWO_WAY_BY_SERVER || client_sync_type == ALERT_ONE_WAY_FROM_CLIENT || client_sync_type == ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER) { + + err = __execute_sync_arrange_changelog(account_id, client_sync_type, (*sync_return_obj)->status); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed to process_update"); + goto error; + } + } + + err = __execute_sync_status(account_id, server_sync_type, sync_obj, sync_return_obj); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __execute_sync_status"); + goto error; + } + + err = __execute_sync_change(account_id, server_sync_type, sync_obj, sync_return_obj); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __execute_sync_change"); + goto error; + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __execute_sync_arrange_changelog(int account_id, alert_type_e sync_type, GList * status) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err; + + int i = 0; + int count = 0; + int list_length = g_list_length(status); + char **itemIdList = (char **)calloc(list_length, sizeof(char *)); + if (itemIdList == NULL) { + _DEBUG_ERROR("Failed to alloc memory"); + err = SE_INTERNAL_NO_MEMORY; + goto error; + } + + GList *appliedStatus_iter = NULL; + applied_status_s *pAppliedStatus = NULL; + for (appliedStatus_iter = status; appliedStatus_iter != NULL; appliedStatus_iter = g_list_next(appliedStatus_iter)) { + pAppliedStatus = appliedStatus_iter->data; + + switch (pAppliedStatus->status) { + case 200: + case 201: + case 202: + case 203: + case 204: + case 205: + case 207: + case 208: + case 209: + case 210: + case 211: + { + /*clean up change log */ + if (pAppliedStatus->luid != NULL) + itemIdList[count++] = strdup(pAppliedStatus->luid); + + if (sync_type == ALERT_TWO_WAY || sync_type == ALERT_TWO_WAY_BY_SERVER || sync_type == ALERT_ONE_WAY_FROM_CLIENT || sync_type == ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER) { + + if (pAppliedStatus->change_type == CHANGE_DELETE) { + da_err = sync_agent_delete_item(pAppliedStatus->luid, 0); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in da_delete_item_by_item_id_internal"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + } + break; + } + case 206: + case 420: + break; + case 400: + case 500: + { + sync_agent_da_item_changelog_s *get_changelog = NULL; + da_err = sync_agent_create_changelog(&get_changelog); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_create_changelog !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + da_err = sync_agent_get_changelog(account_id, pAppliedStatus->luid, &get_changelog); + if (da_err == SYNC_AGENT_DA_ERR_NO_DATA) { + _DEBUG_VERBOSE("%s item does not exist in ChangeLog tbl", pAppliedStatus->luid); + sync_agent_free_changelog(get_changelog); + break; + } else if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_changelog !!"); + sync_agent_free_changelog(get_changelog); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + if (get_changelog->status != NULL) { + if (strcmp(get_changelog->status, "SYNC_ERROR") == 0) { + if (pAppliedStatus->luid != NULL) + itemIdList[count++] = strdup(pAppliedStatus->luid); + } else { + sync_agent_da_item_changelog_s *set_changelog = NULL; + + da_err = sync_agent_create_changelog(&set_changelog); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_create_changelog !!"); + sync_agent_free_changelog(get_changelog); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + set_changelog->item_id = strdup(pAppliedStatus->luid); + set_changelog->status = strdup("SYNC_ERROR"); + set_changelog->access_name = strdup("SE"); + + sync_agent_da_update_changelog_query_s update_ch_query; + update_ch_query.option = SYNC_AGENT_DA_UPDATE_CHANGELOG_OPTION_SYNC_STATUS; + update_ch_query.update_item = set_changelog; + + da_err = sync_agent_update_changelog(account_id, &update_ch_query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_update_changelog !!"); + sync_agent_free_changelog(get_changelog); + sync_agent_free_changelog(set_changelog); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + sync_agent_free_changelog(set_changelog); + } + } + + sync_agent_free_changelog(get_changelog); + break; + } + } + } + + if (list_length >= 1) { + _DEBUG_TRACE("before da_delete_item_changelog_by_item_id_list_internal"); + _DEBUG_TRACE("count = %d", count); + + sync_agent_da_delete_changelog_query_s query; + query.option = SYNC_AGENT_DA_DELETE_CHANGELOG_OPTION_ITEM_ID_LIST; + query.item_id_list = itemIdList; + query.count = count; + + da_err = sync_agent_delete_changelog(account_id, &query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_changelog !!"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + } + + error: + + /*free itemIdList */ + if (itemIdList != NULL) { + for (i = 0; i < list_length; i++) { + if (itemIdList[i] != NULL) + free(itemIdList[i]); + } + free(itemIdList); + } + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __execute_sync_status(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + int content_type; + bool existEqualItem; + bool needToSave; + sync_result_s *pClientSyncResult; + GList *changedDatastore_iter = NULL; + changed_datastore_s *pSyncChangedDatastore = NULL; + for (changedDatastore_iter = (*sync_obj)->changed_datastore; changedDatastore_iter != NULL;) { + pSyncChangedDatastore = (changed_datastore_s *) changedDatastore_iter->data; + _DEBUG_VERBOSE("pChangedDatastore = %p", pSyncChangedDatastore); + + int datastoreContentType = 0; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (strcmp(pSyncChangedDatastore->source, datastoreinfo_per_content_type[content_type]->source) == 0) { + datastoreContentType = content_type; + break; + } + } + } + + GList *changedItem_iter = NULL; + changed_item_s *changedItem = NULL; + for (changedItem_iter = pSyncChangedDatastore->sent_item; changedItem_iter != NULL;) { + changedItem = changedItem_iter->data; + + existEqualItem = false; + GList *appliedStatus_iter = NULL; + applied_status_s *pAppliedStatus = NULL; + for (appliedStatus_iter = (*sync_return_obj)->status; appliedStatus_iter != NULL; appliedStatus_iter = g_list_next(appliedStatus_iter)) { + pAppliedStatus = appliedStatus_iter->data; + + if (strcmp(pAppliedStatus->luid, changedItem->luid) == 0) { + add_receive_count(datastoreinfo_per_content_type[datastoreContentType]->client_sync_result, 1); + + if (pAppliedStatus->status >= 200 && pAppliedStatus->status <= 210) { + switch (changedItem->change_type) { + case CHANGE_ADD: + add_add_count(datastoreinfo_per_content_type[datastoreContentType]->client_sync_result, 1); + break; + case CHANGE_REPLACE: + add_replace_count(datastoreinfo_per_content_type[datastoreContentType]->client_sync_result, 1); + break; + case CHANGE_DELETE: + add_delete_count(datastoreinfo_per_content_type[datastoreContentType]->client_sync_result, 1); + break; + default: + break; + } + } else { + /* if status is not success count it is failed */ + } + + (*sync_return_obj)->status = g_list_remove((*sync_return_obj)->status, pAppliedStatus); + free_applied_status(pAppliedStatus); + pAppliedStatus = NULL; + + changedItem_iter = g_list_next(changedItem_iter); + + pSyncChangedDatastore->sent_item = g_list_remove(pSyncChangedDatastore->sent_item, changedItem); + free_changed_item(changedItem); + changedItem = NULL; + + existEqualItem = true; + break; + } + } + if (existEqualItem == false) + changedItem_iter = g_list_next(changedItem_iter); + } + + changedDatastore_iter = g_list_next(changedDatastore_iter); + + needToSave = false; + pClientSyncResult = datastoreinfo_per_content_type[datastoreContentType]->client_sync_result; + if (pClientSyncResult->number_of_change == pClientSyncResult->received_count) { + needToSave = true; + + if (datastoreinfo_per_content_type[datastoreContentType]->client_sync_result != NULL) + datastoreinfo_per_content_type[datastoreContentType]->client_sync_result->session_result = SYNC_SESSION_SUCCEEDED; + + /*remove datastore from list and + free current ChangedDatastore it does not need anymore because all item in datastore has been sent and receive status */ + (*sync_obj)->changed_datastore = g_list_remove((*sync_obj)->changed_datastore, pSyncChangedDatastore); + free_changed_datastore(pSyncChangedDatastore); + pSyncChangedDatastore = NULL; + } + + operation_type_e operation_type; + if (datastoreinfo_per_content_type[datastoreContentType]->client_sync_result->number_of_change == 0) + operation_type = OPERATION_NOOP; + else + operation_type = OPERATION_ADD; + err = __process_update(account_id, server_sync_type, SYNC_PROGRESS_SUCCESS, operation_type, datastoreContentType, false, needToSave, datastoreinfo_per_content_type[datastoreContentType]->client_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in process_update"); + goto error; + } + } + + error: + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e __execute_sync_change(int account_id, alert_type_e server_sync_type, sync_obj_s ** sync_obj, sync_return_obj_s ** sync_return_obj) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + sync_agent_da_service_item_s *service_item = NULL; + sync_agent_da_item_s *fw_item = NULL; + int content_type; + GList *f_id_list = NULL; + sync_result_s *tempServerSyncResult = NULL; + + /* process command that from server sended to client(sync, add, replace etc...) */ + changed_datastore_s *pSyncReturnChangedDatastore = NULL; + sending_status_s *sendingStatus = NULL; + GList *iter = NULL; + for (iter = (*sync_return_obj)->changed_datastore; iter != NULL;) { + pSyncReturnChangedDatastore = (changed_datastore_s *) iter->data; + + int datastoreContentType = 0; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (strcmp(pSyncReturnChangedDatastore->target, datastoreinfo_per_content_type[content_type]->source) == 0) { + datastoreContentType = content_type; + break; + } + } + } + + /*noti to UI numberOfChanges from server */ + if (pSyncReturnChangedDatastore->has_number_of_changes) { + set_number_of_change(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result, pSyncReturnChangedDatastore->number_of_changes); + + operation_type_e operation_type; + if (datastoreinfo_per_content_type[datastoreContentType]->server_sync_result->number_of_change == 0) + operation_type = OPERATION_NOOP; + else + operation_type = OPERATION_ADD; + err = __process_update(account_id, server_sync_type, SYNC_PROGRESS_SUCCESS, operation_type, datastoreContentType, true, false, datastoreinfo_per_content_type[datastoreContentType]->server_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in process_update"); + goto error; + } + } + + sendingStatus = create_sending_status(pSyncReturnChangedDatastore->target, pSyncReturnChangedDatastore->source); + if (sendingStatus == NULL) { + err = SE_INTERNAL_NO_MEMORY; + _DEBUG_ERROR("failed to alloc memory"); + goto error; + } + + /*get folderId */ + char *folderId = NULL; + sync_agent_da_get_folder_id_list_query_s query; + query.option = SYNC_AGENT_DA_GET_FOLDER_ID_OPTION_FOLDER_TYPE_ID; + query.account_id = account_id; + query.item_type_id = datastoreinfo_per_content_type[datastoreContentType]->datastore_id; + query.folder_type_id = datastoreinfo_per_content_type[datastoreContentType]->folder_type_id; + + da_err = sync_agent_get_folder_id_list(&query, &f_id_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_get_folder_id_list_inferface() failed !!"); + goto error; + } + + if (g_list_length(f_id_list) > 0) { + GList *iter = g_list_nth(f_id_list, 0); + folderId = (char *)(iter->data); + } else { + _DEBUG_ERROR("failed to get folderId"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + int changeItemCount = g_list_length(pSyncReturnChangedDatastore->change_item); + if (changeItemCount > 0) { + /*begin transaction */ + _DEBUG_VERBOSE("sync_agent_begin_service with datastoreContentType = %d", datastoreContentType); +// sync_agent_begin_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id); + sync_agent_begin_transaction(); + + /*back up syncresult structure for rollback case */ + tempServerSyncResult = dup_sync_result(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result); + } + + bool needToSave = false; + sync_result_s *pServerSyncResult = NULL; + GList *changedIter = NULL; + changed_item_s *changedItem = NULL; + applied_status_s *appliedStatus = NULL; + + for (changedIter = pSyncReturnChangedDatastore->change_item; changedIter != NULL; changedIter = g_list_next(changedIter)) { + changedItem = (changedIter->data); + + _DEBUG_VERBOSE("changedItem->changeType : %d", changedItem->change_type); + _DEBUG_VERBOSE("changedItem->luid : %s", changedItem->luid); + _DEBUG_VERBOSE("changedItem->content_type : %s", changedItem->content_type); + _DEBUG_VERBOSE("changedItem->indexOfDatastore : %d", changedItem->index_of_datastore); + _DEBUG_VERBOSE("changedItem->data : %s", changedItem->data); + + add_receive_count(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result, 1); + + bool da_fail = false; + command_result_e returnResult = COMMAND_RESULT_INIT; + switch (changedItem->change_type) { + case CHANGE_ADD: + { + /* add to service DB */ + if (changedItem->data != NULL) { + char *fw_id = NULL; + + da_err = sync_agent_create_service_item(&service_item); + if ((da_err != SYNC_AGENT_DA_SUCCESS) || (service_item == NULL)) { + _DEBUG_ERROR("failed in sync_agent_create_service_item() = %d", da_err); + returnResult = ___convert_return_status(da_err); + da_fail = true; + break; + } + + service_item->item_id = g_strdup(changedItem->luid); + service_item->content_type = datastoreinfo_per_content_type[datastoreContentType]->datastore_id; + service_item->account_id = account_id; + service_item->folder_id = g_strdup(folderId); + service_item->access_name = g_strdup("Engine"); + service_item->data = g_strdup(changedItem->data); + sync_agent_begin_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id); + + da_err = sync_agent_add_service_item(service_item, &fw_id, false); + + sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 1); + + _DEBUG_VERBOSE("da_err = %d", da_err); + + if (da_err == SYNC_AGENT_DA_SUCCESS) { + int acc_cnt; + bool success = true; + char *service_id = sync_agent_get_service_item_id(fw_id); + + GList *folder_list = NULL; + sync_agent_da_get_folder_list_query_s query; + query.option = SYNC_AGENT_DA_GET_FOLDER_LIST_OPTION_SERVICE_ID_MAPPING; + query.account_id = account_id; + query.folder_id = folderId; + da_err = sync_agent_get_folder_list(&query, &folder_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_get_folder_list() failed !!"); + success = false; + } + + acc_cnt = g_list_length(folder_list); + + _DEBUG_VERBOSE("acc_cnt = %d", acc_cnt); + if (acc_cnt > 0) { + char **fw_item_id_list = sync_agent_generate_item_luid(1, acc_cnt); + char **id_list = (char **)calloc(acc_cnt, sizeof(char *)); + if (id_list == NULL) { + _DEBUG_ERROR("CALLOC failed !!!"); + success = false; + break; + } + + if (fw_item_id_list == NULL) { + _DEBUG_ERROR("failed in sync_agent_generate_item_luid"); + da_err = SYNC_AGENT_DA_ERRORS; + success = false; + } else { + int i = 0; + GList *iter = NULL; + sync_agent_da_folder_s *iter_data; + + for (iter = folder_list; iter != NULL; iter = g_list_next(iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_folder_s *) (iter->data); + + da_err = sync_agent_create_item(&fw_item); + if ((da_err != SYNC_AGENT_DA_SUCCESS) || (fw_item == NULL)) { + _DEBUG_ERROR("failed in sync_agent_create_item() = %d", da_err); + success = false; + break; + } + + fw_item->item_id = g_strdup(fw_item_id_list[i]); + fw_item->data_store_id = datastoreinfo_per_content_type[datastoreContentType]->datastore_id; + fw_item->account_id = iter_data->account_id; + fw_item->folder_id = g_strdup(iter_data->folder_id); + fw_item->service_id = g_strdup(service_id); + fw_item->access_name = g_strdup("DACI_ChangeLog"); + + da_err = sync_agent_add_item(fw_item, &(id_list[i]), true); + if (fw_item != NULL) + sync_agent_free_item(fw_item); + free(fw_item_id_list[i]); + free(id_list[i]); + + i++; + + _DEBUG_VERBOSE("da_err = %d", da_err); + + if (da_err != SYNC_AGENT_DA_SUCCESS) { + success = false; + break; + } + } + if (fw_item_id_list != NULL) { + free(fw_item_id_list); + } + if (id_list != NULL) { + free(id_list); + } + } + } + + if (success == true) { + returnResult = COMMAND_RESULT_ADDED; + add_add_count(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result, 1); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + sync_agent_free_folder_list(folder_list); + + if (service_id != NULL) + free(service_id); + + } else if (da_err == SYNC_AGENT_DA_ERR_NOT_SUPPORTED || da_err == SYNC_AGENT_DA_ERR_INVALID_CONTENT || da_err == SYNC_AGENT_DA_ERR_ALREADY_EXIST) { + /*just return error to server */ + returnResult = ___convert_return_status(da_err); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + + if (service_item != NULL) + sync_agent_free_service_item(service_item); + + if (fw_id != NULL) + free(fw_id); + } else + returnResult = COMMAND_RESULT_COMMAND_FAIL; + + break; + } + case CHANGE_REPLACE: + { + if (changedItem->data != NULL) { + /* update from service DB */ + da_err = sync_agent_create_service_item(&service_item); + if (da_err != SYNC_AGENT_DA_SUCCESS || (service_item == NULL)) { + _DEBUG_ERROR("failed in sync_agent_create_service_item() = %d", da_err); + returnResult = ___convert_return_status(da_err); + da_fail = true; + break; + } + + service_item->item_id = g_strdup(changedItem->luid); + service_item->content_type = datastoreinfo_per_content_type[datastoreContentType]->datastore_id; + service_item->account_id = account_id; + service_item->folder_id = g_strdup(folderId); + service_item->access_name = g_strdup("Engine"); + service_item->data = (const void *)g_strdup(changedItem->data); + + sync_agent_begin_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id); + + da_err = sync_agent_update_service_item(service_item, changedItem->luid, false); + + sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 1); + + _DEBUG_VERBOSE("da_err = %d", da_err); + if (da_err == SYNC_AGENT_DA_SUCCESS) { + + GList *item_list = NULL; + sync_agent_da_get_item_list_query_s query; + query.option = SYNC_AGENT_DA_GET_ITEM_LIST_OPTION_SERVICE_ID_MAPPING; + query.item_id = changedItem->luid; + + da_err = sync_agent_get_item_list(account_id, &query, &item_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_list !!"); + } + + bool success = true; + GList *iter = NULL; + sync_agent_da_item_s *iter_data; + + for (iter = item_list; iter != NULL; iter = g_list_next(iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_item_s *) (iter->data); + + da_err = sync_agent_update_item(iter_data->item_id, 1); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + success = false; + break; + } + } + + if (success == true) { + returnResult = COMMAND_RESULT_OK; + add_replace_count(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result, 1); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + + sync_agent_free_item_list(item_list); + } else if (da_err == SYNC_AGENT_DA_ERR_NOT_SUPPORTED || da_err == SYNC_AGENT_DA_ERR_INVALID_CONTENT) { + /*just return error to server */ + returnResult = ___convert_return_status(da_err); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + + if (service_item != NULL) + sync_agent_free_service_item(service_item); + } else + returnResult = COMMAND_RESULT_COMMAND_FAIL; + + break; + } + case CHANGE_DELETE: + { + /* delete from service DB */ + GList *item_list = NULL; + sync_agent_da_get_item_list_query_s query; + query.option = SYNC_AGENT_DA_GET_ITEM_LIST_OPTION_SERVICE_ID_MAPPING; + query.item_id = changedItem->luid; + + da_err = sync_agent_get_item_list(account_id, &query, &item_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_item_list !!"); + } + + sync_agent_begin_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id); + + da_err = sync_agent_delete_service_item(changedItem->luid, false); + + sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 1); + + _DEBUG_VERBOSE("[sync_agent_delete_service_item] result : %d", da_err); + if (da_err == SYNC_AGENT_DA_SUCCESS) { + bool success = true; + GList *iter = NULL; + sync_agent_da_item_s *iter_data; + + for (iter = item_list; iter != NULL; iter = g_list_next(iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_item_s *) (iter->data); + + da_err = sync_agent_delete_item(iter_data->item_id, true); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + success = false; + break; + } + } + + if (success == true) { + returnResult = COMMAND_RESULT_DELETE_WITHOUT_ARCHIVE; + add_delete_count(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result, 1); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + } else if (da_err == SYNC_AGENT_DA_ERR_NO_DATA || da_err == SYNC_AGENT_DA_ERR_SUB_DATA_EXIST || da_err == SYNC_AGENT_DA_ERR_INVALID_CONTENT) { + /*just return error to server */ + returnResult = ___convert_return_status(da_err); + } else { + /*this case just fail do rollback and goto fail */ + returnResult = ___convert_return_status(da_err); + da_fail = true; + } + sync_agent_free_item_list(item_list); + break; + } + default: + break; + } + + if (da_fail == true) { + /*replace syncresult when rollback happened */ + if (datastoreinfo_per_content_type[datastoreContentType]->server_sync_result != NULL) + free(datastoreinfo_per_content_type[datastoreContentType]->server_sync_result); + + datastoreinfo_per_content_type[datastoreContentType]->server_sync_result = tempServerSyncResult; + tempServerSyncResult = NULL; + + _DEBUG_VERBOSE("Transaction_Rollback"); + _DEBUG_VERBOSE("sync_agent_end_service with datastoreContentType = %d", datastoreContentType); +// sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 0); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_ROLLBACK); + + err = SE_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed in DA"); + goto error; + } + + appliedStatus = create_applied_status(changedItem->luid, changedItem->change_type, returnResult); + if (appliedStatus == NULL) { + _DEBUG_VERBOSE("Transaction_Rollback"); + _DEBUG_VERBOSE("sync_agent_end_service with datastoreContentType = %d", datastoreContentType); +// sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 0); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_ROLLBACK); + + err = SE_INTERNAL_NO_MEMORY; + _DEBUG_ERROR("failed to alloc memory"); + goto error; + } + add_sending_status_applied_status(sendingStatus, appliedStatus); + } + + if (changeItemCount > 0) { + /*end transaction */ + _DEBUG_VERBOSE("sync_agent_end_service with datastoreContentType = %d", datastoreContentType); +// sync_agent_end_service(datastoreinfo_per_content_type[datastoreContentType]->datastore_id, 1); + sync_agent_end_transaction(SYNC_AGENT_DA_TRANSACTION_COMMIT); + } + + /* Do not need to send update event to ui when changeItemCount less than 0 */ + /* send update event about add, delete, replace count during this sync command */ + if (changeItemCount >= 0) { + needToSave = false; + pServerSyncResult = datastoreinfo_per_content_type[datastoreContentType]->server_sync_result; + if (pServerSyncResult->number_of_change == pServerSyncResult->received_count) { + needToSave = true; + + if (datastoreinfo_per_content_type[datastoreContentType]->server_sync_result != NULL) + datastoreinfo_per_content_type[datastoreContentType]->server_sync_result->session_result = SYNC_SESSION_SUCCEEDED; + } + + operation_type_e operation_type; + if (datastoreinfo_per_content_type[datastoreContentType]->server_sync_result->number_of_change == 0) + operation_type = OPERATION_NOOP; + else + operation_type = OPERATION_ADD; + err = __process_update(account_id, server_sync_type, SYNC_PROGRESS_SUCCESS, operation_type, datastoreContentType, true, needToSave, datastoreinfo_per_content_type[datastoreContentType]->server_sync_result); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in process_update"); + goto error; + } + } + + (*sync_obj)->sending_status = g_list_append((*sync_obj)->sending_status, sendingStatus); + sendingStatus = NULL; + + iter = g_list_next(iter); + + (*sync_return_obj)->changed_datastore = g_list_remove((*sync_return_obj)->changed_datastore, pSyncReturnChangedDatastore); + free_changed_datastore(pSyncReturnChangedDatastore); + pSyncReturnChangedDatastore = NULL; + + if (tempServerSyncResult != NULL) { + free(tempServerSyncResult); + tempServerSyncResult = NULL; + } + } + + error: + sync_agent_free_folder_id_list(f_id_list); + + if (tempServerSyncResult != NULL) + free(tempServerSyncResult); + + /* for prevent */ + free_sending_status(sendingStatus); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _update_sync_result(int account_id) +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + int content_type; + + sync_agent_da_last_anchor_s next_anchor_info; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (!datastoreinfo_per_content_type[content_type]->client_sync_type) + continue; + + next_anchor_info.access_name = "Engine"; + next_anchor_info.account_id = account_id; + next_anchor_info.data_store_id = datastoreinfo_per_content_type[content_type]->datastore_id; + next_anchor_info.last_anchor_client = datastoreinfo_per_content_type[content_type]->next_anchor_client; + next_anchor_info.last_anchor_server = datastoreinfo_per_content_type[content_type]->next_anchor_server; + + da_err = sync_agent_update_last_anchor(&next_anchor_info); + if (da_err != SYNC_AGENT_DA_SUCCESS) + _DEBUG_ERROR("failed in da_set_last_anchor_internal"); + + da_err = sync_agent_set_service_change_point(account_id, datastoreinfo_per_content_type[content_type]->datastore_id); + if (da_err != SYNC_AGENT_DA_SUCCESS) + _DEBUG_ERROR("failed in sync_agent_set_service_change_point"); + } + } + + _INNER_FUNC_EXIT; + return err; +} + +static command_result_e ___convert_return_status(sync_agent_da_return_e da_err) +{ + _INNER_FUNC_ENTER; + + command_result_e returnResult = COMMAND_RESULT_INIT; + switch (da_err) { + case 1: /*SYNC_AGENT_DA_SUCCESS */ + /*never comes this case + break; */ + case -813: /*SYNC_AGENT_DA_ERR_ALREADY_EXIST */ + returnResult = COMMAND_RESULT_ALREADY_EXIST; /*[A] Already exists exception */ + break; + case -815: /*SYNC_AGENT_DA_ERR_MEMORY_FULL *//* oma : 420 (device full exception) */ + returnResult = COMMAND_RESULT_DEVICE_FULL; /*[AR] Device full exception */ + break; + case -820: /*SYNC_AGENT_DA_ERR_NOT_SUPPORTED *//* oma : 415 (unsupported media type or format exception) */ + returnResult = COMMAND_RESULT_UNSUPPORTED_TYPE; /*[AR] Unsupported media type or format exception */ + break; + case -819: /*SYNC_AGENT_DA_ERR_NO_DATA *//* kies : not found, oma : 211 (item not deleted exception) */ + returnResult = COMMAND_RESULT_NOT_EXIST; /*[D] Item not deleted exception */ + break; + case -800: /*SYNC_AGENT_DA_ERRORS */ + case -801: /*SYNC_AGENT_DA_NOT_FOUND_PLUG_IN */ + case -802: /*SYNC_AGENT_DA_ERR_OPEN_FAILED */ + case -803: /*SYNC_AGENT_DA_ERR_CLOSE_FAILED */ + case -804: /*SYNC_AGENT_DA_ERR_TRANSACTION_FAILED */ + case -805: /*SYNC_AGENT_DA_ERR_CREATE_TABLE_FAILED */ + case -806: /*SYNC_AGENT_DA_ERR_DROP_TABLE_FAILED */ + case -807: /*SYNC_AGENT_DA_ERR_QUERY_FAILED */ + case -808: /*SYNC_AGENT_DA_ERR_NOT_OPENED */ + case -809: /*SYNC_AGENT_DA_ERR_ACCOUNT_FULL */ + case -810: /*SYNC_AGENT_DA_ERR_DELETE_LAST_ACCOUNT */ + case -811: /*SYNC_AGENT_DA_ERR_PRIMARY_KEY_NOT_UNIQUE */ + case -812: /*SYNC_AGENT_DA_ERR_DB_HANDLER_MGR */ + case -814: /*SYNC_AGENT_DA_ERR_INVALID_CONTENT */ + case -816: /*SYNC_AGENT_DA_ERR_SUB_DATA_EXIST *//* oma : 427 (item not empty) */ + case -817: /*SYNC_AGENT_DA_ERR_LOCKED *//* kies : cannot access */ + case -818: /*SYNC_AGENT_DA_ERR_MORE_DATA */ + case -821: /*SYNC_AGENT_DA_ERR_NOT_EXECUTE *//* kies : ex) sms send command, no network service */ + default: + returnResult = COMMAND_RESULT_COMMAND_FAIL; /*[ARD] Command failed exception */ + break; + } + + _INNER_FUNC_EXIT; + return returnResult; +} + +static char *__convert_cttype_str(int datastore_id) +{ + _INNER_FUNC_ENTER; + + char *cttype = NULL; + /*FIXME : check type and version (contact : vCard2.1 , calendar : vCalendar 1.0 , memo : plain text) of real item data.. */ + switch (datastore_id) { + case TYPE_CONTACT: /*contact (vCard2.1) */ + cttype = ELEMENT_TEXT_VCARD; + break; + case TYPE_CALENDAR: /*calendar (vCalendar2.0) */ + cttype = ELEMENT_TEXT_VCAL; + break; + case TYPE_MEMO: /*note(Memo) */ + cttype = ELEMENT_TEXT_PLAIN; + break; + case TYPE_CALLLOG: + cttype = ELEMENT_TEXT_XCALLLOG; + break; + default: + break; + } + + _INNER_FUNC_EXIT; + return cttype; +} + +static int ___convert_sync_type_value(char *sync_type_str) +{ + _INNER_FUNC_ENTER; + + int sync_type_value; + + if (strcmp(sync_type_str, DEFINE_ALERT_SLOW_SYNC_STR) == 0) + sync_type_value = ALERT_SLOW_SYNC; + else if (strcmp(sync_type_str, DEFINE_ALERT_TWO_WAY_STR) == 0) + sync_type_value = ALERT_TWO_WAY; + else if (strcmp(sync_type_str, DEFINE_ALERT_ONE_WAY_FROM_CLIENT_STR) == 0) + sync_type_value = ALERT_ONE_WAY_FROM_CLIENT; + else if (strcmp(sync_type_str, DEFINE_ALERT_ONE_WAY_FROM_SERVER_STR) == 0) + sync_type_value = ALERT_ONE_WAY_FROM_SERVER; + else if (strcmp(sync_type_str, DEFINE_ALERT_REFRESH_FROM_SERVER_STR) == 0) + sync_type_value = ALERT_REFRESH_FROM_SERVER; + else if (strcmp(sync_type_str, DEFINE_ALERT_REFRESH_FROM_CLIENT_STR) == 0) + sync_type_value = ALERT_REFRESH_FROM_CLIENT; + else + sync_type_value = ALERT_UNKNOWN; + + _INNER_FUNC_EXIT; + return sync_type_value; +} + +static char *__convert_sync_type_str(alert_type_e sync_type) +{ + _INNER_FUNC_ENTER; + + char *sync_Type = NULL; + + switch (sync_type) { + case ALERT_TWO_WAY: + sync_Type = DEFINE_ALERT_TWO_WAY_STR; + break; + case ALERT_SLOW_SYNC: + sync_Type = DEFINE_ALERT_SLOW_SYNC_STR; + break; + case ALERT_ONE_WAY_FROM_CLIENT: + sync_Type = DEFINE_ALERT_ONE_WAY_FROM_CLIENT_STR; + break; + case ALERT_REFRESH_FROM_CLIENT: + sync_Type = DEFINE_ALERT_REFRESH_FROM_CLIENT_STR; + break; + case ALERT_ONE_WAY_FROM_SERVER: + sync_Type = DEFINE_ALERT_ONE_WAY_FROM_SERVER_STR; + break; + case ALERT_REFRESH_FROM_SERVER: + sync_Type = DEFINE_ALERT_REFRESH_FROM_SERVER_STR; + break; + default: + sync_Type = DEFINE_ALERT_UNKNOWN_STR; + break; + } + + _INNER_FUNC_EXIT; + return sync_Type; +} + +static char *___convert_sync_progress_status_str(sync_progress_status_e progress_status) +{ + _INNER_FUNC_ENTER; + + char *progress = NULL; + + switch (progress_status) { + case SYNC_PROGRESS_NONE: + progress = DEFINE_PROGRESS_NONE; + break; + case SYNC_PROGRESS_SUCCESS: + progress = DEFINE_PROGRESS_SUCCESS; + break; + case SYNC_FAILED_DB: + progress = DEFINE_FAILED_DB; + break; + case SYNC_FAILED_DB_FORBIDDEN: + progress = DEFINE_FAILED_DB_FORBIDDEN; + break; + case SYNC_FAILED_DB_ITEM: + progress = DEFINE_FAILED_DB_ITEM; + break; + case SYNC_FAILED_DB_CONFIG: + progress = DEFINE_FAILED_DB_CONFIG; + break; + case SYNC_FAILED_DB_DEVICEFULL: + progress = DEFINE_FAILED_DB_DEVICEFULL; + break; + default: + break; + } + + _INNER_FUNC_EXIT; + return progress; +} + +static char *___convert_operation_type_str(operation_type_e operation_type) +{ + _INNER_FUNC_ENTER; + + char *operation = NULL; + + switch (operation_type) { + case OPERATION_NOOP: + operation = DEFINE_NOOP; + break; + case OPERATION_ADD: + operation = DEFINE_ADD; + break; + case OPERATION_DELETE: + operation = DEFINE_DELETE; + break; + case OPERATION_MOVE: + operation = DEFINE_MOVE; + break; + case OPERATION_COPY: + operation = DEFINE_COPY; + break; + case OPERATION_REPLACE: + operation = DEFINE_REPLACE; + break; + default: + break; + } + + _INNER_FUNC_EXIT; + return operation; +} + +static char *_convert_sync_progress_str(sync_progress_e process) +{ + _INNER_FUNC_ENTER; + + char *syncProcess = NULL; + + switch (process) { + case PROGRESS_NONE: + syncProcess = DEFINE_SYNC_PROGRESS_NONE; + break; + case PROGRESS_INIT: + syncProcess = DEFINE_SYNC_INIT; + break; + case PROGRESS_CONNECTING: + syncProcess = DEFINE_SYNC_CONNECTING; + break; + case PROGRESS_AUTHENTICATED: + syncProcess = DEFINE_SYNC_AUTHENTICATED; + break; + case PROGRESS_DONE: + syncProcess = DEFINE_SYNC_DONE; + break; + case PROGRESS_ERROR: + syncProcess = DEFINE_SYNC_ERROR; + break; + default: + break; + } + + _INNER_FUNC_EXIT; + return syncProcess; +} + +static char *_convert_sync_error_str(sync_error_e error) +{ + _INNER_FUNC_ENTER; + + char *syncError = NULL; + + switch (error) { + case ERROR_NONE: + syncError = DEFINE_ERROR_NONE; + break; + case ERROR_CONNECTION: + syncError = DEFINE_ERROR_CONNECTION; + break; + case ERROR_SYNCHDR: + syncError = DEFINE_ERROR_SYNCHDR; + break; + case ERROR_INTERNAL: + syncError = DEFINE_ERROR_INTERNAL; + break; + case ERROR_SUSPENDED: + syncError = DEFINE_ERROR_SUSPENDED; + break; + case ERROR_DB: + syncError = DEFINE_ERROR_DB; + break; + case ERROR_ABORT: + syncError = DEFINE_ERROR_ABORT; + break; + case ERROR_SERVER: + syncError = DEFINE_ERROR_SERVER; + break; + case ERROR_MEMORY_FULL: + syncError = DEFINE_ERROR_MEMORY_FULL; + break; + case ERROR_AUTHENTICATE: + syncError = DEFINE_ERROR_AUTHENTICATE; + break; + case ERROR_AUTOCONFIG_NOT_SUPPORT_BY_SERVER: + syncError = DEFINE_ERROR_AUTOCONFIG_NOT_SUPPORT_BY_SERVER; + break; + case ERROR_LOW_BATTERY: + syncError = DEFINE_ERROR_LOW_BATTERY; + break; + default: + break; + } + + _INNER_FUNC_EXIT; + return syncError; +} + +static se_error_type_e _check_low_battery() +{ + _INNER_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_dev_return_e dci_err = SYNC_AGENT_DEV_RETURN_SUCCESS; + char *battery_level = NULL; + int int_battery_level = 0; + + dci_err = sync_agent_get_devinfo(1, "Battery", &battery_level); + if (dci_err != SYNC_AGENT_DEV_RETURN_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_devinfo = %d", dci_err); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + _DEBUG_TRACE("battery_level =%s", battery_level); + + if (battery_level != NULL) { + int_battery_level = atoi(battery_level); + + if (int_battery_level < LOW_BATTERY_LEVEL) { + _DEBUG_ERROR("LOW Battery = %d", int_battery_level); + err = SE_INTERNAL_LOW_BATTERY; + goto error; + } + } + + error: + + if (battery_level != NULL) + free(battery_level); + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _open_services() +{ + _EXTERN_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + int content_type; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (!datastoreinfo_per_content_type[content_type]->client_sync_type) + continue; + + da_err = sync_agent_open_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_open_service(%d) is failed", content_type); + err = SE_INTERNAL_DA_ERROR; + break; + } + } + } + + _INNER_FUNC_EXIT; + return err; +} + +static se_error_type_e _close_services() +{ + _EXTERN_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + int content_type; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (!datastoreinfo_per_content_type[content_type]->client_sync_type) + continue; + + da_err = sync_agent_close_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) + _DEBUG_ERROR("sync_agent_close_service(%d) is failed", content_type); + } + } + + _INNER_FUNC_EXIT; + return err; +} + +bool synchronize(int account_id, char *sync_mode, san_package_s * san_package) +{ + _EXTERN_FUNC_ENTER; + + _DEBUG_INFO("accountID = %d", account_id); + _DEBUG_INFO("sync_mode = %s", sync_mode); + + /*FIXME remove msg file */ + int ret_val = remove(OMA_DS_MSG_PATH); + if (ret_val < 0) { + _DEBUG_ERROR("failed in synchronize - remove()"); + } + + /*FIXME time check */ + long t, dt; + t = myclock(); + + se_error_type_e err = SE_INTERNAL_OK; + sync_agent_dev_return_e dci_result = SYNC_AGENT_DEV_RETURN_SUCCESS; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + common_error_type_e errorCode = COMMON_OK; + sync_progress_e process = PROGRESS_NONE; + sync_error_e error = ERROR_NONE; + + alert_type_e client_sync_type = ALERT_UNKNOWN; + alert_type_e server_sync_type = ALERT_UNKNOWN; + int only_from_client = 0; + + int session_time = sync_agent_convert_seconds_to_utc(time(NULL)); /*lastSessionTime for resultView; */ + _DEBUG_INFO("session_time = %d", session_time); + + pre_sync_return_obj_s *pre_sync_return_obj = NULL; + sync_obj_s *sync_obj = NULL; + sync_return_obj_s *sync_return_obj = NULL; + + bool cancel_flag = false; + int content_type; + char *session_id = NULL; + + char *access_name = NULL; + bool server_flag = false; + + char *msg = NULL; + unsigned int msg_size; + char *recvMsg = NULL; + unsigned int recvMsg_size; + + sync_agent_acc_error_e acc_err = SYNC_AGENT_ACC_SUCCESS; + sync_agent_fw_account_s *fw_account = NULL; + + dci_result = sync_agent_execute_dev_function(DEFINE_PLATFORM, "pm_lock", 3, LCD_OFF, STAY_CUR_STATE, 0); + if (dci_result != SYNC_AGENT_DEV_RETURN_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_execute_dev_function lock = %d", dci_result); + } + + /* low battery check */ + err = _check_low_battery(); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("check_low_battery = %d", err); + goto fail_part; + } + + da_err = sync_agent_open_agent(); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_open_agent = %d", da_err); + err = SE_INTERNAL_DA_ERROR; + goto fail_part; + } + + /* prepare for sending pre sync */ + err = _prepare_pre_sync(account_id, sync_mode, san_package, &client_sync_type); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __prepare_pre_sync = %d", err); + goto fail_part; + } + + /* check cancel flag */ + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + err = SE_INTERNAL_CANCEL; + _DEBUG_INFO("cancle flag is on"); + goto cancel_part; + } + + pre_sync_return_obj = (pre_sync_return_obj_s *) calloc(1, sizeof(pre_sync_return_obj_s)); + if (pre_sync_return_obj == NULL) { + _DEBUG_ERROR("failed to alloc memory"); + err = SE_INTERNAL_NO_MEMORY; + goto fail_part; + } + + acc_err = sync_agent_create_fw_account(&fw_account); + if (acc_err != SYNC_AGENT_ACC_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_create_fw_account"); + err = SE_INTERNAL_NO_MEMORY; + goto fail_part; + } + + acc_err = sync_agent_get_fw_account(account_id, &fw_account); + if (acc_err != SYNC_AGENT_ACC_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_update_fw_account"); + err = SE_INTERNAL_ERROR; + goto fail_part; + } + + access_name = strdup(fw_account->access_name); + if (strcmp(access_name, "DIVE") == 0) { + server_flag = true; + } + + /*pkg 1 */ + if (strcmp(sync_mode, DEFINE_SYNC_MODE_PUSH) == 0) { + _DEBUG_INFO("sessionID = %d", san_package->session_id); + session_id = g_strdup_printf("%u", san_package->session_id); /*freed in pre_sync */ + errorCode = pre_sync(TRANSPORT_TYPE, account_id, session_id, server_flag, (void **)&pre_sync_return_obj); + } else + errorCode = pre_sync(TRANSPORT_TYPE, account_id, NULL, server_flag, (void **)&pre_sync_return_obj); + + /* check cancel flag */ + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + err = SE_INTERNAL_CANCEL; + _DEBUG_INFO("cancle flag is on"); + goto cancel_part; + } + + _DEBUG_INFO("pre_sync errorCode =[%d]", errorCode); + if (errorCode != COMMON_OK) { + err = SE_INTERNAL_SA_ERROR; + goto fail_part; + } + + /*execute pre_sync return */ + server_sync_type = client_sync_type; + err = _execute_pre_sync(account_id, session_time, pre_sync_return_obj, &server_sync_type); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __process_pre_sync = %d", err); + goto fail_part; + } + + if (server_sync_type == ALERT_REFRESH_FROM_CLIENT || server_sync_type == ALERT_ONE_WAY_FROM_CLIENT) + only_from_client = 1; + + _DEBUG_INFO("client_sync_type = %d", client_sync_type); + _DEBUG_INFO("server_sync_type = %d", server_sync_type); + _DEBUG_INFO("only_from_client = %d", only_from_client); + + _session_process(account_id, server_sync_type, PROGRESS_AUTHENTICATED, ERROR_NONE); + + /* check cancel flag */ + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + err = SE_INTERNAL_CANCEL; + _DEBUG_INFO("cancle flag is on"); + goto cancel_part; + } + + err = _open_services(); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __prepare_pre_sync = %d", err); + goto fail_part; + } + + /* pkg 3 */ + _DEBUG_INFO("pre_sync end pkg3 start"); + sync_obj = (sync_obj_s *) calloc(1, sizeof(sync_obj_s)); + if (sync_obj == NULL) { + _DEBUG_ERROR("failed to alloc memory"); + err = SE_INTERNAL_NO_MEMORY; + goto fail_part; + } + + sync_return_obj = (sync_return_obj_s *) calloc(1, sizeof(sync_return_obj_s)); + if (sync_return_obj == NULL) { + _DEBUG_ERROR("failed to alloc memory"); + err = SE_INTERNAL_NO_MEMORY; + goto fail_part; + } + + err = _assemble_changed_datastores(account_id, server_sync_type, &sync_obj); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __assemble_changeddatastore = %d", err); + goto fail_part; + } + + /* check cancel flag */ + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + err = SE_INTERNAL_CANCEL; + _DEBUG_INFO("cancle flag is on"); + goto cancel_part; + } + + int isFinish = 0; + while (!isFinish) { + + errorCode = generate_msg((void **)&sync_obj, server_flag, &msg, &msg_size); + if (errorCode != COMMON_OK) { + _DEBUG_ERROR("Failed in generate_Msg = %d", errorCode); + err = SE_INTERNAL_SA_ERROR; + goto fail_part; + } + + errorCode = exchange_msg(TRANSPORT_TYPE, msg, msg_size, &recvMsg, &recvMsg_size); + if (errorCode != COMMON_OK) { + _DEBUG_ERROR("Failed in exchange_Msg = %d", errorCode); + if (errorCode == COMMON_CANCEL) { + bool cancel_status = check_cancel_status(); + if (cancel_status) { + err = SE_INTERNAL_SUSPEND; + _DEBUG_INFO("cancle flag is on"); + goto suspend_part; + } + } else { + err = SE_INTERNAL_SA_ERROR; + goto fail_part; + } + } + + /* check cancel flag */ + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + bool cancel_status = check_cancel_status(); + if (cancel_status) { + err = SE_INTERNAL_SUSPEND; + _DEBUG_INFO("cancle flag is on"); + goto suspend_part; + } + } + + errorCode = process_recv_msg(recvMsg, recvMsg_size, only_from_client, (void **)&sync_return_obj, &isFinish); + if (errorCode != COMMON_OK) { + _DEBUG_ERROR("Failed in processRecv_Msg = %d", errorCode); + err = SE_INTERNAL_SA_ERROR; + goto fail_part; + } + + err = _execute_sync(account_id, client_sync_type, server_sync_type, &sync_obj, &sync_return_obj); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __execute_sync = %d", err); + goto fail_part; + } + + free_changed_datastores(sync_return_obj->changed_datastore); + sync_return_obj->changed_datastore = NULL; + + free_applied_statuses(sync_return_obj->status); + sync_return_obj->status = NULL; + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recvMsg != NULL) { + free(recvMsg); + recvMsg = NULL; + } + } + + err = _update_sync_result(account_id); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in __update_anchor = %d", err); + goto fail_part; + } + + _write_sync_data(account_id, client_sync_type, SYNC_SESSION_SUCCEEDED, session_time, only_from_client); + + goto return_part; + + suspend_part: + + errorCode = suspend_sync(TRANSPORT_TYPE, account_id, server_flag); + if (errorCode != COMMON_OK) { + _DEBUG_ERROR("Failed in suspend_sync = %d", errorCode); + err = SE_INTERNAL_SA_ERROR; + if (errorCode == COMMON_SUSPEND_FAIL) + _off_resume_flag(account_id); + + goto fail_part; + } + + cancel_part: + + /*clean up for SA unusual end sync process case */ + clean_up_sa(); + + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (datastoreinfo_per_content_type[content_type]->client_sync_type) { + if (datastoreinfo_per_content_type[content_type]->client_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->client_sync_result->session_result = SYNC_SESSION_STOPPED; + + if (datastoreinfo_per_content_type[content_type]->server_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->server_sync_result->session_result = SYNC_SESSION_STOPPED; + + } + } + } + + _write_sync_data(account_id, client_sync_type, SYNC_SESSION_STOPPED, session_time, only_from_client); + + goto return_part; + + fail_part: + + /*clean up for SA unusual end sync process case */ + clean_up_sa(); + + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + if (datastoreinfo_per_content_type[content_type]->client_sync_type) { + if (datastoreinfo_per_content_type[content_type]->client_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->client_sync_result->session_result = SYNC_SESSION_FAILED; + + if (datastoreinfo_per_content_type[content_type]->server_sync_result != NULL) + datastoreinfo_per_content_type[content_type]->server_sync_result->session_result = SYNC_SESSION_FAILED; + } + } + } + + _write_sync_data(account_id, client_sync_type, SYNC_SESSION_FAILED, session_time, only_from_client); + + return_part: + + if (err == SE_INTERNAL_SA_ERROR) + convert_common_errorcode(errorCode, &process, &error); + else + convert_engine_errorcode(err, &process, &error); + + /* off when session finish normal or cancel case(not suspend) */ + if (err != SE_INTERNAL_SUSPEND) + _off_resume_flag(account_id); + + _off_synchronising_account(account_id); + + _session_process(account_id, server_sync_type, process, error); + _DEBUG_INFO("server_sync_type = %d", server_sync_type); + _DEBUG_INFO("process = %d", process); + _DEBUG_INFO("error = %d", error); + + sync_agent_close_agent(); + _close_services(); + + dci_result = sync_agent_execute_dev_function(DEFINE_PLATFORM, "pm_unlock", 2, LCD_OFF, RESET_TIMER); + if (dci_result != SYNC_AGENT_DEV_RETURN_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_execute_dev_function unlock"); + } + + sync_agent_free_fw_account(fw_account); + + if (access_name != NULL) { + free(access_name); + access_name = NULL; + } + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recvMsg != NULL) { + free(recvMsg); + recvMsg = NULL; + } + + if (pre_sync_return_obj != NULL) { + free_pre_sync_return_obj(pre_sync_return_obj); + pre_sync_return_obj = NULL; + } + + if (sync_obj != NULL) { + free_sync_obj(sync_obj); + sync_obj = NULL; + } + + if (sync_return_obj != NULL) { + free_sync_return_obj(sync_return_obj); + sync_return_obj = NULL; + } + + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + free_datastore(datastoreinfo_per_content_type[content_type]); + datastoreinfo_per_content_type[content_type] = NULL; + } + } + + /*FIXME*/ dt = myclock() - t; + _DEBUG_ERROR("\n=============TOTAL---- % d . % d sec\n", dt / 1000, dt % 1000); + + _EXTERN_FUNC_EXIT; + if (err != SE_INTERNAL_OK) + return false; + else + return true; +} + +void convert_common_errorcode(common_error_type_e errorCode, sync_progress_e * process, sync_error_e * error) +{ + _EXTERN_FUNC_ENTER; + + switch (errorCode) { + case COMMON_CANCEL: + case COMMON_SUSPEND_FAIL: + case COMMON_OK: /*ERROR_INTERNAL_OK */ + { + /* Do nothing : Error None + * pre_sync : PROGRESS_AUTHENTICATED + * sync end : PROGRESS_DONE + process = PROGRESS_AUTHENTICATED; + process = PROGRESS_DONE; + */ + *process = PROGRESS_DONE; + *error = ERROR_NONE; + } + break; + case COMMON_MISCONFIGURATION: /*ERROR_INTERNAL_MISCONFIGURATION : need configure infomation (account_id, id, pw, server_url...) */ + { + *process = PROGRESS_ERROR; + *error = ERROR_SYNCHDR; + } + break; + case COMMON_AUTHENTICATION_ERROR: /*ERROR_AUTH_REQUIRED, ERROR_AUTH_REJECTED */ + { + *process = PROGRESS_ERROR; + *error = ERROR_AUTHENTICATE; + } + break; + case COMMON_NOT_FOUND: /*ERROR_NOT_FOUND (ERROR_INTERNAL ??) */ + { + *process = PROGRESS_ERROR; + *error = ERROR_SYNCHDR; + } + break; + case COMMON_NO_MEMORY: /*ERROR_INTERNAL_NO_MEMORY */ + { + *process = PROGRESS_ERROR; + *error = ERROR_MEMORY_FULL; + } + break; + case COMMON_INTERNAL_ERROR: /*ERROR_INTERNAL_NOT_DEFINED || ERROR_INTERNAL_BINDER_ERROR */ + { + *process = PROGRESS_ERROR; + *error = ERROR_INTERNAL; + } + break; + case COMMON_SERVER_ERROR: /*ERROR_GENERIC || ERROR_SERVER_FAILURE */ + { + *process = PROGRESS_ERROR; + *error = ERROR_SERVER; + } + break; + case COMMON_CONNECTION_ERROR: /*ERROR_INTERNAL_CONNECTION_ERROR */ + { + *process = PROGRESS_ERROR; + *error = ERROR_CONNECTION; + } + break; + case COMMON_AUTOCONFIG_NOT_SUPPORT_BY_SERVER: /*ERROR_INTERNAL_AUTOCONFIG_NOT_SUPPORT_BY_SERVER */ + { + *process = PROGRESS_ERROR; + *error = ERROR_AUTOCONFIG_NOT_SUPPORT_BY_SERVER; + } + break; + default: + { + *process = PROGRESS_ERROR; + *error = ERROR_INTERNAL; /*?? unknown error */ + } + break; + } + + _EXTERN_FUNC_EXIT; +} + +void convert_engine_errorcode(se_error_type_e err, sync_progress_e * process, sync_error_e * error) +{ + _EXTERN_FUNC_ENTER; + + switch (err) { + case SE_INTERNAL_SUSPEND: + case SE_INTERNAL_CANCEL: + case SE_INTERNAL_OK: + *process = PROGRESS_DONE; + *error = ERROR_NONE; + break; + case ERROR_UNKNOWN: + case SE_INTERNAL_SA_ERROR: + case SE_INTERNAL_SCHEDULER_ERROR: + case SE_INTERNAL_ENGINE_CONTROLER_ERROR: + case SE_INTERNAL_EVENT_ERROR: + case SE_INTERNAL_NOT_DEFINED: + case SE_INTERNAL_ERROR: + *process = PROGRESS_ERROR; + *error = ERROR_INTERNAL; + break; + case SE_INTERNAL_NO_MEMORY: + *process = PROGRESS_ERROR; + *error = ERROR_MEMORY_FULL; + break; + case SE_INTERNAL_DA_ERROR: + *process = PROGRESS_ERROR; + *error = ERROR_DB; + break; + case SE_INTERNAL_MISCONFIGURATION: + *process = PROGRESS_ERROR; + *error = ERROR_SYNCHDR; + break; + case SE_INTERNAL_LOW_BATTERY: + *process = PROGRESS_ERROR; + *error = ERROR_LOW_BATTERY; + break; + } + + _EXTERN_FUNC_EXIT; +} + +se_error_type_e session_process(char *profileDirName, alert_type_e server_sync_type, sync_progress_e process, sync_error_e error) +{ + _EXTERN_FUNC_ENTER; + + _DEBUG_INFO("profileDirName = %s", profileDirName); + _DEBUG_INFO("process = %d", process); + _DEBUG_INFO("error = %d", error); + + se_error_type_e err = SE_INTERNAL_OK; + + char *sync_type = NULL; + char *syncProcess = NULL; + char *syncError = NULL; + + sync_type = __convert_sync_type_str(server_sync_type); + + syncProcess = _convert_sync_progress_str(process); + + syncError = _convert_sync_error_str(error); + + if (sync_type == NULL || syncProcess == NULL || syncError == NULL) { + err = SE_INTERNAL_NOT_DEFINED; + goto error; + } + + err = send_noti_session_process(profileDirName, sync_type, syncProcess, syncError); + if (err != SE_INTERNAL_OK) { + _DEBUG_ERROR("failed in send_noti_session_process"); + goto error; + } + + _EXTERN_FUNC_EXIT; + + error: + + return err; +} + +se_error_type_e reset_synchronizing_profiles() +{ + _EXTERN_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + sync_agent_acc_error_e acc_err = SYNC_AGENT_ACC_SUCCESS; + sync_agent_fw_account_s *fw_account = NULL; + GList *account_info_list = NULL; + GList *iter = NULL; + + sync_agent_da_return_e da_err = sync_agent_open_agent(); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_open_agent"); + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + sync_agent_fw_account_query_s query; + query.query = ACCOUNT_QUERY_BY_NONE; + + acc_err = sync_agent_query_fw_account(&query, &account_info_list); + if (acc_err != SYNC_AGENT_ACC_SUCCESS) { + _DEBUG_ERROR("sync_agent_query_fw_account is failed"); + goto error; + } + + for (iter = account_info_list; iter != NULL; iter = g_list_next(iter)) { + fw_account = (sync_agent_fw_account_s *) iter->data; + + _DEBUG_INFO("account = %d", fw_account->account_id); + _off_synchronising_account(fw_account->account_id); + + _DEBUG_INFO("construct_itemTbl From service start"); + + int content_type; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT - 1; content_type++) { + + da_err = sync_agent_open_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_open_service(%d) is failed ", content_type); + continue; + } + + _DEBUG_INFO("sync_agent_construct_item_tbl_from_service(%d, %d);", fw_account->account_id, content_type); + sync_agent_construct_item_tbl_from_service(fw_account->account_id, content_type); + + da_err = sync_agent_close_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_close_service(%d) is failed ", content_type); + continue; + } + } + + _DEBUG_INFO("construct_itemTbl From service end"); + } + + error: + + sync_agent_close_agent(); + + sync_agent_free_fw_account_list(account_info_list); + + _EXTERN_FUNC_EXIT; + + return err; +} + +bool refresh_from_service_all(int account_id) +{ + _EXTERN_FUNC_ENTER; + + se_error_type_e err = SE_INTERNAL_OK; + + sync_agent_da_return_e da_err = sync_agent_open_agent(); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + err = SE_INTERNAL_DA_ERROR; + goto error; + } + + int content_type; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT - 1; content_type++) { + + da_err = sync_agent_open_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_open_service(%d) is failed ", content_type); + continue; + } + + _DEBUG_INFO("sync_agent_refresh_item_tbl_from_service(%d, %d);", account_id, content_type); + sync_agent_refresh_item_tbl_from_service(account_id, content_type); + + da_err = sync_agent_close_service(content_type); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_close_service(%d) is failed ", content_type); + continue; + } + } + + error: + + sync_agent_close_agent(); + + _EXTERN_FUNC_EXIT; + + if (err != SE_INTERNAL_OK) + return false; + else + return true; +} + +se_error_type_e cancel_sync_request() +{ + _EXTERN_FUNC_ENTER; + se_error_type_e err = SE_INTERNAL_OK; + + cancel_connection_sync_request(TRANSPORT_TYPE); + + _EXTERN_FUNC_EXIT; + + return err; +} |