diff options
Diffstat (limited to 'src/agent/service-adapter/sa_common_interface.c')
-rwxr-xr-x | src/agent/service-adapter/sa_common_interface.c | 2812 |
1 files changed, 2812 insertions, 0 deletions
diff --git a/src/agent/service-adapter/sa_common_interface.c b/src/agent/service-adapter/sa_common_interface.c new file mode 100755 index 0000000..614aded --- /dev/null +++ b/src/agent/service-adapter/sa_common_interface.c @@ -0,0 +1,2812 @@ +/* + * 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. + */ + +/** + * @SA_Common_Interface.c + * @version 0.1 + * @brief This file is the source file of implementation of interface of Service Adapter + */ + +#include <sync_agent.h> + +#include "common/common_vconf.h" +#include "common/common_define.h" +#include "common/common_util.h" +#include "service-adapter/protocol-binder/oma_ds_protocol_binder.h" +#include "service-adapter/network-binder/na_binder.h" +#include "service-adapter/sa_define.h" +#include "service-adapter/sa_common_interface.h" +#include "service-adapter/sa_elements.h" +#include "service-adapter/sa_elements_internal.h" +#include "service-adapter/sa_command.h" +#include "service-adapter/sa_command_internal.h" +#include "service-adapter/sa_session.h" +#include "service-adapter/sa_session_internal.h" +#include "service-adapter/sa_devinf_internal.h" +#include "service-adapter/sa_util.h" +#include "service-adapter/sa_devinf.h" + +#ifndef OMADS_AGENT_LOG +#undef LOG_TAG +#define LOG_TAG "OMA_DS_SA" +#endif + +session_s *static_session = NULL; + +static sa_error_type_e _create_session(int account_id, char *session_id, bool server_flag, session_s ** session); +static sa_error_type_e _generate_presync_msg(session_s * session, bool server_flag, char **msg, unsigned int *msg_size); +static sa_error_type_e _generate_msg(session_s * session, void **sync_obj, bool server_flag, char **msg, unsigned int *msg_size); +static sa_error_type_e _generate_autoconfigure_msg(char *id, char *pwd, char *target_url, char **msg, unsigned int *msg_size, session_s * session); +static sa_error_type_e _generate_suspend_msg(session_s * session, bool server_flag, char **msg, unsigned int *msg_size); +static sa_error_type_e _exchange_msg(session_s * session, char *acc_type, int transport_type, char *send_msg, unsigned int send_msg_length, char **recv_msg, unsigned int *recv_msg_length); + +static sa_error_type_e _process_recv_msg(session_s * session, char *recv_msg, unsigned int recv_msg_length, int only_from_client, void **sync_return_obj, int *is_finish); +static sa_error_type_e _process_autoconfigure_recv_msg(char *recv_msg, unsigned int recv_msg_length, session_s * session); +static common_error_type_e _convert_error_type(sa_error_type_e error_type); + +static sa_error_type_e __get_account_info(int account_id, char **id, char **pwd, char **server_url, char **next_nonce); +static sa_error_type_e __object_binder(syncml_s * syncml, bool server_flag, char **msg, unsigned int *msg_size); +static sa_error_type_e __reverse_object_binder(syncml_s ** syncml, char *recv_msg, unsigned int recv_msg_length); +static sa_error_type_e __generate_msg_status_map_command(session_s ** session, sync_obj_s ** sync, GList ** commands, GList ** commands_last); +static sa_error_type_e __generate_msg_exist_sending_map_command(sync_agent_pb_protocol_binder_info_s * binder, session_s ** session, GList ** commands, GList ** commands_last); +static sa_error_type_e __generate_msg_changes_command(sync_agent_pb_protocol_binder_info_s * binder, session_s ** session, sync_obj_s ** sync, GList ** commands, GList ** commands_last, bool * is_need_next_msg); +static void __clean_up_sa(session_s * session); +static sa_error_type_e __process_jssion_id(session_s * session, GList * recv_header); +static sa_error_type_e __check_resume_session(session_s * session, bool * resume); + +static sa_error_type_e __get_account_info(int account_id, char **id, char **pwd, char **server_url, char **next_nonce) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + GList *config_list = NULL; + GList *iter = NULL; + sync_agent_da_config_s *config_data = NULL; + + sync_agent_acc_error_e acc_err = SYNC_AGENT_ACC_SUCCESS; + sync_agent_fw_account_s *fw_account = NULL; + + if (!account_id) { + errorType = SA_INTERNAL_MISCONFIGURATION; + goto error; + } + + 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"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + 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"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + if (fw_account->email != NULL) + *id = strdup(fw_account->email); + + if (fw_account->password != NULL) + *pwd = strdup(fw_account->password); + + da_err = sync_agent_get_config_list(account_id, &config_list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + errorType = SA_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, DEFINE_CONFIG_KEY_PROFILE_SERVER_IP) == 0) { + if (config_data->value != NULL) + *server_url = strdup(config_data->value); + } + + if (strcmp(config_data->key, DEFINE_CONFIG_KEY_PROFILE_NEXT_NONCE) == 0) { + if (config_data->value != NULL) + *next_nonce = strdup(config_data->value); + } + } + } + } + + error: + + sync_agent_free_fw_account(fw_account); + + sync_agent_free_config_list(config_list); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _create_session(int account_id, char *session_id, bool server_flag, session_s ** session) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + char *id = NULL; + char *pwd = NULL; + char *targetUrl = NULL; + char *sourceUrl = NULL; + char *sourceName = NULL; + char *nextNonce = NULL; + chal_s *pTempChal = NULL; + unsigned int sessionID = 0; + + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + + if ((*session) != NULL) { + if ((*session)->chal != NULL) { + pTempChal = (*session)->chal; + (*session)->chal = NULL; + } + + if ((*session)->has_opend) + sessionID = (*session)->naci_session_id; + + free_session(*session); + *session = NULL; + } + + sync_agent_dev_return_e err = sync_agent_get_devinfo(DEFINE_PLATFORM, "DevID", &sourceUrl); + if (err != SYNC_AGENT_DEV_RETURN_SUCCESS) { + _DEBUG_ERROR("failed to get devinfo"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + errorType = __get_account_info(account_id, &id, &pwd, &targetUrl, &nextNonce); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("faied in __get_accountinfo"); + goto error; + } + + if (server_flag == true) { + sourceName = id; + } + + errorType = create_location(sourceUrl, sourceName, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_location"); + goto error; + } + + errorType = create_location(targetUrl, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_location"); + goto error; + } + + /* create session info */ + errorType = create_session(VERSION_12, PROTOCOL_TYPE_DS, account_id, session_id, pSourceLocation, pTargetLocation, session); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create session"); + goto error; + } + + if (pTempChal != NULL) { + (*session)->chal = pTempChal; + pTempChal = NULL; + } + + (*session)->naci_session_id = sessionID; + + error: + + if (id != NULL) + free(id); + if (pwd != NULL) + free(pwd); + if (targetUrl != NULL) + free(targetUrl); + if (sourceUrl != NULL) + free(sourceUrl); + if (nextNonce != NULL) + free(nextNonce); + if (pTempChal != NULL) + free_chal(pTempChal); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _generate_presync_msg(session_s * session, bool server_flag, char **msg, unsigned int *msg_size) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + char *id = NULL; + char *pwd = NULL; + char *targetUrl = NULL; + char *nextNonce = NULL; + char *credData = NULL; + char *decoded_nonce = NULL; + bool resume = false; + char *value = NULL; + alert_type_e alert_type = ALERT_UNKNOWN; + + /*pkg1 always has final tag */ + int isFinal = 1; + + sync_hdr_s *pSyncHdr = NULL; + cred_s *pCred = NULL; + devinf_s *devInfObj = NULL; + syncml_s *syncml = NULL; + + /*case SAN, MUST use sessionid from SAN message.. */ + if (session->session_id == NULL) { + session->session_id = g_strdup_printf("%ld", time(NULL)); + if (session->session_id == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + } + + errorType = __get_account_info(session->account_id, &id, &pwd, &targetUrl, &nextNonce); + if (errorType != SA_INTERNAL_OK) + goto error; + + _DEBUG_TRACE("id = %s", id); + _DEBUG_TRACE("pwd = %s", pwd); + _DEBUG_TRACE("sessionId = %s", session->session_id); + _DEBUG_TRACE("serverUrl = %s", targetUrl); + + /* set pkg status */ + session->pkg_status = SYNCML_PKG_1; + + chal_s *chal = session->chal; + auth_type_e authType; + format_type_e formatType = FORMAT_TYPE_UNKNOWN; + unsigned int nonce_size = 0; + if (chal == NULL) { + _DEBUG_TRACE("CHAL DOES NOT EXIST"); + if (nextNonce != NULL) { + /*server sent nonce info in previous sync session */ + authType = AUTH_TYPE_MD5; + decoded_nonce = (char *)g_base64_decode(nextNonce, &nonce_size); + formatType = FORMAT_TYPE_BASE64; + } else { + authType = AUTH_TYPE_BASIC; + formatType = FORMAT_TYPE_BASE64; + } + + errorType = create_cred_string(authType, id, pwd, decoded_nonce, nonce_size, &credData); + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred string"); + goto error; + } + + errorType = create_cred(id, pwd, authType, formatType, credData, &pCred); + } else { + _DEBUG_TRACE("CHAL DOES EXIST"); + if (chal->type == AUTH_TYPE_MD5) { + if (chal->format == FORMAT_TYPE_BASE64) + decoded_nonce = (char *)g_base64_decode(chal->nonce_b64, &nonce_size); + else { + if (chal->nonce_plain != NULL) { + decoded_nonce = strdup(chal->nonce_plain); + nonce_size = chal->nonce_length; + } + } + } + + errorType = create_cred_string(chal->type, id, pwd, decoded_nonce, nonce_size, &credData); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred string"); + goto error; + } + + errorType = create_cred(id, pwd, chal->type, FORMAT_TYPE_BASE64, credData, &pCred); + } + + if (credData != NULL) { + free(credData); + credData = NULL; + } + + if (decoded_nonce != NULL) { + free(decoded_nonce); + decoded_nonce = NULL; + } + + if (nextNonce != NULL) { + free(nextNonce); + nextNonce = NULL; + } + nonce_size = 0; + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred"); + goto error; + } + + set_session_cred(session, pCred); + pCred = NULL; + + /* create SyncHdr */ + errorType = create_sync_hdr(session, &pSyncHdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create synchdr"); + goto error; + } + + /* create devInf */ + errorType = create_devinf(session, &devInfObj); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create devInf"); + goto error; + } + + set_session_devinf(session, devInfObj); + + errorType = __check_resume_session(session, &resume); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __check_resume_session"); + goto error; + } + + GList *commands = NULL; + GList *commands_last = NULL; + + char *sourceDevInf = NULL; + char *contentType = NULL; + + if (session->protocol_version == VERSION_10) + sourceDevInf = ELEMENT_DEVINF_10; + else if (session->protocol_version == VERSION_11) + sourceDevInf = ELEMENT_DEVINF_11; + else if (session->protocol_version == VERSION_12) + sourceDevInf = ELEMENT_DEVINF_12; + + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + contentType = ELEMENT_DEVINF_XML; + else + contentType = ELEMENT_DEVINF_WBXML; + + if (resume != true) { + if (server_flag != true) { + /* create Put command */ + command_s *pPutCommand = NULL; + location_s *pLocation = NULL; + + errorType = create_location(sourceDevInf, NULL, &pLocation); + if (errorType != SA_INTERNAL_OK) + goto error; + + errorType = create_put_command(session, pLocation, contentType, devInfObj, &pPutCommand); + if (errorType != SA_INTERNAL_OK) + goto error; + put_into_list(&commands, &commands_last, pPutCommand); + } + } + + /* if it is not dive server */ + if (server_flag != true) { + /* create Get command */ + command_s *pGetCommand = NULL; + location_s *location = NULL; + errorType = create_location(sourceDevInf, NULL, &location); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_get_command(session, location, contentType, &pGetCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create get command"); + goto error; + } + put_into_list(&commands, &commands_last, pGetCommand); + } + + command_s *pAlertCommand = NULL; + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + 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) { + errorType = create_location(datastoreinfo_per_content_type[content_type]->source, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + + /* change errorType because locURI is required so need to return SA_INTERNAL_MISCONFIGURATION error + when SA_INTERNAL_NOT_DEFINED error case */ + if (errorType == SA_INTERNAL_NOT_DEFINED) + errorType = SA_INTERNAL_MISCONFIGURATION; + + goto error; + } + + errorType = create_location(datastoreinfo_per_content_type[content_type]->target, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + + /* change errorType because locURI is required so need to return SA_INTERNAL_MISCONFIGURATION error + when SA_INTERNAL_NOT_DEFINED error case */ + if (errorType == SA_INTERNAL_NOT_DEFINED) + errorType = SA_INTERNAL_MISCONFIGURATION; + goto error; + } + + _DEBUG_TRACE("datastoreinfo_per_content_type[%d]->id = %d", content_type, datastoreinfo_per_content_type[content_type]->id); + _DEBUG_TRACE("datastoreinfo_per_content_type[%d]->pw = %d", content_type, datastoreinfo_per_content_type[content_type]->pw); + + if (datastoreinfo_per_content_type[content_type]->id != NULL && datastoreinfo_per_content_type[content_type]->pw != NULL) { + + /*FIXME is there a nextNonce for datastore ?? */ + if (nextNonce != NULL) { + /*server sent nonce info in previous sync session */ + authType = AUTH_TYPE_MD5; + decoded_nonce = (char *)g_base64_decode(nextNonce, &nonce_size); + } else { + authType = AUTH_TYPE_BASIC; + formatType = FORMAT_TYPE_BASE64; + } + + errorType = create_cred_string(authType, datastoreinfo_per_content_type[content_type]->id, datastoreinfo_per_content_type[content_type]->pw, decoded_nonce, nonce_size, &credData); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred string"); + goto error; + } + + errorType = create_cred(id, pwd, authType, FORMAT_TYPE_BASE64, credData, &pCred); + + if (credData != NULL) { + free(credData); + credData = NULL; + } + } + + if (resume == true) + alert_type = ALERT_RESUME; + else + alert_type = datastoreinfo_per_content_type[content_type]->client_sync_type; + + errorType = create_alert_command(session, alert_type, + pSourceLocation, pTargetLocation, datastoreinfo_per_content_type[content_type]->last_anchor_client, datastoreinfo_per_content_type[content_type]->next_anchor_client, pCred, &pAlertCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create alert command"); + goto error; + } + } else + continue; + put_into_list(&commands, &commands_last, pAlertCommand); + } + } + + errorType = create_syncml(pSyncHdr, NULL, commands, isFinal, &syncml); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create syncml"); + goto error; + } + + session->is_sending_final = isFinal; + if (isFinal) + session->pkg_status = SYNCML_PKG_2; + + /* convert Msg */ + errorType = __object_binder(syncml, server_flag, msg, msg_size); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in objectBinder"); + goto error; + } + + /*free generate structure */ + free_syncml(syncml); + + if (id != NULL) + free(id); + if (pwd != NULL) + free(pwd); + if (targetUrl != NULL) + free(targetUrl); + if (nextNonce != NULL) + free(nextNonce); + if (value != NULL) + free(value); + if (pCred != NULL) + free_cred(pCred); + + _INNER_FUNC_EXIT; + return errorType; + + error: + + if (credData != NULL) + free(credData); + + if (id != NULL) + free(id); + if (pwd != NULL) + free(pwd); + if (targetUrl != NULL) + free(targetUrl); + if (nextNonce != NULL) + free(nextNonce); + if (value != NULL) + free(value); + if (syncml != NULL) + free_syncml(syncml); + if (pSyncHdr != NULL) + free_sync_hdr(pSyncHdr); + if (pCred != NULL) + free_cred(pCred); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _generate_msg(session_s * session, void **sync_obj, bool server_flag, char **msg, unsigned int *msg_size) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + bool isNeedNextMsg = false; + + sync_agent_pb_protocol_binder_function_set_s *binder_function_set = NULL; + sync_agent_pb_protocol_binder_info_s *binder = NULL; + + sync_agent_pb_error_e err = init_oma_ds_1_2_binder_function_set(&binder_function_set); + + if (server_flag != true) + binder = oma_ds_1_2_binder_init(binder, COMMUNICATION_TYPE, false, false, false, true, false, binder_function_set); + else + binder = oma_ds_1_2_binder_init(binder, COMMUNICATION_TYPE, false, true, false, true, true, binder_function_set); + + /* create SyncHdr */ + sync_hdr_s *pSyncHdr = NULL; + errorType = create_sync_hdr(session, &pSyncHdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create synchdr"); + goto error; + } + + err = oma_ds_1_2_binder_append(binder, PE_SYNCML_START, NULL); + err = oma_ds_1_2_binder_append(binder, PE_HEADER, pSyncHdr); + err = oma_ds_1_2_binder_append(binder, PE_BODY_START, NULL); + + sync_obj_s **sync = (sync_obj_s **) sync_obj; + GList *commands = NULL; + GList *commands_last = NULL; + int isFinal = 0; + + errorType = __generate_msg_status_map_command(&session, sync, &commands, &commands_last); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __generate_msg_status_map_command"); + goto error; + } + + /*append status command */ + GList *status_iter = NULL; + status_s *pStatus = NULL; + for (status_iter = session->status; status_iter != NULL; status_iter = g_list_next(status_iter)) { + pStatus = (status_s *) status_iter->data; + err = oma_ds_1_2_binder_append(binder, PE_STATUS, pStatus); + } + + /*append results command */ + GList *results_iter = NULL; + command_s *pResultsCommand = NULL; + for (results_iter = session->results_command; results_iter != NULL; results_iter = g_list_next(results_iter)) { + pResultsCommand = (command_s *) results_iter->data; + put_into_list(&commands, &commands_last, pResultsCommand); + err = oma_ds_1_2_binder_append(binder, PE_RESULTS_START, pResultsCommand); + + if (pResultsCommand->type == COMMAND_TYPE_RESULTS) { + if (pResultsCommand->private.results.item != NULL) { + if (pResultsCommand->private.results.item->data_type == ITEM_DEVINF) { + err = oma_ds_1_2_binder_append(binder, PE_DEVINF, pResultsCommand->private.results.item); + } + } + + err = oma_ds_1_2_binder_append(binder, PE_RESULTS_END, NULL); + } + } + + /*append map command */ + GList *map_iter = NULL; + command_s *pMapCommand = NULL; + for (map_iter = session->map_command; map_iter != NULL; map_iter = g_list_next(map_iter)) { + pMapCommand = (command_s *) map_iter->data; + err = oma_ds_1_2_binder_append(binder, PE_MAP, pMapCommand); + } + + /* free sendgStatus structure from SE */ + free_sending_statuses((*sync)->sending_status); + (*sync)->sending_status = NULL; + + if (session->pkg_status == SYNCML_PKG_3) { + + errorType = __generate_msg_exist_sending_map_command(binder, &session, &commands, &commands_last); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __generate_msg_status_map_command"); + goto error; + } + + errorType = __generate_msg_changes_command(binder, &session, sync, &commands, &commands_last, &isNeedNextMsg); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __generate_msg_status_map_command"); + goto error; + } + + if (!isNeedNextMsg) + isFinal = 1; + } + + if (session->pkg_status == SYNCML_PKG_5 && session->is_receiving_final) + isFinal = 1; + + /*if we have to send alert command(222,223 etc) */ + GList *alert_iter = NULL; + command_s *pAlertCommand = NULL; + for (alert_iter = session->alert_command; alert_iter != NULL; alert_iter = g_list_next(alert_iter)) { + pAlertCommand = alert_iter->data; + put_into_list(&commands, &commands_last, pAlertCommand); + err = oma_ds_1_2_binder_append(binder, PE_ALERT, pAlertCommand); + } + + if (isFinal) + err = oma_ds_1_2_binder_append(binder, PE_FINAL, NULL); + + session->is_sending_final = isFinal; + + err = oma_ds_1_2_binder_append(binder, PE_BODY_END, NULL); + err = oma_ds_1_2_binder_append(binder, PE_SYNCML_END, NULL); + + oma_ds_1_2_binder_get_stream(binder, msg, msg_size); + _DEBUG_TRACE("final msg size = %d", *msg_size); + + /*FIXME for debugging */ + char *xml = NULL; + unsigned int xml_len = 0; + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + set_xml_to_file(*msg, OMA_DS_MSG_PATH); + else { + err = sync_agent_get_xml_from_protocol_binder(binder, &xml, &xml_len); + if (err == SYNC_AGENT_PB_RETURN_OK) { + set_xml_to_file(xml, OMA_DS_MSG_PATH); + + if (xml != NULL) { + free(xml); + xml = NULL; + } + } + } + + oma_ds_1_2_binder_terminate(binder); + + if (session->pkg_status == SYNCML_PKG_3 && session->is_sending_final) + session->pkg_status = SYNCML_PKG_4; + else if (session->pkg_status == SYNCML_PKG_5 && session->is_sending_final) + session->pkg_status = SYNCML_PKG_6; + + free_sync_hdr(pSyncHdr); + if (session->status != NULL) { + if (session->suspend_status != NULL) { + free_statuses(session->suspend_status); + session->suspend_status = NULL; + } + session->suspend_status = static_session->status; + session->status = NULL; + } + free_commands(commands); + + session->alert_command = NULL; + session->results_command = NULL; + + _INNER_FUNC_EXIT; + return errorType; + + error: + + free_sync_hdr(pSyncHdr); + if (session->status != NULL) { + free_statuses(session->status); + session->status = NULL; + } + free_commands(commands); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e __generate_msg_status_map_command(session_s ** session, sync_obj_s ** sync, GList ** commands, GList ** commands_last) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + + GList *iter = NULL; + sending_status_s *sendingStatus = NULL; + /* send status of sync, add, replace, delete command */ + for (iter = (*sync)->sending_status; iter != NULL; iter = g_list_next(iter)) { + sendingStatus = (iter->data); + + int needMap = 0; + GList *sendingIter = NULL; + applied_status_s *appliedStatus = NULL; + for (sendingIter = sendingStatus->items; sendingIter != NULL; sendingIter = g_list_next(sendingIter)) { + appliedStatus = (sendingIter->data); + + /* set data in status of add, replace, delete command */ + GList *statusIter = NULL; + status_s *status = NULL; + for (statusIter = (*session)->temp_status; statusIter != NULL; statusIter = g_list_next(statusIter)) { + status = statusIter->data; + + if (status->type == COMMAND_TYPE_ADD || status->type == COMMAND_TYPE_REPLACE || status->type == COMMAND_TYPE_DELETE) { + + /* if there is a status for add command it have to be checked + because map command has to be generated + otherwise replace, delete command doesnot need to generate map command */ + if (status->type == COMMAND_TYPE_ADD) + needMap = 1; + + if (status->source_ref != NULL) { + /*add command */ + sync_agent_da_mapping_s *mapping = NULL; + da_err = sync_agent_create_mapping(&mapping); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_create_mapping !!"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + sync_agent_da_get_mapping_query_s query; + query.account_id = (*session)->account_id; + query.luid = appliedStatus->luid; + + da_err = sync_agent_get_mapping(&query, &mapping); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_mapping !!"); + errorType = SA_INTERNAL_DA_ERROR; + sync_agent_free_mapping(mapping); + goto error; + } + + if (mapping != NULL) { + if (mapping->guid == NULL) { + errorType = SA_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed to get guid"); + sync_agent_free_mapping(mapping); + goto error; + } + + if (strcmp(mapping->guid, get_location_loc_uri(status->source_ref)) == 0) { + if (status->data != NULL) { + free(status->data); + status->data = NULL; + } + status->data = g_strdup_printf("%d", appliedStatus->status); + /*move to status list from tempStatus */ + (*session)->status = g_list_append((*session)->status, status); + (*session)->temp_status = g_list_remove((*session)->temp_status, status); + + sync_agent_free_mapping(mapping); + + break; + } + + sync_agent_free_mapping(mapping); + + } else { + _DEBUG_ERROR("mapping is NULL !!"); + errorType = SA_INTERNAL_DA_ERROR; + sync_agent_free_mapping(mapping); + goto error; + } + } + + if (status->target_ref != NULL) { + /*replace, delete */ + if (strcmp(appliedStatus->luid, get_location_loc_uri(status->target_ref)) == 0) { + if (status->data != NULL) { + free(status->data); + status->data = NULL; + } + status->data = g_strdup_printf("%d", appliedStatus->status); + /*move to status list from tempStatus */ + (*session)->status = g_list_append((*session)->status, status); + (*session)->temp_status = g_list_remove((*session)->temp_status, status); + break; + } + } + } + } + } + + if (needMap) { + /* create map command */ + command_s *mapCommand = NULL; + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + errorType = create_location(sendingStatus->source, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_location(sendingStatus->target, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_map_command(*session, pSourceLocation, pTargetLocation, &mapCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create map command"); + goto error; + } + + GList *sendingIter = NULL; + applied_status_s *appliedStatus = NULL; + + for (sendingIter = sendingStatus->items; sendingIter != NULL; sendingIter = g_list_next(sendingIter)) { + appliedStatus = (sendingIter->data); + + if (appliedStatus->change_type == CHANGE_ADD) { + + if (appliedStatus->status == ITEM_ADDED) { + item_s *temp = create_item(); + if (temp == NULL) { + _DEBUG_ERROR("failed to create item"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + errorType = create_location(appliedStatus->luid, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + sync_agent_da_mapping_s *mapping = NULL; + da_err = sync_agent_create_mapping(&mapping); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_create_mapping !!"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + sync_agent_da_get_mapping_query_s query; + query.account_id = (*session)->account_id; + query.luid = appliedStatus->luid; + + da_err = sync_agent_get_mapping(&query, &mapping); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_mapping !!"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + if (mapping != NULL) { + if (mapping->guid == NULL) { + errorType = SA_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed to get guid"); + goto error; + } + errorType = create_location(mapping->guid, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + if (mapping->guid != NULL) { + free(mapping->guid); + mapping->guid = NULL; + } + } else { + _DEBUG_ERROR("mapping is NULL !!"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + set_item_source(temp, pSourceLocation); + set_item_target(temp, pTargetLocation); + set_map_command_item(mapCommand, temp); + } else { + sync_agent_da_delete_mapping_query_s query; + query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_LUID; + query.account_id = (*session)->account_id; + query.luid = appliedStatus->luid; + + da_err = sync_agent_delete_mapping(&query); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + errorType = SA_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed in sync_agent_delete_mapping !!"); + goto error; + } + } + } + } + put_into_list(commands, commands_last, mapCommand); + (*session)->map_command = g_list_append((*session)->map_command, mapCommand); + increase_command_ref_count(mapCommand); + } + } + + error: + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e __generate_msg_exist_sending_map_command(sync_agent_pb_protocol_binder_info_s * binder, session_s ** session, GList ** commands, GList ** commands_last) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK; + sync_agent_da_return_e ret = SYNC_AGENT_DA_ERRORS; + + /*if there is something in the mapping_tbl it have to be sent before sync command */ + int existSendingMap = sync_agent_is_exist_mapping_by_account_id((*session)->account_id); + + if (existSendingMap) { + GList *mapping_list = NULL; + sync_agent_da_get_mapping_list_query_s query; + query.option = SYNC_AGENT_DA_GET_MAPPING_LIST_OPTION_ACCOUNT_ID; + query.account_id = (*session)->account_id; + + ret = sync_agent_get_mapping_list(&query, &mapping_list); + if (ret != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_mapping_list !!"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + + bool exist = false; + int content_type; + sync_agent_da_mapping_s *mapping_data = (sync_agent_da_mapping_s *) ((GList *) (g_list_nth(mapping_list, g_list_length(mapping_list) - 1))->data); + int lastItemTypeId = mapping_data->data_store_id; + + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) { + _DEBUG_VERBOSE("datastoreinfo_per_content_type[%d]->datastore_id = %d", content_type, datastoreinfo_per_content_type[content_type]->datastore_id); + if (datastoreinfo_per_content_type[content_type]->client_sync_type) { + if (lastItemTypeId == datastoreinfo_per_content_type[content_type]->datastore_id) { + errorType = create_location(datastoreinfo_per_content_type[content_type]->source, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_location(datastoreinfo_per_content_type[content_type]->target, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + exist = true; + break; + } + } + } + } + + if (exist == false) { + _DEBUG_VERBOSE("Mapping data is not equal with any synchronizing datastore id"); + goto error; + } + + /* create map command using first item */ + command_s *mapCommand = NULL; + errorType = create_map_command(*session, pSourceLocation, pTargetLocation, &mapCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create map command"); + goto error; + } + + GList *iter = NULL; + sync_agent_da_mapping_s *iter_data; + for (iter = mapping_list; iter != NULL; iter = g_list_next(iter)) { + iter_data = NULL; + iter_data = (sync_agent_da_mapping_s *) (iter->data); + + if (lastItemTypeId != iter_data->data_store_id) { + err = oma_ds_1_2_binder_append(binder, PE_MAP, mapCommand); + put_into_list(commands, commands_last, mapCommand); + (*session)->map_command = g_list_append((*session)->map_command, mapCommand); + increase_command_ref_count(mapCommand); + + bool exist = false; + 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) { + if (lastItemTypeId == datastoreinfo_per_content_type[content_type]->datastore_id) { + errorType = create_location(datastoreinfo_per_content_type[content_type]->source, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_location(datastoreinfo_per_content_type[content_type]->target, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + exist = true; + break; + } + } + } + } + if (exist == false) { + _DEBUG_ERROR("Mapping data is not equal with any synchronizing datastore id"); + goto error; + } + } + + lastItemTypeId = iter_data->data_store_id; + item_s *temp = create_item(); + if (temp == NULL) { + _DEBUG_ERROR("failed to create item"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + errorType = create_location(iter_data->luid, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_location(iter_data->guid, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + set_item_source(temp, pSourceLocation); + set_item_target(temp, pTargetLocation); + set_map_command_item(mapCommand, temp); + } + + sync_agent_free_mapping_list(mapping_list); + + err = oma_ds_1_2_binder_append(binder, PE_MAP, mapCommand); + put_into_list(commands, commands_last, mapCommand); + (*session)->map_command = g_list_append((*session)->map_command, mapCommand); + increase_command_ref_count(mapCommand); + } + + error: + + _INNER_FUNC_EXIT; + return errorType; + +} + +static sa_error_type_e __generate_msg_changes_command(sync_agent_pb_protocol_binder_info_s * binder, session_s ** session, sync_obj_s ** sync, GList ** commands, GList ** commands_last, bool * is_need_next_msg) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_SUCCESS; + sync_agent_da_service_item_s *service_item = NULL; + sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK; + unsigned int stream_size = 0; + + char *data = NULL; /*have to be freed */ + char *sendingData = NULL; + + /* generate sync , add, replace, delete command when there is a item in ChangedDatastore */ + GList *iter = NULL; + command_s *syncCommand = NULL; + changed_datastore_s *changedDatastore = NULL; + bool needNextMsg = false; + for (iter = (*sync)->changed_datastore; iter != NULL; iter = g_list_next(iter)) { + changedDatastore = (iter->data); + + if (changedDatastore->need_sync_command) { + /* create sync Command */ + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + errorType = create_location(changedDatastore->source, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_location(changedDatastore->target, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + errorType = create_sync_start_command(*session, pSourceLocation, pTargetLocation, &syncCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create sync start command"); + goto error; + } + + /*set numberOfChanges */ + if (changedDatastore->has_number_of_changes) { + /*if it is first sync command set numberOfChanges */ + set_sync_start_command_number_of_changes(syncCommand, changedDatastore->number_of_changes); + changedDatastore->has_number_of_changes = 0; + } + + /*set Mem */ + /* TODO get current datastore dynamic memory size & recods */ + /* And set Mem structure */ + /*Mem *mem = create_mem(); + set_mem_sharedmem(mem, 1); + set_mem_freemem(mem, 8100); + set_mem_freeid(mem, 81); + set_sync_start_command_mem(syncCommand, mem); */ + + err = oma_ds_1_2_binder_append(binder, PE_SYNC_START, syncCommand); + put_into_list(commands, commands_last, syncCommand); + + GList *itemIter = NULL; + command_s *changeCommand = NULL; + changed_item_s *changedItem = NULL; + oma_ds_protocol_element_e protocol_element = PE_UNDEF; + for (itemIter = changedDatastore->change_item; itemIter != NULL;) { + changedItem = (itemIter->data); + + oma_ds_1_2_binder_get_stream_size(binder, &stream_size); + _DEBUG_VERBOSE("stream_size = %d", stream_size); + _DEBUG_VERBOSE("(*session)->targetMaxMsgSize = %d", (*session)->target_max_msg_size); + + if ((*session)->target_max_msg_size > stream_size) { + /*there is a space for command */ + if (changedItem->change_type == CHANGE_DELETE) { + /* create delete Command */ + errorType = create_delete_command(*session, changedItem->change_type, changedItem->luid, changedItem->content_type, &changeCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create delete command"); + goto error; + } + } else { + int isFirstLargeObj; + if (changedItem->data == NULL) { + char *folderId = NULL; + GList *list = 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 = (*session)->account_id; + query.item_type_id = datastoreinfo_per_content_type[changedItem->index_of_datastore]->datastore_id; + query.folder_type_id = datastoreinfo_per_content_type[changedItem->index_of_datastore]->folder_type_id; + + da_err = sync_agent_get_folder_id_list(&query, &list); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("sync_agent_get_folder_id_list_inferface() failed !!"); + goto error; + } + + if (g_list_length(list) > 0) { + GList *iter = g_list_nth(list, 0); + folderId = (char *)(iter->data); + } else { + _DEBUG_ERROR("failed to get folderId"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + _DEBUG_VERBOSE("datastoreinfo_per_content_type[%d]->datastore_id = %d", changedItem->index_of_datastore, datastoreinfo_per_content_type[changedItem->index_of_datastore]->datastore_id); + _DEBUG_VERBOSE("account_id = %d", (*session)->account_id); + _DEBUG_VERBOSE("folderId = %s", folderId); + _DEBUG_VERBOSE("changedItem->luid = %s", changedItem->luid); + + da_err = sync_agent_create_service_item(&service_item); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + errorType = SA_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed in sync_agent_create_service_item() = %d", da_err); + goto error; + } + + da_err = sync_agent_get_service_item(changedItem->luid, &service_item); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + errorType = SA_INTERNAL_DA_ERROR; + _DEBUG_ERROR("failed in sync_agent_get_service_item() = %d", da_err); + goto error; + } + data = g_strdup((char *)(service_item->data)); + + _DEBUG_VERBOSE("data = %s", data); + sync_agent_free_folder_id_list(list); + if (data == NULL) { + da_err = sync_agent_delete_item(changedItem->luid, 1); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_item !!"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + itemIter = g_list_next(itemIter); + changedDatastore->change_item = g_list_remove(changedDatastore->change_item, changedItem); + free_changed_item(changedItem); + continue; + } + + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_get_service_item =%d", da_err); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + isFirstLargeObj = 1; + } else { + data = changedItem->data; + changedItem->data = NULL; + isFirstLargeObj = 0; + } + + unsigned int sizeOfData = 0; + if (data != NULL) + sizeOfData = strlen(data); + + _DEBUG_VERBOSE("sizeOfData = %d", sizeOfData); + if ((*session)->target_max_msg_size < stream_size + sizeOfData) { + /*can be LargeObj */ + int availableSize = (*session)->target_max_msg_size - stream_size; + if ((*session)->remote_devinf->supports_large_objs /*&& availableSize > session->targetMaxMsgSize / 50 */ ) { + + /*if server support LargeObj & clearly LargeObj */ + sendingData = calloc(availableSize + 1, sizeof(char)); + if (sendingData == NULL) { + _DEBUG_ERROR("failed to allocate sendingData"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + memcpy(sendingData, data, availableSize); + _DEBUG_VERBOSE("sendingData = %s", sendingData); + _DEBUG_VERBOSE("sendingData size = %d", strlen(sendingData)); + + char *remainingData = calloc(sizeOfData - availableSize + 1, sizeof(char)); + if (remainingData == NULL) { + _DEBUG_ERROR("failed to allocate remainingData"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + memcpy(remainingData, data + availableSize, sizeOfData - availableSize); + _DEBUG_VERBOSE("sizeOfData - availableSize = %d", sizeOfData - availableSize); + _DEBUG_VERBOSE("remainingData = %s", remainingData); + _DEBUG_VERBOSE("remainingData size = %d", strlen(remainingData)); + + if (changedItem->data != NULL) + free(changedItem->data); + + set_changed_item_data(changedItem, remainingData); + free(remainingData); + + command_status_s *pTemp = NULL; + errorType = create_command_status((*session)->msg_id, (*session)->cmd_id, &pTemp); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create pending status"); + goto error; + } + (*session)->large_obj = pTemp; + + if (changedItem->change_type == CHANGE_ADD) { + /* create add Command */ + errorType = create_add_command(*session, changedItem->change_type, changedItem->luid, changedItem->content_type, sendingData, isFirstLargeObj == 1 ? sizeOfData : 0, 1, &changeCommand); + } else if (changedItem->change_type == CHANGE_REPLACE) { + /* create replace Command */ + errorType = create_replace_command(*session, changedItem->change_type, changedItem->luid, + changedItem->content_type, sendingData, isFirstLargeObj == 1 ? sizeOfData : 0, 1, &changeCommand); + } + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create add(replace) command"); + goto error; + } + + if (sendingData != NULL) { + free(sendingData); + sendingData = NULL; + } + } else { + needNextMsg = true; + break; + } + } else { + /*can append more commnad */ + if (changedItem->change_type == CHANGE_ADD) { + /* create add Command */ + errorType = create_add_command(*session, changedItem->change_type, changedItem->luid, changedItem->content_type, data, 0, 0, &changeCommand); + } else if (changedItem->change_type == CHANGE_REPLACE) { + /* create replace Command */ + errorType = create_replace_command(*session, changedItem->change_type, changedItem->luid, changedItem->content_type, data, 0, 0, &changeCommand); + } + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create add(replace) command"); + goto error; + } + } + } + } else { + needNextMsg = true; + break; + } + + if (changeCommand->type == COMMAND_TYPE_ADD) + protocol_element = PE_ADD; + else if (changeCommand->type == COMMAND_TYPE_REPLACE) + protocol_element = PE_REPLACE; + else if (changeCommand->type == COMMAND_TYPE_DELETE) + protocol_element = PE_DELETE; + + err = oma_ds_1_2_binder_append(binder, protocol_element, changeCommand); + oma_ds_1_2_binder_get_stream_size(binder, &stream_size); + _DEBUG_VERBOSE("stream size after Changes Command= %d", stream_size); + put_into_list(commands, commands_last, changeCommand); + + if (changedItem->data == NULL) { + itemIter = g_list_next(itemIter); + changedDatastore->sent_item = g_list_append(changedDatastore->sent_item, changedItem); + changedDatastore->change_item = g_list_remove(changedDatastore->change_item, changedItem); + } else { + needNextMsg = true; + break; + } + + if (data != NULL) { + free(data); + data = NULL; + } + } + + /* create sync end Command */ + errorType = create_sync_end_command(&syncCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create sync end command"); + goto error; + } + err = oma_ds_1_2_binder_append(binder, PE_SYNC_END, syncCommand); + put_into_list(commands, commands_last, syncCommand); + + if (needNextMsg) + break; + + int chageItemCount = g_list_length(changedDatastore->change_item); + if (chageItemCount == 0) + changedDatastore->need_sync_command = 0; + } + } + + *is_need_next_msg = needNextMsg; + + error: + + if (sendingData != NULL) { + free(sendingData); + sendingData = NULL; + } + + if (data != NULL) { + free(data); + data = NULL; + } + + if (service_item != NULL) { + sync_agent_free_service_item(service_item); + } + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _generate_suspend_msg(session_s * session, bool server_flag, char **msg, unsigned int *msg_size) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + char *id = NULL; + char *pwd = NULL; + char *sourceUrl = NULL; + char *targetUrl = NULL; + char *nextNonce = NULL; + + sync_hdr_s *pSyncHdr = NULL; + syncml_s *syncml = NULL; + + GList *commands = NULL; + GList *commands_last = NULL; + + command_s *pAlertCommand = NULL; + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + + /* change pkgstatus tp SYNCML_SUSPEND */ + session->pkg_status = SYNCML_SUSPEND; + + sync_agent_dev_return_e err = sync_agent_get_devinfo(DEFINE_PLATFORM, "DevID", &sourceUrl); + if (err != SYNC_AGENT_DEV_RETURN_SUCCESS) { + _DEBUG_ERROR("failed to get devinfo"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + errorType = __get_account_info(session->account_id, &id, &pwd, &targetUrl, &nextNonce); + if (errorType != SA_INTERNAL_OK) + goto error; + + _DEBUG_TRACE("id = %s", id); + _DEBUG_TRACE("pwd = %s", pwd); + _DEBUG_TRACE("clientUrl = %s", sourceUrl); + _DEBUG_TRACE("serverUrl = %s", targetUrl); + _DEBUG_TRACE("nextNonce = %s", nextNonce); + + /* create SyncHdr */ + errorType = create_sync_hdr(session, &pSyncHdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create synchdr"); + goto error; + } + +/* Command *pMapCommand = NULL; + GList *iter = NULL; + for (iter = session->mapCommand; iter != NULL; iter = g_list_next(iter)) { + pMapCommand = (Command *)iter->data; + put_into_list(&commands, &commands_last, pMapCommand); + increase_command_refcount(pMapCommand); + }*/ + + errorType = create_location(targetUrl, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + + /* change errorType because locURI is required so need to return SA_INTERNAL_MISCONFIGURATION error + when SA_INTERNAL_NOT_DEFINED error case */ + if (errorType == SA_INTERNAL_NOT_DEFINED) + errorType = SA_INTERNAL_MISCONFIGURATION; + goto error; + } + + errorType = create_location(sourceUrl, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + + /* change errorType because locURI is required so need to return SA_INTERNAL_MISCONFIGURATION error + when SA_INTERNAL_NOT_DEFINED error case */ + if (errorType == SA_INTERNAL_NOT_DEFINED) + errorType = SA_INTERNAL_MISCONFIGURATION; + goto error; + } + + errorType = create_alert_command(session, ALERT_SUSPEND, pSourceLocation, pTargetLocation, NULL, NULL, NULL, &pAlertCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create alert command"); + goto error; + } + + put_into_list(&commands, &commands_last, pAlertCommand); + + errorType = create_syncml(pSyncHdr, session->suspend_status, commands, 0, &syncml); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create syncml"); + goto error; + } + + /* convert Msg */ + errorType = __object_binder(syncml, server_flag, msg, msg_size); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in objectBinder"); + goto error; + } + + /*free generate structure */ + free_syncml(syncml); + session->suspend_status = NULL; + + if (id != NULL) + free(id); + if (pwd != NULL) + free(pwd); + if (sourceUrl != NULL) + free(sourceUrl); + if (targetUrl != NULL) + free(targetUrl); + if (nextNonce != NULL) + free(nextNonce); + + _INNER_FUNC_EXIT; + return errorType; + + error: + + if (id != NULL) + free(id); + if (pwd != NULL) + free(pwd); + if (sourceUrl != NULL) + free(sourceUrl); + if (targetUrl != NULL) + free(targetUrl); + if (nextNonce != NULL) + free(nextNonce); + if (syncml != NULL) + free_syncml(syncml); + if (pSyncHdr != NULL) + free_sync_hdr(pSyncHdr); + + session->suspend_status = NULL; + + _INNER_FUNC_EXIT; + return errorType; + +} + +static sa_error_type_e _exchange_msg(session_s * session, char *acc_type, int transport_type, char *send_msg, unsigned int send_msg_length, char **recv_msg, unsigned int *recv_msg_length) +{ + _INNER_FUNC_ENTER; + + sync_agent_na_result_e res = SYNC_AGENT_NA_SUCCESS; + sa_error_type_e errorType = SA_INTERNAL_OK; + bool isXML; + char *targetUri = NULL; + char *jsessionId = NULL; + GList *header_info = NULL; + GList *recv_header = NULL; + + if (session != NULL) { + if (session->target != NULL) + targetUri = session->target->loc_uri; + + if (session->jsession_id != NULL) + jsessionId = session->jsession_id; + } else { + _DEBUG_ERROR("session is NULL !"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + isXML = true; + else + isXML = false; + + na_http_header_binder(acc_type, targetUri, isXML, jsessionId, &header_info); + res = sync_agent_send_msg( /*acc_info (id, pw, uri, ...), */ + header_info, transport_type, send_msg, send_msg_length, &recv_header, (unsigned char **)recv_msg, recv_msg_length, SYNC_AGENT_NA_SEND_TYPE_SEND_N_RECEIVE, session->naci_session_id); + + if (res != SYNC_AGENT_NA_SUCCESS) { + _DEBUG_ERROR("res = %d", res); + if (res == SYNC_AGENT_NA_SEND_MSG_CANCEL) + errorType = SA_INTERNAL_CANCEL; + else + errorType = SA_INTERNAL_CONNECTION_ERROR; + goto error; + } + + __process_jssion_id(session, recv_header); + + error: + + if (recv_header != NULL) { + GList *iter = NULL; + sync_agent_na_common_header_info_s *iter_data; + for (iter = recv_header; iter != NULL;) { + iter_data = NULL; + iter_data = ((sync_agent_na_common_header_info_s *) (iter->data)); + + iter = g_list_next(iter); + recv_header = g_list_remove(recv_header, iter_data); + + if (iter_data->key != NULL) + free(iter_data->key); + if (iter_data->value != NULL) + free(iter_data->value); + free(iter_data); + } + g_list_free(recv_header); + } + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _process_recv_msg(session_s * session, char *recv_msg, unsigned int recv_msg_length, int only_from_client, void **sync_return_obj, int *is_finish) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + reset_cmd_id_session(session); + + syncml_s *syncml = (syncml_s *) calloc(1, sizeof(syncml_s)); + if (syncml == NULL) { + _DEBUG_ERROR("failed to allocate syncml"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + GList *pReturnStatus = NULL; + GList *pReturnDatastore = NULL; + + errorType = __reverse_object_binder(&syncml, recv_msg, recv_msg_length); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in reverseObjectBinder"); + goto error; + } + + /* check receive msg */ + errorType = receive_header(session, syncml->hdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Header"); + goto error; + } + + errorType = receive_statuses(session, syncml->status, &pReturnStatus); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Statuses"); + goto error; + } + + errorType = receive_commands(session, syncml->commands, false, &pReturnDatastore); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Commands"); + goto error; + } + + /* do not need to update pkgstatus when suspend */ + if (session->pkg_status == SYNCML_SUSPEND) { + _DEBUG_TRACE("Suspend"); + __clean_up_sa(session); + static_session = NULL; + goto error; + } + + if (syncml->final) { + session->is_sending_final = 0; + session->is_receiving_final = 1; + } else + session->is_receiving_final = 0; + + if (session->pkg_status == SYNCML_PKG_2) { + pre_sync_return_obj_s **pre = (pre_sync_return_obj_s **) sync_return_obj; + + if ((*pre) != NULL) + (*pre)->datastore_info = pReturnDatastore; + + if (session->remote_devinf != NULL) { + if (session->remote_devinf->dev_id != NULL) + (*pre)->dev_id = strdup(session->remote_devinf->dev_id); + } + } else { + sync_return_obj_s **syncReturn = (sync_return_obj_s **) sync_return_obj; + + if ((*syncReturn) != NULL) { + (*syncReturn)->status = pReturnStatus; + (*syncReturn)->changed_datastore = pReturnDatastore; + } + } + + if (session->pkg_status == SYNCML_PKG_2 && session->is_receiving_final) + session->pkg_status = SYNCML_PKG_3; + else if (session->pkg_status == SYNCML_PKG_4 && session->is_receiving_final) { + if (only_from_client) { + *is_finish = 1; + __clean_up_sa(session); + static_session = NULL; + } else + session->pkg_status = SYNCML_PKG_5; + } else if (session->pkg_status == SYNCML_PKG_6 && session->is_receiving_final) { + *is_finish = 1; + __clean_up_sa(session); + static_session = NULL; + } + + error: + + if (syncml != NULL) + free_syncml(syncml); + + _INNER_FUNC_EXIT; + return errorType; + +} + +static sa_error_type_e _generate_autoconfigure_msg(char *id, char *pwd, char *target_url, char **msg, unsigned int *msg_size, session_s * session) +{ + _INNER_FUNC_ENTER; + _DEBUG_TRACE("id = %s, pwd = %s, target_url = %s", id, pwd, target_url); + + sa_error_type_e errorType = SA_INTERNAL_OK; + + int isFinal = 1; + char *credData = NULL; + cred_s *pCred = NULL; + sync_hdr_s *pSyncHdr = NULL; + syncml_s *syncml = NULL; + + GList *commands = NULL; + GList *commands_last = NULL; + + errorType = create_cred_string(AUTH_TYPE_BASIC, id, pwd, NULL, 0, &credData); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred string"); + goto error; + } + + errorType = create_cred(id, pwd, AUTH_TYPE_BASIC, FORMAT_TYPE_BASE64, credData, &pCred); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create cred"); + goto error; + } + + if (credData != NULL) { + free(credData); + credData = NULL; + } + + set_session_cred(session, pCred); + + errorType = create_sync_hdr(session, &pSyncHdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create synchdr"); + goto error; + } + + char *sourceDevInf = NULL; + if (session->protocol_version == VERSION_10) + sourceDevInf = ELEMENT_DEVINF_10; + else if (session->protocol_version == VERSION_11) + sourceDevInf = ELEMENT_DEVINF_11; + else if (session->protocol_version == VERSION_12) + sourceDevInf = ELEMENT_DEVINF_12; + + location_s *pLocation = NULL; + errorType = create_location(sourceDevInf, NULL, &pLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to create location"); + goto error; + } + + char *contentType = NULL; + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + contentType = ELEMENT_DEVINF_XML; + else + contentType = ELEMENT_DEVINF_WBXML; + + /* create Get command */ + command_s *pGetCommand = NULL; + errorType = create_get_command(session, pLocation, contentType, &pGetCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to get command"); + goto error; + } + put_into_list(&commands, &commands_last, pGetCommand); + + errorType = create_syncml(pSyncHdr, NULL, commands, isFinal, &syncml); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed to get syncml"); + goto error; + } + + errorType = __object_binder(syncml, false, msg, msg_size); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in objectBinder"); + goto error; + } + + /*free generate structure */ + free_syncml(syncml); + syncml = NULL; + + _INNER_FUNC_EXIT; + return errorType; + + error: + if (pSyncHdr != NULL) + free_sync_hdr(pSyncHdr); + if (pCred != NULL) + free_cred(pCred); + if (credData != NULL) + free(credData); + if (commands != NULL) + free_commands(commands); + if (syncml != NULL) + free(syncml); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e _process_autoconfigure_recv_msg(char *recv_msg, unsigned int recv_msg_length, session_s * session) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + syncml_s *syncml = (syncml_s *) calloc(1, sizeof(syncml_s)); + if (syncml == NULL) { + _DEBUG_ERROR("failed to allocate syncml"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + errorType = __reverse_object_binder(&syncml, recv_msg, recv_msg_length); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in reverseObjectBinder"); + goto error; + } + + /* check receive msg */ + errorType = receive_header(session, syncml->hdr); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Header"); + goto error; + } + + errorType = receive_statuses(session, syncml->status, NULL); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Statuses"); + goto error; + } + + errorType = receive_commands(session, syncml->commands, true, NULL); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in receive_Commands"); + goto error; + } + + error: + + if (syncml != NULL) + free_syncml(syncml); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e __object_binder(syncml_s * syncml, bool server_flag, char **msg, unsigned int *msg_size) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + sync_agent_pb_protocol_binder_function_set_s *binder_function_set = NULL; + + sync_agent_pb_error_e err = init_oma_ds_1_2_binder_function_set(&binder_function_set); + + sync_agent_pb_protocol_binder_info_s *binder = NULL; + char *xml = NULL; + unsigned int xml_len = 0; + + if (server_flag != true) + binder = oma_ds_1_2_binder_init(binder, COMMUNICATION_TYPE, false, false, false, true, false, binder_function_set); + else + binder = oma_ds_1_2_binder_init(binder, COMMUNICATION_TYPE, false, true, false, true, true, binder_function_set); + + err = oma_ds_1_2_binder_append(binder, PE_SYNCML_START, NULL); + err = oma_ds_1_2_binder_append(binder, PE_HEADER, syncml->hdr); + err = oma_ds_1_2_binder_append(binder, PE_BODY_START, NULL); + + GList *status_iter = NULL; + status_s *pStatus = NULL; + for (status_iter = syncml->status; status_iter != NULL; status_iter = g_list_next(status_iter)) { + pStatus = status_iter->data; + err = oma_ds_1_2_binder_append(binder, PE_STATUS, pStatus); + } + + GList *iter = NULL; + command_s *pCommand = NULL; + oma_ds_protocol_element_e protocol_element = PE_UNDEF; + for (iter = syncml->commands; iter != NULL; iter = g_list_next(iter)) { + pCommand = (command_s *) (iter->data); + + command_type_e type = pCommand->type; + switch (type) { + case COMMAND_TYPE_UNKNOWN: + protocol_element = PE_UNDEF; + break; + case COMMAND_TYPE_ALERT: + protocol_element = PE_ALERT; + break; + case COMMAND_TYPE_SYNC_START: + protocol_element = PE_SYNC_START; + break; + case COMMAND_TYPE_SYNC_END: + protocol_element = PE_SYNC_END; + break; + case COMMAND_TYPE_PUT: + protocol_element = PE_PUT_START; + break; + case COMMAND_TYPE_ADD: + protocol_element = PE_ADD; + break; + case COMMAND_TYPE_REPLACE: + protocol_element = PE_REPLACE; + break; + case COMMAND_TYPE_DELETE: + protocol_element = PE_DELETE; + break; + case COMMAND_TYPE_MAP: + protocol_element = PE_MAP; + break; + case COMMAND_TYPE_GET: + protocol_element = PE_GET; + break; + case COMMAND_TYPE_RESULTS: + protocol_element = PE_RESULTS_START; + break; + case COMMAND_TYPE_HEADER: + protocol_element = PE_HEADER; + break; + } + err = oma_ds_1_2_binder_append(binder, protocol_element, pCommand); + + if (type == COMMAND_TYPE_RESULTS) { + err = oma_ds_1_2_binder_append(binder, PE_RESULTS_END, NULL); + } + + if (type == COMMAND_TYPE_PUT) { + if (pCommand->private.access.item != NULL) { + if (pCommand->private.access.item->private.devinf != NULL) { + err = oma_ds_1_2_binder_append(binder, PE_DEVINF, pCommand->private.access.item); + } + } + err = oma_ds_1_2_binder_append(binder, PE_PUT_END, NULL); + } + } + + if (syncml->final) { + err = oma_ds_1_2_binder_append(binder, PE_FINAL, NULL); + } + + err = oma_ds_1_2_binder_append(binder, PE_BODY_END, NULL); + err = oma_ds_1_2_binder_append(binder, PE_SYNCML_END, NULL); + + oma_ds_1_2_binder_get_stream(binder, msg, msg_size); + + /*FIXME for debugging */ + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + set_xml_to_file(*msg, OMA_DS_MSG_PATH); + else { + err = sync_agent_get_xml_from_protocol_binder(binder, &xml, &xml_len); + if (err == SYNC_AGENT_PB_RETURN_OK) { + set_xml_to_file(xml, OMA_DS_MSG_PATH); + + if (xml != NULL) { + free(xml); + xml = NULL; + } + } + } + + oma_ds_1_2_binder_terminate(binder); + + if (err != SYNC_AGENT_PB_RETURN_OK) + errorType = SA_INTERNAL_BINDER_ERROR; + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e __reverse_object_binder(syncml_s ** syncml, char *recv_msg, unsigned int recv_msg_length) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_pb_protocol_binder_function_set_s *binder_function_set = NULL; + + sync_agent_pb_error_e err = init_oma_ds_1_2_binder_function_set(&binder_function_set); + sync_agent_pb_protocol_binder_reverse_info_s *binder = NULL; + char *xml = NULL; + unsigned int xml_len = 0; + + sync_agent_pb_decoding_e dec; + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + dec = SYNC_AGENT_PB_DECODING_XML; + else + dec = SYNC_AGENT_PB_DECODING_WBXML; + + err = reverse_oma_ds_1_2_binder_init(recv_msg, recv_msg_length, dec, binder_function_set, NULL, &binder); + + if (err != SYNC_AGENT_PB_RETURN_OK) { + errorType = SA_INTERNAL_BINDER_ERROR; + _DEBUG_ERROR("reverse_oma_ds_1_2_binder_init error =%d", err); + return errorType; + } + + /*FIXME for debugging */ + if (COMMUNICATION_TYPE == SYNC_AGENT_PB_ENCODING_XML) + set_xml_to_file(recv_msg, OMA_DS_MSG_PATH); + else { + err = sync_agent_get_xml_from_reverse_protocol_binder(binder, &xml, &xml_len); + if (err == SYNC_AGENT_PB_RETURN_OK) { + set_xml_to_file(xml, OMA_DS_MSG_PATH); + + if (xml != NULL) { + free(xml); + xml = NULL; + } + } + } + + oma_ds_protocol_element_e protocol_element = PE_UNDEF; + char *protocol_element_name = NULL; + Content_Ptr pContent = NULL; + command_s *tempCommandfordevInf = NULL; + while (err == SYNC_AGENT_PB_RETURN_OK) { + protocol_element = PE_UNDEF; + err = reverse_oma_ds_1_2_binder_next(binder, &protocol_element, &protocol_element_name, &pContent); + switch (protocol_element) { + case PE_ADD: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_ATOMIC_START: + case PE_ATOMIC_END: + case PE_COPY: + case PE_DELETE: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_EXEC: + case PE_GET: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_MAP: + case PE_PUT_START: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + tempCommandfordevInf = pContent; + break; + case PE_SEARCH: + case PE_SEQUENCE_START: + case PE_SEQUENCE_END: + case PE_SYNC_START: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_SYNC_END: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + protocol_element = PE_UNDEF; + break; + case PE_REPLACE: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_ALERT: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + break; + case PE_RESULTS_START: + (*syncml)->commands = g_list_append((*syncml)->commands, pContent); + tempCommandfordevInf = pContent; + break; + case PE_STATUS: + (*syncml)->status = g_list_append((*syncml)->status, pContent); + protocol_element = PE_UNDEF; + break; + case PE_HEADER: + (*syncml)->hdr = pContent; + sync_agent_set_user_data_in_reverse_protocol_binder(binder, (*syncml)->hdr); + break; + case PE_PUT_GET: + case PE_CMD_GROUP: + case PE_GENERIC: + case PE_FINAL: + (*syncml)->final = (int)pContent; + break; + case PE_DEVINF: + if (tempCommandfordevInf != NULL) { + tempCommandfordevInf->private.results.item->private.devinf = pContent; + tempCommandfordevInf = NULL; + } + break; + default: + break; + } + + if (protocol_element_name != NULL) { + free(protocol_element_name); + protocol_element_name = NULL; + } + + if (err == SYNC_AGENT_PB_RETURN_HAS_NO_MORE_ELEMENT) { + break; + } + } + + sync_agent_destroy_reverse_protocol_binder(binder); + + free_oma_ds_1_2_binder_function_set(binder_function_set); + + if (err != SYNC_AGENT_PB_RETURN_OK && err != SYNC_AGENT_PB_RETURN_HAS_NO_MORE_ELEMENT) + errorType = SA_INTERNAL_BINDER_ERROR; + + _INNER_FUNC_EXIT; + return errorType; +} + +static common_error_type_e _convert_error_type(sa_error_type_e error_type) +{ + _INNER_FUNC_ENTER; + + common_error_type_e sa_errorType = COMMON_OK; + + if (error_type == SA_INTERNAL_OK) + sa_errorType = COMMON_OK; + else if (error_type == SA_INTERNAL_MISCONFIGURATION) + sa_errorType = COMMON_MISCONFIGURATION; + else if (error_type == SA_INTERNAL_AUTHENTICATION_ERROR) + sa_errorType = COMMON_AUTHENTICATION_ERROR; + else if (error_type == SA_INTERNAL_NOT_FOUND) + sa_errorType = COMMON_NOT_FOUND; + else if (error_type == SA_INTERNAL_NO_MEMORY) + sa_errorType = COMMON_NO_MEMORY; + else if (error_type == SA_INTERNAL_NOT_DEFINED || error_type == SA_INTERNAL_BINDER_ERROR || error_type == SA_INTERNAL_ERROR || error_type == SA_INTERNAL_DA_ERROR) + sa_errorType = COMMON_INTERNAL_ERROR; + else if (error_type == SA_INTERNAL_SERVER_ERROR || error_type == SA_INTERNAL_SERVER_FAILURE) + sa_errorType = COMMON_SERVER_ERROR; + else if (error_type == SA_INTERNAL_CONNECTION_ERROR) + sa_errorType = COMMON_CONNECTION_ERROR; + else if (error_type == SA_INTERNAL_AUTOCONFIG_NOT_SUPPORT_BY_SERVER) + sa_errorType = COMMON_AUTOCONFIG_NOT_SUPPORT_BY_SERVER; + else if (error_type == SA_INTERNAL_CANCEL) + sa_errorType = COMMON_CANCEL; + else if (error_type == SA_INTERNAL_BUSY_SIGNALING) + sa_errorType = COMMON_BUSY_SIGNALING; + else if (error_type == SA_INTERNAL_SUSPEND_FAIL) + sa_errorType = COMMON_SUSPEND_FAIL; + + _INNER_FUNC_EXIT; + return sa_errorType; + + /*from processRecvMsg + 401 ->ERROR_AUTH_REJECTED :wrong password(header, datastore) + 407 -> ERROR_AUTH_REQUIRED : try one more request and if failed again return ERROR_AUTH_REQUIRED(header, datastore) + 404 -> ERROR_NOT_FOUND -> no datastore (important -> have to be noted to user) + + 1500 -> ERROR_INTERNAL_OK : processRecvMsg has been completed without any error + + 1513 -> ERROR_INTERNAL_NOT_DEFINED + 1512 -> ERROR_INTERNAL_NO_MEMORY + 1503 -> ERROR_INTERNAL_BINDER_ERROR + + 500 -> ERROR_GENERIC (our problem -> do not ever never receive this error) + 511 ->ERROR_SERVER_FAILURE(our problem -> do not ever never receive this error) + + can be return to engine value + from generatePreSyncMsg + 1506 -> ERROR_INTERNAL_MISCONFIGURATION : need configure infomation + 1500 -> ERROR_INTERNAL_OK : generatePreSyncMsg has been completed without any error + 1512 -> ERROR_INTERNAL_NO_MEMORY : failed to allocate memory + 1513 -> ERROR_INTERNAL_NOT_DEFINED : something is not defined that must have + 1503 -> ERROR_INTERNAL_BINDER_ERROR : binder error + + from exchangeMsg + + from processRecvMsg + 401 ->ERROR_AUTH_REJECTED :wrong password(header, datastore) + 407 -> ERROR_AUTH_REQUIRED : try one more request and if failed again return ERROR_AUTH_REQUIRED(header, datastore) + 404 -> ERROR_NOT_FOUND -> no datastore (important -> have to be noted to user) + + 1500 -> ERROR_INTERNAL_OK : processRecvMsg has been completed without any error + + 1513 -> ERROR_INTERNAL_NOT_DEFINED + 1512 -> ERROR_INTERNAL_NO_MEMORY + 1503 -> ERROR_INTERNAL_BINDER_ERROR + + 500 -> ERROR_GENERIC (our problem -> do not ever never receive this error) + 511 ->ERROR_SERVER_FAILURE(our problem -> do not ever never receive this error) */ + +} + +static void __clean_up_sa(session_s * session) +{ + _INNER_FUNC_ENTER; + + if (session != NULL) { + + if (session->has_opend) { + sync_agent_close_connection(TRANSPORT_TYPE, session->naci_session_id); + session->has_opend = 0; + } + + free_session(session); + session = NULL; + } + + _INNER_FUNC_EXIT; +} + +static sa_error_type_e __process_jssion_id(session_s * session, GList * recv_header) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_na_result_e res = SYNC_AGENT_NA_SUCCESS; + + _DEBUG_VERBOSE(" CKECK JSESSION\n"); + char *temp_jsessionid = NULL; + char *real_jsessionid = NULL; + res = sync_agent_get_header_info(1, recv_header, "Set-Cookie", &temp_jsessionid); + if (res == SYNC_AGENT_NA_SUCCESS) { + if (temp_jsessionid != NULL) { + real_jsessionid = strstr(temp_jsessionid, "JSESSIONID"); + if (real_jsessionid != NULL) { + session->jsession_id = strdup(real_jsessionid); + _DEBUG_VERBOSE("session->jsessionId = %s", session->jsession_id); + + } + } + } else + _DEBUG_ERROR("failed in sync_agent_get_header_info = %d", res); + + if (temp_jsessionid != NULL) + free(temp_jsessionid); + + _INNER_FUNC_EXIT; + return errorType; +} + +static sa_error_type_e __check_resume_session(session_s * session, bool * resume) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + char *value = NULL; + bool result; + + result = get_config(session->account_id, DEFINE_CONFIG_KEY_PROFILE_RESUME, &value); + _DEBUG_VERBOSE("resume = %s", value); + if (result == false) { + _DEBUG_ERROR("failed in get_config"); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + if (strcmp(value, "1") == 0) + *resume = true; + else + *resume = false; + + error: + + if (value != NULL) + free(value); + + _INNER_FUNC_EXIT; + return errorType; + +} + +int pre_sync(int transportType, int account_id, char *session_id, int server_flag, void **pre_sync_return_obj) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + char *msg = NULL; + unsigned int msg_size = 0; + char *recv_msg = NULL; + unsigned int recv_msg_size = 0; + unsigned int naci_session_id; + + /* create session structure */ + errorType = _create_session(account_id, session_id, server_flag, &static_session); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __create_session"); + goto error; + } + + /* generate preSync Msg */ + errorType = _generate_presync_msg(static_session, server_flag, &msg, &msg_size); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __generate_presync_msg"); + goto error; + } + + if (!static_session->has_opend) { + sync_agent_na_result_e res = sync_agent_open_connection(transportType, NETWORK_TIMEOUT, &naci_session_id); + if (res != SYNC_AGENT_NA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_open_connection res = %d", res); + errorType = SA_INTERNAL_CONNECTION_ERROR; + goto error; + } + static_session->naci_session_id = naci_session_id; + static_session->has_opend = 1; + _DEBUG_INFO("naci_session_id = %d", naci_session_id); + } + /* exchange Msg */ + errorType = _exchange_msg(static_session, DEFINE_PROTOCOL_TYPE, transportType, msg, msg_size, &recv_msg, &recv_msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + errorType = _process_recv_msg(static_session, recv_msg, recv_msg_size, 0, pre_sync_return_obj, NULL); + if (errorType == SA_INTERNAL_AUTHENTICATION_ERROR) { + /*when errortype is ERROR_AUTH_REQUIRED try request using chal just one more time + it can be only happend when server required MD5 authentication(we send basic authentication every time by default) */ + + /* create session structure */ + errorType = _create_session(account_id, session_id, server_flag, &static_session); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __create_session"); + goto error; + } + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recv_msg != NULL) { + free(recv_msg); + recv_msg = NULL; + } + + errorType = _generate_presync_msg(static_session, server_flag, &msg, &msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + errorType = _exchange_msg(static_session, DEFINE_PROTOCOL_TYPE, transportType, msg, msg_size, &recv_msg, &recv_msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + errorType = _process_recv_msg(static_session, recv_msg, recv_msg_size, 0, pre_sync_return_obj, NULL); + if (errorType != SA_INTERNAL_OK) + goto error; + } + + error: + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recv_msg != NULL) { + free(recv_msg); + recv_msg = NULL; + } + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("errorType : %d", errorType); + __clean_up_sa(static_session); + static_session = NULL; + } + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +int generate_msg(void **syncObj, int server_flag, char **msg, unsigned int *msg_size) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + errorType = _generate_msg(static_session, syncObj, server_flag, msg, msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + error: + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("errorType : %d", errorType); + __clean_up_sa(static_session); + static_session = NULL; + } + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +int exchange_msg(int transport_type, char *send_msg, unsigned int send_msg_length, char **recv_msg, unsigned int *recv_msg_length) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + errorType = _exchange_msg(static_session, DEFINE_PROTOCOL_TYPE, transport_type, send_msg, send_msg_length, recv_msg, recv_msg_length); + if (errorType != SA_INTERNAL_OK) + goto error; + + error: + + if (errorType != SA_INTERNAL_OK && errorType != SA_INTERNAL_CANCEL) { + _DEBUG_ERROR("errorType : %d", errorType); + __clean_up_sa(static_session); + static_session = NULL; + } + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +int process_recv_msg(char *recv_msg, unsigned int recv_msg_length, int only_from_client, void **sync_return_obj, int *is_finish) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + errorType = _process_recv_msg(static_session, recv_msg, recv_msg_length, only_from_client, sync_return_obj, is_finish); + if (errorType != SA_INTERNAL_OK) + goto error; + + error: + + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("errorType : %d", errorType); + __clean_up_sa(static_session); + static_session = NULL; + } + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +void clean_up_sa() +{ + _EXTERN_FUNC_ENTER; + + __clean_up_sa(static_session); + static_session = NULL; + + _EXTERN_FUNC_EXIT; +} + +int auto_configure(char *addr, char *id, char *password, GList ** configure) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + session_s *session = NULL; + + char *sourceUrl = NULL; + char *sessionId = NULL; + + char *msg = NULL; + unsigned int msg_size = 0; + + char *recv_msg = NULL; + unsigned int recv_msg_size = 0; + + bool cancel_flag = false; + unsigned int session_id; + + location_s *pSourceLocation = NULL; + location_s *pTargetLocation = NULL; + + sessionId = g_strdup_printf("%ld", time(NULL)); + if (sessionId == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + sync_agent_dev_return_e err = sync_agent_get_devinfo(DEFINE_PLATFORM, "DevID", &sourceUrl); + if (err != SYNC_AGENT_DEV_RETURN_SUCCESS) { + errorType = SA_INTERNAL_ERROR; + goto error; + } + + errorType = create_location(sourceUrl, NULL, &pSourceLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_location"); + goto error; + } + + errorType = create_location(addr, NULL, &pTargetLocation); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_location"); + goto error; + } + + errorType = create_session(VERSION_12, PROTOCOL_TYPE_DS, 0, sessionId, pSourceLocation, pTargetLocation, &session); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_session"); + goto error; + } + + if (session == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + errorType = _generate_autoconfigure_msg(id, password, addr, &msg, &msg_size, session); + if (errorType != SA_INTERNAL_OK) + goto error; + + if (!session->has_opend) { + sync_agent_na_result_e res = sync_agent_open_connection(TRANSPORT_TYPE, NETWORK_TIMEOUT, &session_id); + if (res != SYNC_AGENT_NA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_open_connection res = %d", res); + errorType = SA_INTERNAL_CONNECTION_ERROR; + goto error; + } + session->naci_session_id = session_id; + session->has_opend = 1; + _DEBUG_INFO("session_id = %d", session_id); + } + + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + errorType = SA_INTERNAL_CANCEL; + goto error; + } + + /* exchange Msg */ + errorType = _exchange_msg(session, DEFINE_PROTOCOL_TYPE, TRANSPORT_TYPE, msg, msg_size, &recv_msg, &recv_msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + errorType = SA_INTERNAL_CANCEL; + goto error; + } + + errorType = _process_autoconfigure_recv_msg(recv_msg, recv_msg_size, session); + if (errorType != SA_INTERNAL_OK) + goto error; + + cancel_flag = sync_agent_check_cancel_flag(); + if (cancel_flag) { + errorType = SA_INTERNAL_CANCEL; + goto error; + } + + devinf_s *devInf = session->remote_devinf; + if (devInf != NULL) { + + GList *tempConfigure = NULL; + + GList *contactCandidate = NULL; + GList *calendarCandidate = NULL; + GList *memoCandidate = NULL; + + /*set inputted name by user */ + contactCandidate = g_list_append(contactCandidate, strdup(DEFINE_SOURCE_CONTACT_URI)); + /* + char *target = NULL; + target= get_vconf_str(profilePath, DS_SETTING_CONTACT_TGTURI); + if (target != NULL) { + _DEBUG_INFO("Contacts target =%s", target); + if (strcmp(target, "") !=0) + contactCandidate = g_list_append(contactCandidate, strdup(target)); + + free(target); + target = NULL; + } + */ + + calendarCandidate = g_list_append(calendarCandidate, strdup(DEFINE_SOURCE_CALENDAR_URI)); + /* + target = get_vconf_str(profilePath, DS_SETTING_CALENDAR_TGTURI); + if (target != NULL) { + _DEBUG_INFO("Organizer target =%s", target); + if (strcmp(target, "") !=0) + calendarCandidate = g_list_append(calendarCandidate, strdup(target)); + + free(target); + target = NULL; + } + */ + + memoCandidate = g_list_append(memoCandidate, strdup(DEFINE_SOURCE_MEMO_URI)); + /* + target = get_vconf_str(profilePath, DS_SETTING_MEMO_TGTURI); + if (target != NULL) { + _DEBUG_INFO("Memo target =%s", target); + if (strcmp(target, "") !=0) + memoCandidate = g_list_append(memoCandidate, strdup(target)); + + free(target); + target = NULL; + } + */ + + GList *iter = NULL; + GList *innerIter = NULL; + devinf_datastore_s *devInfDataStore = NULL; + int exist; + char *candidate; + for (iter = devInf->datastores; iter != NULL; iter = g_list_next(iter)) { + devInfDataStore = iter->data; + exist = 0; + candidate = NULL; + + _DEBUG_INFO("devInfDataStore->sourceref = %s", devInfDataStore->source_ref); + + if (strcmp(devInfDataStore->rx_pref->ct_type, ELEMENT_TEXT_VCARD) == 0 || strcmp(devInfDataStore->rx_pref->ct_type, ELEMENT_TEXT_VCARD_30) == 0) { + + for (innerIter = g_list_next(contactCandidate); innerIter != NULL; innerIter = g_list_next(innerIter)) { + candidate = innerIter->data; + + if (strcmp(candidate, devInfDataStore->source_ref) == 0) + exist = 1; + } + if (!exist) { + if (devInfDataStore->source_ref != NULL) + contactCandidate = g_list_append(contactCandidate, strdup(devInfDataStore->source_ref)); + } + + } else if (strcmp(devInfDataStore->rx_pref->ct_type, ELEMENT_TEXT_VCAL) == 0 || strcmp(devInfDataStore->rx_pref->ct_type, ELEMENT_TEXT_ICAL) == 0) { + + for (innerIter = g_list_next(calendarCandidate); innerIter != NULL; innerIter = g_list_next(innerIter)) { + candidate = innerIter->data; + + if (strcmp(candidate, devInfDataStore->source_ref) == 0) + exist = 1; + } + if (!exist) { + if (devInfDataStore->source_ref != NULL) + calendarCandidate = g_list_append(calendarCandidate, strdup(devInfDataStore->source_ref)); + } + + } else if (strcmp(devInfDataStore->rx_pref->ct_type, ELEMENT_TEXT_PLAIN) == 0) { + + for (innerIter = g_list_next(memoCandidate); innerIter != NULL; innerIter = g_list_next(innerIter)) { + candidate = innerIter->data; + + if (strcmp(candidate, devInfDataStore->source_ref) == 0) + exist = 1; + } + if (!exist) { + if (devInfDataStore->source_ref != NULL) + memoCandidate = g_list_append(memoCandidate, strdup(devInfDataStore->source_ref)); + } + } + } + + tempConfigure = g_list_append(tempConfigure, contactCandidate); + tempConfigure = g_list_append(tempConfigure, calendarCandidate); + tempConfigure = g_list_append(tempConfigure, memoCandidate); + + *configure = tempConfigure; + +// *congifure = g_list_append(*congifure, contactCandidate); +// *congifure = g_list_append(*congifure, calendarCandidate); +// *congifure = g_list_append(*congifure, memoCandidate); + + } else { + errorType = SA_INTERNAL_AUTOCONFIG_NOT_SUPPORT_BY_SERVER; + goto error; + } + + error: + + /*close network */ + if (session != NULL) { + if (session->has_opend) + sync_agent_close_connection(TRANSPORT_TYPE, session->naci_session_id); + } + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recv_msg != NULL) { + free(recv_msg); + recv_msg = NULL; + } + + if (sessionId != NULL) + free(sessionId); + + if (sourceUrl != NULL) + free(sourceUrl); + + if (session != NULL) { + free_session(session); + session = NULL; + } + + if (errorType != SA_INTERNAL_OK) + _DEBUG_ERROR("errorType =%d", errorType); + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +int check_cancel_status() +{ + _EXTERN_FUNC_ENTER; + + bool result = false; + retvm_if(static_session == NULL, false, "session is NULL"); + + if (static_session->pkg_status == SYNCML_PKG_5 || static_session->pkg_status == SYNCML_PKG_6) + result = false; + else + result = true; + + _EXTERN_FUNC_EXIT; + + return result; +} + +int suspend_sync(int transport_type, int account_id, int server_flag) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + char *msg = NULL; + unsigned int msg_size = 0; + char *recv_msg = NULL; + unsigned int recv_msg_size = 0; + + /* generate preSync Msg */ + errorType = _generate_suspend_msg(static_session, server_flag, &msg, &msg_size); + if (errorType != SA_INTERNAL_OK) + goto error; + + /* exchange Msg */ + errorType = _exchange_msg(static_session, DEFINE_PROTOCOL_TYPE, transport_type, msg, msg_size, &recv_msg, &recv_msg_size); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("errorType = %d", errorType); + goto error; + } + + errorType = _process_recv_msg(static_session, recv_msg, recv_msg_size, 0, NULL, NULL); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("errorType = %d", errorType); + goto error; + } + + error: + + if (msg != NULL) { + free(msg); + msg = NULL; + } + + if (recv_msg != NULL) { + free(recv_msg); + recv_msg = NULL; + } + + if (errorType != SA_INTERNAL_OK) + _DEBUG_ERROR("errorType =%d", errorType); + + _EXTERN_FUNC_EXIT; + return _convert_error_type(errorType); +} + +int cancel_connection_sync_request(int transport_type) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e err = SA_INTERNAL_OK; + sync_agent_na_result_e res = SYNC_AGENT_NA_SUCCESS; + + if (static_session != NULL) { + _DEBUG_INFO("sessionId = %d", static_session->naci_session_id); + + res = sync_agent_cancel_msg(transport_type, static_session->naci_session_id); + if (res != SYNC_AGENT_NA_SUCCESS) { + _DEBUG_ERROR("res = %d", res); + err = SA_INTERNAL_CONNECTION_ERROR; + goto error; + } + } + + error: + + _EXTERN_FUNC_EXIT; + return _convert_error_type(err); +} |