3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
21 * @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
24 #include <sync_agent.h>
26 #include "common/common_util.h"
27 #include "service-adapter/sa_session.h"
28 #include "service-adapter/sa_session_internal.h"
29 #include "service-adapter/sa_elements.h"
30 #include "service-adapter/sa_elements_internal.h"
31 #include "service-adapter/sa_command.h"
32 #include "service-adapter/sa_command_internal.h"
33 #include "service-adapter/sa_devinf.h"
35 #ifndef OMADS_AGENT_LOG
37 #define LOG_TAG "OMA_DS_SA"
40 static sa_error_type_e _receive_alert_status(session_s * session, status_s * status);
41 static sa_error_type_e _receive_put_status(session_s * session, status_s * status);
42 static sa_error_type_e _receive_get_status(session_s * session, status_s * status);
43 static sa_error_type_e _receive_results_status(session_s * session, status_s * status);
44 static sa_error_type_e _receive_sync_status(session_s * session, status_s * status);
45 static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status);
46 static sa_error_type_e _receive_map_status(session_s * session, status_s * status);
48 static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore);
49 static sa_error_type_e _receive_put_command(session_s * session, command_s * command);
50 static sa_error_type_e _receive_get_command(session_s * session, command_s * command);
51 static sa_error_type_e _receive_results_command(session_s * session, command_s * command);
52 static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore);
53 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);
55 static void __free_pending_status(command_status_s * command_status);
56 static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id);
58 static sa_error_type_e _receive_alert_status(session_s * session, status_s * status)
62 sa_error_type_e errorType = SA_INTERNAL_OK;
64 unsigned int code = get_status_code(status);
65 _DEBUG_TRACE("code = %d", code);
67 if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
69 407 Authentication required
70 405 command not allowed
71 406 optional feature not supported
73 412 Incomplete command
74 415 unsupported media type or format
75 404 not found ->it have to be considered
76 TODO error handling it's error~!!!!! */
78 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
79 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
80 else if (code == ERROR_COMMAND_NOT_ALLOWED || code == ERROR_UNSUPPORTED_FEATURE || code == ERROR_GENERIC)
81 errorType = SA_INTERNAL_SERVER_ERROR;
82 else if (code == ERROR_NOT_FOUND) {
83 /*do not need to return errorType when code is ERROR_NOT_FOUND */
88 /* delete mapping when receive 508 status for alert command */
89 if (code == ERROR_REQUIRE_REFRESH) {
90 sync_agent_da_return_e ret = SYNC_AGENT_DA_ERRORS;
92 sync_agent_da_delete_mapping_query_s query;
93 query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_ACCOUNT_ID;
94 query.account_id = session->account_id;
96 ret = sync_agent_delete_mapping(&query);
97 if (ret != SYNC_AGENT_DA_SUCCESS) {
98 _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
102 /* TODO off resume flag if status is not 200 */
103 if (session->pkg_status == SYNCML_SUSPEND) {
105 errorType = SA_INTERNAL_SUSPEND_FAIL;
113 static sa_error_type_e _receive_put_status(session_s * session, status_s * status)
117 sa_error_type_e errorType = SA_INTERNAL_OK;
119 unsigned int code = get_status_code(status);
120 _DEBUG_TRACE("code = %d", code);
123 /*TODO error handling it's error~!!!!!
125 407 authentication required
127 413 request entity too large
128 416 requested size too big
129 415 unspported media type or format
131 500 command failed */
132 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
133 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
134 else if (code == ERROR_GENERIC)
135 errorType = SA_INTERNAL_SERVER_ERROR;
137 errorType = SA_INTERNAL_ERROR;
144 static sa_error_type_e _receive_get_status(session_s * session, status_s * status)
148 sa_error_type_e errorType = SA_INTERNAL_OK;
150 unsigned int code = get_status_code(status);
151 _DEBUG_TRACE("code = %d", code);
154 /*TODO error handling it's error~!!!!!
156 407 authentication required
158 413 request entity too large
159 415 unspported media type or format
160 500 command failed */
161 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
162 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
163 else if (code == ERROR_NOT_FOUND)
164 errorType = SA_INTERNAL_NOT_FOUND;
165 else if (code == ERROR_GENERIC)
166 errorType = SA_INTERNAL_SERVER_ERROR;
168 errorType = SA_INTERNAL_ERROR;
175 static sa_error_type_e _receive_results_status(session_s * session, status_s * status)
179 sa_error_type_e errorType = SA_INTERNAL_OK;
181 unsigned int code = get_status_code(status);
182 _DEBUG_TRACE("code = %d", code);
185 /*TODO error handling it's error~!!!!!
187 407 authentication required
189 413 request entity too large
190 415 unspported media type or format
191 500 command failed */
192 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
193 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
194 else if (code == ERROR_NOT_FOUND)
195 errorType = SA_INTERNAL_NOT_FOUND;
196 else if (code == ERROR_GENERIC)
197 errorType = SA_INTERNAL_SERVER_ERROR;
199 errorType = SA_INTERNAL_ERROR;
206 static sa_error_type_e _receive_sync_status(session_s * session, status_s * status)
210 sa_error_type_e errorType = SA_INTERNAL_OK;
212 unsigned int code = get_status_code(status);
213 _DEBUG_TRACE("code = %d", code);
215 if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
216 /*TODO error handling it's error~!!!!!
218 407 authentication required
221 405 command not allowed
223 500 command failed */
224 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
225 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
226 else if (code == ERROR_NOT_FOUND)
227 errorType = SA_INTERNAL_NOT_FOUND;
228 else if (code == ERROR_GENERIC)
229 errorType = SA_INTERNAL_SERVER_ERROR;
231 errorType = SA_INTERNAL_ERROR;
238 static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status)
242 _DEBUG_TRACE("cmdID = %d", status->cmd_id);
243 _DEBUG_TRACE("msgRef = %d", status->msg_ref);
244 _DEBUG_TRACE("cmdRef = %d", status->cmd_ref);
245 _DEBUG_TRACE("type = %d", status->type);
246 _DEBUG_TRACE("data = %s", status->data);
248 unsigned int code = get_status_code(status);
249 _DEBUG_TRACE("code = %d", code);
251 sa_error_type_e errorType = SA_INTERNAL_OK;
253 if (session->large_obj != NULL) {
254 /*LargeObj status it does not need to pass engine */
255 command_status_s *largeObj = session->large_obj;
256 if (largeObj->cmd_id == status->cmd_ref && largeObj->msg_id == status->msg_ref) {
258 if (code == CHUNK_ACCEPTED) {
259 __free_pending_status(largeObj);
260 session->large_obj = NULL;
262 } else if (code == ERROR_REQUESTED_SIZE_TOO_BIG) {
263 /*TODO error handling for large obj
264 can not send this item */
265 } else if (code == ERROR_SIZE_REQUIRED) {
272 if (status->source_ref != NULL) {
273 applied_status_s *appliedStatus = create_applied_status(get_location_loc_uri(status->source_ref),
274 convert_change_type_command_type(status->type), code);
275 if (appliedStatus == NULL) {
276 _DEBUG_ERROR("failed in create_appliedstatus");
277 return SA_INTERNAL_NO_MEMORY;
279 *return_status = g_list_append(*return_status, appliedStatus);
286 static sa_error_type_e _receive_map_status(session_s * session, status_s * status)
290 sa_error_type_e errorType = SA_INTERNAL_OK;
291 sync_agent_da_return_e da_err;
294 command_s *pCommand = NULL;
295 unsigned int code = 0;
296 for (iter = session->map_command; iter != NULL; iter = g_list_next(iter)) {
297 pCommand = iter->data;
299 if (pCommand->msg_id == status->msg_ref && pCommand->cmd_id == status->cmd_ref) {
300 code = get_status_code(status);
301 _DEBUG_TRACE("code = %d", code);
304 GList *itemIter = NULL;
306 for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) {
307 item = itemIter->data;
308 _DEBUG_TRACE(" LUID = %s has been removed\n", get_location_loc_uri(item->source));
310 sync_agent_da_delete_mapping_query_s query;
311 query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_LUID;
312 query.account_id = session->account_id;
313 query.luid = get_location_loc_uri(item->source);
315 da_err = sync_agent_delete_mapping(&query);
316 if (da_err != SYNC_AGENT_DA_SUCCESS) {
317 errorType = SA_INTERNAL_DA_ERROR;
318 _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
322 session->map_command = g_list_remove(session->map_command, pCommand);
323 free_command(pCommand);
325 } else if (code >= 400) {
327 407 authentication required
329 510 data store failure
330 500 command failed */
333 /*map command has failed so delete failed map command from session->mapCpmmand */
334 GList *itemIter = NULL;
336 for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) {
337 item = itemIter->data;
338 _DEBUG_TRACE("LUID = %s has been removed\n", get_location_loc_uri(item->source));
340 sync_agent_da_delete_mapping_query_s query;
341 query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_LUID;
342 query.account_id = session->account_id;
343 query.luid = get_location_loc_uri(item->source);
345 da_err = sync_agent_delete_mapping(&query);
346 if (da_err != SYNC_AGENT_DA_SUCCESS) {
347 errorType = SA_INTERNAL_DA_ERROR;
348 _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
352 session->map_command = g_list_remove(session->map_command, pCommand);
353 free_command(pCommand);
356 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
357 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
358 else if (code == ERROR_NOT_FOUND)
359 errorType = SA_INTERNAL_NOT_FOUND;
361 // else if (code == ERROR_GENERIC)
362 // errorType = SA_INTERNAL_SERVER_ERROR;
364 errorType = SA_INTERNAL_ERROR;
373 static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore)
377 sa_error_type_e errorType = SA_INTERNAL_OK;
378 status_s *temp = NULL;
380 if (command->source == NULL) {
381 errorType = SA_INTERNAL_NOT_DEFINED;
385 if (command->target == NULL) {
386 errorType = SA_INTERNAL_NOT_DEFINED;
390 407 Authentication required
391 405 command not allowed
392 406 optional feature not supported
394 412 Incomplete command
395 415 unsupported media type or format */
397 // if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) == 0 ||
398 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) == 0 ||
399 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) == 0 ||
400 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) == 0) {
402 // DatastoreInfo *datastore = create_datastoreinfo(get_location_locuri(command->target), get_location_locuri(command->source));
403 // if (datastore == NULL) {
404 // errorType = SA_INTERNAL_NO_MEMORY;
408 // if (command->private.alert.anchor != NULL){
409 // set_datastoreinfo_lastanchor(datastore, command->private.alert.anchor->lastAnchor);
410 // set_datastoreinfo_nextanchor(datastore, command->private.alert.anchor->nextAnchor);
413 // set_datastoreInfo_synctype(datastore, command->private.alert.type);
414 // set_datastoreinfo_maxobjsize(datastore, command->private.alert.maxObjSize);
416 // *returnDatastore = g_list_append(*returnDatastore, datastore);
418 // errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp);
419 // if (errorType != SA_INTERNAL_OK)
422 // temp->item = create_item();
423 // if (temp->item == NULL) {
424 // errorType = SA_INTERNAL_NO_MEMORY;
427 // set_item_anchor(temp->item, command->private.alert.anchor);
428 // session->status = g_list_append(session->status, temp);
430 // } else if (strcmp(get_location_locuri(command->target), get_location_locuri(session->source)) == 0 &&
431 // strcmp(get_location_locuri(command->source), get_location_locuri(session->target)) == 0) {
433 // errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp);
434 // if (errorType != SA_INTERNAL_OK)
437 // session->status = g_list_append(session->status, temp);
439 // goto not_found_error;
442 bool is_data_store = false;
443 for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) {
444 if (datastoreinfo_per_content_type[content_type] != NULL)
445 if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) {
446 is_data_store = true;
452 datastore_info_s *datastore = create_datastore_info(get_location_loc_uri(command->target), get_location_loc_uri(command->source));
453 if (datastore == NULL) {
454 errorType = SA_INTERNAL_NO_MEMORY;
458 if (command->private.alert.anchor != NULL) {
459 set_datastore_info_last_anchor(datastore, command->private.alert.anchor->last_anchor);
460 set_datastore_info_next_anchor(datastore, command->private.alert.anchor->next_anchor);
463 set_datastore_info_sync_type(datastore, command->private.alert.type);
464 set_datastore_info_max_obj_size(datastore, command->private.alert.max_obj_size);
466 *return_datastore = g_list_append(*return_datastore, datastore);
468 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp);
469 if (errorType != SA_INTERNAL_OK)
472 temp->item = create_item();
473 if (temp->item == NULL) {
474 errorType = SA_INTERNAL_NO_MEMORY;
477 set_item_anchor(temp->item, command->private.alert.anchor);
478 session->status = g_list_append(session->status, temp);
480 } 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) {
482 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp);
483 if (errorType != SA_INTERNAL_OK)
486 session->status = g_list_append(session->status, temp);
488 goto not_found_error;
494 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_ALERT, &temp);
495 if (errorType != SA_INTERNAL_OK)
498 session->status = g_list_append(session->status, temp);
501 return SA_INTERNAL_NOT_FOUND;
512 static sa_error_type_e _receive_put_command(session_s * session, command_s * command)
516 sa_error_type_e errorType = SA_INTERNAL_OK;
519 407 authentication required
521 413 request entity too large
522 416 requested size too big
523 415 unspported media type or format
525 500 command failed */
527 status_s *temp = NULL;
529 if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) {
531 if (command->private.access.item != NULL) {
532 session->remote_devinf = command->private.access.item->private.devinf;
534 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_PUT, &temp);
535 if (errorType != SA_INTERNAL_OK)
538 goto not_found_error;
540 session->status = g_list_append(session->status, temp);
546 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_PUT, &temp);
547 if (errorType != SA_INTERNAL_OK)
550 session->status = g_list_append(session->status, temp);
553 return SA_INTERNAL_NOT_FOUND;
561 static sa_error_type_e _receive_get_command(session_s * session, command_s * command)
565 sa_error_type_e errorType = SA_INTERNAL_OK;
566 status_s *temp = NULL;
567 command_s *pCommand = NULL;
568 location_s *pLocation = NULL;
570 if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) {
572 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_GET, &temp);
573 if (errorType != SA_INTERNAL_OK)
576 session->status = g_list_append(session->status, temp);
578 char *sourceDevInf = NULL;
579 if (session->protocol_version == VERSION_10)
580 sourceDevInf = ELEMENT_DEVINF_10;
581 else if (session->protocol_version == VERSION_11)
582 sourceDevInf = ELEMENT_DEVINF_11;
583 else if (session->protocol_version == VERSION_12)
584 sourceDevInf = ELEMENT_DEVINF_12;
586 errorType = create_location(sourceDevInf, NULL, &pLocation);
587 if (errorType != SA_INTERNAL_OK)
590 errorType = create_results_command(session, pLocation, ELEMENT_DEVINF_XML, session->devinf, &pCommand);
591 if (errorType != SA_INTERNAL_OK)
594 set_results_command_msg_ref(pCommand, command->msg_id);
595 set_results_command_cmd_ref(pCommand, command->cmd_id);
596 set_results_command_target_ref(pCommand, command->private.access.item->target);
598 session->results_command = g_list_append(session->results_command, pCommand);
600 goto not_found_error;
606 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_GET, &temp);
607 if (errorType != SA_INTERNAL_OK)
610 session->status = g_list_append(session->status, temp);
613 return SA_INTERNAL_NOT_FOUND;
621 static sa_error_type_e _receive_results_command(session_s * session, command_s * command)
625 sa_error_type_e errorType = SA_INTERNAL_OK;
627 status_s *temp = NULL;
629 if (strcmp(command->private.results.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.results.type, ELEMENT_DEVINF_WBXML) == 0) {
631 if (command->private.results.item != NULL) {
632 session->remote_devinf = command->private.results.item->private.devinf;
634 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_RESULTS, &temp);
635 if (errorType != SA_INTERNAL_OK)
638 session->status = g_list_append(session->status, temp);
641 goto not_found_error;
647 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_RESULTS, &temp);
648 if (errorType != SA_INTERNAL_OK)
651 session->status = g_list_append(session->status, temp);
654 return SA_INTERNAL_NOT_FOUND;
662 static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore)
666 sa_error_type_e errorType = SA_INTERNAL_OK;
667 status_s *temp = NULL;
669 retvm_if(command == NULL, SA_INTERNAL_NOT_DEFINED, "command is NULL");
671 retvm_if(command->source == NULL, SA_INTERNAL_NOT_DEFINED, "command->source is NULL");
672 retvm_if(command->target == NULL, SA_INTERNAL_NOT_DEFINED, "command->target is NULL");
675 need to check that if target has not exist in client
676 it's a error(return status)
677 and return Datastore index
680 407 authentication required
683 405 command not allowed
687 TODO compare with alert command(?) */
689 // if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) != 0 &&
690 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) != 0 &&
691 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) != 0 &&
692 // strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) != 0)
693 // goto not_found_error;
695 // Status *temp = NULL;
696 // errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START , &temp);
697 // if (errorType != SA_INTERNAL_OK)
700 // session->status = g_list_append(session->status, temp);
702 // _DEBUG_TRACE("hasNumChanged = %d",command->private.sync.hasNumChanged);
703 // _DEBUG_TRACE("numberOfChanges = %d",command->private.sync.numChanged);
705 // /*for return to engine*/
706 // ChangedDatastore *pChangedDatastore = create_changeddatastore(get_location_locuri(command->source),
707 // get_location_locuri(command->target), command->private.sync.hasNumChanged,
708 // command->private.sync.hasNumChanged ? command->private.sync.numChanged : 0);
709 // if (pChangedDatastore == NULL) {
710 // errorType = SA_INTERNAL_NO_MEMORY;
713 // *changedDatastore = pChangedDatastore;
717 for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) {
718 if (datastoreinfo_per_content_type[content_type] != NULL)
719 if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) {
726 goto not_found_error;
728 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START, &temp);
729 if (errorType != SA_INTERNAL_OK)
732 session->status = g_list_append(session->status, temp);
734 _DEBUG_TRACE("hasNumChanged = %d", command->private.sync.has_num_changed);
735 _DEBUG_TRACE("numberOfChanges = %d", command->private.sync.num_changed);
737 /*for return to engine */
738 changed_datastore_s *pChangedDatastore = create_changed_datastore(get_location_loc_uri(command->source),
739 get_location_loc_uri(command->target), command->private.sync.has_num_changed,
740 command->private.sync.has_num_changed ? command->private.sync.num_changed : 0);
741 if (pChangedDatastore == NULL) {
742 errorType = SA_INTERNAL_NO_MEMORY;
745 *changed_datastore = pChangedDatastore;
751 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_SYNC_START, &temp);
752 if (errorType != SA_INTERNAL_OK)
755 session->status = g_list_append(session->status, temp);
758 return SA_INTERNAL_NOT_FOUND;
766 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)
769 _DEBUG_TRACE("start command type : %d\n", command->private.change.type);
771 sa_error_type_e errorType = SA_INTERNAL_OK;
774 changed_item_s *changed = NULL;
776 change_type_e changeType = command->private.change.type;
777 for (iter = command->private.change.items; iter != NULL; iter = g_list_next(iter)) {
778 item_s *changedItem = (iter->data);
780 if (changedItem->more_data) {
781 if (session->large_obj_cmd != NULL) {
782 /*if there is a chunked item before...
783 it's not firest chunked item.... data have to be merged(check source location)
784 there will be another chunked item */
786 command_s *pLargeObjcmd = session->large_obj_cmd;
787 if (pLargeObjcmd->private.change.items != NULL) {
788 /*moreData item must be last item in item list */
789 GList *largeObjItems = session->large_obj_cmd->private.change.items;
790 GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
791 item_s *item = largeObjLastItem->data;
792 alert_type_e alertType = ALERT_UNKNOWN;
793 if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) {
794 /*two item's source are equal
795 append incomming string */
796 if (item->private.data != NULL) {
797 char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
798 free(item->private.data);
799 item->private.data = tmp;
801 item->private.data = strdup(changedItem->private.data);
803 status_s *temp = NULL;
804 errorType = create_new_status_location(session, CHUNK_ACCEPTED, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
805 if (errorType != SA_INTERNAL_OK) {
806 _DEBUG_ERROR("failed in create_new_status_location");
809 session->status = g_list_append(session->status, temp);
810 alertType = ALERT_NEXT_MESSAGE;
812 /* it's a new data object or command but this command also have a moreData */
813 alertType = ALERT_NO_END_OF_DATA;
815 /* create alert command */
816 command_s *pAlertCommand = NULL;
817 errorType = create_alert_command(session, alertType, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
818 if (errorType != SA_INTERNAL_OK) {
819 _DEBUG_ERROR("failed in create_alert_command");
822 session->alert_command = g_list_append(session->alert_command, pAlertCommand);
826 just buffered it. does not generate LUID, and does not pass to engine */
827 oma_status_type_e statusErrorType = ERROR_UNKNOWN;
828 if (changedItem->size == 0) {
830 statusErrorType = ERROR_SIZE_REQUIRED;
832 /* size is specified */
833 if (changedItem->size > session->source_max_obj_size) {
834 /*but it is bigger than client maxObjSize */
835 statusErrorType = ERROR_REQUESTED_SIZE_TOO_BIG;
837 /*chunked item accepted */
838 session->large_obj_cmd = command;
839 increase_command_ref_count(command);
841 statusErrorType = CHUNK_ACCEPTED;
843 /* create alert command */
844 command_s *pAlertCommand = NULL;
845 errorType = create_alert_command(session, ALERT_NEXT_MESSAGE, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
846 if (errorType != SA_INTERNAL_OK) {
847 _DEBUG_ERROR("failed in create_alert_command");
850 session->alert_command = g_list_append(session->alert_command, pAlertCommand);
853 status_s *temp = NULL;
854 errorType = create_new_status_location(session, statusErrorType, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
855 if (errorType != SA_INTERNAL_OK) {
856 _DEBUG_ERROR("failed in create_new_status_location");
859 session->status = g_list_append(session->status, temp);
863 if (session->large_obj_cmd != NULL) {
865 /*if there is a chunked item before...
866 it's not firest chunked item.... data have to be merged(check source location)
867 there will be no more chunked item. this command have to be pass to engine */
869 command_s *pLargeObjcmd = session->large_obj_cmd;
870 if (pLargeObjcmd->private.change.items != NULL) {
871 /*moreData item must be last item in item list */
872 GList *largeObjItems = session->large_obj_cmd->private.change.items;
873 GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
874 item_s *item = largeObjLastItem->data;
876 if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) {
877 /* two item's source are equal
878 append incomming string */
879 if (item->private.data != NULL) {
880 char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
881 free(item->private.data);
882 item->private.data = tmp;
884 item->private.data = strdup(changedItem->private.data);
886 if (item->private.data == NULL) {
887 _DEBUG_ERROR("item->private.data is null !!");
892 if (item->size == strlen(item->private.data)) {
893 /*delete pointing from pLargeObjCmd */
894 largeObjLastItem->data = NULL;
895 _DEBUG_TRACE("delete pointing from pLargeObjCmd");
896 /*free Item from incomming Cmd */
897 free_item(changedItem);
898 _DEBUG_TRACE("free Item from incomming Cmd");
899 /*pointing to Merged item in incomming Cmd */
902 _DEBUG_TRACE("pointing to Merged item in incomming Cmd");
904 free_command(session->large_obj_cmd);
905 session->large_obj_cmd = NULL;
907 status_s *temp = NULL;
908 errorType = create_new_status_location(session, ERROR_SIZE_MISMATCH, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
909 if (errorType != SA_INTERNAL_OK) {
910 _DEBUG_ERROR("failed in create_new_status_location");
913 session->status = g_list_append(session->status, temp);
916 /* it's a new data object or command send 223
917 create alert command */
918 command_s *pAlertCommand = NULL;
919 errorType = create_alert_command(session, ALERT_NO_END_OF_DATA, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
920 if (errorType != SA_INTERNAL_OK) {
921 _DEBUG_ERROR("failed in create_alert_command");
924 session->alert_command = g_list_append(session->alert_command, pAlertCommand);
928 if (changeType == CHANGE_ADD) {
929 int datastore_id = 0;
930 if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD) == 0 || strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD_30) == 0)
931 datastore_id = TYPE_CONTACT;
932 else if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCAL) == 0)
933 datastore_id = TYPE_CALENDAR;
934 else if (strcmp(changedItem->content_type, ELEMENT_TEXT_PLAIN) == 0)
935 datastore_id = TYPE_MEMO;
937 luid = luid_str_list[(*index)++];
939 _DEBUG_ERROR("luid is null");
940 errorType = SA_INTERNAL_ERROR;
944 _DEBUG_TRACE("index = %d", *index);
945 _DEBUG_TRACE("luid = %s", luid);
947 errorType = __add_mapping(session, get_location_loc_uri(changedItem->source), luid, datastore_id);
948 if (errorType != SA_INTERNAL_OK) {
949 _DEBUG_ERROR("failed in __add_mapping");
953 luid = get_location_loc_uri(changedItem->target);
955 _DEBUG_ERROR("luid is null");
956 errorType = SA_INTERNAL_ERROR;
961 changed = create_changed_item(changeType, luid);
962 if (changed == NULL) {
963 _DEBUG_ERROR("changed is null");
964 errorType = SA_INTERNAL_NO_MEMORY;
968 if (changeType != CHANGE_DELETE) {
969 set_changed_item_content_type(changed, changedItem->content_type);
970 set_changed_item_data(changed, changedItem->private.data);
973 status_s *temp = NULL;
974 errorType = create_new_status_location(session, ERROR_UNKNOWN, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
975 if (errorType != SA_INTERNAL_OK) {
976 _DEBUG_ERROR("failed in create_new_status_location");
979 session->temp_status = g_list_append(session->temp_status, temp);
981 (*changed_datastore)->change_item = g_list_append((*changed_datastore)->change_item, changed);
989 free_changed_item(changed);
995 static void __free_pending_status(command_status_s * command_status)
999 retm_if(command_status == NULL, "pendingStatus is NULL");
1001 free(command_status);
1002 command_status = NULL;
1008 static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id)
1012 sa_error_type_e errorType = SA_INTERNAL_OK;
1013 sync_agent_da_return_e da_err = SYNC_AGENT_DA_ERRORS;
1015 sync_agent_da_mapping_s *mapping = NULL;
1016 da_err = sync_agent_create_mapping(&mapping);
1017 if (da_err != SYNC_AGENT_DA_SUCCESS) {
1018 _DEBUG_ERROR("failed in sync_agent_create_mapping !!");
1022 mapping->account_id = session->account_id;
1023 mapping->data_store_id = datastore_id;
1024 mapping->luid = strdup(luid);
1025 mapping->guid = strdup(guid);
1026 mapping->access_name = strdup("SA");
1028 _DEBUG_VERBOSE("account_id = %d", mapping->account_id);
1029 _DEBUG_VERBOSE("data_store_id = %d", mapping->data_store_id);
1030 _DEBUG_VERBOSE("luid = %s", mapping->luid);
1031 _DEBUG_VERBOSE("guid = %s", mapping->guid);
1032 _DEBUG_VERBOSE("access_name = %s", mapping->access_name);
1034 da_err = sync_agent_add_mapping(mapping);
1035 if (da_err != SYNC_AGENT_DA_SUCCESS) {
1036 _DEBUG_ERROR("failed in sync_agent_add_mapping = %d", da_err);
1037 sync_agent_free_mapping(mapping);
1038 errorType = SA_INTERNAL_DA_ERROR;
1042 sync_agent_free_mapping(mapping);
1050 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)
1054 sa_error_type_e errorType = SA_INTERNAL_OK;
1056 *session = (session_s *) calloc(1, sizeof(session_s));
1057 if (*session == NULL) {
1058 errorType = SA_INTERNAL_NO_MEMORY;
1062 if (sess_id != NULL)
1063 (*session)->session_id = strdup(sess_id);
1065 if (source_location != NULL)
1066 (*session)->source = source_location;
1068 if (target_location != NULL)
1069 (*session)->target = target_location;
1071 (*session)->protocol_type = protocol_type;
1072 (*session)->protocol_version = protocol_version;
1073 (*session)->account_id = account_id;
1075 (*session)->msg_id = 0;
1076 (*session)->cmd_id = 1;
1078 (*session)->source_max_msg_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_MSG_SIZE;
1079 (*session)->source_max_obj_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_OBJ_SIZE;
1081 (*session)->target_max_msg_size = 0;
1082 (*session)->target_max_obj_size = 0;
1084 (*session)->naci_session_id = 0;
1085 (*session)->has_opend = 0;
1093 void free_session(session_s * session)
1097 retm_if(session == NULL, "session is NULL");
1099 if (session->session_id != NULL) {
1100 free(session->session_id);
1101 session->session_id = NULL;
1104 if (session->jsession_id != NULL) {
1105 free(session->jsession_id);
1106 session->jsession_id = NULL;
1109 _DEBUG_INFO("session->status");
1110 free_statuses(session->status);
1111 session->status = NULL;
1113 _DEBUG_INFO("session->tempStatus");
1114 free_statuses(session->temp_status);
1115 session->temp_status = NULL;
1117 _DEBUG_INFO("session->suspendStatus");
1118 free_statuses(session->suspend_status);
1119 session->suspend_status = NULL;
1121 if (session->target != NULL) {
1122 free_location(session->target);
1123 session->target = NULL;
1126 if (session->source != NULL) {
1127 free_location(session->source);
1128 session->source = NULL;
1131 if (session->org_target != NULL) {
1132 free_location(session->org_target);
1133 session->org_target = NULL;
1136 if (session->cred != NULL) {
1137 free_cred(session->cred);
1138 session->cred = NULL;
1141 if (session->chal != NULL) {
1142 free_chal(session->chal);
1143 session->chal = NULL;
1146 if (session->devinf != NULL) {
1147 free_devinf(session->devinf);
1148 session->devinf = NULL;
1151 if (session->remote_devinf != NULL) {
1152 free_devinf(session->remote_devinf);
1153 session->remote_devinf = NULL;
1156 if (session->large_obj_cmd != NULL) {
1157 free_command(session->large_obj_cmd);
1158 session->large_obj_cmd = NULL;
1161 free_commands(session->map_command);
1162 session->map_command = NULL;
1164 free_commands(session->alert_command);
1165 session->alert_command = NULL;
1167 free_commands(session->results_command);
1168 session->results_command = NULL;
1170 if (session->large_obj != NULL)
1171 free(session->large_obj);
1173 if (session != NULL)
1180 sa_error_type_e create_command_status(unsigned int msg_id, unsigned int cmd_id, command_status_s ** command_status)
1184 sa_error_type_e errorType = SA_INTERNAL_OK;
1186 *command_status = (command_status_s *) calloc(1, sizeof(command_status_s));
1187 if (*command_status == NULL) {
1188 errorType = SA_INTERNAL_NO_MEMORY;
1192 (*command_status)->msg_id = msg_id;
1193 (*command_status)->cmd_id = cmd_id;
1201 void set_session_cred(session_s * session, cred_s * cred)
1205 sa_error_type_e errorType = SA_INTERNAL_OK;
1207 if (session == NULL) {
1208 errorType = SA_INTERNAL_NOT_DEFINED;
1213 errorType = SA_INTERNAL_NOT_DEFINED;
1217 session->cred = cred;
1226 void set_session_devinf(session_s * session, devinf_s * devinf)
1230 sa_error_type_e errorType = SA_INTERNAL_OK;
1232 if (session == NULL) {
1233 errorType = SA_INTERNAL_NOT_DEFINED;
1237 if (devinf == NULL) {
1238 errorType = SA_INTERNAL_NOT_DEFINED;
1242 session->devinf = devinf;
1251 sa_error_type_e receive_header(session_s * session, sync_hdr_s * header)
1255 sa_error_type_e errorType = SA_INTERNAL_OK;
1256 location_s *pLocation = NULL;
1258 if (session == NULL) {
1259 _DEBUG_ERROR("session is NULL");
1260 errorType = SA_INTERNAL_NOT_DEFINED;
1264 if (header == NULL) {
1265 _DEBUG_ERROR("header is NULL");
1266 errorType = SA_INTERNAL_NOT_DEFINED;
1269 if (session->session_id && header->session_id) {
1270 if (strcmp(session->session_id, header->session_id) != 0) {
1271 errorType = SA_INTERNAL_SERVER_ERROR;
1276 session->last_recieved_msg_id = header->message_id;
1278 if (0 < header->max_msg_size)
1279 session->target_max_msg_size = header->max_msg_size;
1281 session->target_max_msg_size = OMA_DS_HTTP_DEFAULT_SERVER_MAX_MSG_SIZE;
1283 if (0 < header->max_obj_size)
1284 session->target_max_obj_size = header->max_obj_size;
1286 if (header->response_uri != NULL) {
1287 if (session->org_target == NULL) {
1288 session->org_target = session->target;
1289 session->target = NULL;
1292 if (session->target != NULL)
1293 free_location(session->target);
1295 errorType = create_location(header->response_uri, get_location_loc_name(session->org_target), &pLocation);
1296 if (errorType != SA_INTERNAL_OK)
1298 session->target = pLocation;
1300 if (session->target == NULL) {
1301 errorType = SA_INTERNAL_NO_MEMORY;
1306 status_s *temp = NULL;
1307 oma_status_type_e statusData = ERROR_UNKNOWN;
1308 if (header->cred != NULL) {
1309 errorType = compare_cred(header->cred, session->cred);
1310 if (errorType == SA_INTERNAL_OK)
1311 statusData = AUTH_ACCEPTED;
1312 else if (errorType == SA_INTERNAL_AUTHENTICATION_ERROR) {
1313 statusData = ERROR_AUTH_REJECTED;
1317 statusData = NO_ERROR;
1320 errorType = create_status(statusData, session->cmd_id++, session->last_recieved_msg_id, 0, header->source, header->target, COMMAND_TYPE_HEADER, &temp);
1321 if (errorType != SA_INTERNAL_OK)
1324 session->status = g_list_append(session->status, temp);
1332 sa_error_type_e receive_statuses(session_s * session, GList * receive_status, GList ** return_status)
1336 sa_error_type_e errorType = SA_INTERNAL_OK;
1338 GList *statusItem = receive_status;
1339 status_s *status = NULL;
1340 while (statusItem) {
1341 status = statusItem->data;
1343 if (status->cmd_ref == 0) {
1344 /*status of SyncHdr */
1345 assert(status->type == COMMAND_TYPE_HEADER);
1346 assert(status->data);
1347 oma_status_type_e statusType = atoi(status->data);
1349 /* TODO off resume flag if status is 400(bad request) */
1350 if (session->pkg_status == SYNCML_SUSPEND) {
1351 if (statusType == ERROR_BAD_REQUEST) {
1352 errorType = SA_INTERNAL_SUSPEND_FAIL;
1357 if (statusType == AUTH_ACCEPTED) {
1359 when auth type is AUTH_TYPE_BASIC does not need to send cred in syncHdr in same session
1360 when auth type is AUTH_TYPE_MD5 the next nonce in Chal MUST used for the digest when the next sync session is started. */
1361 if (session->cred->type == AUTH_TYPE_MD5) {
1362 chal_s *chal = status->chal;
1364 /*chal in status have to be stored in config_tbl because it have to be used next sync session */
1365 _DEBUG_INFO("format type :%d", chal->format);
1368 sync_agent_da_config_s config;
1369 config.config_id = session->account_id;
1371 if (chal->format == FORMAT_TYPE_BASE64)
1372 value = chal->nonce_b64;
1374 value = g_base64_encode((unsigned char *)chal->nonce_plain, chal->nonce_length);
1376 bool result = set_config_str(session->account_id, DEFINE_CONFIG_KEY_PROFILE_NEXT_NONCE, value, "string", "SA");
1377 if (result == false) {
1378 errorType = SA_INTERNAL_ERROR;
1379 _DEBUG_ERROR("failed in set_Config");
1383 } else if (session->cred->type == AUTH_TYPE_BASIC) {
1384 /*do not need cred anymore
1385 but we just send it again */
1387 } else if (statusType == NO_ERROR) {
1389 when auth type is AUTH_TYPE_BASIC sam credentials must be sent within the next request
1390 when auth type is AUTH_TYPE_MD5 The next nonce in Chal MUST used when the next request is sent */
1391 if (session->cred->type == AUTH_TYPE_MD5) {
1392 /*if auth type is AUTH_TYPE_MD5 */
1393 if (status->chal != NULL) {
1394 /*if there is a chal in status duplicate to session
1395 chal have to used when next request is sent */
1396 if (session->chal != NULL) {
1397 free_chal(session->chal);
1398 session->chal = NULL;
1400 session->chal = status->chal;
1401 status->chal = NULL;
1404 } else if (statusType == ERROR_AUTH_REQUIRED || statusType == ERROR_AUTH_REJECTED) {
1405 if (status->chal != NULL) {
1406 if (session->chal != NULL) {
1407 free_chal(session->chal);
1408 session->chal = NULL;
1410 session->chal = status->chal;
1411 status->chal = NULL;
1413 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
1415 } else if (statusType == ERROR_SERVER_FAILURE) {
1416 errorType = SA_INTERNAL_SERVER_FAILURE;
1418 } else if (statusType == IN_PROGRESS) {
1420 errorType = SA_INTERNAL_BUSY_SIGNALING;
1424 /*status except status of SyncHdr */
1425 if (status->type == COMMAND_TYPE_ALERT) {
1426 errorType = _receive_alert_status(session, status);
1427 } else if (status->type == COMMAND_TYPE_PUT) {
1428 errorType = _receive_put_status(session, status);
1429 } else if (status->type == COMMAND_TYPE_GET) {
1430 errorType = _receive_get_status(session, status);
1431 } else if (status->type == COMMAND_TYPE_RESULTS) {
1432 errorType = _receive_results_status(session, status);
1433 } else if (status->type == COMMAND_TYPE_SYNC_START) {
1434 errorType = _receive_sync_status(session, status);
1435 } else if (status->type == COMMAND_TYPE_MAP) {
1436 errorType = _receive_map_status(session, status);
1437 } else if (status->type == COMMAND_TYPE_ADD || status->type == COMMAND_TYPE_REPLACE || status->type == COMMAND_TYPE_DELETE) {
1438 errorType = _receive_changes_status(session, status, return_status);
1441 if (errorType != SA_INTERNAL_OK)
1444 statusItem = g_list_next(statusItem);
1453 sa_error_type_e receive_commands(session_s * session, GList * receive_command, bool auto_config, GList ** return_datastore)
1457 sa_error_type_e errorType = SA_INTERNAL_OK;
1458 int item_luid_count = 0;
1461 char **luid_str_list = NULL;
1462 changed_datastore_s *changedDatastore = NULL;
1465 command_s *command = NULL;
1466 for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) {
1467 command = iter->data;
1469 if (command->type == COMMAND_TYPE_ADD)
1470 item_luid_count += g_list_length(command->private.change.items);
1473 _DEBUG_INFO("item_luid_count = %d", item_luid_count);
1475 if (item_luid_count > 0) {
1476 luid_str_list = sync_agent_generate_item_luid(1, item_luid_count);
1477 if (luid_str_list == NULL) {
1478 _DEBUG_ERROR("failed in sync_agent_generate_item_luid");
1479 errorType = SA_INTERNAL_ERROR;
1484 for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) {
1485 command = iter->data;
1487 if (auto_config != true || (auto_config == true && command->type == COMMAND_TYPE_RESULTS)) {
1488 switch (command->type) {
1489 case COMMAND_TYPE_UNKNOWN:
1490 case COMMAND_TYPE_HEADER:
1491 case COMMAND_TYPE_MAP:
1492 /*never receive theses commands */
1494 case COMMAND_TYPE_ALERT:
1495 errorType = _receive_alert_command(session, command, return_datastore);
1497 case COMMAND_TYPE_PUT:
1498 errorType = _receive_put_command(session, command);
1500 case COMMAND_TYPE_GET:
1501 errorType = _receive_get_command(session, command);
1503 case COMMAND_TYPE_RESULTS:
1504 errorType = _receive_results_command(session, command);
1506 case COMMAND_TYPE_SYNC_START:
1507 errorType = _receive_sync_command(session, command, &changedDatastore);
1509 case COMMAND_TYPE_SYNC_END:
1511 if (changedDatastore != NULL) {
1512 if (changedDatastore->has_number_of_changes || g_list_length(changedDatastore->change_item) > 0) {
1513 *return_datastore = g_list_append(*return_datastore, changedDatastore);
1514 changedDatastore = NULL;
1516 if (changedDatastore != NULL) {
1517 free_changed_datastore(changedDatastore);
1518 changedDatastore = NULL;
1524 case COMMAND_TYPE_ADD:
1525 case COMMAND_TYPE_REPLACE:
1526 case COMMAND_TYPE_DELETE:
1528 if (command->type != COMMAND_TYPE_ADD || luid_str_list != NULL) {
1529 errorType = _receive_changes_command(session, command, luid_str_list, &index, &changedDatastore);
1531 _DEBUG_ERROR("luid_str_list is NULL !!");
1532 errorType = SA_INTERNAL_ERROR;
1533 if (changedDatastore != NULL) {
1534 free_changed_datastore(changedDatastore);
1535 changedDatastore = NULL;
1543 if (errorType != SA_INTERNAL_OK) {
1544 if (changedDatastore != NULL) {
1545 free_changed_datastore(changedDatastore);
1546 changedDatastore = NULL;
1555 if (changedDatastore != NULL)
1556 free_changed_datastore(changedDatastore);
1558 if (luid_str_list != NULL) {
1559 /*free luid_str_list */
1560 for (i = 0; i < item_luid_count; i++)
1561 free(luid_str_list[i]);
1563 free(luid_str_list);
1570 void reset_cmd_id_session(session_s * session)
1574 if (session != NULL)
1575 session->cmd_id = 1;