diff options
Diffstat (limited to 'src/agent/service-adapter/sa_session.c')
-rwxr-xr-x | src/agent/service-adapter/sa_session.c | 1578 |
1 files changed, 1578 insertions, 0 deletions
diff --git a/src/agent/service-adapter/sa_session.c b/src/agent/service-adapter/sa_session.c new file mode 100755 index 0000000..3ff27a1 --- /dev/null +++ b/src/agent/service-adapter/sa_session.c @@ -0,0 +1,1578 @@ +/* + * 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_Session.c + * @version 0.1 + * @brief This file is the source file of implementation of functions for Session structure which is used in Service Adapter and processing receive command & status + */ + +#include <sync_agent.h> + +#include "common/common_util.h" +#include "service-adapter/sa_session.h" +#include "service-adapter/sa_session_internal.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_devinf.h" + +#ifndef OMADS_AGENT_LOG +#undef LOG_TAG +#define LOG_TAG "OMA_DS_SA" +#endif + +static sa_error_type_e _receive_alert_status(session_s * session, status_s * status); +static sa_error_type_e _receive_put_status(session_s * session, status_s * status); +static sa_error_type_e _receive_get_status(session_s * session, status_s * status); +static sa_error_type_e _receive_results_status(session_s * session, status_s * status); +static sa_error_type_e _receive_sync_status(session_s * session, status_s * status); +static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status); +static sa_error_type_e _receive_map_status(session_s * session, status_s * status); + +static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore); +static sa_error_type_e _receive_put_command(session_s * session, command_s * command); +static sa_error_type_e _receive_get_command(session_s * session, command_s * command); +static sa_error_type_e _receive_results_command(session_s * session, command_s * command); +static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore); +static sa_error_type_e _receive_changes_command(session_s * session, command_s * command, char **luid_str_list, int *index, changed_datastore_s ** changed_datastore); + +static void __free_pending_status(command_status_s * command_status); +static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id); + +static sa_error_type_e _receive_alert_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code >= 400 && code != ERROR_REQUIRE_REFRESH) { + /*401 unauthorized + 407 Authentication required + 405 command not allowed + 406 optional feature not supported + 500 command failed + 412 Incomplete command + 415 unsupported media type or format + 404 not found ->it have to be considered + TODO error handling it's error~!!!!! */ + + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_COMMAND_NOT_ALLOWED || code == ERROR_UNSUPPORTED_FEATURE || code == ERROR_GENERIC) + errorType = SA_INTERNAL_SERVER_ERROR; + else if (code == ERROR_NOT_FOUND) { + /*do not need to return errorType when code is ERROR_NOT_FOUND */ + + } + } + + /* delete mapping when receive 508 status for alert command */ + if (code == ERROR_REQUIRE_REFRESH) { + sync_agent_da_return_e ret = SYNC_AGENT_DA_ERRORS; + + sync_agent_da_delete_mapping_query_s query; + query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_ACCOUNT_ID; + query.account_id = session->account_id; + + ret = sync_agent_delete_mapping(&query); + if (ret != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_delete_mapping !!"); + } + } + + /* TODO off resume flag if status is not 200 */ + if (session->pkg_status == SYNCML_SUSPEND) { + if (code != 200) { + errorType = SA_INTERNAL_SUSPEND_FAIL; + } + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_put_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code >= 400) { + /*TODO error handling it's error~!!!!! + 401 unauthorized + 407 authentication required + 411 size required + 413 request entity too large + 416 requested size too big + 415 unspported media type or format + 420 device full + 500 command failed */ + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_GENERIC) + errorType = SA_INTERNAL_SERVER_ERROR; + else + errorType = SA_INTERNAL_ERROR; + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_get_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code >= 400) { + /*TODO error handling it's error~!!!!! + 401 unauthorized + 407 authentication required + 404 not found + 413 request entity too large + 415 unspported media type or format + 500 command failed */ + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_NOT_FOUND) + errorType = SA_INTERNAL_NOT_FOUND; + else if (code == ERROR_GENERIC) + errorType = SA_INTERNAL_SERVER_ERROR; + else + errorType = SA_INTERNAL_ERROR; + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_results_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code >= 400) { + /*TODO error handling it's error~!!!!! + 401 unauthorized + 407 authentication required + 404 not found + 413 request entity too large + 415 unspported media type or format + 500 command failed */ + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_NOT_FOUND) + errorType = SA_INTERNAL_NOT_FOUND; + else if (code == ERROR_GENERIC) + errorType = SA_INTERNAL_SERVER_ERROR; + else + errorType = SA_INTERNAL_ERROR; + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_sync_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code >= 400 && code != ERROR_REQUIRE_REFRESH) { + /*TODO error handling it's error~!!!!! + 401 unauthorized + 407 authentication required + 403 forbidden + 404 not found + 405 command not allowed + 508 refresh required + 500 command failed */ + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_NOT_FOUND) + errorType = SA_INTERNAL_NOT_FOUND; + else if (code == ERROR_GENERIC) + errorType = SA_INTERNAL_SERVER_ERROR; + else + errorType = SA_INTERNAL_ERROR; + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status) +{ + _INNER_FUNC_ENTER; + + _DEBUG_TRACE("cmdID = %d", status->cmd_id); + _DEBUG_TRACE("msgRef = %d", status->msg_ref); + _DEBUG_TRACE("cmdRef = %d", status->cmd_ref); + _DEBUG_TRACE("type = %d", status->type); + _DEBUG_TRACE("data = %s", status->data); + + unsigned int code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + sa_error_type_e errorType = SA_INTERNAL_OK; + + if (session->large_obj != NULL) { + /*LargeObj status it does not need to pass engine */ + command_status_s *largeObj = session->large_obj; + if (largeObj->cmd_id == status->cmd_ref && largeObj->msg_id == status->msg_ref) { + + if (code == CHUNK_ACCEPTED) { + __free_pending_status(largeObj); + session->large_obj = NULL; + return errorType; + } else if (code == ERROR_REQUESTED_SIZE_TOO_BIG) { + /*TODO error handling for large obj + can not send this item */ + } else if (code == ERROR_SIZE_REQUIRED) { + + } + } + } + + /*pass to engine */ + if (status->source_ref != NULL) { + applied_status_s *appliedStatus = create_applied_status(get_location_loc_uri(status->source_ref), + convert_change_type_command_type(status->type), code); + if (appliedStatus == NULL) { + _DEBUG_ERROR("failed in create_appliedstatus"); + return SA_INTERNAL_NO_MEMORY; + } + *return_status = g_list_append(*return_status, appliedStatus); + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_map_status(session_s * session, status_s * status) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_da_return_e da_err; + + GList *iter = NULL; + command_s *pCommand = NULL; + unsigned int code = 0; + for (iter = session->map_command; iter != NULL; iter = g_list_next(iter)) { + pCommand = iter->data; + + if (pCommand->msg_id == status->msg_ref && pCommand->cmd_id == status->cmd_ref) { + code = get_status_code(status); + _DEBUG_TRACE("code = %d", code); + + if (code == 200) { + GList *itemIter = NULL; + item_s *item = NULL; + for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) { + item = itemIter->data; + _DEBUG_TRACE(" LUID = %s has been removed\n", get_location_loc_uri(item->source)); + + 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 = get_location_loc_uri(item->source); + + 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 !!"); + return errorType; + } + } + session->map_command = g_list_remove(session->map_command, pCommand); + free_command(pCommand); + break; + } else if (code >= 400) { + /*401 unauthorized + 407 authentication required + 420 device full + 510 data store failure + 500 command failed */ + + if (code >= 500) { + /*map command has failed so delete failed map command from session->mapCpmmand */ + GList *itemIter = NULL; + item_s *item = NULL; + for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) { + item = itemIter->data; + _DEBUG_TRACE("LUID = %s has been removed\n", get_location_loc_uri(item->source)); + + 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 = get_location_loc_uri(item->source); + + 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 !!"); + return errorType; + } + } + session->map_command = g_list_remove(session->map_command, pCommand); + free_command(pCommand); + break; + } + if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED) + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + else if (code == ERROR_NOT_FOUND) + errorType = SA_INTERNAL_NOT_FOUND; + /* for prevent */ +// else if (code == ERROR_GENERIC) +// errorType = SA_INTERNAL_SERVER_ERROR; + else + errorType = SA_INTERNAL_ERROR; + } + } + } + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + status_s *temp = NULL; + + if (command->source == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + if (command->target == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + /*401 unauthorized + 407 Authentication required + 405 command not allowed + 406 optional feature not supported + 500 command failed + 412 Incomplete command + 415 unsupported media type or format */ + +// if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) == 0 || +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) == 0 || +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) == 0 || +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) == 0) { +// +// DatastoreInfo *datastore = create_datastoreinfo(get_location_locuri(command->target), get_location_locuri(command->source)); +// if (datastore == NULL) { +// errorType = SA_INTERNAL_NO_MEMORY; +// goto error; +// } +// +// if (command->private.alert.anchor != NULL){ +// set_datastoreinfo_lastanchor(datastore, command->private.alert.anchor->lastAnchor); +// set_datastoreinfo_nextanchor(datastore, command->private.alert.anchor->nextAnchor); +// } +// +// set_datastoreInfo_synctype(datastore, command->private.alert.type); +// set_datastoreinfo_maxobjsize(datastore, command->private.alert.maxObjSize); +// +// *returnDatastore = g_list_append(*returnDatastore, datastore); +// +// errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp); +// if (errorType != SA_INTERNAL_OK) +// goto error; +// +// temp->item = create_item(); +// if (temp->item == NULL) { +// errorType = SA_INTERNAL_NO_MEMORY; +// goto error; +// } +// set_item_anchor(temp->item, command->private.alert.anchor); +// session->status = g_list_append(session->status, temp); +// +// } else if (strcmp(get_location_locuri(command->target), get_location_locuri(session->source)) == 0 && +// strcmp(get_location_locuri(command->source), get_location_locuri(session->target)) == 0) { +// +// errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp); +// if (errorType != SA_INTERNAL_OK) +// goto error; +// +// session->status = g_list_append(session->status, temp); +// } else +// goto not_found_error; + + int content_type; + bool is_data_store = false; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) + if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) { + is_data_store = true; + break; + } + } + + if (is_data_store) { + datastore_info_s *datastore = create_datastore_info(get_location_loc_uri(command->target), get_location_loc_uri(command->source)); + if (datastore == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + if (command->private.alert.anchor != NULL) { + set_datastore_info_last_anchor(datastore, command->private.alert.anchor->last_anchor); + set_datastore_info_next_anchor(datastore, command->private.alert.anchor->next_anchor); + } + + set_datastore_info_sync_type(datastore, command->private.alert.type); + set_datastore_info_max_obj_size(datastore, command->private.alert.max_obj_size); + + *return_datastore = g_list_append(*return_datastore, datastore); + + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + temp->item = create_item(); + if (temp->item == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + set_item_anchor(temp->item, command->private.alert.anchor); + session->status = g_list_append(session->status, temp); + + } else if (strcmp(get_location_loc_uri(command->target), get_location_loc_uri(session->source)) == 0 && strcmp(get_location_loc_uri(command->source), get_location_loc_uri(session->target)) == 0) { + + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + } else + goto not_found_error; + + _INNER_FUNC_ENTER; + return errorType; + + not_found_error: + errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_ALERT, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return SA_INTERNAL_NOT_FOUND; + + error: + + if (temp != NULL) + free(temp); + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_put_command(session_s * session, command_s * command) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + /*401 unauthorized + 407 authentication required + 411 size required + 413 request entity too large + 416 requested size too big + 415 unspported media type or format + 420 device full + 500 command failed */ + + status_s *temp = NULL; + + if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) { + /*if it is devinf */ + if (command->private.access.item != NULL) { + session->remote_devinf = command->private.access.item->private.devinf; + } + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_PUT, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + } else + goto not_found_error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return errorType; + + not_found_error: + errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_PUT, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return SA_INTERNAL_NOT_FOUND; + + error: + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_get_command(session_s * session, command_s * command) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + status_s *temp = NULL; + command_s *pCommand = NULL; + location_s *pLocation = NULL; + + if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) { + + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_GET, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + 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; + + errorType = create_location(sourceDevInf, NULL, &pLocation); + if (errorType != SA_INTERNAL_OK) + goto error; + + errorType = create_results_command(session, pLocation, ELEMENT_DEVINF_XML, session->devinf, &pCommand); + if (errorType != SA_INTERNAL_OK) + goto error; + + set_results_command_msg_ref(pCommand, command->msg_id); + set_results_command_cmd_ref(pCommand, command->cmd_id); + set_results_command_target_ref(pCommand, command->private.access.item->target); + + session->results_command = g_list_append(session->results_command, pCommand); + } else + goto not_found_error; + + _INNER_FUNC_ENTER; + return errorType; + + not_found_error: + errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_GET, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return SA_INTERNAL_NOT_FOUND; + + error: + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_results_command(session_s * session, command_s * command) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + status_s *temp = NULL; + + if (strcmp(command->private.results.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.results.type, ELEMENT_DEVINF_WBXML) == 0) { + /*if it is devinf */ + if (command->private.results.item != NULL) { + session->remote_devinf = command->private.results.item->private.devinf; + + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_RESULTS, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + } + } else + goto not_found_error; + + _INNER_FUNC_ENTER; + return errorType; + + not_found_error: + errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_RESULTS, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return SA_INTERNAL_NOT_FOUND; + + error: + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + status_s *temp = NULL; + + retvm_if(command == NULL, SA_INTERNAL_NOT_DEFINED, "command is NULL"); + + retvm_if(command->source == NULL, SA_INTERNAL_NOT_DEFINED, "command->source is NULL"); + retvm_if(command->target == NULL, SA_INTERNAL_NOT_DEFINED, "command->target is NULL"); + + /*TODO + need to check that if target has not exist in client + it's a error(return status) + and return Datastore index + + 401 unauthorized + 407 authentication required + 403 forbidden + 404 not founc + 405 command not allowed + 508 refresh required + 500 command failed + + TODO compare with alert command(?) */ + +// if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) != 0 && +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) != 0 && +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) != 0 && +// strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) != 0) +// goto not_found_error; +// +// Status *temp = NULL; +// errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START , &temp); +// if (errorType != SA_INTERNAL_OK) +// goto error; +// +// session->status = g_list_append(session->status, temp); +// +// _DEBUG_TRACE("hasNumChanged = %d",command->private.sync.hasNumChanged); +// _DEBUG_TRACE("numberOfChanges = %d",command->private.sync.numChanged); +// +// /*for return to engine*/ +// ChangedDatastore *pChangedDatastore = create_changeddatastore(get_location_locuri(command->source), +// get_location_locuri(command->target), command->private.sync.hasNumChanged, +// command->private.sync.hasNumChanged ? command->private.sync.numChanged : 0); +// if (pChangedDatastore == NULL) { +// errorType = SA_INTERNAL_NO_MEMORY; +// goto error; +// } else +// *changedDatastore = pChangedDatastore; + + int content_type; + bool exist = false; + for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) { + if (datastoreinfo_per_content_type[content_type] != NULL) + if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) { + exist = true; + break; + } + } + + if (!exist) + goto not_found_error; + + errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _DEBUG_TRACE("hasNumChanged = %d", command->private.sync.has_num_changed); + _DEBUG_TRACE("numberOfChanges = %d", command->private.sync.num_changed); + + /*for return to engine */ + changed_datastore_s *pChangedDatastore = create_changed_datastore(get_location_loc_uri(command->source), + get_location_loc_uri(command->target), command->private.sync.has_num_changed, + command->private.sync.has_num_changed ? command->private.sync.num_changed : 0); + if (pChangedDatastore == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } else + *changed_datastore = pChangedDatastore; + + _INNER_FUNC_ENTER; + return errorType; + + not_found_error: + errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_SYNC_START, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + _INNER_FUNC_ENTER; + return SA_INTERNAL_NOT_FOUND; + + error: + + _INNER_FUNC_ENTER; + return errorType; +} + +static sa_error_type_e _receive_changes_command(session_s * session, command_s * command, char **luid_str_list, int *index, changed_datastore_s ** changed_datastore) +{ + _INNER_FUNC_ENTER; + _DEBUG_TRACE("start command type : %d\n", command->private.change.type); + + sa_error_type_e errorType = SA_INTERNAL_OK; + + GList *iter = NULL; + changed_item_s *changed = NULL; + char *luid; + change_type_e changeType = command->private.change.type; + for (iter = command->private.change.items; iter != NULL; iter = g_list_next(iter)) { + item_s *changedItem = (iter->data); + + if (changedItem->more_data) { + if (session->large_obj_cmd != NULL) { + /*if there is a chunked item before... + it's not firest chunked item.... data have to be merged(check source location) + there will be another chunked item */ + + command_s *pLargeObjcmd = session->large_obj_cmd; + if (pLargeObjcmd->private.change.items != NULL) { + /*moreData item must be last item in item list */ + GList *largeObjItems = session->large_obj_cmd->private.change.items; + GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1); + item_s *item = largeObjLastItem->data; + alert_type_e alertType = ALERT_UNKNOWN; + if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) { + /*two item's source are equal + append incomming string */ + if (item->private.data != NULL) { + char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data); + free(item->private.data); + item->private.data = tmp; + } else { + item->private.data = strdup(changedItem->private.data); + } + status_s *temp = NULL; + errorType = create_new_status_location(session, CHUNK_ACCEPTED, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_new_status_location"); + goto error; + } + session->status = g_list_append(session->status, temp); + alertType = ALERT_NEXT_MESSAGE; + } else { + /* it's a new data object or command but this command also have a moreData */ + alertType = ALERT_NO_END_OF_DATA; + } + /* create alert command */ + command_s *pAlertCommand = NULL; + errorType = create_alert_command(session, alertType, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_alert_command"); + goto error; + } + session->alert_command = g_list_append(session->alert_command, pAlertCommand); + } + } else { + /*first chunked item + just buffered it. does not generate LUID, and does not pass to engine */ + oma_status_type_e statusErrorType = ERROR_UNKNOWN; + if (changedItem->size == 0) { + /*size required */ + statusErrorType = ERROR_SIZE_REQUIRED; + } else { + /* size is specified */ + if (changedItem->size > session->source_max_obj_size) { + /*but it is bigger than client maxObjSize */ + statusErrorType = ERROR_REQUESTED_SIZE_TOO_BIG; + } else { + /*chunked item accepted */ + session->large_obj_cmd = command; + increase_command_ref_count(command); + + statusErrorType = CHUNK_ACCEPTED; + + /* create alert command */ + command_s *pAlertCommand = NULL; + errorType = create_alert_command(session, ALERT_NEXT_MESSAGE, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_alert_command"); + goto error; + } + session->alert_command = g_list_append(session->alert_command, pAlertCommand); + } + + status_s *temp = NULL; + errorType = create_new_status_location(session, statusErrorType, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_new_status_location"); + goto error; + } + session->status = g_list_append(session->status, temp); + } + } + } else { + if (session->large_obj_cmd != NULL) { + + /*if there is a chunked item before... + it's not firest chunked item.... data have to be merged(check source location) + there will be no more chunked item. this command have to be pass to engine */ + + command_s *pLargeObjcmd = session->large_obj_cmd; + if (pLargeObjcmd->private.change.items != NULL) { + /*moreData item must be last item in item list */ + GList *largeObjItems = session->large_obj_cmd->private.change.items; + GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1); + item_s *item = largeObjLastItem->data; + + if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) { + /* two item's source are equal + append incomming string */ + if (item->private.data != NULL) { + char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data); + free(item->private.data); + item->private.data = tmp; + } else { + item->private.data = strdup(changedItem->private.data); + + if (item->private.data == NULL) { + _DEBUG_ERROR("item->private.data is null !!"); + goto error; + } + } + + if (item->size == strlen(item->private.data)) { + /*delete pointing from pLargeObjCmd */ + largeObjLastItem->data = NULL; + _DEBUG_TRACE("delete pointing from pLargeObjCmd"); + /*free Item from incomming Cmd */ + free_item(changedItem); + _DEBUG_TRACE("free Item from incomming Cmd"); + /*pointing to Merged item in incomming Cmd */ + iter->data = item; + changedItem = item; + _DEBUG_TRACE("pointing to Merged item in incomming Cmd"); + + free_command(session->large_obj_cmd); + session->large_obj_cmd = NULL; + } else { + status_s *temp = NULL; + errorType = create_new_status_location(session, ERROR_SIZE_MISMATCH, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_new_status_location"); + goto error; + } + session->status = g_list_append(session->status, temp); + } + } else { + /* it's a new data object or command send 223 + create alert command */ + command_s *pAlertCommand = NULL; + errorType = create_alert_command(session, ALERT_NO_END_OF_DATA, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_alert_command"); + goto error; + } + session->alert_command = g_list_append(session->alert_command, pAlertCommand); + } + } + } + if (changeType == CHANGE_ADD) { + int datastore_id = 0; + if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD) == 0 || strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD_30) == 0) + datastore_id = TYPE_CONTACT; + else if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCAL) == 0) + datastore_id = TYPE_CALENDAR; + else if (strcmp(changedItem->content_type, ELEMENT_TEXT_PLAIN) == 0) + datastore_id = TYPE_MEMO; + + luid = luid_str_list[(*index)++]; + if (luid == NULL) { + _DEBUG_ERROR("luid is null"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + + _DEBUG_TRACE("index = %d", *index); + _DEBUG_TRACE("luid = %s", luid); + + errorType = __add_mapping(session, get_location_loc_uri(changedItem->source), luid, datastore_id); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in __add_mapping"); + goto error; + } + } else { + luid = get_location_loc_uri(changedItem->target); + if (luid == NULL) { + _DEBUG_ERROR("luid is null"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + } + + changed = create_changed_item(changeType, luid); + if (changed == NULL) { + _DEBUG_ERROR("changed is null"); + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + if (changeType != CHANGE_DELETE) { + set_changed_item_content_type(changed, changedItem->content_type); + set_changed_item_data(changed, changedItem->private.data); + } + + status_s *temp = NULL; + errorType = create_new_status_location(session, ERROR_UNKNOWN, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp); + if (errorType != SA_INTERNAL_OK) { + _DEBUG_ERROR("failed in create_new_status_location"); + goto error; + } + session->temp_status = g_list_append(session->temp_status, temp); + + (*changed_datastore)->change_item = g_list_append((*changed_datastore)->change_item, changed); + changed = NULL; + } + } + + error: + + if (changed != NULL) + free_changed_item(changed); + + _INNER_FUNC_ENTER; + return errorType; +} + +static void __free_pending_status(command_status_s * command_status) +{ + _INNER_FUNC_ENTER; + + retm_if(command_status == NULL, "pendingStatus is NULL"); + + free(command_status); + command_status = NULL; + + _INNER_FUNC_EXIT; + return; +} + +static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id) +{ + _INNER_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + sync_agent_da_return_e da_err = SYNC_AGENT_DA_ERRORS; + + 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 !!"); + goto error; + } + + mapping->account_id = session->account_id; + mapping->data_store_id = datastore_id; + mapping->luid = strdup(luid); + mapping->guid = strdup(guid); + mapping->access_name = strdup("SA"); + + _DEBUG_VERBOSE("account_id = %d", mapping->account_id); + _DEBUG_VERBOSE("data_store_id = %d", mapping->data_store_id); + _DEBUG_VERBOSE("luid = %s", mapping->luid); + _DEBUG_VERBOSE("guid = %s", mapping->guid); + _DEBUG_VERBOSE("access_name = %s", mapping->access_name); + + da_err = sync_agent_add_mapping(mapping); + if (da_err != SYNC_AGENT_DA_SUCCESS) { + _DEBUG_ERROR("failed in sync_agent_add_mapping = %d", da_err); + sync_agent_free_mapping(mapping); + errorType = SA_INTERNAL_DA_ERROR; + goto error; + } + + sync_agent_free_mapping(mapping); + + error: + + _INNER_FUNC_EXIT; + return errorType; +} + +sa_error_type_e create_session(protocol_version_e protocol_version, protocol_type_e protocol_type, int account_id, char *sess_id, location_s * source_location, location_s * target_location, session_s ** session) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + *session = (session_s *) calloc(1, sizeof(session_s)); + if (*session == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + if (sess_id != NULL) + (*session)->session_id = strdup(sess_id); + + if (source_location != NULL) + (*session)->source = source_location; + + if (target_location != NULL) + (*session)->target = target_location; + + (*session)->protocol_type = protocol_type; + (*session)->protocol_version = protocol_version; + (*session)->account_id = account_id; + + (*session)->msg_id = 0; + (*session)->cmd_id = 1; + + (*session)->source_max_msg_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_MSG_SIZE; + (*session)->source_max_obj_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_OBJ_SIZE; + + (*session)->target_max_msg_size = 0; + (*session)->target_max_obj_size = 0; + + (*session)->naci_session_id = 0; + (*session)->has_opend = 0; + + error: + + _EXTERN_FUNC_EXIT; + return errorType; +} + +void free_session(session_s * session) +{ + _EXTERN_FUNC_ENTER; + + retm_if(session == NULL, "session is NULL"); + + if (session->session_id != NULL) { + free(session->session_id); + session->session_id = NULL; + } + + if (session->jsession_id != NULL) { + free(session->jsession_id); + session->jsession_id = NULL; + } + + _DEBUG_INFO("session->status"); + free_statuses(session->status); + session->status = NULL; + + _DEBUG_INFO("session->tempStatus"); + free_statuses(session->temp_status); + session->temp_status = NULL; + + _DEBUG_INFO("session->suspendStatus"); + free_statuses(session->suspend_status); + session->suspend_status = NULL; + + if (session->target != NULL) { + free_location(session->target); + session->target = NULL; + } + + if (session->source != NULL) { + free_location(session->source); + session->source = NULL; + } + + if (session->org_target != NULL) { + free_location(session->org_target); + session->org_target = NULL; + } + + if (session->cred != NULL) { + free_cred(session->cred); + session->cred = NULL; + } + + if (session->chal != NULL) { + free_chal(session->chal); + session->chal = NULL; + } + + if (session->devinf != NULL) { + free_devinf(session->devinf); + session->devinf = NULL; + } + + if (session->remote_devinf != NULL) { + free_devinf(session->remote_devinf); + session->remote_devinf = NULL; + } + + if (session->large_obj_cmd != NULL) { + free_command(session->large_obj_cmd); + session->large_obj_cmd = NULL; + } + + free_commands(session->map_command); + session->map_command = NULL; + + free_commands(session->alert_command); + session->alert_command = NULL; + + free_commands(session->results_command); + session->results_command = NULL; + + if (session->large_obj != NULL) + free(session->large_obj); + + if (session != NULL) + free(session); + + _EXTERN_FUNC_EXIT; + return; +} + +sa_error_type_e create_command_status(unsigned int msg_id, unsigned int cmd_id, command_status_s ** command_status) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + *command_status = (command_status_s *) calloc(1, sizeof(command_status_s)); + if (*command_status == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + + (*command_status)->msg_id = msg_id; + (*command_status)->cmd_id = cmd_id; + + error: + + _EXTERN_FUNC_EXIT; + return errorType; +} + +void set_session_cred(session_s * session, cred_s * cred) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + if (session == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + if (cred == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + session->cred = cred; + + error: + + _EXTERN_FUNC_EXIT; + return; + +} + +void set_session_devinf(session_s * session, devinf_s * devinf) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + if (session == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + if (devinf == NULL) { + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + session->devinf = devinf; + + error: + + _EXTERN_FUNC_EXIT; + return; + +} + +sa_error_type_e receive_header(session_s * session, sync_hdr_s * header) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + location_s *pLocation = NULL; + + if (session == NULL) { + _DEBUG_ERROR("session is NULL"); + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + + if (header == NULL) { + _DEBUG_ERROR("header is NULL"); + errorType = SA_INTERNAL_NOT_DEFINED; + goto error; + } + if (session->session_id && header->session_id) { + if (strcmp(session->session_id, header->session_id) != 0) { + errorType = SA_INTERNAL_SERVER_ERROR; + goto error; + } + } + + session->last_recieved_msg_id = header->message_id; + + if (0 < header->max_msg_size) + session->target_max_msg_size = header->max_msg_size; + else + session->target_max_msg_size = OMA_DS_HTTP_DEFAULT_SERVER_MAX_MSG_SIZE; + + if (0 < header->max_obj_size) + session->target_max_obj_size = header->max_obj_size; + + if (header->response_uri != NULL) { + if (session->org_target == NULL) { + session->org_target = session->target; + session->target = NULL; + } + + if (session->target != NULL) + free_location(session->target); + + errorType = create_location(header->response_uri, get_location_loc_name(session->org_target), &pLocation); + if (errorType != SA_INTERNAL_OK) + goto error; + session->target = pLocation; + + if (session->target == NULL) { + errorType = SA_INTERNAL_NO_MEMORY; + goto error; + } + } + + status_s *temp = NULL; + oma_status_type_e statusData = ERROR_UNKNOWN; + if (header->cred != NULL) { + errorType = compare_cred(header->cred, session->cred); + if (errorType == SA_INTERNAL_OK) + statusData = AUTH_ACCEPTED; + else if (errorType == SA_INTERNAL_AUTHENTICATION_ERROR) { + statusData = ERROR_AUTH_REJECTED; + } else + goto error; + } else { + statusData = NO_ERROR; + } + + errorType = create_status(statusData, session->cmd_id++, session->last_recieved_msg_id, 0, header->source, header->target, COMMAND_TYPE_HEADER, &temp); + if (errorType != SA_INTERNAL_OK) + goto error; + + session->status = g_list_append(session->status, temp); + + error: + + _EXTERN_FUNC_EXIT; + return errorType; +} + +sa_error_type_e receive_statuses(session_s * session, GList * receive_status, GList ** return_status) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + + GList *statusItem = receive_status; + status_s *status = NULL; + while (statusItem) { + status = statusItem->data; + + if (status->cmd_ref == 0) { + /*status of SyncHdr */ + assert(status->type == COMMAND_TYPE_HEADER); + assert(status->data); + oma_status_type_e statusType = atoi(status->data); + + /* TODO off resume flag if status is 400(bad request) */ + if (session->pkg_status == SYNCML_SUSPEND) { + if (statusType == ERROR_BAD_REQUEST) { + errorType = SA_INTERNAL_SUSPEND_FAIL; + goto error; + } + } + + if (statusType == AUTH_ACCEPTED) { + /*212 + when auth type is AUTH_TYPE_BASIC does not need to send cred in syncHdr in same session + when auth type is AUTH_TYPE_MD5 the next nonce in Chal MUST used for the digest when the next sync session is started. */ + if (session->cred->type == AUTH_TYPE_MD5) { + chal_s *chal = status->chal; + if (chal != NULL) { + /*chal in status have to be stored in config_tbl because it have to be used next sync session */ + _DEBUG_INFO("format type :%d", chal->format); + + char *value; + sync_agent_da_config_s config; + config.config_id = session->account_id; + + if (chal->format == FORMAT_TYPE_BASE64) + value = chal->nonce_b64; + else + value = g_base64_encode((unsigned char *)chal->nonce_plain, chal->nonce_length); + + bool result = set_config_str(session->account_id, DEFINE_CONFIG_KEY_PROFILE_NEXT_NONCE, value, "string", "SA"); + if (result == false) { + errorType = SA_INTERNAL_ERROR; + _DEBUG_ERROR("failed in set_Config"); + goto error; + } + } + } else if (session->cred->type == AUTH_TYPE_BASIC) { + /*do not need cred anymore + but we just send it again */ + } + } else if (statusType == NO_ERROR) { + /*200 + when auth type is AUTH_TYPE_BASIC sam credentials must be sent within the next request + when auth type is AUTH_TYPE_MD5 The next nonce in Chal MUST used when the next request is sent */ + if (session->cred->type == AUTH_TYPE_MD5) { + /*if auth type is AUTH_TYPE_MD5 */ + if (status->chal != NULL) { + /*if there is a chal in status duplicate to session + chal have to used when next request is sent */ + if (session->chal != NULL) { + free_chal(session->chal); + session->chal = NULL; + } + session->chal = status->chal; + status->chal = NULL; + } + } + } else if (statusType == ERROR_AUTH_REQUIRED || statusType == ERROR_AUTH_REJECTED) { + if (status->chal != NULL) { + if (session->chal != NULL) { + free_chal(session->chal); + session->chal = NULL; + } + session->chal = status->chal; + status->chal = NULL; + } + errorType = SA_INTERNAL_AUTHENTICATION_ERROR; + goto error; + } else if (statusType == ERROR_SERVER_FAILURE) { + errorType = SA_INTERNAL_SERVER_FAILURE; + goto error; + } else if (statusType == IN_PROGRESS) { + /*busy signaling */ + errorType = SA_INTERNAL_BUSY_SIGNALING; + goto error; + } + } else { + /*status except status of SyncHdr */ + if (status->type == COMMAND_TYPE_ALERT) { + errorType = _receive_alert_status(session, status); + } else if (status->type == COMMAND_TYPE_PUT) { + errorType = _receive_put_status(session, status); + } else if (status->type == COMMAND_TYPE_GET) { + errorType = _receive_get_status(session, status); + } else if (status->type == COMMAND_TYPE_RESULTS) { + errorType = _receive_results_status(session, status); + } else if (status->type == COMMAND_TYPE_SYNC_START) { + errorType = _receive_sync_status(session, status); + } else if (status->type == COMMAND_TYPE_MAP) { + errorType = _receive_map_status(session, status); + } else if (status->type == COMMAND_TYPE_ADD || status->type == COMMAND_TYPE_REPLACE || status->type == COMMAND_TYPE_DELETE) { + errorType = _receive_changes_status(session, status, return_status); + } + + if (errorType != SA_INTERNAL_OK) + goto error; + } + statusItem = g_list_next(statusItem); + } + + error: + + _EXTERN_FUNC_EXIT; + return errorType; +} + +sa_error_type_e receive_commands(session_s * session, GList * receive_command, bool auto_config, GList ** return_datastore) +{ + _EXTERN_FUNC_ENTER; + + sa_error_type_e errorType = SA_INTERNAL_OK; + int item_luid_count = 0; + int index = 0; + int i; + char **luid_str_list = NULL; + changed_datastore_s *changedDatastore = NULL; + + GList *iter = NULL; + command_s *command = NULL; + for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) { + command = iter->data; + + if (command->type == COMMAND_TYPE_ADD) + item_luid_count += g_list_length(command->private.change.items); + } + + _DEBUG_INFO("item_luid_count = %d", item_luid_count); + + if (item_luid_count > 0) { + luid_str_list = sync_agent_generate_item_luid(1, item_luid_count); + if (luid_str_list == NULL) { + _DEBUG_ERROR("failed in sync_agent_generate_item_luid"); + errorType = SA_INTERNAL_ERROR; + goto error; + } + } + + for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) { + command = iter->data; + + if (auto_config != true || (auto_config == true && command->type == COMMAND_TYPE_RESULTS)) { + switch (command->type) { + case COMMAND_TYPE_UNKNOWN: + case COMMAND_TYPE_HEADER: + case COMMAND_TYPE_MAP: + /*never receive theses commands */ + break; + case COMMAND_TYPE_ALERT: + errorType = _receive_alert_command(session, command, return_datastore); + break; + case COMMAND_TYPE_PUT: + errorType = _receive_put_command(session, command); + break; + case COMMAND_TYPE_GET: + errorType = _receive_get_command(session, command); + break; + case COMMAND_TYPE_RESULTS: + errorType = _receive_results_command(session, command); + break; + case COMMAND_TYPE_SYNC_START: + errorType = _receive_sync_command(session, command, &changedDatastore); + break; + case COMMAND_TYPE_SYNC_END: + { + if (changedDatastore != NULL) { + if (changedDatastore->has_number_of_changes || g_list_length(changedDatastore->change_item) > 0) { + *return_datastore = g_list_append(*return_datastore, changedDatastore); + changedDatastore = NULL; + } else { + if (changedDatastore != NULL) { + free_changed_datastore(changedDatastore); + changedDatastore = NULL; + } + } + } + } + break; + case COMMAND_TYPE_ADD: + case COMMAND_TYPE_REPLACE: + case COMMAND_TYPE_DELETE: + { + if (command->type != COMMAND_TYPE_ADD || luid_str_list != NULL) { + errorType = _receive_changes_command(session, command, luid_str_list, &index, &changedDatastore); + } else { + _DEBUG_ERROR("luid_str_list is NULL !!"); + errorType = SA_INTERNAL_ERROR; + if (changedDatastore != NULL) { + free_changed_datastore(changedDatastore); + changedDatastore = NULL; + } + goto error; + } + } + break; + } + + if (errorType != SA_INTERNAL_OK) { + if (changedDatastore != NULL) { + free_changed_datastore(changedDatastore); + changedDatastore = NULL; + } + goto error; + } + } + } + + error: + + if (changedDatastore != NULL) + free_changed_datastore(changedDatastore); + + if (luid_str_list != NULL) { + /*free luid_str_list */ + for (i = 0; i < item_luid_count; i++) + free(luid_str_list[i]); + + free(luid_str_list); + } + + _EXTERN_FUNC_EXIT; + return errorType; +} + +void reset_cmd_id_session(session_s * session) +{ + _EXTERN_FUNC_ENTER; + + if (session != NULL) + session->cmd_id = 1; + + _EXTERN_FUNC_EXIT; +} |