summaryrefslogtreecommitdiff
path: root/src/agent/service-adapter/sa_session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/agent/service-adapter/sa_session.c')
-rwxr-xr-xsrc/agent/service-adapter/sa_session.c1578
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;
+}