4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JuHak Park <juhaki.park@samsung.com>,
7 * JuneHyuk Lee <junhyuk7.lee@samsung.com>,
8 * SunBong Ha <sunbong.ha@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
28 * For any sort of issue you concern as to this software,
29 * you may use following point of contact.
30 * All resources contributed on this software
31 * are orinigally written by S-Core Inc., a member of Samsung Group.
33 * SeongWon Shim <seongwon.shim@samsung.com>
39 * @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
43 #include "agent-framework/SyncAgent_Info.h"
45 #include "agent-framework/DACI/DACI_Luid.h"
46 #include "agent-framework/DACI/DACI_Agent_Handler_Manager.h"
47 #include "agent-framework/Utility/fw_log.h"
48 #include "Common/Common_Util.h"
49 #include "ServiceAdapter/SA_Session.h"
50 #include "ServiceAdapter/SA_Session_Internal.h"
51 #include "ServiceAdapter/SA_Elements.h"
52 #include "ServiceAdapter/SA_Elements_Internal.h"
53 #include "ServiceAdapter/SA_Command.h"
54 #include "ServiceAdapter/SA_Command_Internal.h"
55 #include "ServiceAdapter/SA_DevInf.h"
57 #define LOG_TAG "OMA_DS_SA"
59 static SA_ErrorType __receive_alert_status(Session *session, Status *status);
60 static SA_ErrorType __receive_put_status(Session *session, Status *status);
61 static SA_ErrorType __receive_get_status(Session *session, Status *status);
62 static SA_ErrorType __receive_results_status(Session *session, Status *status);
63 static SA_ErrorType __receive_sync_status(Session *session, Status *status);
64 static SA_ErrorType __receive_changes_status(Session *session, Status *status, GList **returnStatus);
65 static SA_ErrorType __receive_map_status(Session *session, Status *status);
67 static SA_ErrorType __receive_alert_command(Session *session, Command *command, GList **returnDatastore);
68 static SA_ErrorType __receive_put_command(Session *session, Command *command);
69 static SA_ErrorType __receive_get_command(Session *session, Command *command);
70 static SA_ErrorType __receive_results_command(Session *session, Command *command);
71 static SA_ErrorType __receive_sync_command(Session *session, Command *command, ChangedDatastore **changedDatastore);
72 static SA_ErrorType __receive_changes_command(Session *session, Command *command,
73 char **luid_str_list, int *index, ChangedDatastore **changedDatastore);
75 static void __free_pending_status(PendingStatus *pendingStatus);
76 static SA_ErrorType __add_mapping(Session *session, char *guid, char *luid, int datastore_id);
79 static SA_ErrorType __receive_alert_status(Session *session, Status *status)
83 SA_ErrorType errorType = SA_INTERNAL_OK;
85 unsigned int code = get_status_code(status);
86 FW_LOGV("code = %d", code);
88 if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
90 407 Authentication required
91 405 command not allowed
92 406 optional feature not supported
94 412 Incomplete command
95 415 unsupported media type or format
96 404 not found ->it have to be considered
97 TODO error handling it's error~!!!!!*/
99 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
100 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
101 else if (code == ERROR_COMMAND_NOT_ALLOWED || code == ERROR_UNSUPPORTED_FEATURE || code == ERROR_GENERIC)
102 errorType = SA_INTERNAL_SERVER_ERROR;
103 else if (code == ERROR_NOT_FOUND) {
104 /*do not need to return errorType when code is ERROR_NOT_FOUND*/
113 static SA_ErrorType __receive_put_status(Session *session, Status *status)
117 SA_ErrorType errorType = SA_INTERNAL_OK;
119 unsigned int code = get_status_code(status);
120 FW_LOGV("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
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_ErrorType __receive_get_status(Session *session, Status *status)
148 SA_ErrorType errorType = SA_INTERNAL_OK;
150 unsigned int code = get_status_code(status);
151 FW_LOGV("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
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_ErrorType __receive_results_status(Session *session, Status *status)
179 SA_ErrorType errorType = SA_INTERNAL_OK;
181 unsigned int code = get_status_code(status);
182 FW_LOGV("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
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_ErrorType __receive_sync_status(Session *session, Status *status)
210 SA_ErrorType errorType = SA_INTERNAL_OK;
212 unsigned int code = get_status_code(status);
213 FW_LOGV("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
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_ErrorType __receive_changes_status(Session *session, Status *status, GList **returnStatus)
242 FW_LOGV("cmdID = %d", status->cmdID);
243 FW_LOGV("msgRef = %d", status->msgRef);
244 FW_LOGV("cmdRef = %d", status->cmdRef);
245 FW_LOGV("type = %d", status->type);
246 FW_LOGV("data = %s", status->data);
248 unsigned int code = get_status_code(status);
249 FW_LOGV("code = %d", code);
251 SA_ErrorType errorType = SA_INTERNAL_OK;
253 if (session->largeObj) {
254 /*LargeObj status it does not need to pass engine*/
255 PendingStatus *largeObj = session->largeObj;
256 if (largeObj->cmdID == status->cmdRef && largeObj->msgID == status->msgRef) {
258 if (code == CHUNK_ACCEPTED) {
259 __free_pending_status(largeObj);
260 session->largeObj = 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->sourceRef) {
273 AppliedStatus *appliedStatus = create_appliedstatus(get_location_locuri(status->sourceRef),
274 convert_change_type_command_type(status->type) , code);
275 if (appliedStatus == NULL) {
276 FW_LOGE("failed in create_appliedstatus");
277 return SA_INTERNAL_NO_MEMORY;
279 *returnStatus = g_list_append(*returnStatus, appliedStatus);
286 static SA_ErrorType __receive_map_status(Session *session, Status *status)
290 SA_ErrorType errorType = SA_INTERNAL_OK;
294 Command *pCommand = NULL;
295 unsigned int code = 0;
296 for (iter = session->mapCommand; iter != NULL; iter = g_list_next(iter)) {
297 pCommand = iter->data;
299 if (pCommand->msgID == status->msgRef && pCommand->cmdID == status->cmdRef) {
300 code = get_status_code(status);
301 FW_LOGV("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 FW_LOGV(" LUID = %s has been removed\n", get_location_locuri(item->source));
309 da_err = DACI_Delete_Mapping_By_Luid(session->accountId, get_location_locuri(item->source));
310 if (da_err != DACI_SUCCESS) {
311 errorType = SA_INTERNAL_DA_ERROR;
312 FW_LOGE("failed in DACI_Delete_Mapping_By_Luid");
316 session->mapCommand = g_list_remove(session->mapCommand , pCommand);
317 free_command(pCommand);
319 } else if (code >= 400) {
321 407 authentication required
323 510 data store failure
327 /*map command has failed so delete failed map command from session->mapCpmmand*/
328 GList *itemIter = NULL;
330 for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) {
331 item = itemIter->data;
332 FW_LOGV("LUID = %s has been removed\n", get_location_locuri(item->source));
333 da_err = DACI_Delete_Mapping_By_Luid(session->accountId, get_location_locuri(item->source));
334 if (da_err != DACI_SUCCESS) {
335 errorType = SA_INTERNAL_DA_ERROR;
336 FW_LOGE("failed in DACI_Delete_Mapping_By_Luid");
340 session->mapCommand = g_list_remove(session->mapCommand , pCommand);
341 free_command(pCommand);
344 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
345 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
346 else if (code == ERROR_NOT_FOUND)
347 errorType = SA_INTERNAL_NOT_FOUND;
348 else if (code == ERROR_GENERIC)
349 errorType = SA_INTERNAL_SERVER_ERROR;
351 errorType = SA_INTERNAL_ERROR;
360 static SA_ErrorType __receive_alert_command(Session *session, Command *command, GList **returnDatastore)
364 SA_ErrorType errorType = SA_INTERNAL_OK;
366 if (!command->source) {
367 errorType = SA_INTERNAL_NOT_DEFINED;
371 if (!command->target) {
372 errorType = SA_INTERNAL_NOT_DEFINED;
376 407 Authentication required
377 405 command not allowed
378 406 optional feature not supported
380 412 Incomplete command
381 415 unsupported media type or format*/
384 if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) == 0 ||
385 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) == 0 ||
386 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) == 0 ||
387 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) == 0) {
389 DatastoreInfo *datastore = create_datastoreinfo(get_location_locuri(command->target), get_location_locuri(command->source));
390 if (datastore == NULL) {
391 errorType = SA_INTERNAL_NO_MEMORY;
394 set_datastoreInfo_synctype(datastore, command->private.alert.type);
395 set_datastoreinfo_lastanchor(datastore, command->private.alert.anchor->lastAnchor);
396 set_datastoreinfo_nextanchor(datastore, command->private.alert.anchor->nextAnchor);
397 set_datastoreinfo_maxobjsize(datastore, command->private.alert.maxObjSize);
399 *returnDatastore = g_list_append(*returnDatastore, datastore);
401 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp);
402 if (errorType != SA_INTERNAL_OK)
405 temp->item = create_item();
407 errorType = SA_INTERNAL_NO_MEMORY;
410 set_item_anchor(temp->item, command->private.alert.anchor);
411 session->status = g_list_append(session->status, temp);
413 } else if (strcmp(get_location_locuri(command->target), get_location_locuri(session->source)) == 0 &&
414 strcmp(get_location_locuri(command->source), get_location_locuri(session->target)) == 0) {
416 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT , &temp);
417 if (errorType != SA_INTERNAL_OK)
420 session->status = g_list_append(session->status, temp);
422 goto not_found_error;
429 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_ALERT , &temp);
430 if (errorType != SA_INTERNAL_OK)
433 session->status = g_list_append(session->status, temp);
434 return SA_INTERNAL_NOT_FOUND;
437 FW_LOGE("error: %d", errorType);
441 static SA_ErrorType __receive_put_command(Session *session, Command *command)
445 SA_ErrorType errorType = SA_INTERNAL_OK;
448 407 authentication required
450 413 request entity too large
451 416 requested size too big
452 415 unspported media type or format
458 if (strcmp(command->private.access.type , ELEMENT_DEVINF_XML) == 0 ||
459 strcmp(command->private.access.type , ELEMENT_DEVINF_WBXML) == 0) {
461 if (command->private.access.item) {
462 session->remoteDevInf = command->private.access.item->private.devInf;
464 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_PUT, &temp);
465 if (errorType != SA_INTERNAL_OK)
468 goto not_found_error;
472 session->status = g_list_append(session->status, temp);
479 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_PUT , &temp);
480 if (errorType != SA_INTERNAL_OK)
483 session->status = g_list_append(session->status, temp);
484 return SA_INTERNAL_NOT_FOUND;
487 FW_LOGE("error: %d", errorType);
491 static SA_ErrorType __receive_get_command(Session *session, Command *command)
495 SA_ErrorType errorType = SA_INTERNAL_OK;
497 Command *pCommand = NULL;
498 Location *pLocation = NULL;
500 if (strcmp(command->private.access.type , ELEMENT_DEVINF_XML) == 0 ||
501 strcmp(command->private.access.type , ELEMENT_DEVINF_WBXML) == 0) {
503 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_GET, &temp);
504 if (errorType != SA_INTERNAL_OK)
507 session->status = g_list_append(session->status, temp);
509 char *sourceDevInf = NULL;
510 if (session->protocolVersion == VERSION_10)
511 sourceDevInf = ELEMENT_DEVINF_10;
512 else if (session->protocolVersion == VERSION_11)
513 sourceDevInf = ELEMENT_DEVINF_11;
514 else if (session->protocolVersion == VERSION_12)
515 sourceDevInf = ELEMENT_DEVINF_12;
517 errorType = create_location(sourceDevInf, NULL, &pLocation);
518 if (errorType != SA_INTERNAL_OK)
521 errorType = create_results_command(session, pLocation, ELEMENT_DEVINF_XML, session->devInf, &pCommand);
522 if (errorType != SA_INTERNAL_OK)
525 set_results_command_msgref(pCommand, command->msgID);
526 set_results_command_cmdref(pCommand, command->cmdID);
527 set_results_command_targetref(pCommand, command->private.access.item->target);
529 session->resultsCommand = g_list_append(session->resultsCommand, pCommand);
531 goto not_found_error;
539 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_GET , &temp);
540 if (errorType != SA_INTERNAL_OK)
543 session->status = g_list_append(session->status, temp);
544 return SA_INTERNAL_NOT_FOUND;
547 FW_LOGE("error: %d", errorType);
551 static SA_ErrorType __receive_results_command(Session *session, Command *command)
555 SA_ErrorType errorType = SA_INTERNAL_OK;
559 if (strcmp(command->private.results.type , ELEMENT_DEVINF_XML) == 0 ||
560 strcmp(command->private.results.type , ELEMENT_DEVINF_WBXML) == 0) {
562 if (command->private.results.item) {
563 session->remoteDevInf = command->private.results.item->private.devInf;
565 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_RESULTS, &temp);
566 if (errorType != SA_INTERNAL_OK)
569 session->status = g_list_append(session->status, temp);
572 goto not_found_error;
579 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_RESULTS , &temp);
580 if (errorType != SA_INTERNAL_OK)
583 session->status = g_list_append(session->status, temp);
584 return SA_INTERNAL_NOT_FOUND;
587 FW_LOGE("error: %d", errorType);
591 static SA_ErrorType __receive_sync_command(Session *session, Command *command, ChangedDatastore **changedDatastore)
595 SA_ErrorType errorType = SA_INTERNAL_OK;
597 if (!command->source) {
598 errorType = SA_INTERNAL_NOT_DEFINED;
602 if (!command->target) {
603 errorType = SA_INTERNAL_NOT_DEFINED;
608 need to check that if target has not exist in client
609 it's a error(return status)
610 and return Datastore index
613 407 authentication required
616 405 command not allowed
620 TODO compare with alert command(?)*/
622 if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source) != 0 &&
623 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source) != 0 &&
624 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source) != 0 &&
625 strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source) != 0)
626 goto not_found_error;
629 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START , &temp);
630 if (errorType != SA_INTERNAL_OK)
633 session->status = g_list_append(session->status, temp);
635 /*for return to engine*/
636 ChangedDatastore *pChangedDatastore = create_changeddatastore(get_location_locuri(command->source),
637 get_location_locuri(command->target), command->private.sync.hasNumChanged,
638 command->private.sync.hasNumChanged ? command->private.sync.numChanged : 0);
639 if (pChangedDatastore == NULL) {
640 errorType = SA_INTERNAL_NO_MEMORY;
643 *changedDatastore = pChangedDatastore;
650 errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_SYNC_START , &temp);
651 if (errorType != SA_INTERNAL_OK)
654 session->status = g_list_append(session->status, temp);
655 return SA_INTERNAL_NOT_FOUND;
658 FW_LOGE("error: %d", errorType);
662 static SA_ErrorType __receive_changes_command(Session *session, Command *command, char **luid_str_list,
663 int *index, ChangedDatastore **changedDatastore)
665 FW_LOGV("start command type : %d\n", command->private.change.type);
667 SA_ErrorType errorType = SA_INTERNAL_OK;
670 ChangedItem *changed = NULL;
672 ChangeType changeType = command->private.change.type;
673 for (iter = command->private.change.items; iter != NULL; iter = g_list_next(iter)) {
674 Item *changedItem = (iter->data);
676 if (changedItem->moreData) {
677 if (session->pLargeObjCmd) {
678 /*if there is a chunked item before...
679 it's not firest chunked item.... data have to be merged(check source location)
680 there will be another chunked item*/
682 Command *pLargeObjcmd = session->pLargeObjCmd;
683 if (pLargeObjcmd->private.change.items) {
684 /*moreData item must be last item in item list*/
685 GList *largeObjItems = session->pLargeObjCmd->private.change.items;
686 GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
687 Item *item = largeObjLastItem->data;
688 AlertType alertType = ALERT_UNKNOWN;
689 if (strcmp(get_location_locuri(item->source), get_location_locuri(changedItem->source)) == 0) {
690 /*two item's source are equal
691 append incomming string*/
692 if (item->private.data) {
693 char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
694 free(item->private.data);
695 item->private.data = tmp;
697 item->private.data = strdup(changedItem->private.data);
700 errorType = create_new_status_location(session, CHUNK_ACCEPTED, command, changedItem->source,
701 changedItem->target, convert_command_type_change_type(changeType), &temp);
702 if (errorType != SA_INTERNAL_OK) {
703 FW_LOGE("failed in create_new_status_location");
706 session->status = g_list_append(session->status, temp);
707 alertType = ALERT_NEXT_MESSAGE;
709 /* it's a new data object or command but this command also have a moreData*/
710 alertType = ALERT_NO_END_OF_DATA;
712 /* create alert command*/
713 Command *pAlertCommand = NULL;
714 errorType = create_alert_command(session, alertType, dup_location(session->source), dup_location(session->target),
715 NULL, NULL, NULL, &pAlertCommand);
716 if (errorType != SA_INTERNAL_OK) {
717 FW_LOGE("failed in create_alert_command");
720 session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
724 just buffered it. does not generate LUID, and does not pass to engine*/
725 OMA_StatusType statusErrorType = ERROR_UNKNOWN;
726 if (changedItem->size == 0) {
728 statusErrorType = ERROR_SIZE_REQUIRED;
730 /* size is specified*/
731 if (changedItem->size > session->sourceMaxObjSize) {
732 /*but it is bigger than client maxObjSize*/
733 statusErrorType = ERROR_REQUESTED_SIZE_TOO_BIG;
735 /*chunked item accepted*/
736 session->pLargeObjCmd = command;
737 increase_command_refcount(command);
739 statusErrorType = CHUNK_ACCEPTED;
741 /* create alert command*/
742 Command *pAlertCommand = NULL;
743 errorType = create_alert_command(session, ALERT_NEXT_MESSAGE,
744 dup_location(session->source), dup_location(session->target),
745 NULL, NULL, NULL, &pAlertCommand);
746 if (errorType != SA_INTERNAL_OK) {
747 FW_LOGE("failed in create_alert_command");
750 session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
754 errorType = create_new_status_location(session, statusErrorType, command, changedItem->source, changedItem->target,
755 convert_command_type_change_type(changeType) , &temp);
756 if (errorType != SA_INTERNAL_OK) {
757 FW_LOGE("failed in create_new_status_location");
760 session->status = g_list_append(session->status, temp);
764 if (session->pLargeObjCmd) {
766 /*if there is a chunked item before...
767 it's not firest chunked item.... data have to be merged(check source location)
768 there will be no more chunked item. this command have to be pass to engine*/
770 Command *pLargeObjcmd = session->pLargeObjCmd;
771 if (pLargeObjcmd->private.change.items) {
772 /*moreData item must be last item in item list*/
773 GList *largeObjItems = session->pLargeObjCmd->private.change.items;
774 GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
775 Item *item = largeObjLastItem->data;
777 if (strcmp(get_location_locuri(item->source), get_location_locuri(changedItem->source)) == 0) {
778 /* two item's source are equal
779 append incomming string*/
780 if (item->private.data) {
781 char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
782 free(item->private.data);
783 item->private.data = tmp;
785 item->private.data = strdup(changedItem->private.data);
787 if (item->private.data == NULL) {
788 FW_LOGE("item->private.data is null !!");
793 if (item->size == strlen(item->private.data)) {
794 /*delete pointing from pLargeObjCmd*/
795 largeObjLastItem->data = NULL;
796 FW_LOGV("delete pointing from pLargeObjCmd");
797 /*free Item from incomming Cmd*/
798 free_item(changedItem);
799 FW_LOGV("free Item from incomming Cmd");
800 /*pointing to Merged item in incomming Cmd*/
803 FW_LOGV("pointing to Merged item in incomming Cmd");
805 free_command(session->pLargeObjCmd);
806 session->pLargeObjCmd = NULL;
809 errorType = create_new_status_location(session, ERROR_SIZE_MISMATCH, command,
810 changedItem->source, changedItem->target,
811 convert_command_type_change_type(changeType), &temp);
812 if (errorType != SA_INTERNAL_OK) {
813 FW_LOGE("failed in create_new_status_location");
816 session->status = g_list_append(session->status, temp);
819 /* it's a new data object or command send 223
820 create alert command*/
821 Command *pAlertCommand = NULL;
822 errorType = create_alert_command(session, ALERT_NO_END_OF_DATA,
823 dup_location(session->source), dup_location(session->target),
824 NULL, NULL, NULL, &pAlertCommand);
825 if (errorType != SA_INTERNAL_OK) {
826 FW_LOGE("failed in create_alert_command");
829 session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
833 if (changeType == CHANGE_ADD) {
834 int datastore_id = 0;
835 if (strcmp(changedItem->contenttype, ELEMENT_TEXT_VCARD) == 0 ||
836 strcmp(changedItem->contenttype, ELEMENT_TEXT_VCARD_30) == 0)
837 datastore_id = TYPE_CONTACT;
838 else if (strcmp(changedItem->contenttype, ELEMENT_TEXT_VCAL) == 0)
839 datastore_id = TYPE_CALENDAR;
840 else if (strcmp(changedItem->contenttype, ELEMENT_TEXT_PLAIN) == 0)
841 datastore_id = TYPE_MEMO;
843 luid = luid_str_list[(*index)++];
845 FW_LOGE("luid is null");
846 errorType = SA_INTERNAL_ERROR;
850 FW_LOGV("index = %d", *index);
851 FW_LOGV("luid = %s", luid);
853 errorType = __add_mapping(session, get_location_locuri(changedItem->source), luid, datastore_id);
854 if (errorType != SA_INTERNAL_OK) {
855 FW_LOGE("failed in __add_mapping");
859 luid = get_location_locuri(changedItem->target);
861 FW_LOGE("luid is null");
862 errorType = SA_INTERNAL_ERROR;
867 changed = create_changeditem(changeType, luid);
868 if (changed == NULL) {
869 FW_LOGE("changed is null");
870 errorType = SA_INTERNAL_NO_MEMORY;
874 if (changeType != CHANGE_DELETE) {
875 set_changeditem_contenttype(changed, changedItem->contenttype);
876 set_changeditem_data(changed, changedItem->private.data);
880 errorType = create_new_status_location(session, ERROR_UNKNOWN, command,
881 changedItem->source, changedItem->target,
882 convert_command_type_change_type(changeType), &temp);
883 if (errorType != SA_INTERNAL_OK) {
884 FW_LOGE("failed in create_new_status_location");
887 session->tempStatus = g_list_append(session->tempStatus, temp);
889 (*changedDatastore)->changeItem = g_list_append((*changedDatastore)->changeItem, changed);
897 FW_LOGE("error: %d", errorType);
901 static void __free_pending_status(PendingStatus *pendingStatus)
909 pendingStatus = NULL;
916 static SA_ErrorType __add_mapping(Session *session, char *guid, char *luid, int datastore_id)
920 SA_ErrorType errorType = SA_INTERNAL_OK;
922 daci_mapping mapping;
923 mapping.account_id = session->accountId;
924 mapping.data_store_id = datastore_id;
927 mapping.access_name = "SA";
929 DACI_RETURN da_err = DACI_Add_Mapping(&mapping);
930 if (da_err != DACI_SUCCESS) {
931 FW_LOGE("failed in DACI_Add_Mapping = %d", da_err);
932 errorType = SA_INTERNAL_DA_ERROR;
941 FW_LOGE("error: %d", errorType);
945 SA_ErrorType create_session(ProtocolVersion protocolVersion, ProtocolType protocolType, int accountId,
946 char *sessID, char *source, char *target, Session** pSession)
950 SA_ErrorType errorType = SA_INTERNAL_OK;
951 Location *pSourceLocation = NULL;
952 Location *pTargetLocation = NULL;
954 *pSession = (Session *) calloc(1, sizeof(Session));
956 if ((*pSession) == NULL) {
957 errorType = SA_INTERNAL_NO_MEMORY;
961 errorType = create_location(source, NULL, &pSourceLocation);
962 if (errorType != SA_INTERNAL_OK)
965 errorType = create_location(target, NULL, &pTargetLocation);
966 if (errorType != SA_INTERNAL_OK)
969 (*pSession)->protocolType = protocolType;
970 (*pSession)->protocolVersion = protocolVersion;
971 (*pSession)->accountId = accountId;
972 (*pSession)->sessionID = strdup(sessID);
973 (*pSession)->msgID = 0;
974 (*pSession)->source = pSourceLocation;
975 (*pSession)->target = pTargetLocation;
976 (*pSession)->cmdID = 1;
978 (*pSession)->sourceMaxMsgSize = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_MSG_SIZE;
979 (*pSession)->sourceMaxObjSize = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_OBJ_SIZE;
981 (*pSession)->targetMaxMsgSize = 0;
982 (*pSession)->targetMaxObjSize = 0;
984 (*pSession)->NACI_sessionID = 0;
985 (*pSession)->hasOpend = 0;
992 FW_LOGE("error: %d", errorType);
996 void free_session(Session *session)
1003 if (session->sessionID) {
1004 free(session->sessionID);
1005 session->sessionID = NULL;
1008 free_statuses(session->status);
1009 session->status = NULL;
1011 free_statuses(session->tempStatus);
1012 session->status = NULL;
1014 if (session->target) {
1015 free_location(session->target);
1016 session->target = NULL;
1019 if (session->source) {
1020 free_location(session->source);
1021 session->source = NULL;
1024 if (session->orgTarget) {
1025 free_location(session->orgTarget);
1026 session->orgTarget = NULL;
1029 if (session->cred) {
1030 free_cred(session->cred);
1031 session->cred = NULL;
1034 if (session->chal) {
1035 free_chal(session->chal);
1036 session->chal = NULL;
1039 if (session->devInf) {
1040 free_devinf(session->devInf);
1041 session->devInf = NULL;
1044 if (session->remoteDevInf) {
1045 free_devinf(session->remoteDevInf);
1046 session->remoteDevInf = NULL;
1049 if (session->pLargeObjCmd) {
1050 free_command(session->pLargeObjCmd);
1051 session->pLargeObjCmd = NULL;
1054 free_commands(session->resultsCommand);
1055 session->resultsCommand = NULL;
1057 free_commands(session->mapCommand);
1058 session->mapCommand = NULL;
1069 SA_ErrorType create_pending_status(unsigned int msgID, unsigned int cmdID, PendingStatus **pPendingStatus)
1073 SA_ErrorType errorType = SA_INTERNAL_OK;
1075 *pPendingStatus = (PendingStatus *)calloc(1, sizeof(PendingStatus));
1077 if (*pPendingStatus == NULL) {
1078 errorType = SA_INTERNAL_NO_MEMORY;
1082 (*pPendingStatus)->msgID = msgID;
1083 (*pPendingStatus)->cmdID = cmdID;
1090 FW_LOGE("error: %d", errorType);
1094 void set_session_cred(Session *session, Cred *cred)
1098 SA_ErrorType errorType = SA_INTERNAL_OK;
1101 errorType = SA_INTERNAL_NOT_DEFINED;
1106 errorType = SA_INTERNAL_NOT_DEFINED;
1110 session->cred = cred;
1116 FW_LOGE("error: %d", errorType);
1121 void set_session_devinf(Session *session, DevInf *devInf)
1125 SA_ErrorType errorType = SA_INTERNAL_OK;
1128 errorType = SA_INTERNAL_NOT_DEFINED;
1133 errorType = SA_INTERNAL_NOT_DEFINED;
1137 session->devInf = devInf;
1143 FW_LOGE("error: %d", errorType);
1148 SA_ErrorType receive_header(Session *session, SyncHdr *header)
1152 SA_ErrorType errorType = SA_INTERNAL_OK;
1153 Location *pLocation = NULL;
1156 errorType = SA_INTERNAL_NOT_DEFINED;
1161 errorType = SA_INTERNAL_NOT_DEFINED;
1164 if (session->sessionID && header->sessionID) {
1165 if (strcmp(session->sessionID, header->sessionID) != 0) {
1166 errorType = SA_INTERNAL_SERVER_ERROR;
1171 session->lastRecievedMsgID = header->messageID;
1173 if (0 < header->maxmsgsize)
1174 session->targetMaxMsgSize = header->maxmsgsize;
1176 session->targetMaxMsgSize = OMA_DS_HTTP_DEFAULT_SERVER_MAX_MSG_SIZE;
1178 if (0 < header->maxobjsize)
1179 session->targetMaxObjSize = header->maxobjsize;
1181 if (header->responseURI) {
1182 if (!session->orgTarget) {
1183 session->orgTarget = session->target;
1184 session->target = NULL;
1187 if (session->target)
1188 free_location(session->target);
1190 errorType = create_location(header->responseURI, get_location_locname(session->orgTarget), &pLocation);
1191 if (errorType != SA_INTERNAL_OK)
1193 session->target = pLocation;
1195 if (!session->target) {
1196 errorType = SA_INTERNAL_NO_MEMORY;
1201 Status *temp = NULL;
1202 OMA_StatusType statusData = ERROR_UNKNOWN;
1204 errorType = compare_cred(header->cred, session->cred);
1205 if (errorType == SA_INTERNAL_OK)
1206 statusData = AUTH_ACCEPTED;
1207 else if (errorType == SA_INTERNAL_AUTHENTICATION_ERROR) {
1208 statusData = ERROR_AUTH_REJECTED;
1212 statusData = NO_ERROR;
1215 errorType = create_status(statusData, session->cmdID++, session->lastRecievedMsgID, 0,
1216 header->source, header->target, COMMAND_TYPE_HEADER, &temp);
1217 if (errorType != SA_INTERNAL_OK)
1220 session->status = g_list_append(session->status, temp);
1227 FW_LOGE("error: %d", errorType);
1231 SA_ErrorType receive_statuses(Session *session, GList *receiveStatus, GList **returnStatus)
1235 SA_ErrorType errorType = SA_INTERNAL_OK;
1237 GList *statusItem = receiveStatus;
1238 Status *status = NULL;
1239 while (statusItem) {
1240 status = statusItem->data;
1242 if (status->cmdRef == 0) {
1243 /*status of SyncHdr*/
1244 assert(status->type == COMMAND_TYPE_HEADER);
1245 assert(status->data);
1246 OMA_StatusType statusType = atoi(status->data);
1248 if (statusType == AUTH_ACCEPTED) {
1250 when auth type is AUTH_TYPE_BASIC does not need to send cred in syncHdr in same session
1251 when auth type is AUTH_TYPE_MD5 the next nonce in Chal MUST used for the digest when the next sync session is started.*/
1252 if (session->cred->type == AUTH_TYPE_MD5) {
1253 Chal *chal = status->chal;
1255 /*chal in status have to be stored in config_tbl because it have to be used next sync session*/
1256 FW_LOGV("format type :%d", chal->format);
1260 config.config_id = session->accountId;
1262 if (chal->format == FORMAT_TYPE_BASE64)
1263 value = chal->nonce_b64;
1265 value = g_base64_encode((const unsigned char *)chal->nonce_plain, chal->nonce_length);
1267 bool result = set_config_str(session->accountId, DEFINE_CONFIG_KEY_PROFILE_NEXT_NONCE, value, "string", "SA");
1268 if (result == false) {
1269 errorType = SA_INTERNAL_ERROR;
1270 FW_LOGE("failed in set_Config");
1274 } else if (session->cred->type == AUTH_TYPE_BASIC) {
1275 /*do not need cred anymore
1276 but we just send it again*/
1278 } else if (statusType == NO_ERROR) {
1280 when auth type is AUTH_TYPE_BASIC sam credentials must be sent within the next request
1281 when auth type is AUTH_TYPE_MD5 The next nonce in Chal MUST used when the next request is sent*/
1282 if (session->cred->type == AUTH_TYPE_MD5) {
1283 /*if auth type is AUTH_TYPE_MD5*/
1285 /*if there is a chal in status duplicate to session
1286 chal have to used when next request is sent*/
1287 session->chal = dup_chal(status->chal);
1290 } else if (statusType == ERROR_AUTH_REQUIRED || statusType == ERROR_AUTH_REJECTED) {
1292 session->chal = dup_chal(status->chal);
1293 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
1295 } else if (statusType == ERROR_SERVER_FAILURE) {
1296 errorType = SA_INTERNAL_SERVER_FAILURE;
1298 } else if (statusType == IN_PROGRESS) {
1300 errorType = SA_INTERNAL_BUSY_SIGNALING;
1304 /*status except status of SyncHdr*/
1305 if (status->type == COMMAND_TYPE_ALERT) {
1306 errorType = __receive_alert_status(session, status);
1307 } else if (status->type == COMMAND_TYPE_PUT) {
1308 errorType = __receive_put_status(session, status);
1309 } else if (status->type == COMMAND_TYPE_GET) {
1310 errorType = __receive_get_status(session, status);
1311 } else if (status->type == COMMAND_TYPE_RESULTS) {
1312 errorType = __receive_results_status(session, status);
1313 } else if (status->type == COMMAND_TYPE_SYNC_START) {
1314 errorType = __receive_sync_status(session, status);
1315 } else if (status->type == COMMAND_TYPE_MAP) {
1316 errorType = __receive_map_status(session, status);
1317 } else if (status->type == COMMAND_TYPE_ADD ||
1318 status->type == COMMAND_TYPE_REPLACE ||
1319 status->type == COMMAND_TYPE_DELETE) {
1320 errorType = __receive_changes_status(session, status, returnStatus);
1323 if (errorType != SA_INTERNAL_OK)
1326 statusItem = g_list_next(statusItem);
1334 FW_LOGE(" error, Error Type %d", errorType);
1338 SA_ErrorType receive_commands(Session *session, GList *receiveCommand, bool autoConfig, GList **returnDatastore)
1342 SA_ErrorType errorType = SA_INTERNAL_OK;
1343 int item_luid_count = 0;
1346 char **luid_str_list = NULL;
1349 Command *command = NULL;
1350 for (iter = receiveCommand; iter != NULL; iter = g_list_next(iter)) {
1351 command = iter->data;
1353 if (command->type == COMMAND_TYPE_ADD)
1354 item_luid_count += g_list_length(command->private.change.items);
1357 FW_LOGV("item_luid_count = %d", item_luid_count);
1359 if (item_luid_count > 0) {
1360 luid_str_list = DACI_Generate_Item_Luid(1, item_luid_count);
1361 if (luid_str_list == NULL) {
1362 FW_LOGE("failed in DACI_Generate_Item_Luid");
1363 errorType = SA_INTERNAL_ERROR;
1368 ChangedDatastore *changedDatastore = NULL;
1369 for (iter = receiveCommand; iter != NULL; iter = g_list_next(iter)) {
1370 command = iter->data;
1372 if (autoConfig != true || (autoConfig == true && command->type == COMMAND_TYPE_RESULTS)) {
1373 switch (command->type) {
1374 case COMMAND_TYPE_UNKNOWN:
1375 case COMMAND_TYPE_HEADER:
1376 case COMMAND_TYPE_MAP:
1377 /*never receive theses commands*/
1379 case COMMAND_TYPE_ALERT:
1380 errorType = __receive_alert_command(session, command, returnDatastore);
1382 case COMMAND_TYPE_PUT:
1383 errorType = __receive_put_command(session, command);
1385 case COMMAND_TYPE_GET:
1386 errorType = __receive_get_command(session, command);
1388 case COMMAND_TYPE_RESULTS:
1389 errorType = __receive_results_command(session, command);
1391 case COMMAND_TYPE_SYNC_START:
1392 errorType = __receive_sync_command(session, command, &changedDatastore);
1394 case COMMAND_TYPE_SYNC_END:
1395 if (changedDatastore) {
1396 *returnDatastore = g_list_append(*returnDatastore, changedDatastore);
1397 changedDatastore = NULL;
1400 case COMMAND_TYPE_ADD:
1401 case COMMAND_TYPE_REPLACE:
1402 case COMMAND_TYPE_DELETE:
1403 errorType = __receive_changes_command(session, command, luid_str_list, &index, &changedDatastore);
1407 if (errorType != SA_INTERNAL_OK)
1412 if (luid_str_list != NULL) {
1413 /*free luid_str_list*/
1414 for (i = 0; i < item_luid_count; i++)
1415 free(luid_str_list[i]);
1417 free(luid_str_list);
1426 if (luid_str_list != NULL) {
1427 /*free luid_str_list*/
1428 for (i = 0; i < item_luid_count; i++)
1429 free(luid_str_list[i]);
1431 free(luid_str_list);
1434 FW_LOGE("error: %d", errorType);
1438 void reset_cmdID_session(Session *session)